approve_token_spending
Authorize a specific address to spend your ERC20 tokens by defining the token, spender, and amount. Essential for enabling token interactions with DeFi protocols or exchanges.
Instructions
Approve another address (like a DeFi protocol or exchange) to spend your ERC20 tokens. This is often required before interacting with DeFi protocols.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | The amount of tokens to approve in token units, not wei (e.g., '1000' to approve spending 1000 tokens). Use a very large number for unlimited approval. | |
| network | No | Network name (e.g. 'bsc', 'opbnb', 'ethereum', 'base', etc.) or chain ID. Supports others main popular networks. Defaults to BSC mainnet. | bsc |
| privateKey | No | Private key of the token owner account in hex format (with or without 0x prefix). SECURITY: This is used only for transaction signing and is not stored. | 0x5a2b7e4d9c8f1a3e6b0d2c5f4e3d2a1b0c9f8e7d6a5b4c3d2e1f0a9b8c7d6e5f4 |
| spenderAddress | Yes | The contract address being approved to spend your tokens (e.g., a DEX or lending protocol) | |
| tokenAddress | Yes | The contract address of the ERC20 token to approve for spending (e.g., '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' for USDC on Ethereum) |
Implementation Reference
- src/evm/modules/wallet/tools.ts:75-121 (registration)Registration of the 'approve_token_spending' MCP tool, including input schema definition and handler function that delegates to services.approveERC20// Approve ERC20 token spending server.tool( "approve_token_spending", "Approve another address (like a DeFi protocol or exchange) to spend your ERC20 tokens. This is often required before interacting with DeFi protocols.", { privateKey: privateKeyParam, tokenAddress: z .string() .describe( "The contract address of the ERC20 token to approve for spending (e.g., '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48' for USDC on Ethereum)" ), spenderAddress: z .string() .describe( "The contract address being approved to spend your tokens (e.g., a DEX or lending protocol)" ), amount: z .string() .describe( "The amount of tokens to approve in token units, not wei (e.g., '1000' to approve spending 1000 tokens). Use a very large number for unlimited approval." ), network: defaultNetworkParam }, async ({ privateKey, tokenAddress, spenderAddress, amount, network }) => { try { const result = await services.approveERC20( tokenAddress, spenderAddress, amount, privateKey, network ) return mcpToolRes.success({ success: true, txHash: result.txHash, tokenAddress, spenderAddress, amount: result.amount.formatted, symbol: result.token.symbol, network }) } catch (error) { return mcpToolRes.error(error, "approving token spending") } } )
- src/evm/modules/wallet/tools.ts:98-120 (handler)The MCP tool handler logic for 'approve_token_spending', which performs the approval by calling the helper function and formats the response.async ({ privateKey, tokenAddress, spenderAddress, amount, network }) => { try { const result = await services.approveERC20( tokenAddress, spenderAddress, amount, privateKey, network ) return mcpToolRes.success({ success: true, txHash: result.txHash, tokenAddress, spenderAddress, amount: result.amount.formatted, symbol: result.token.symbol, network }) } catch (error) { return mcpToolRes.error(error, "approving token spending") } }
- src/evm/services/transfer.ts:139-211 (helper)Core helper function 'approveERC20' that executes the ERC20 approve transaction using viem's walletClient.writeContract on the 'approve' method. Handles ENS resolution, token decimals, amount parsing, and returns transaction details.export async function approveERC20( tokenAddressOrEns: string, spenderAddressOrEns: string, amount: string, privateKey: string | `0x${string}`, network: string = "ethereum" ): Promise<{ txHash: Hash amount: { raw: bigint formatted: string } token: { symbol: string decimals: number } }> { // Resolve ENS names to addresses if needed const tokenAddress = (await resolveAddress( tokenAddressOrEns, network )) as Address const spenderAddress = (await resolveAddress( spenderAddressOrEns, network )) as Address // Ensure the private key has 0x prefix const formattedKey = typeof privateKey === "string" && !privateKey.startsWith("0x") ? (`0x${privateKey}` as `0x${string}`) : (privateKey as `0x${string}`) // Get token details const publicClient = getPublicClient(network) const contract = getContract({ address: tokenAddress, abi: ERC20_ABI, client: publicClient }) // Get token decimals and symbol const decimals = (await contract.read.decimals()) as number const symbol = (await contract.read.symbol()) as string // Parse the amount with the correct number of decimals const rawAmount = parseUnits(amount, decimals) // Create wallet client for sending the transaction const walletClient = getWalletClient(formattedKey, network) // Send the transaction const hash = await walletClient.writeContract({ address: tokenAddress, abi: ERC20_ABI, functionName: "approve", args: [spenderAddress, rawAmount], account: walletClient.account!, chain: walletClient.chain }) return { txHash: hash, amount: { raw: rawAmount, formatted: amount }, token: { symbol, decimals } } }
- src/evm/modules/wallet/index.ts:6-9 (registration)Higher-level registration of the wallet module, which calls registerWalletTools to register the 'approve_token_spending' tool among others.export function registerWallet(server: McpServer) { registerWalletTools(server) registerWaletPrompts(server) }