# 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.
**Author:** [Alex Lowe](https://theaicareerlab.com/about) — Founder, The AI Career Lab
**Published:** 2026-07-02
**Canonical URL:** https://theaicareerlab.com/blog/x402-mcp-server-agents-pay
**Category:** guide
**Tags:** MCP, x402, AI agents, agent payments, USDC, Claude Code, Vercel, 2026
---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`:

```ts
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:

```ts
// 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:

```json
{"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

1. **Pin your AI SDK version.** `x402-mcp@0.1.1` needs `ai@5.0.33` — 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.

2. **The default facilitator is testnet-only.** `x402.org/facilitator` settles Base Sepolia only. Mainnet means Coinbase's CDP facilitator and real keys. Plan the env flip; don't discover it on launch day.

3. **Prices are atomic units in the envelope.** You write `price: 0.005`; the 402 quote says `maxAmountRequired: "5000"` — USDC has six decimals. Every balance check and spending ceiling speaks atomic units.

4. **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.

5. **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.

6. **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.

7. **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.
## 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.

---

*Canonical version: https://theaicareerlab.com/blog/x402-mcp-server-agents-pay*
*This document is the Markdown companion served for AI crawlers and answer engines. See the canonical URL for the rendered version with navigation, related content, and interactive elements.*