Skip to main content
Glama

get_token_info

Retrieve ERC-20 token details including name, symbol, and decimals using contract address and chain ID to verify token information before transactions.

Instructions

Get the name, symbol, and decimals of any ERC-20 token by its contract address. Useful for discovering token details before transfers or approvals.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
tokenYesERC-20 token contract address
chain_idYesChain ID

Implementation Reference

  • src/index.ts:880-912 (registration)
    Tool registration for 'get_token_info' - registers the tool with MCP server, defines the schema using zod, and provides the handler function
    server.tool(
      'get_token_info',
      'Get the name, symbol, and decimals of any ERC-20 token by its contract address. ' +
        'Useful for discovering token details before transfers or approvals.',
      {
        token: z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe('ERC-20 token contract address'),
        chain_id: z.number().int().describe('Chain ID'),
      },
      async ({ token, chain_id }) => {
        if (isSolanaChain(chain_id)) {
          throw new Error('get_token_info is not supported on Solana. Use Solana token metadata programs to query SPL token details.');
        }
        // Make 3 parallel eth_call requests: name(), symbol(), decimals()
        const [nameResult, symbolResult, decimalsResult] = await Promise.all([
          api('/eth-call', 'POST', { chain_id, to: token, data: '0x06fdde03' }).catch(() => ({ result: '0x' })),
          api('/eth-call', 'POST', { chain_id, to: token, data: '0x95d89b41' }).catch(() => ({ result: '0x' })),
          api('/eth-call', 'POST', { chain_id, to: token, data: '0x313ce567' }).catch(() => ({ result: '0x' })),
        ]) as { result: string }[];
    
        const name = decodeAbiString(nameResult.result);
        const symbol = decodeAbiString(symbolResult.result);
        const decimalsHex = decimalsResult.result.replace('0x', '');
        const decimals = decimalsHex ? parseInt(decimalsHex, 16) : 0;
    
        return jsonResponse({
          token,
          chain_id,
          name: name || 'Unknown',
          symbol: symbol || 'Unknown',
          decimals,
        });
      },
    );
  • Handler function for get_token_info - validates chain is not Solana, makes 3 parallel eth_call requests for name(), symbol(), decimals(), decodes results and returns token metadata
    async ({ token, chain_id }) => {
      if (isSolanaChain(chain_id)) {
        throw new Error('get_token_info is not supported on Solana. Use Solana token metadata programs to query SPL token details.');
      }
      // Make 3 parallel eth_call requests: name(), symbol(), decimals()
      const [nameResult, symbolResult, decimalsResult] = await Promise.all([
        api('/eth-call', 'POST', { chain_id, to: token, data: '0x06fdde03' }).catch(() => ({ result: '0x' })),
        api('/eth-call', 'POST', { chain_id, to: token, data: '0x95d89b41' }).catch(() => ({ result: '0x' })),
        api('/eth-call', 'POST', { chain_id, to: token, data: '0x313ce567' }).catch(() => ({ result: '0x' })),
      ]) as { result: string }[];
    
      const name = decodeAbiString(nameResult.result);
      const symbol = decodeAbiString(symbolResult.result);
      const decimalsHex = decimalsResult.result.replace('0x', '');
      const decimals = decimalsHex ? parseInt(decimalsHex, 16) : 0;
    
      return jsonResponse({
        token,
        chain_id,
        name: name || 'Unknown',
        symbol: symbol || 'Unknown',
        decimals,
      });
    },
  • Input schema for get_token_info using zod - requires 'token' (0x-prefixed 40-char hex address) and 'chain_id' (integer)
    {
      token: z.string().regex(/^0x[a-fA-F0-9]{40}$/).describe('ERC-20 token contract address'),
      chain_id: z.number().int().describe('Chain ID'),
    },
  • Helper function decodeAbiString() - decodes ABI-encoded string return values from hex, handles malformed data gracefully, used to decode token name and symbol from eth_call results
    /**
     * Decode an ABI-encoded string return value from hex.
     * Handles malformed data gracefully — returns empty string on any parsing failure.
     */
    function decodeAbiString(hex: string): string {
      try {
        const clean = hex.replace('0x', '');
        if (clean.length < 128) return ''; // offset + length minimum
        // First 32 bytes = offset, next 32 bytes at that offset = length
        const offset = parseInt(clean.slice(0, 64), 16) * 2;
        if (isNaN(offset) || offset + 64 > clean.length) return '';
        const length = parseInt(clean.slice(offset, offset + 64), 16);
        if (isNaN(length) || length === 0) return '';
        const dataHex = clean.slice(offset + 64, offset + 64 + length * 2);
        const pairs = dataHex.match(/.{2}/g);
        if (!pairs) return '';
        // Convert hex to UTF-8
        const bytes = new Uint8Array(pairs.map(b => parseInt(b, 16)));
        return new TextDecoder().decode(bytes);
      } catch {
        return '';
      }
    }

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/hifriendbot/agentwallet-mcp'

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