get_token_balance
Retrieve ERC20 token balances for wallet addresses across EVM networks, supporting ENS names and multiple blockchain networks.
Instructions
Get the ERC20 token balance for an address
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| address | Yes | The wallet address or ENS name | |
| tokenAddress | Yes | The ERC20 token contract address | |
| network | No | Network name or chain ID. Defaults to Ethereum mainnet. |
Implementation Reference
- src/core/tools.ts:370-429 (registration)Registration and handler implementation for the 'get_token_balance' MCP tool. Includes input schema validation with Zod and the execution logic that delegates to services.getERC20Balance.'get_token_balance', 'Get the balance of an ERC20 token for an address', { tokenAddress: z .string() .describe( "The contract address or ENS name of the ERC20 token (e.g., '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' for USDC or 'uniswap.eth')" ), ownerAddress: z .string() .describe( "The wallet address or ENS name to check the balance for (e.g., '0x1234...' or 'vitalik.eth')" ), network: z .string() .optional() .describe( "Network name (e.g., 'ethereum', 'optimism', 'arbitrum', 'base', etc.) or chain ID. Supports all EVM-compatible networks. Defaults to Ethereum mainnet." ) }, async ({ tokenAddress, ownerAddress, network = 'ethereum' }) => { try { const balance = await services.getERC20Balance( tokenAddress, ownerAddress, network ); return { content: [ { type: 'text', text: JSON.stringify( { tokenAddress, owner: ownerAddress, network, raw: balance.raw.toString(), formatted: balance.formatted, symbol: balance.token.symbol, decimals: balance.token.decimals }, null, 2 ) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error fetching token balance: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
- src/core/services/balance.ts:98-136 (helper)Core helper function getERC20Balance that implements the actual blockchain query: resolves ENS names, creates viem contract instance, reads balanceOf, symbol, and decimals from the ERC20 token contract.export async function getERC20Balance( tokenAddressOrEns: string, ownerAddressOrEns: string, network = 'ethereum' ): Promise<{ raw: bigint; formatted: string; token: { symbol: string; decimals: number; } }> { // Resolve ENS names to addresses if needed const tokenAddress = await resolveAddress(tokenAddressOrEns, network); const ownerAddress = await resolveAddress(ownerAddressOrEns, network); const publicClient = getPublicClient(network); const contract = getContract({ address: tokenAddress, abi: erc20Abi, client: publicClient, }); const [balance, symbol, decimals] = await Promise.all([ contract.read.balanceOf([ownerAddress]), contract.read.symbol(), contract.read.decimals() ]); return { raw: balance, formatted: formatUnits(balance, decimals), token: { symbol, decimals } }; }
- src/core/services/balance.ts:13-35 (helper)ERC20 ABI definition used by getERC20Balance to read token symbol, decimals, and balanceOf.const erc20Abi = [ { inputs: [], name: 'symbol', outputs: [{ type: 'string' }], stateMutability: 'view', type: 'function' }, { inputs: [], name: 'decimals', outputs: [{ type: 'uint8' }], stateMutability: 'view', type: 'function' }, { inputs: [{ type: 'address', name: 'account' }], name: 'balanceOf', outputs: [{ type: 'uint256' }], stateMutability: 'view', type: 'function' } ] as const;
- src/server/server.ts:18-19 (registration)Top-level registration call that includes get_token_balance via registerEVMTools.registerEVMTools(server); registerEVMPrompts(server);