Skip to main content
Glama

get_supported_tokens

Search for token contract addresses supported by Relay across multiple blockchain networks to prepare for quotes and transactions.

Instructions

Search for tokens supported by Relay across chains. Use this to find token contract addresses before getting quotes. Returns token symbol, name, address, and chain availability.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chainIdsNoFilter to specific chain IDs (e.g. [1, 8453] for Ethereum and Base). Omit for all chains.
termNoSearch by token name or symbol (e.g. "USDC", "ethereum").
verifiedNoOnly return verified tokens. Defaults to true.
limitNoMax number of token groups to return. Defaults to 20.

Implementation Reference

  • Main implementation of the get_supported_tokens tool. Contains the tool registration with input schema (Zod) and the handler function that fetches currencies from the Relay API, transforms the response, and returns formatted results with a text summary and JSON data.
    export function register(server: McpServer) {
      server.tool(
        "get_supported_tokens",
        "Search for tokens supported by Relay across chains. Use this to find token contract addresses before getting quotes. Returns token symbol, name, address, and chain availability.",
        {
          chainIds: z
            .array(z.number())
            .optional()
            .describe(
              "Filter to specific chain IDs (e.g. [1, 8453] for Ethereum and Base). Omit for all chains."
            ),
          term: z
            .string()
            .optional()
            .describe(
              'Search by token name or symbol (e.g. "USDC", "ethereum").'
            ),
          verified: z
            .boolean()
            .optional()
            .default(true)
            .describe("Only return verified tokens. Defaults to true."),
          limit: z
            .number()
            .optional()
            .default(20)
            .describe("Max number of token groups to return. Defaults to 20."),
        },
        async ({ chainIds, term, verified, limit }) => {
          const result = await getCurrencies({
            chainIds,
            term,
            verified,
            limit,
          });
    
          const tokens = result.map((group) => {
            const first = group[0];
            return {
              symbol: first.symbol,
              name: first.name,
              chains: group.map((entry) => ({
                chainId: entry.chainId,
                address: entry.address,
                decimals: entry.decimals,
              })),
            };
          });
    
          const summary = `Found ${tokens.length} token${tokens.length !== 1 ? "s" : ""}${term ? ` matching "${term}"` : ""}. ${tokens
            .slice(0, 5)
            .map((t) => `${t.symbol} (on ${t.chains.length} chain${t.chains.length !== 1 ? "s" : ""})`)
            .join(", ")}${tokens.length > 5 ? "..." : ""}.`;
    
          return {
            content: [
              { type: "text", text: summary },
              { type: "text", text: JSON.stringify(tokens, null, 2) },
            ],
          };
        }
      );
    }
  • Input validation schema for get_supported_tokens tool. Defines optional parameters: chainIds (array of numbers), term (string for searching token name/symbol), verified (boolean, defaults to true), and limit (number, defaults to 20).
      chainIds: z
        .array(z.number())
        .optional()
        .describe(
          "Filter to specific chain IDs (e.g. [1, 8453] for Ethereum and Base). Omit for all chains."
        ),
      term: z
        .string()
        .optional()
        .describe(
          'Search by token name or symbol (e.g. "USDC", "ethereum").'
        ),
      verified: z
        .boolean()
        .optional()
        .default(true)
        .describe("Only return verified tokens. Defaults to true."),
      limit: z
        .number()
        .optional()
        .default(20)
        .describe("Max number of token groups to return. Defaults to 20."),
    },
  • src/index.ts:5-5 (registration)
    Import statement for the get_supported_tokens tool registration function from ./tools/get-supported-tokens.js
    import { register as registerGetSupportedTokens } from "./tools/get-supported-tokens.js";
  • src/index.ts:21-21 (registration)
    Registration call that registers the get_supported_tokens tool with the MCP server instance
    registerGetSupportedTokens(server);
  • Helper function getCurrencies that makes a POST request to the Relay API's /currencies/v1 endpoint with parameters (chainIds, term, verified, limit) and returns a 2D array of CurrencyEntry objects grouped by token
    export async function getCurrencies(
      params: CurrenciesRequest
    ): Promise<CurrencyEntry[][]> {
      return relayApi<CurrencyEntry[][]>("/currencies/v1", {
        method: "POST",
        body: params,
      });
    }
Behavior3/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 describes the search functionality and return format (token symbol, name, address, chain availability), but lacks details on rate limits, authentication needs, error conditions, or pagination behavior beyond the 'limit' parameter. This is adequate but leaves gaps for a search tool.

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 front-loaded with the core purpose in the first sentence, followed by usage guidance and return details. Every sentence earns its place with no wasted words, making it highly efficient and easy to scan.

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 (search with filtering), no annotations, and no output schema, the description is reasonably complete. It covers purpose, usage context, and return format, but could benefit from more behavioral details (e.g., performance expectations or error handling) to fully compensate for the lack of structured fields.

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?

Schema description coverage is 100%, so the schema fully documents all four parameters. The description adds no additional parameter semantics beyond what's in the schema, but the baseline is 3 when schema coverage is high. The description does imply the tool's purpose aligns with the parameters (e.g., searching with 'term'), but doesn't enhance the schema's details.

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 ('Search for tokens supported by Relay across chains') and resources ('tokens'), distinguishing it from siblings like get_supported_chains (which focuses on chains rather than tokens) and get_swap_quote (which is for quotes, not token discovery).

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

Usage Guidelines4/5

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

The description provides clear context for when to use this tool ('Use this to find token contract addresses before getting quotes'), which implicitly suggests it's a preparatory step for tools like get_swap_quote or execute_bridge. However, it doesn't explicitly state when not to use it or name specific alternatives among siblings.

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