read_contract
Query smart contract data by calling read-only functions to retrieve state information, with automatic ABI fetching from block explorers.
Instructions
Call read-only functions on a smart contract. Automatically fetches ABI from block explorer if not provided (requires ETHERSCAN_API_KEY). Falls back to common functions if contract is not verified. Use this to query contract state and data.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| contractAddress | Yes | The contract address | |
| functionName | Yes | Function name (e.g., 'name', 'symbol', 'balanceOf', 'totalSupply', 'owner') | |
| args | No | Function arguments as strings (e.g., ['0xAddress'] for balanceOf) | |
| abiJson | No | Full contract ABI as JSON string (optional - will auto-fetch verified contract ABI if not provided) | |
| network | No | Network name or chain ID. Defaults to Ethereum mainnet. |
Implementation Reference
- src/core/tools.ts:1106-1145 (handler)The handler function that implements the core logic of the 'read_contract' tool. It parses the ABI if necessary, constructs ReadContractParameters, calls the underlying readContract helper, formats the result using helpers.formatJson, and handles errors appropriately.abi, functionName, args = [], network = 'ethereum' }) => { try { // Parse ABI if it's a string const parsedAbi = typeof abi === 'string' ? JSON.parse(abi) : abi; const params = { address: contractAddress as Address, abi: parsedAbi, functionName, args }; const result = await services.readContract(params, network); return { content: [ { type: 'text', text: services.helpers.formatJson(result) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error reading contract: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );
- src/core/tools.ts:1079-1105 (schema)Zod schema defining the input parameters for the 'read_contract' tool, including contractAddress, abi (JSON array), functionName, optional args array, and optional network..string() .describe('The address of the smart contract to interact with'), abi: z .array(z.any()) .describe( 'The ABI (Application Binary Interface) of the smart contract function, as a JSON array' ), functionName: z .string() .describe( "The name of the function to call on the contract (e.g., 'balanceOf')" ), args: z .array(z.any()) .optional() .describe( "The arguments to pass to the function, as an array (e.g., ['0x1234...'])" ), network: z .string() .optional() .describe( "Network name (e.g., 'ethereum', 'optimism', 'arbitrum', 'base', 'polygon') or chain ID. Defaults to Ethereum mainnet." ) }, async ({ contractAddress,
- src/core/tools.ts:1076-1146 (registration)Registration of the 'read_contract' MCP tool using server.tool(), providing name, description, input schema, and handler function."Read data from a smart contract by calling a view/pure function. This doesn't modify blockchain state and doesn't require gas or signing.", { contractAddress: z .string() .describe('The address of the smart contract to interact with'), abi: z .array(z.any()) .describe( 'The ABI (Application Binary Interface) of the smart contract function, as a JSON array' ), functionName: z .string() .describe( "The name of the function to call on the contract (e.g., 'balanceOf')" ), args: z .array(z.any()) .optional() .describe( "The arguments to pass to the function, as an array (e.g., ['0x1234...'])" ), network: z .string() .optional() .describe( "Network name (e.g., 'ethereum', 'optimism', 'arbitrum', 'base', 'polygon') or chain ID. Defaults to Ethereum mainnet." ) }, async ({ contractAddress, abi, functionName, args = [], network = 'ethereum' }) => { try { // Parse ABI if it's a string const parsedAbi = typeof abi === 'string' ? JSON.parse(abi) : abi; const params = { address: contractAddress as Address, abi: parsedAbi, functionName, args }; const result = await services.readContract(params, network); return { content: [ { type: 'text', text: services.helpers.formatJson(result) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error reading contract: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); // Write to contract
- Helper function re-exported from services that performs the actual contract read using viem's publicClient.readContract. Called by the tool handler.export async function readContract( params: ReadContractParameters, network = 'ethereum' ) { const client = getPublicClient(network); return await client.readContract(params); }