get_swap_quote
Obtain token swap quotes across blockchain networks, including estimated output amounts, fees, and transaction time estimates for cross-chain or same-chain token exchanges.
Instructions
Get a quote for swapping between different tokens, optionally across chains (e.g. ETH on Ethereum → USDC on Base, or USDC → WETH on the same chain). Returns estimated output amount, fees, and time estimate.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| originChainId | Yes | Source chain ID (e.g. 1 for Ethereum). | |
| destinationChainId | Yes | Destination chain ID. Can be the same as originChainId for same-chain swaps. | |
| originCurrency | Yes | Token address to swap from. Use "0x0000000000000000000000000000000000000000" for native ETH. | |
| destinationCurrency | Yes | Token address to swap to. Use "0x0000000000000000000000000000000000000000" for native ETH. | |
| amount | Yes | Amount to swap in the origin token's smallest unit (wei for ETH). | |
| sender | Yes | Sender wallet address. | |
| recipient | No | Recipient wallet address. Defaults to sender. |
Implementation Reference
- src/tools/get-swap-quote.ts:6-115 (handler)Main implementation of the get_swap_quote tool. Contains the handler function that fetches quotes, processes the response, formats output, and returns structured content with summary, JSON details, and deeplink resources.
export function register(server: McpServer) { server.tool( "get_swap_quote", "Get a quote for swapping between different tokens, optionally across chains (e.g. ETH on Ethereum → USDC on Base, or USDC → WETH on the same chain). Returns estimated output amount, fees, and time estimate.", { originChainId: z .number() .describe("Source chain ID (e.g. 1 for Ethereum)."), destinationChainId: z .number() .describe( "Destination chain ID. Can be the same as originChainId for same-chain swaps." ), originCurrency: z .string() .describe( 'Token address to swap from. Use "0x0000000000000000000000000000000000000000" for native ETH.' ), destinationCurrency: z .string() .describe( 'Token address to swap to. Use "0x0000000000000000000000000000000000000000" for native ETH.' ), amount: z .string() .describe( "Amount to swap in the origin token's smallest unit (wei for ETH)." ), sender: z.string().describe("Sender wallet address."), recipient: z .string() .optional() .describe("Recipient wallet address. Defaults to sender."), }, async ({ originChainId, destinationChainId, originCurrency, destinationCurrency, amount, sender, recipient, }) => { const quote = await getQuote({ user: sender, originChainId, destinationChainId, originCurrency, destinationCurrency, amount, recipient, }); const { details, fees } = quote; const isCrossChain = originChainId !== destinationChainId; const action = isCrossChain ? "Cross-chain swap" : "Swap"; const summary = `${action}: ${details.currencyIn.amountFormatted} ${details.currencyIn.currency.symbol} (chain ${originChainId}) → ${details.currencyOut.amountFormatted} ${details.currencyOut.currency.symbol} (chain ${destinationChainId}). Total fees: $${fees.relayer.amountUsd}. ETA: ~${details.timeEstimate}s.`; const deeplinkUrl = await buildRelayAppUrl({ destinationChainId, fromChainId: originChainId, fromCurrency: originCurrency, toCurrency: destinationCurrency, amount: details.currencyIn.amountFormatted, toAddress: recipient || sender, }); const content: Array<Record<string, unknown>> = [ { type: "text", text: summary }, { type: "text", text: JSON.stringify( { amountIn: details.currencyIn.amountFormatted, amountOut: details.currencyOut.amountFormatted, amountInUsd: details.currencyIn.amountUsd, amountOutUsd: details.currencyOut.amountUsd, fees: { gas: { formatted: fees.gas.amountFormatted, usd: fees.gas.amountUsd }, relayer: { formatted: fees.relayer.amountFormatted, usd: fees.relayer.amountUsd }, }, totalImpact: details.totalImpact, timeEstimateSeconds: details.timeEstimate, rate: details.rate, relayAppUrl: deeplinkUrl ?? undefined, }, null, 2 ), }, ]; if (deeplinkUrl) { content.push({ type: "resource_link", uri: deeplinkUrl, name: "Execute swap on Relay", description: "Open the Relay app to sign and execute this swap", mimeType: "text/html", }); content.push({ type: "text", text: `To execute this swap, open the Relay app: ${deeplinkUrl}`, }); } return { content }; } ); } - src/tools/get-swap-quote.ts:10-39 (schema)Input schema validation using Zod. Defines required parameters: originChainId, destinationChainId, originCurrency, destinationCurrency, amount, sender, and optional recipient.
{ originChainId: z .number() .describe("Source chain ID (e.g. 1 for Ethereum)."), destinationChainId: z .number() .describe( "Destination chain ID. Can be the same as originChainId for same-chain swaps." ), originCurrency: z .string() .describe( 'Token address to swap from. Use "0x0000000000000000000000000000000000000000" for native ETH.' ), destinationCurrency: z .string() .describe( 'Token address to swap to. Use "0x0000000000000000000000000000000000000000" for native ETH.' ), amount: z .string() .describe( "Amount to swap in the origin token's smallest unit (wei for ETH)." ), sender: z.string().describe("Sender wallet address."), recipient: z .string() .optional() .describe("Recipient wallet address. Defaults to sender."), }, - src/index.ts:7-7 (registration)Import statement for the get_swap_quote tool registration function.
import { register as registerGetSwapQuote } from "./tools/get-swap-quote.js"; - src/index.ts:23-23 (registration)Registration call that registers the get_swap_quote tool with the MCP server instance.
registerGetSwapQuote(server); - src/relay-api.ts:212-220 (helper)Helper function getQuote that makes a POST request to the Relay API /quote/v2 endpoint to fetch swap quotes with all necessary parameters.
export async function getQuote(params: QuoteRequest): Promise<QuoteResponse> { return relayApi<QuoteResponse>("/quote/v2", { method: "POST", body: { ...params, tradeType: params.tradeType || "EXACT_INPUT", }, }); }