Skip to main content
Glama

get_bridge_quote

Obtain a quote for transferring the same token between blockchain networks, including estimated output amount, fees breakdown, and time estimate.

Instructions

Get a quote for bridging the same token from one chain to another (e.g. ETH on Ethereum → ETH on Base). Returns estimated output amount, fees breakdown, and time estimate. Use get_swap_quote instead if you want to change the token type.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
originChainIdYesSource chain ID (e.g. 1 for Ethereum).
destinationChainIdYesDestination chain ID (e.g. 8453 for Base).
currencyYesToken address to bridge. Use "0x0000000000000000000000000000000000000000" for native ETH.
amountYesAmount to bridge in the token's smallest unit (wei for ETH). Example: "1000000000000000000" for 1 ETH.
senderYesSender wallet address.
recipientNoRecipient wallet address. Defaults to sender if not provided.

Implementation Reference

  • Main implementation of the get_bridge_quote tool. Contains the registration with McpServer, input schema definition (lines 10-36), and the async handler function (lines 37-100) that fetches a quote using getQuote(), formats the response, builds a deeplink URL, and returns structured content with summary, JSON details, and resource link.
    export function register(server: McpServer) {
      server.tool(
        "get_bridge_quote",
        "Get a quote for bridging the same token from one chain to another (e.g. ETH on Ethereum → ETH on Base). Returns estimated output amount, fees breakdown, and time estimate. Use get_swap_quote instead if you want to change the token type.",
        {
          originChainId: z
            .number()
            .describe("Source chain ID (e.g. 1 for Ethereum)."),
          destinationChainId: z
            .number()
            .describe("Destination chain ID (e.g. 8453 for Base)."),
          currency: z
            .string()
            .describe(
              'Token address to bridge. Use "0x0000000000000000000000000000000000000000" for native ETH.'
            ),
          amount: z
            .string()
            .describe(
              "Amount to bridge in the token's smallest unit (wei for ETH). Example: \"1000000000000000000\" for 1 ETH."
            ),
          sender: z
            .string()
            .describe("Sender wallet address."),
          recipient: z
            .string()
            .optional()
            .describe(
              "Recipient wallet address. Defaults to sender if not provided."
            ),
        },
        async ({ originChainId, destinationChainId, currency, amount, sender, recipient }) => {
          const quote = await getQuote({
            user: sender,
            originChainId,
            destinationChainId,
            originCurrency: currency,
            destinationCurrency: currency,
            amount,
            recipient,
          });
    
          const { details, fees } = quote;
          const summary = `Bridge ${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: currency,
            toCurrency: currency,
            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 bridge on Relay",
              description: "Open the Relay app to sign and execute this bridge",
              mimeType: "text/html",
            });
            content.push({
              type: "text",
              text: `To execute this bridge, open the Relay app: ${deeplinkUrl}`,
            });
          }
    
          return { content };
        }
      );
    }
  • src/index.ts:6-6 (registration)
    Import statement for get_bridge_quote tool registration.
    import { register as registerGetBridgeQuote } from "./tools/get-bridge-quote.js";
  • src/index.ts:22-22 (registration)
    Registration of get_bridge_quote tool with the MCP server.
    registerGetBridgeQuote(server);
  • Helper function getQuote() that makes a POST request to the Relay API /quote/v2 endpoint. Accepts QuoteRequest parameters and returns QuoteResponse with fees, details, steps, and time estimate.
    export async function getQuote(params: QuoteRequest): Promise<QuoteResponse> {
      return relayApi<QuoteResponse>("/quote/v2", {
        method: "POST",
        body: {
          ...params,
          tradeType: params.tradeType || "EXACT_INPUT",
        },
      });
    }
  • Helper function buildRelayAppUrl() that constructs a Relay app deeplink URL for executing the bridge. Maps chain IDs to chain names and builds a URL with query parameters for fromChainId, currencies, amount, and toAddress.
    export async function buildRelayAppUrl(
      params: DeeplinkParams
    ): Promise<string | null> {
      const nameMap = await getChainNameMap();
      const chainName = nameMap.get(params.destinationChainId);
      if (!chainName) return null;
    
      const url = new URL(`https://relay.link/bridge/${chainName}`);
    
      if (params.fromChainId !== undefined)
        url.searchParams.set("fromChainId", String(params.fromChainId));
      if (params.fromCurrency)
        url.searchParams.set("fromCurrency", params.fromCurrency);
      if (params.toCurrency)
        url.searchParams.set("toCurrency", params.toCurrency);
      if (params.amount) url.searchParams.set("amount", params.amount);
      if (params.toAddress) url.searchParams.set("toAddress", params.toAddress);
      if (params.tradeType) url.searchParams.set("tradeType", params.tradeType);
    
      return url.toString();
    }
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes what the tool does (returns estimates and breakdowns) and clarifies it's for quoting only (not execution), which is useful context. However, it doesn't mention potential limitations like rate limits, error conditions, or whether the quote is time-sensitive, leaving some behavioral aspects uncovered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is perfectly concise and well-structured in just two sentences. The first sentence clearly states the purpose, scope, and return values, while the second provides crucial usage guidance. Every word earns its place with no redundancy or fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (6 parameters, no output schema, no annotations), the description provides excellent contextual completeness. It clearly explains what the tool does, when to use it, and what it returns. The only minor gap is the lack of output schema, but the description adequately describes the return values (estimated output amount, fees breakdown, time estimate).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, so the schema already documents all parameters thoroughly. The description doesn't add any parameter-specific information beyond what's in the schema, but it does provide context about the tool's purpose that helps understand parameter usage. This meets the baseline of 3 when schema coverage is high.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with specific verbs ('Get a quote for bridging') and resources ('the same token from one chain to another'), and distinguishes it from sibling tools by explicitly mentioning when to use get_swap_quote instead. It provides concrete examples (ETH on Ethereum → ETH on Base) and specifies the return values (estimated output amount, fees breakdown, time estimate).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly provides usage guidelines by stating 'Use get_swap_quote instead if you want to change the token type,' which clearly differentiates when to use this tool versus an alternative. This gives the agent specific direction on tool selection based on the user's intent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/relayprotocol/relay-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server