Skip to main content

GMGN Plugin

[!IMPORTANT] Complete the Base MCP onboarding flow defined in SKILL.md before calling any GMGN endpoint. The user’s wallet address — passed as from_address in every quote call — is fetched lazily when needed.

Overview

GMGN is a trading platform providing token swap routing and on-chain market intelligence for Base mainnet. This plugin calls the GMGN HTTP API via web_request to obtain full unsigned transaction calldata from the quote endpoint, then submits it through send_calls — no server-side key binding or additional MCP server required. Shell requirement: Every request requires a Unix timestamp (±5 s accuracy) and a fresh UUID v4 as auth parameters. These must be generated via shell commands (date +%s and uuidgen) to guarantee correctness. This plugin only runs on CLI harnesses (Claude Code, Codex) where shell access is available. Three capabilities are exposed:
  • Swap quotes — returns complete unsigned calldata (data.tx.to/value/data) and ERC-20 approval transactions (data.tx.approve_txs) ready for send_calls
  • Gas prices — current low/average/high fee tiers for Base
  • Trending tokens — top tokens ranked by swap activity, volume, and holder count
Chain: Base mainnet (chainId 8453)

Auth

All requests require the X-APIKEY header and two query parameters generated via shell:
ParameterDescriptionShell command
timestampCurrent Unix timestamp in seconds (valid window ±5 s)date +%s
client_idFresh UUID v4 per request (replay protection, 7 s window)uuidgen | tr '[:upper:]' '[:lower:]'
Generate before every request:
A public API key is available for all read-only operations:

Surface Routing

CapabilityToolNotes
Generate auth paramsshell (bash)date +%s for timestamp; uuidgen for client_id — required before every request
Swap quoteweb_requestGET /v1/trade/quote — returns unsigned calldata
Gas priceweb_requestGET /v1/trade/gas_price
Trending tokensweb_requestGET /v1/market/rank
Execute swapsend_callsUses calldata from quote response — no signing required
All HTTP calls go to openapi.gmgn.ai (in the allowlist). Shell is required for auth parameter generation.

Endpoints

Base URL: https://openapi.gmgn.ai

1. GET /v1/trade/quote — Swap Quote + Calldata

Returns the full unsigned transaction ready for send_calls. This is the primary endpoint for executing swaps. Query parameters:
ParameterRequiredDescription
chainYesbase
from_addressYesUser’s wallet address
input_tokenYesInput token contract address (0x000...000 for native ETH)
output_tokenYesOutput token contract address
input_amountYesInput amount in base units (USDC: × 1e6, ETH: × 1e18)
slippageYesInteger 0–100 (e.g., 5 = 5%). See Risks & Warnings.
timestampYesAuth: Unix seconds
client_idYesAuth: fresh UUID v4
Example request (swap 0.00001 ETH → token):
Response data fields: Top-level summary fields:
FieldDescription
input_tokenInput token contract address
output_tokenOutput token contract address
input_amountInput amount (base units)
output_amountExpected output amount (base units)
min_output_amountMinimum output after slippage (base units)
slippageSlippage percentage
txFull unsigned transaction object (see below)
data.tx fields (the full unsigned transaction for send_calls):
FieldDescription
tx.toRouter contract address — use as to in send_calls
tx.valueNative ETH to send in wei (string) — use as value in send_calls
tx.dataEncoded calldata — use as data in send_calls
tx.approve_txsApproval transactions to send before the swap (empty for native ETH input)
tx.amount_inInput amount (base units)
tx.amount_outExpected output amount (base units)
tx.amount_min_outMinimum output after slippage (base units)
tx.amount_in_usdInput value in USD
tx.amount_out_usdExpected output value in USD
tx.amount_in_decimalsInput token decimals
tx.amount_out_decimalsOutput token decimals
tx.gas_limitEstimated gas limit (string)
tx.deadlineTransaction deadline (Unix timestamp)
tx.chain_idChain ID (8453 for Base)
Example response:
Convert to human-readable: data.tx.amount_out / 10^data.tx.amount_out_decimals, data.tx.amount_min_out / 10^data.tx.amount_out_decimals.

2. GET /v1/trade/gas_price — Gas Price

Returns current recommended gas price tiers for Base. Query parameters:
ParameterRequiredDescription
chainYesbase
timestampYesAuth: Unix seconds
client_idYesAuth: fresh UUID v4
Key response fields under data:
FieldDescription
low / average / highGas price tiers in wei
low_estimate_time / average_estimate_time / high_estimate_timeEstimated confirmation time (seconds)
suggest_base_feeSuggested EIP-1559 base fee (wei)
average_prio_feeAverage priority fee (wei)
native_token_usd_priceETH price in USD

Returns top trending tokens on Base ranked by swap activity. Query parameters:
ParameterRequiredDefaultDescription
chainYesbase
intervalNo1hTime window: 1m / 5m / 1h / 6h / 24h
limitNo10Number of results (1–100)
order_byNodefaultSort field: default / swaps / volume / marketcap / holder_count / change1h
directionNodescasc / desc
filtersNonot_honeypot,verified,renouncedSafety filters (repeatable): not_honeypot, verified, renounced, has_social, not_wash_trading
timestampYesAuth: Unix seconds
client_idYesAuth: fresh UUID v4
Response: data.rank array with token address, symbol, price (USD), market cap, 1h/24h price change, swap count, volume, holder count, and liquidity.

Orchestration

Swap flow: “Swap 0.00001 ETH for token X on Base”


Submission

Build the send_calls payload from the quote response:
If data.tx.approve_txs is empty (native ETH input), omit the approval call and send only the swap call.
Call send_calls("base", calls), then get_request_status only after the user acts on the approval link.

Example Prompts

Swap 0.00001 ETH for a token on Base
  1. get_wallets → address.
  2. web_request GET /v1/trade/quote with input_token=0x000...000 (native ETH), input_amount=10000000000000, target token as output_token, slippage=5.
  3. Display expected and minimum output, USD values.
  4. Build approval + swap calls from data.tx.approve_txs and data.tx.to/value/data.
  5. send_calls("base", [...approvalCalls, swapCall]).
Swap 100 USDC for ETH on Base
  1. get_wallets → address.
  2. web_request GET /v1/trade/quote with input_token=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (USDC), input_amount=100000000 (100 × 1e6), output_token=0x0000000000000000000000000000000000000000.
  3. USDC requires an ERC-20 approval — include data.tx.approve_txs[0] before the swap call.
  4. send_calls("base", calls).
Show trending tokens on Base
  1. web_request GET /v1/market/rank?chain=base&interval=1h&limit=10&order_by=volume.
  2. Present token list with price, change, and volume.
What’s the price to buy token X with 50 USDC?
  1. get_wallets → address.
  2. web_request GET /v1/trade/quote with USDC as input, target token as output, input_amount=50000000.
  3. Show data.tx.amount_out_usd, effective price (data.tx.amount_in_usd / (data.tx.amount_out / 10^data.tx.amount_out_decimals)), and slippage impact.

Risks & Warnings

Slippage

ToleranceLevelAction
≤ 1%NormalProceed.
> 1% and ≤ 5%ElevatedMention the value and ask the user to confirm.
> 5% and ≤ 20%HighWarn that the trade can fill significantly below quote and is a likely sandwich target. Require explicit confirmation.
> 20%Very highStrongly warn; do not submit without the user re-confirming the exact number.

Low Liquidity

For meme tokens with low liquidity, higher slippage (10–20%) is common. Always warn the user and require explicit confirmation before proceeding. Thin markets increase the risk of severe price impact and sandwich attacks.

Quote Expiry

Quotes expire at data.tx.deadline (Unix timestamp). If the user has not confirmed within ~30 seconds, re-fetch the quote before submitting. Submitting an expired quote will cause the transaction to revert on-chain.

Notes

  • Native ETH address: 0x0000000000000000000000000000000000000000
  • USDC on Base: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
  • WETH on Base: 0x4200000000000000000000000000000000000006
  • Token amounts are in base units. Use data.tx.amount_in_decimals / data.tx.amount_out_decimals from the quote response to convert to human-readable values.
  • data.tx.data is unsigned calldata — pass it directly to send_calls; never sign or modify it.
  • data.tx.approve_txs handles ERC-20 allowances. It is empty when the input is native ETH or when a sufficient allowance already exists.
  • timestamp must be within ±5 seconds of server time. client_id must be a fresh UUID per request.
  • Use chain: "base" (not numeric chain ID) with send_calls.