I shipped a paid MCP gateway today: tools/list is free, tools/call costs $0.05 in USDC per call, settled via x402 v2 on Base. It's live right now — no signup, no API keys. The payment is the credential.
But the real story isn't the pricing. It's the implementation detail that every MCP builder attempting x402 will hit — and that quietly breaks the entire payment flow if you miss it.
Here's what happens when you bolt x402 onto an MCP server the naive way. The agent calls tools/call without payment. Your server returns a JSON-RPC error: -32000, Payment Required. Done, right?
Wrong. MCP clients swallow JSON-RPC errors before the model ever sees them. The client sees an error code, the model sees "tool call failed," and the payment challenge — the accepts array, the price, the payTo — never reaches the agent. The agent can't pay because it never learned the price.
This is documented by anchor-x402 (18 paid x402 services, MIT-licensed), and I hit it myself. The fix is simple but non-obvious:
Return the payment challenge as a successful result with isError: true, not as a JSON-RPC error.
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [{
"type": "text",
"text": "Payment required: $0.05 USDC. Sign and retry with PAYMENT-SIGNATURE."
}],
"structuredContent": {
"x402Version": 2,
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"amount": "50000",
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0xc29185fa176357612f3194735753e520e91adc46"
}]
},
"isError": true
}
}
The agent model reads this, sees the price and the challenge, signs an EIP-3009 transferWithAuthorization, and retries. The flow works end-to-end. isError: true means the client passes it through to the model instead of eating it.
The second design decision I copied from anchor-x402: tools/list and discovery are always free. This is correct by construction — agents can't discover what they can't see. Charging for tools/list is a paywall on your own storefront.
The full pattern:
tools/list → free, alwaystools/call → paid, isError: true result on unpaid attempts/.well-known/x402 → free, machine-readable manifest
Every byte of actual data sits behind a 402. Everything the agent needs to decide to buy is free. That's the whole distribution model for machine commerce.
The x402 MCP space is filling fast at the utility layer: converters, validators, formatters at $0.001–$0.02/call (anchor-x402, agent402). Real numbers from the wild: an MCPize author reports ~$8,500/mo net on a security-auditor server; self-hosted x402 did 3.3M transactions in 30 days at ~$0.46 average.
But nobody does trading or telemetry MCP tools. That's the lane I took:
get_market_cycle`` scrape_url
Both follow fail-closed commerce: bot-blocked pages, bad symbols, garbled output return no-charge errors. Failed delivery never earns payment. Firecrawl's charge-on-4xx is a cited complaint in the ecosystem; I went the other way.
curl -X POST https://squeezeos-api.onrender.com/v1/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
curl -X POST https://squeezeos-api.onrender.com/v1/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"get_market_cycle","arguments":{"symbol":"AAPL"}}}'
The manifest is at https://squeezeos-api.onrender.com/.well-known/x402. x402 v2, USDC on Base, CDP facilitator sponsors gas.
If you're putting x402 payments on your MCP server: never return the challenge as a JSON-RPC error. isError: true result, challenge in structuredContent. That's the difference between a payment flow that works and one that silently dies in the client.
Built by ScriptMasterLabs (service-disabled veteran-owned small business). Happy to answer questions about the x402 integration or the verify→execute→accept→settle flow.