We Built an MCP Server That AI Agents Pay — the Full x402 Loop, Verified On-Chain
A field report on x402 agent payments: per-call USDC pricing on MCP tools, the client-side payment loop nobody documents, and seven gotchas from getting real money to settle on-chain.
In the first week of July 2026, three things shipped within 48 hours of each other: Apify opened 20,000+ web-scraping Actors to autonomous agent payments, Cloudflare opened the waitlist for its Monetization Gateway, and Vercel's x402-mcp library made it possible to put a price on an MCP tool in one function call. The pitch is simple: an AI agent hits your endpoint, gets told "that costs half a cent," pays in USDC, and gets its data — no account, no API key, no human in the loop.
We wanted to know how much of that is real, so we built it: an MCP server that sells live Clash Royale metagame data per-call. It is running at mcp.trophycoach.com/api/mcp right now, and agents have paid it. This is what we learned — including the parts the launch posts skip.
What x402 actually is
HTTP has had a 402 Payment Required status code since the 1990s. Nobody ever used it. x402 is an open protocol (started by Coinbase, now under open governance) that finally gives it a job: when a client calls a paid resource without payment, the server responds with a 402 and a machine-readable price quote — amount, currency, recipient address, network. The client signs a payment authorization, retries the request with it attached, and the server verifies, executes, and settles.
Three properties make this work for agents where credit cards never could:
- No account. The payment authorization is self-contained. A brand-new agent with a funded wallet can buy from you on its first request.
- Gasless for the payer. Payments use EIP-3009 (
transferWithAuthorization): the agent signs a message; a third-party "facilitator" service submits the on-chain transaction. The paying wallet needs USDC but zero ETH. - Micro-viable. Settlement on Base (an Ethereum L2) makes a half-cent charge economically sane. Try that with a card processor's 30-cent minimum.
The architecture: be a thin wrapper
Our biggest design decision was what not to build. The MCP server owns no data pipeline, no database, no scraper. It is a monetization membrane around an API we already operate (ClashCoachAI's deck-meta endpoints). Four tools, one free:
| Tool | Price | What it returns |
|---|---|---|
get_meta_overview |
free | The catalog: ranges, tools, prices |
get_deck_meta |
$0.005 | Dominant decks, threats, card levels |
get_matchups |
$0.005 | Head-to-head deck win rates |
compare_ranges |
$0.01 | Cross-range meta shifts (2–5 ranges) |
The free tool matters more than it looks: agents (and their humans) need a zero-cost way to discover your catalog before they can decide to spend.
Server-side, x402-mcp wraps Vercel's mcp-handler and adds exactly one concept — a paidTool:
const handler = createPaidMcpHandler(
(server) => {
server.paidTool(
"get_deck_meta",
"Current deck meta for a trophy range.",
{ price: 0.005 }, // USD
{ range: z.enum(TROPHY_RANGES) }, // zod schema
{},
async ({ range }) => json(await upstream().getMetaByRange(range)),
);
},
{ serverInfo: { name: "trophycoach-mcp", version: "0.1.0" } },
{
recipient: process.env.WALLET_ADDRESS, // where USDC lands
facilitator: { url: "https://x402.org/facilitator" },
network: "base-sepolia", // testnet; "base" for mainnet
basePath: "/api",
},
);
export { handler as GET, handler as POST };That is genuinely the whole payment integration on the server. The interesting part is the client.
The part nobody documents: clients don't auto-pay
We assumed wrapping our MCP client with withPayment() meant paid calls would just work. They don't — our first test "passed" while actually receiving a payment-required error we weren't checking for. The wrapper doesn't intercept and pay. Instead it adds two client-side tools (generatePaymentAuthorization and viewAccountBalance) and expects the agent to drive a three-step loop:
// 1. Call the paid tool with no payment -> 402 envelope, not data
const unpaid = await tools.get_deck_meta.execute({ range: "7000-8000" });
const requirements = JSON.parse(text(unpaid)).accepts[0];
// { maxAmountRequired: "5000", payTo: "0x3f0A...", network: "base-sepolia", ... }
// 2. Sign an EIP-3009 authorization for exactly that quote
const { paymentAuthorization } = await tools.generatePaymentAuthorization
.execute({ paymentRequirements: requirements });
// 3. Retry WITH payment -> real data, and USDC moves on-chain
const paid = await tools.get_deck_meta.execute({
range: "7000-8000",
paymentAuthorization,
});This is a deliberate design, not a gap: the LLM decides whether a price is worth paying, with a client-configured ceiling (maxPaymentValue) as the hard stop. But if you're writing a deterministic test client, you are the LLM — you must implement the catch-quote-sign-retry loop yourself, and you must check isError on every result, because the 402 envelope arrives as a perfectly successful MCP response.
Proof it works
On Base Sepolia testnet, with a faucet-funded payer wallet: the paid call returned live production data and the payer's balance dropped from 20.000 to 19.995 USDC, with exactly 0.005 USDC arriving in the recipient wallet. We've since run the loop end-to-end against the deployed server repeatedly — six settlements and counting.
Every paid call also emits a structured log line:
{"type":"tool_call","tool":"get_deck_meta","paid":true,"priceUsd":0.005,"ok":true,"ms":31}That's a v0 revenue ledger straight from runtime logs — no dashboard required until the volume justifies one.
Seven gotchas that will cost you an afternoon
-
Pin your AI SDK version.
[email protected]needs[email protected]— the experimental MCP client it builds on was removed in later 5.0.x releases and in v6. The peer range says>=5.0.0; the peer range lies. -
The default facilitator is testnet-only.
x402.org/facilitatorsettles Base Sepolia only. Mainnet means Coinbase's CDP facilitator and real keys. Plan the env flip; don't discover it on launch day. -
Prices are atomic units in the envelope. You write
price: 0.005; the 402 quote saysmaxAmountRequired: "5000"— USDC has six decimals. Every balance check and spending ceiling speaks atomic units. -
Verify-then-execute-then-settle. The server verifies payment before your handler runs and only settles after it succeeds — so agents don't pay for your bugs. Schema-invalid calls are rejected before any charge, which also means input validation is your anti-griefing layer.
-
RPC nodes lie for a few seconds. Our balance check re-read right after settlement and saw no change — the money had moved; the node was serving a stale block. Retry balance assertions for ~15 seconds before declaring failure.
-
Your own bot protection will block you. Our upstream API sits behind Vercel's security checkpoint, which 429'd our own server's proxy calls. Fix: a protection-bypass token sent as a header. Corollary: if you put your paid endpoint behind aggressive bot protection, you are blocking your customers — they are all bots.
-
Domain aliases don't always auto-attach. Adding a custom domain to the Vercel project didn't alias it to the existing deployment — fresh 404 until an explicit
vercel alias set. Verify with a real request, not the dashboard checkmark.
What this means if you build MCP tools
The whole integration was a day of work, and most of that was learning the gotchas above — the actual payment surface is one function and four env vars. If you already operate an API with data agents want, the marginal cost of an x402-monetized MCP wrapper is now close to zero.
The scaffolding is commoditized (Vercel ships a free template); the real questions are the ones scaffolds can't answer for you: what data is worth half a cent to an agent, and how agents will discover you. That second problem — discovery — is the open one, and it's where we're heading next.
Want to see the loop live? Point any x402-capable MCP client at https://mcp.trophycoach.com/api/mcp. The overview tool is free; the most expensive mistake you can make after that is one cent.
Curious where AI actually fits your job?
Answer a few questions and get a free, personalized 30-day AI plan for your exact role — the tasks to automate first, and the prompts to do it.
Frequently asked questions
What is the x402 protocol?+
x402 is an open protocol (started by Coinbase, now under open governance) that puts HTTP's long-dormant 402 Payment Required status code to work. When a client calls a paid resource without payment, the server responds with a machine-readable price quote. The client signs a payment authorization, retries with it attached, and the server verifies, executes, and settles — typically in USDC on the Base network. No account or API key is needed on either side.
Do AI agents really pay without a human in the loop?+
Yes, with one nuance: the client-side wrapper doesn't auto-pay. The agent (or your test harness) must drive a three-step loop — call the tool, receive the 402 price quote, sign an EIP-3009 payment authorization, and retry with it attached. A client-configured spending ceiling (maxPaymentValue) acts as the hard stop. In our verified runs, an agent paid $0.005 in USDC per call and received live data with no human intervention.
How much does it cost to charge per-call on an MCP server?+
The integration itself is close to free: the x402-mcp library is open source, the testnet facilitator is a free public service, and payments are gasless for the payer (EIP-3009 transferWithAuthorization means the paying wallet needs USDC but zero ETH). Settlement on Base makes half-cent charges economically viable — there is no Stripe-style 30-cent minimum.
What's the difference between testnet and mainnet for x402 payments?+
The default facilitator at x402.org/facilitator settles only on Base Sepolia (testnet, with free faucet USDC from faucet.circle.com). Going to mainnet means switching the network config to 'base' and using a production facilitator such as Coinbase's CDP facilitator — plus a properly custodied recipient wallet, since real USDC will accumulate there.
Do I need to build a data pipeline to sell data to AI agents?+
No — the highest-leverage pattern is a thin monetization wrapper around an API you already operate. Our entire server owns no database and no scraper: it proxies existing endpoints and adds per-call pricing. The whole payment surface is one function (paidTool) and four environment variables.
Related Guides
Vibe Coding Mistakes: 12 Ways AI-Generated Apps Break in Production (and How to Fix Each)
Vibe coding produces great first screens and fragile internals. Here are the 12 failure modes AI-generated apps hit in production — leaked keys, unvalidated tool inputs, silent mutations, package bloat — each with a concrete fix.
Best AI Coding Stack for Solo Founders (2026)
The exact AI coding stack to buy as a solo founder: one $20 agent, free hosting and database to start, and a clear rule for when to upgrade — without paying for overlapping tools.
Claude for Financial Services: What Anthropic's Free Plugin Does (and the Layer It Leaves to You)
Anthropic shipped a free Claude for Financial Services plugin that builds plans, models, and rebalances. Here's exactly what it covers, what it leaves out, and how advisors fill the compliance and client-communication gap.