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’ssend_calls. Use KyberSwap when the user wants the best rate across all available liquidity — not just a single protocol’s pools.
Surface Routing
| Capability | Harness surface (Claude Code, Cursor) | Chat-only surface (Claude.ai, ChatGPT) |
|---|---|---|
| GET /routes (quote) | Harness HTTP tool — no allowlist needed | web_request — requires aggregator-api.kyberswap.com allowlisted |
| POST /route/build (calldata) | Harness HTTP tool — no allowlist needed | web_request — requires aggregator-api.kyberswap.com allowlisted |
| Token resolution | Harness HTTP tool — no allowlist needed | web_request — requires token-api.kyberswap.com allowlisted |
| Submit swap | send_calls — all surfaces | send_calls — all surfaces |
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 arouteSummary required verbatim in the build step.
| Param | Required | Notes |
|---|---|---|
tokenIn | ✅ | Token address. Native token: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE |
tokenOut | ✅ | Token address |
amountIn | ✅ | Amount in base units — plain integer string. 1 ETH = 1000000000000000000, 100 USDC = 100000000 |
to | recommended | Recipient wallet address |
slippageTolerance | recommended | Basis points (50 = 0.5%). See Risks & Warnings |
source | recommended | Pass base-mcp for attribution |
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.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.
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
get_wallets→walletAddress.- Resolve token symbols to addresses — use the
## Notestable first, then the token-api endpoint. - Compute
amountInin base units: multiply human amount by10^decimals(ETH=18, USDC=6, WBTC=8). - Determine slippage: default
50bps for common pairs,100bps for long-tail tokens. Apply thresholds in## Risks & Warningsbefore proceeding. GET /api/v1/routes→routeSummary,amountOut,amountOutUsd,gasUsd. Show the quoted output and gas cost to the user; confirm before proceeding.POST /api/v1/route/build→data(swap calldata),transactionValue,routerAddress. VerifyrouterAddressequals0x6131B5fae19EA4f9D964eAc0408E4408b66337b5— abort and warn the user if it differs.- 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.
- Native tokenIn →
send_calls(chain, calls)→approvalUrl,requestId.- Present
approvalUrlto the user. Do not auto-approve. Callget_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:
hex(transactionValue): "0x" + BigInt(transactionValue).toString(16) — transactionValue is a decimal wei string from the API.
ERC-20 approval calldata encoding:
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”get_wallets→ address.GET /api/v1/routesonbase— tokenIn=0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913(USDC, 6 dec), tokenOut=0xEeee...eEEE, amountIn=100000000.- Show quoted output and gas to user; confirm.
POST /api/v1/route/build→data(swap calldata),transactionValue="0"→ hex-encode to"0x0".- Encode approve calldata: router spends
100000000USDC. send_calls("base", [approval_call, swap_call]).
get_wallets→ address.GET /api/v1/routesonarbitrum— tokenIn=0xEeee...eEEE, tokenOut=0xaf88d065e77c8cC2239327C5EDb3A432268e5831(USDC), amountIn=100000000000000000.- Show quoted output and gas to user; confirm.
POST /api/v1/route/build→data(swap calldata),transactionValue="10000000000000000"→ hex-encode to"0xde0b6b3a7640000"(non-zero, native input).- No approval needed — native ETH.
send_calls("arbitrum", [swap_call])with value=transactionValue.
get_wallets→ address.GET /api/v1/routesonpolygon— tokenIn=0xEeee...eEEE, tokenOut=0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359(USDC), amountIn=500000000000000000000.- Return
amountOutUsdandgasUsdto 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:
If the user does not specify slippage, default to
Tolerance Level Action ≤ 100 bps (1%) Normal Proceed. > 100 and ≤ 500 bps (5%) Elevated Mention the value and ask the user to confirm. > 500 and ≤ 2000 bps (20%) High Warn that the trade can fill significantly below quote and is a likely sandwich target. Require explicit confirmation. > 2000 bps Very high Strongly warn; do not submit without the user re-confirming the exact number. 50bps for common pairs (ETH/USDC, WBTC/ETH) and100bps for long-tail or volatile tokens. Always pass an explicit value — the API defaults to 0 bps ifslippageToleranceis 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:
| Token | Chain | Address |
|---|---|---|
| USDC | Base | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| USDC | Arbitrum | 0xaf88d065e77c8cC2239327C5EDb3A432268e5831 |
| USDC | Ethereum | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 |
| USDC | Optimism | 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85 |
| USDC | Polygon | 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359 |
| WETH | Base | 0x4200000000000000000000000000000000000006 |
| DAI | Base | 0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb |
| cbBTC | Base | 0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf |
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.