--- name: agent-payment-x402 description: Add x402 payment execution to AI agents — per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents need to pay for APIs, services, or other agents. origin: community --- # Agent Payment Execution (x402) Enable AI agents to make autonomous payments with built-in spending controls. Uses the x402 HTTP payment protocol and MCP tools so agents can pay for external services, APIs, or other agents without custodial risk. ## When to Use Use when: your agent needs to pay for an API call, purchase a service, settle with another agent, enforce per-task spending limits, or manage a non-custodial wallet. Pairs naturally with cost-aware-llm-pipeline and security-review skills. ## How It Works ### x402 Protocol x402 extends HTTP 402 (Payment Required) into a machine-negotiable flow. When a server returns `402`, the agent's payment tool automatically negotiates price, checks budget, signs a transaction, and retries — no human in the loop. ### Spending Controls Every payment tool call enforces a `SpendingPolicy`: - **Per-task budget** — max spend for a single agent action - **Per-session budget** — cumulative limit across an entire session - **Allowlisted recipients** — restrict which addresses/services the agent can pay - **Rate limits** — max transactions per minute/hour ### Non-Custodial Wallets Agents hold their own keys via ERC-4337 smart accounts. The orchestrator sets policy before delegation; the agent can only spend within bounds. No pooled funds, no custodial risk. ## MCP Integration The payment layer exposes standard MCP tools that slot into any Claude Code or agent harness setup. > **Security note**: Always pin the package version. This tool manages private keys — unpinned `npx` installs introduce supply-chain risk. ```json { "mcpServers": { "agentpay": { "command": "npx", "args": ["agentwallet-sdk@6.0.0"] } } } ``` ### Available Tools (agent-callable) | Tool | Purpose | |------|---------| | `get_balance` | Check agent wallet balance | | `send_payment` | Send payment to address or ENS | | `check_spending` | Query remaining budget | | `list_transactions` | Audit trail of all payments | > **Note**: Spending policy is set by the **orchestrator** before delegating to the agent — not by the agent itself. This prevents agents from escalating their own spending limits. Configure policy via `set_policy` in your orchestration layer or pre-task hook, never as an agent-callable tool. ## Examples ### Budget enforcement in an MCP client When building an orchestrator that calls the agentpay MCP server, enforce budgets before dispatching paid tool calls. > **Prerequisites**: Install the package before adding the MCP config — `npx` without `-y` will prompt for confirmation in non-interactive environments, causing the server to hang: `npm install -g agentwallet-sdk@6.0.0` ```typescript import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; async function main() { // 1. Validate credentials before constructing the transport. // A missing key must fail immediately — never let the subprocess start without auth. const walletKey = process.env.WALLET_PRIVATE_KEY; if (!walletKey) { throw new Error("WALLET_PRIVATE_KEY is not set — refusing to start payment server"); } // Connect to the agentpay MCP server via stdio transport. // Whitelist only the env vars the server needs — never forward all of process.env // to a third-party subprocess that manages private keys. const transport = new StdioClientTransport({ command: "npx", args: ["agentwallet-sdk@6.0.0"], env: { PATH: process.env.PATH ?? "", NODE_ENV: process.env.NODE_ENV ?? "production", WALLET_PRIVATE_KEY: walletKey, }, }); const agentpay = new Client({ name: "orchestrator", version: "1.0.0" }); await agentpay.connect(transport); // 2. Set spending policy before delegating to the agent. // Always verify success — a silent failure means no controls are active. const policyResult = await agentpay.callTool({ name: "set_policy", arguments: { per_task_budget: 0.50, per_session_budget: 5.00, allowlisted_recipients: ["api.example.com"], }, }); if (policyResult.isError) { throw new Error( `Failed to set spending policy — do not delegate: ${JSON.stringify(policyResult.content)}` ); } // 3. Use preToolCheck before any paid action await preToolCheck(agentpay, 0.01); } // Pre-tool hook: fail-closed budget enforcement with four distinct error paths. async function preToolCheck(agentpay: Client, apiCost: number): Promise { // Path 1: Reject invalid input (NaN/Infinity bypass the < comparison) if (!Number.isFinite(apiCost) || apiCost < 0) { throw new Error(`Invalid apiCost: ${apiCost} — action blocked`); } // Path 2: Transport/connectivity failure let result; try { result = await agentpay.callTool({ name: "check_spending" }); } catch (err) { throw new Error(`Payment service unreachable — action blocked: ${err}`); } // Path 3: Tool returned an error (e.g., auth failure, wallet not initialised) if (result.isError) { throw new Error( `check_spending failed — action blocked: ${JSON.stringify(result.content)}` ); } // Path 4: Parse and validate the response shape let remaining: number; try { const parsed = JSON.parse( (result.content as Array<{ text: string }>)[0].text ); if (!Number.isFinite(parsed?.remaining)) { throw new TypeError("missing or non-finite 'remaining' field"); } remaining = parsed.remaining; } catch (err) { throw new Error( `check_spending returned unexpected format — action blocked: ${err}` ); } // Path 5: Budget exceeded if (remaining < apiCost) { throw new Error( `Budget exceeded: need $${apiCost} but only $${remaining} remaining` ); } } main().catch((err) => { console.error(err); process.exitCode = 1; }); ``` ## Best Practices - **Set budgets before delegation**: When spawning sub-agents, attach a SpendingPolicy via your orchestration layer. Never give an agent unlimited spend. - **Pin your dependencies**: Always specify an exact version in your MCP config (e.g., `agentwallet-sdk@6.0.0`). Verify package integrity before deploying to production. - **Audit trails**: Use `list_transactions` in post-task hooks to log what was spent and why. - **Fail closed**: If the payment tool is unreachable, block the paid action — don't fall back to unmetered access. - **Pair with security-review**: Payment tools are high-privilege. Apply the same scrutiny as shell access. - **Test with testnets first**: Use Base Sepolia for development; switch to Base mainnet for production. ## Production Reference - **npm**: [`agentwallet-sdk`](https://www.npmjs.com/package/agentwallet-sdk) - **Merged into NVIDIA NeMo Agent Toolkit**: [PR #17](https://github.com/NVIDIA/NeMo-Agent-Toolkit-Examples/pull/17) — x402 payment tool for NVIDIA's agent examples - **Protocol spec**: [x402.org](https://x402.org)