send_payment
Send USDC payments to any Ethereum address. A 2% service fee is deducted from your wallet. Confirm amount and recipient before calling.
Instructions
Send a USDC payment to any Ethereum address. A 2% service fee is deducted automatically from your wallet. Confirm amount and recipient with the user before calling.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| to | Yes | Recipient Ethereum address (0x-prefixed, 42 chars) | |
| amount | Yes | USDC amount as string, e.g. "2.50" | |
| memo | No | Optional note for the payment | |
| idempotencyKey | No | Optional key to prevent duplicate payments on retry |
Implementation Reference
- src/index.ts:134-156 (registration)Registration of the send_payment tool on the MCP server with description and schema
// Tool 3: Send Payment server.tool( "send_payment", "Send a USDC payment to any Ethereum address. A 2% service fee is deducted automatically from your wallet. Confirm amount and recipient with the user before calling.", { to: z.string().describe("Recipient Ethereum address (0x-prefixed, 42 chars)"), amount: z.string().describe('USDC amount as string, e.g. "2.50"'), memo: z.string().optional().describe("Optional note for the payment"), idempotencyKey: z.string().optional().describe("Optional key to prevent duplicate payments on retry"), }, async ({ to, amount, memo, idempotencyKey }) => { try { const body: Record<string, unknown> = { to, amount, currency: "USDC" }; if (memo) body.memo = memo; if (idempotencyKey) body.idempotencyKey = idempotencyKey; const res = await callApi("POST", "/payments", body); if (!res.ok) return errorResponse("Payment failed", res); return successResponse(res.json); } catch (e) { return { content: [{ type: "text" as const, text: `Payment error: ${e}` }], isError: true }; } }, ); - src/index.ts:144-155 (handler)Handler function that sends a USDC payment to an Ethereum address via POST /payments API endpoint
async ({ to, amount, memo, idempotencyKey }) => { try { const body: Record<string, unknown> = { to, amount, currency: "USDC" }; if (memo) body.memo = memo; if (idempotencyKey) body.idempotencyKey = idempotencyKey; const res = await callApi("POST", "/payments", body); if (!res.ok) return errorResponse("Payment failed", res); return successResponse(res.json); } catch (e) { return { content: [{ type: "text" as const, text: `Payment error: ${e}` }], isError: true }; } }, - src/index.ts:138-143 (schema)Zod schema defining input parameters: to (Ethereum address), amount (USDC string), memo (optional), idempotencyKey (optional)
{ to: z.string().describe("Recipient Ethereum address (0x-prefixed, 42 chars)"), amount: z.string().describe('USDC amount as string, e.g. "2.50"'), memo: z.string().optional().describe("Optional note for the payment"), idempotencyKey: z.string().optional().describe("Optional key to prevent duplicate payments on retry"), }, - src/index.ts:33-62 (helper)Helper function used by send_payment handler to make the HTTP POST request to /payments endpoint
async function callApi( method: "GET" | "POST", path: string, body?: Record<string, unknown>, auth = true, ): Promise<ApiResult> { if (auth && !API_KEY) { return { ok: false, status: 401, json: { error: "config_missing", message: "CARDZERO_API_KEY is not set. Get one at https://cardzero.ai", }, }; } const headers: Record<string, string> = {}; if (auth) headers["Authorization"] = `Bearer ${API_KEY}`; if (body) headers["Content-Type"] = "application/json"; const res = await fetch(`${API_URL}${path}`, { method, headers, body: body ? JSON.stringify(body) : undefined, }); const json = await res.json() as Record<string, unknown>; return { ok: res.ok, status: res.status, json }; }