跳到正文
DEV Community· edvyno·· 3 小時前AI 評分62

MCP 伺服器如何以 x402 為 tools/call 按次收費

MCP servers that charge per call: the x402 handshake in tools/call

AI 導讀

作者介紹 x402 如何讓 MCP 伺服器以 HTTP 402 Payment Required 要求付款,並由用戶端結算後重試 tools/call。作者的伺服器有 16 項工具,以 USDC 在 Base 按次收費;用戶端以 X-PAYMENT 提交付款證明後重試,無須註冊帳戶。

正文

You can build an MCP server in an afternoon. Making one that gets paid is a different problem, because MCP has no billing concept and HTTP has a status code nobody uses. Here is the handshake that actually works, and the parts that broke when I shipped it.

Context, disclosed: I run a paid crypto-intel MCP server (16 tools, USDC per call on Base, no signup). The numbers below are measured on it, including the unflattering ones.

The gap MCP leaves open

tools/call is a JSON-RPC method over a transport. Nothing in the spec says who is allowed to call, how often, or what it costs. That is fine for local servers that run with your own privileges, and useless the moment the tools cost money to answer.

Three options exist:

  1. API keys. A signup, a database, a plan page. For an agent, this means a human in the loop before the first call — the worst possible friction for something that is supposed to act autonomously.
  2. OAuth. Great for user-delegated data. Terrible for a $0.02 price feed, where the token dance costs more than the datum.
  3. Pay per call. No identity at all: the price is in the response, the client pays, the client retries. This is what x402 does, and it is the only one of the three that an unattended agent can do end to end.

The handshake, concretely

x402 uses the one HTTP status code the web never implemented: 402 Payment Required. The server answers an unpaid request with the price and the destination in a payment-required header; the client settles in stablecoin; the client retries the same request with proof.

$ curl -i "https://your-host/mcp" -H 'content-type: application/json' \
    -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
         "params":{"name":"some_paid_tool","arguments":{}}}'

HTTP/2 402
payment-required: <base64 {scheme, network: eip155:8453,
                            asset: USDC, amount, payTo, resource, nonce}>
content-type: application/json

{"price_usd":"0.02","pay_to":"0x…","network":"eip155:8453"}

A paying client does exactly three things: read the challenge, settle it through a facilitator, retry with X-PAYMENT. Fifteen lines in most SDKs. No account, no key exchange, no human.

Two implementation rules I would tattoo on the codebase:

Keep the 402 byte-identical to your middleware. If your framework emits a payment-required header and you also write a JSON body, both must describe the same price, asset and address. Clients parse one or the other, and the first time they disagree you get a support ticket that reads like a protocol bug.

Price belongs in the challenge, not the code. Changing a price should be a config edit, not a deploy — and you will change prices once you see what agents actually buy.

Three things that broke in production

1. Not everything should be paid. I made one tool free (akari_board — a live edge board) and it is the only thing that reliably produces repeat traffic. A free, genuinely useful tool is the demo; the paid tools are the product. Making all 16 paid cut discovery to nothing.

2. Discovery is the whole game. Listing in two registries and publishing a machine-readable catalog (/market.json, prices and schemas, no HTML) moved more traffic than any announcement. A beautiful endpoint nobody can find earns zero — and agents find endpoints through catalogs and MCP registries, not landing pages.

3. Idempotency beats dashboards. Your buyers are programs that retry. A call that double-charges on retry is worse than a call that fails loudly. Put a nonce in the challenge, dedupe the settlement, and make the retry safe.

What the numbers look like

Roughly a month in: three external buyers, $0.06 total, against 16 tools. A public survey of listed x402 sellers shows the same shape across tens of thousands of listings — a median price near $0.03, most earning nothing, and a handful taking the majority of volume.

I am telling you that because the interesting part is not the protocol. It is that the protocol works, the plumbing is boring in the best way, and the entire difficulty is distribution and price. Machine payments have arrived; the market for them has not caught up yet.

If you are building one

  • Ship the free tool first. It is the only thing that compounds.
  • Publish /market.json and /llms.txt; list in every honest directory before adding a 17th tool.
  • Return the 402 challenge in dry-run mode by default, so nobody's first experience is an unexpected charge.
  • Charge for the decision, not the data, if you can. Data is commoditised at $0.02; "this cleared my gate set, here is the size and the stop" is not.

Poking at mine, free: market.json, the board, the MCP endpoint. The server itself is MIT: github.com/edvyno/akari-x402-mcp.

來源:DEV Community · dev.to