A paid MCP tool call, step by step

Every request and response here was captured from the live server on Oct 17, 2026, including a real paid call at 11:57 AM CT (tx 0x8922d5ca…0412b2 on Base).

Server: https://grokzilla.shop/mcp, Streamable HTTP, stateless JSON-RPC. No API key and no session header.

1. initialize

curl -sS https://grokzilla.shop/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"0.0.1"}}}'

Reply (trimmed):

{"jsonrpc":"2.0","id":1,"result":{
  "protocolVersion":"2025-06-18",
  "capabilities":{"tools":{"listChanged":false}},
  "serverInfo":{"name":"grokzilla-micro-pay","version":"0.1.0"},
  "instructions":"Tools are pay-per-call over x402 (USDC on Base, eip155:8453). Discovery tools list_skills and get_skill are free. ..."}}

Then send {"jsonrpc":"2.0","method":"notifications/initialized"}. The server answers HTTP 202 with no body.

2. tools/list

curl -sS https://grokzilla.shop/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

You get 30 tools. list_skills and get_skill are free. The other 28 are paid, one per skill, and each description ends with its price, for example "Price $0.0041 via x402." Here is the json_repair entry:

{"name":"json_repair",
 "description":"Repair malformed or truncated JSON from LLMs, JS or Python: ... Price $0.0041 via x402.",
 "inputSchema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":400000}},"required":["text"]}}

3. tools/call without payment: the challenge

curl -sS https://grokzilla.shop/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"json_repair","arguments":{"text":"{a: 1, b: [2,3,],}"}}}'

The HTTP status is 200, because the challenge rides inside the MCP result, not as an HTTP 402. The skill does not run. Captured reply (the long description and bazaar schema are cut down):

{"jsonrpc":"2.0","id":3,"result":{
  "isError": true,
  "content":[{"type":"text","text":"Payment required. Amount 4100 (atomic USDC) on eip155:8453 via scheme exact, payTo 0xc22f9CAEBAc37fE72D5142f35f21f6696Ea9Ef69. This tool is pay-per-call via x402 (USDC on Base). The skill handler did not run. structuredContent is the PaymentRequired challenge."}],
  "structuredContent":{
    "x402Version": 2,
    "error": "Payment required to access this tool",
    "resource": {
      "url": "mcp://tool/json_repair",
      "description": "Repair malformed or truncated JSON ...",
      "mimeType": "application/json",
      "serviceName": "Grokzilla x402 Micro Pay"
    },
    "accepts": [{
      "scheme": "exact",
      "network": "eip155:8453",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "amount": "4100",
      "payTo": "0xc22f9CAEBAc37fE72D5142f35f21f6696Ea9Ef69",
      "maxTimeoutSeconds": 300,
      "extra": {"name": "USD Coin", "version": "2"}
    }],
    "extensions": {"bazaar": {
      "info": {
        "input": {"type":"mcp","toolName":"json_repair","transport":"streamable-http","inputSchema":{"...":"same as tools/list"},"example":{"text":"```json\n{name: 'Ada', tags: ['math', 'code',], active: True, // note\n}\n```"}},
        "output": {"type":"json","example":{"skill":"json_repair","ok":true,"json":{"name":"Ada","tags":["math","code"],"active":true},"repaired":"{\"name\":\"Ada\",\"tags\":[\"math\",\"code\"],\"active\":true}","fixes":["unquoted_keys","single_quotes","trailing_commas","python_literals","removed_comments"],"changed":true}}
      },
      "schema": {"...": "JSON Schema for info"}
    }}
  }}}

How to read it:

4. Pay and retry

You don't build the payment by hand. An x402-aware MCP client reads structuredContent, signs an exact USDC authorization (EIP-3009) with your wallet, and repeats the same tools/call with the payment in params._meta["x402/payment"]:

{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{
  "name":"json_repair",
  "arguments":{"text":"{a: 1, b: [2,3,],}"},
  "_meta":{"x402/payment": { "...": "PaymentPayload signed by your client" }}}}

The server checks the payment with its facilitator, runs the same handler as the HTTP route, settles, and returns the result. Captured paid reply (Oct 17, 11:57 AM CT; that capture used JSON-RPC id 2):

{"jsonrpc":"2.0","id":2,"result":{
  "content":[{"type":"text","text":"{\"skill\": \"json_repair\", \"ok\": true, ...}"}],
  "structuredContent":{"skill":"json_repair","ok":true,"json":{"a":1,"b":[2,3]},"repaired":"{\"a\":1,\"b\":[2,3]}","fixes":["unquoted_keys","trailing_commas"],"changed":true},
  "isError": false,
  "_meta":{"x402/payment-response":{
    "success": true,
    "payer": "0x708755c5f9ec60aB416D956e1ED3c15775372B52",
    "transaction": "0x8922d5ca49e0267f7462cc747e57ea4bd085afd91cd50e01e135b0ed520412b2",
    "network": "eip155:8453"}}}}

transaction is the Base transaction hash. That one moved 4100 atomic USDC from the payer to 0xc22f…Ef69.

If the payment can't be verified (an unfunded wallet, for example), nothing settles and the skill doesn't run. You get isError: true with the challenge back in structuredContent ("error": "payment_verification_failed") and this _meta:

{"x402/error":{"code":"payment_verification_failed","reason":"payment_verification_failed","message":"The facilitator could not verify this payment."},"charged":false}

Clients that do this today: TypeScript @x402/mcp (createx402MCPClient) and Python x402.mcp. See your agent pays in 30 seconds for a working setup.

When nothing is charged

Same call over plain HTTP

Each tool is also POST https://grokzilla.shop/api/skills/<name> (the skill name with dashes, for example json-repair). Unpaid, that returns a real HTTP 402 with the same accepts[] in the body and base64 in the payment-required header. Add X-X402-Validate-Only: 1 to check your input for free: 422 if it's wrong, 402 if it's ready to pay.