Skip to main content

KyberSwap Plugin

[!IMPORTANT] Complete the short Base MCP onboarding flow defined in SKILL.md before calling any KyberSwap endpoint. The user’s wallet address is fetched lazily when needed.

Overview

KyberSwap is a DEX aggregator that routes trades across 50+ liquidity sources (Uniswap V2/V3/V4, Curve, Balancer, and others) to find the best execution price across 7 chains. The plugin calls the KyberSwap Aggregator HTTP API to fetch a route quote and build unsigned calldata, then submits the result to Base MCP’s send_calls. Use KyberSwap when the user wants the best rate across all available liquidity — not just a single protocol’s pools.

Surface Routing

CapabilityHarness surface (Claude Code, Cursor)Chat-only surface (Claude.ai, ChatGPT)
GET /routes (quote)Harness HTTP tool — no allowlist neededweb_request — requires aggregator-api.kyberswap.com allowlisted
POST /route/build (calldata)Harness HTTP tool — no allowlist neededweb_request — requires aggregator-api.kyberswap.com allowlisted
Token resolutionHarness HTTP tool — no allowlist neededweb_request — requires token-api.kyberswap.com allowlisted
Submit swapsend_calls — all surfacessend_calls — all surfaces
On chat-only surfaces where the allowlist is not configured: inform the user that the swap cannot proceed and direct them to the KyberSwap web UI at kyberswap.com. Do not improvise a workaround. For the full decision tree, see ../references/custom-plugins.md.

Endpoints

Base URL: https://aggregator-api.kyberswap.com/{chain} Chain slugs: base · ethereum · arbitrum · optimism · polygon · bsc · avalanche

GET /api/v1/routes

Fetches the best route and returns a routeSummary required verbatim in the build step.
ParamRequiredNotes
tokenInToken address. Native token: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
tokenOutToken address
amountInAmount in base units — plain integer string. 1 ETH = 1000000000000000000, 100 USDC = 100000000
torecommendedRecipient wallet address
slippageTolerancerecommendedBasis points (50 = 0.5%). See Risks & Warnings
sourcerecommendedPass base-mcp for attribution
Response shape:
Keep the complete routeSummary object exactly as returned — it is required verbatim in the build step.

POST /api/v1/route/build

Builds encoded swap calldata from a previously fetched route.
Do not modify or truncate routeSummary. Routes expire in ~30 seconds — if this step fails with “return amount is not enough”, re-fetch the route and retry. Response shape:
transactionValue is a decimal wei string (e.g. "0" for ERC-20 input, "10000000000000000" for 0.01 ETH). Hex-encode it before passing as value in send_calls: "0x" + BigInt(transactionValue).toString(16). Non-zero only for native token input.

GET /api/v1/public/tokens (token resolution)

Resolve a token symbol to its contract address when not in the known-addresses table in ## Notes.
Pick the result with exact symbol match and highest marketCap. If no whitelisted match, retry without isWhitelisted. Chain IDs: base=8453, ethereum=1, arbitrum=42161, optimism=10, polygon=137, bsc=56, avalanche=43114

Orchestration

Swap

  1. get_walletswalletAddress.
  2. Resolve token symbols to addresses — use the ## Notes table first, then the token-api endpoint.
  3. Compute amountIn in base units: multiply human amount by 10^decimals (ETH=18, USDC=6, WBTC=8).
  4. Determine slippage: default 50 bps for common pairs, 100 bps for long-tail tokens. Apply thresholds in ## Risks & Warnings before proceeding.
  5. GET /api/v1/routesrouteSummary, amountOut, amountOutUsd, gasUsd. Show the quoted output and gas cost to the user; confirm before proceeding.
  6. POST /api/v1/route/builddata (swap calldata), transactionValue, routerAddress. Verify routerAddress equals 0x6131B5fae19EA4f9D964eAc0408E4408b66337b5 — abort and warn the user if it differs.
  7. Build calls array:
    • Native tokenIn[swap_call]
    • ERC-20 tokenIn[approval_call, swap_call] — always include approval, no allowance check needed.
    • USDT on Ethereum — if existing allowance is non-zero, prepend a zero-approval call before the real approval.
  8. send_calls(chain, calls)approvalUrl, requestId.
  9. Present approvalUrl to the user. Do not auto-approve. Call get_request_status(requestId) only after the user acts.

Submission

Target tool: send_calls Map POST /route/build output into send_calls as follows: ERC-20 tokenIn — approval + swap batch:
Native tokenIn — swap only:
hex(transactionValue): "0x" + BigInt(transactionValue).toString(16)transactionValue is a decimal wei string from the API. ERC-20 approval calldata encoding:
Use chain name strings (base, ethereum, arbitrum, optimism, polygon, bsc, avalanche) — not numeric chain IDs. After send_calls returns an approval URL, follow the flow in ../references/approval-mode.md.

Example Prompts

“Swap 100 USDC to ETH on Base”
  1. get_wallets → address.
  2. GET /api/v1/routes on base — tokenIn=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (USDC, 6 dec), tokenOut=0xEeee...eEEE, amountIn=100000000.
  3. Show quoted output and gas to user; confirm.
  4. POST /api/v1/route/builddata (swap calldata), transactionValue="0" → hex-encode to "0x0".
  5. Encode approve calldata: router spends 100000000 USDC.
  6. send_calls("base", [approval_call, swap_call]).
“Swap 0.1 ETH to USDC on Arbitrum”
  1. get_wallets → address.
  2. GET /api/v1/routes on arbitrum — tokenIn=0xEeee...eEEE, tokenOut=0xaf88d065e77c8cC2239327C5EDb3A432268e5831 (USDC), amountIn=100000000000000000.
  3. Show quoted output and gas to user; confirm.
  4. POST /api/v1/route/builddata (swap calldata), transactionValue="10000000000000000" → hex-encode to "0xde0b6b3a7640000" (non-zero, native input).
  5. No approval needed — native ETH.
  6. send_calls("arbitrum", [swap_call]) with value=transactionValue.
“What’s the best rate to swap 500 MATIC to USDC on Polygon?” (read-only)
  1. get_wallets → address.
  2. GET /api/v1/routes on polygon — tokenIn=0xEeee...eEEE, tokenOut=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 (USDC), amountIn=500000000000000000000.
  3. Return amountOutUsd and gasUsd to the user — no transaction submitted.

Risks & Warnings

  • Slippage — Swaps can fill materially worse than the quoted price if market conditions shift between quote and execution. Apply the following thresholds:
    ToleranceLevelAction
    ≤ 100 bps (1%)NormalProceed.
    > 100 and ≤ 500 bps (5%)ElevatedMention the value and ask the user to confirm.
    > 500 and ≤ 2000 bps (20%)HighWarn that the trade can fill significantly below quote and is a likely sandwich target. Require explicit confirmation.
    > 2000 bpsVery highStrongly warn; do not submit without the user re-confirming the exact number.
    If the user does not specify slippage, default to 50 bps for common pairs (ETH/USDC, WBTC/ETH) and 100 bps for long-tail or volatile tokens. Always pass an explicit value — the API defaults to 0 bps if slippageTolerance is omitted, causing most trades to fail.

Notes

Router address (same on all supported chains): 0x6131B5fae19EA4f9D964eAc0408E4408b66337b5 Native token sentinel (ETH/BNB/MATIC/AVAX/etc.): 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE Common token addresses:
TokenChainAddress
USDCBase0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
USDCArbitrum0xaf88d065e77c8cC2239327C5EDb3A432268e5831
USDCEthereum0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
USDCOptimism0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85
USDCPolygon0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359
WETHBase0x4200000000000000000000000000000000000006
DAIBase0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb
cbBTCBase0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf
KyberSwap splits trades across multiple pools when beneficial — routeSummary may describe a multi-hop or split route. Pass it as-is; do not modify it. USDT on Ethereum: if existing allowance is non-zero, the approve call will revert — send a zero-approval first (amount = 0x0...0), then the real approval.