transfer_eth
Transfer native tokens like ETH or MATIC to any address on EVM-compatible networks using a private key for signing. Supports ENS names and multiple networks, including Ethereum, Optimism, Arbitrum, and Base.
Instructions
Transfer native tokens (ETH, MATIC, etc.) to an address
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | Amount to send in ETH (or the native token of the network), as a string (e.g., '0.1') | |
| network | No | Network name (e.g., 'ethereum', 'optimism', 'arbitrum', 'base', etc.) or chain ID. Supports all EVM-compatible networks. Defaults to Ethereum mainnet. | |
| privateKey | Yes | Private key of the sender account in hex format (with or without 0x prefix). SECURITY: This is used only for transaction signing and is not stored. | |
| to | Yes | The recipient address or ENS name (e.g., '0x1234...' or 'vitalik.eth') |
Implementation Reference
- src/core/tools.ts:606-644 (handler)The async handler function that executes the logic for the 'transfer_eth' tool. It calls the services.transferETH helper with the input parameters and formats the response with the transaction hash or an error message.async ({ privateKey, to, amount, network = 'ethereum' }) => { try { const txHash = await services.transferETH( privateKey, to, amount, network ); return { content: [ { type: 'text', text: JSON.stringify( { success: true, txHash, to, amount, network }, null, 2 ) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error transferring ETH: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } }
- src/core/tools.ts:583-605 (schema)Zod input schema defining parameters for the transfer_eth tool: privateKey, to (address/ENS), amount (string), network (optional).{ privateKey: z .string() .describe( 'Private key of the sender account in hex format (with or without 0x prefix). SECURITY: This is used only for transaction signing and is not stored.' ), to: z .string() .describe( "The recipient address or ENS name (e.g., '0x1234...' or 'vitalik.eth')" ), amount: z .string() .describe( "Amount to send in ETH (or the native token of the network), as a string (e.g., '0.1')" ), 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." ) },
- src/core/tools.ts:580-645 (registration)MCP server.tool registration for the 'transfer_eth' tool, specifying name, description, input schema, and handler function.server.tool( 'transfer_eth', 'Transfer native tokens (ETH, MATIC, etc.) to an address', { privateKey: z .string() .describe( 'Private key of the sender account in hex format (with or without 0x prefix). SECURITY: This is used only for transaction signing and is not stored.' ), to: z .string() .describe( "The recipient address or ENS name (e.g., '0x1234...' or 'vitalik.eth')" ), amount: z .string() .describe( "Amount to send in ETH (or the native token of the network), as a string (e.g., '0.1')" ), 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 ({ privateKey, to, amount, network = 'ethereum' }) => { try { const txHash = await services.transferETH( privateKey, to, amount, network ); return { content: [ { type: 'text', text: JSON.stringify( { success: true, txHash, to, amount, network }, null, 2 ) } ] }; } catch (error) { return { content: [ { type: 'text', text: `Error transferring ETH: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } );
- Helper function transferETH that performs the actual ETH transfer using viem's walletClient.sendTransaction. Resolves ENS names, formats private key, parses amount to wei, and returns tx hash.export async function transferETH( privateKey: string | Hex, toAddressOrEns: string, amount: string, // in ether network = 'ethereum' ): Promise<Hash> { // Resolve ENS name to address if needed const toAddress = await resolveAddress(toAddressOrEns, network); // Ensure the private key has 0x prefix const formattedKey = typeof privateKey === 'string' && !privateKey.startsWith('0x') ? (`0x${privateKey}` as Hex) : (privateKey as Hex); const client = getWalletClient(formattedKey, network); const amountWei = parseEther(amount); return client.sendTransaction({ to: toAddress, value: amountWei, account: client.account!, chain: client.chain }); }