Connect x402-enabled APIs to AI clients through an MCP server. Users pay for API calls through prompts without managing wallets or payment flows directly.
This guide shows how to bridge x402-enabled APIs to MCP tools so AI clients can call and pay for them through natural-language prompts. It builds on the server from Build a pay-per-call API.
An MCP server that wraps x402-paid endpoints as tools. The AI client types a natural-language prompt, each tool call triggers a paid x402 request, and settlement is visible on Stablescan. The user never sees a wallet prompt.
Agent wallet funding: The MCP server signs payments with a seed phrase you control. Fund that wallet with USDT0 on mainnet before starting the server. A balance of at least $0.10 covers several paid calls; $1.00 is plenty for extended testing. Top up as needed using a standard USDT0 transfer to the wallet’s address.
─── AI Client ───────────────────────────────────────User: "Pull financials for ACME Corp and assess their credit risk."Client calls get_company_financials tool → MCP server sends x402 paid request → Facilitator settles USDT0 on-chain → API returns financial dataClient calls assess_credit_risk tool with the result → MCP server sends x402 paid request → Facilitator settles USDT0 on-chain → API returns risk assessment → Client responds with the combined result
The MCP server acts as a bridge between AI clients and x402-enabled APIs. Each tool makes a paid request using the x402 client SDK and returns the result.
// mcp-server.tsimport { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";import WalletManagerEvm from "@tetherto/wdk-wallet-evm";import { x402Client, wrapFetchWithPayment } from "@x402/fetch";import { registerExactEvmScheme } from "@x402/evm/exact/client";import { z } from "zod";// --- Wallet and x402 client ---const account = await new WalletManagerEvm(process.env.SEED_PHRASE!, { provider: "https://rpc.stable.xyz",}).getAccount(0);const client = new x402Client();registerExactEvmScheme(client, { signer: account });const fetchWithPayment = wrapFetchWithPayment(fetch, client);// --- x402 API base URL ---const API_BASE = process.env.API_BASE || "http://localhost:4021";// --- MCP server ---const server = new McpServer({ name: "x402-payments", version: "1.0.0",});server.tool( "get_company_financials", "Get company financial data by ticker (paid endpoint, $0.01 per call)", { ticker: z.string().describe("Company ticker symbol (e.g. ACME)") }, async ({ ticker }) => { const response = await fetchWithPayment(`${API_BASE}/financials?ticker=${ticker}`); const data = await response.json(); return { content: [{ type: "text", text: JSON.stringify(data) }] }; },);server.tool( "assess_credit_risk", "Assess credit risk from financial data (paid endpoint, $0.05 per call)", { financials: z.string().describe("JSON string of company financial data") }, async ({ financials }) => { const response = await fetchWithPayment(`${API_BASE}/credit-risk`, { method: "POST", headers: { "Content-Type": "application/json" }, body: financials, }); const data = await response.json(); return { content: [{ type: "text", text: JSON.stringify(data) }] }; },);server.tool( "check_balance", "Check the USDT0 balance of the payment wallet", {}, async () => { const USDT0_STABLE = "0x779Ded0c9e1022225f8E0630b35a9b54bE713736"; const balance = await account.getTokenBalance(USDT0_STABLE); const formatted = (Number(balance) / 1e6).toFixed(2); return { content: [{ type: "text", text: `Wallet balance: ${formatted} USDT0` }], }; },);// --- Start ---const transport = new StdioServerTransport();await server.connect(transport);
Each tool handler calls fetchWithPayment, which handles the full x402 payment cycle automatically. The AI client only sees the tool name, description, and parameters.
claude mcp add x402-payments -- npx tsx /path/to/mcp-server.ts
After configuration, restart your AI client. The tools should appear in the available tool list.
The seed phrase in the MCP configuration controls real funds. Store it securely using your OS keychain or a secrets manager rather than in plain-text config files.