DNAbyD3Docs

Pay for MCP tool calls

How an MCP client pays for a priced tool call with x402 or DNA.

A site on DNA can price the tools on its MCP server. Connecting, listing tools and every other message stay free; a priced tools/call, resources/read or prompts/get without payment gets a tool result asking for it, as the x402 MCP transport specifies.

The exchange

  1. Call the tool. You get a normal JSON-RPC result with isError: true.
  2. Read the terms from structuredContent, pick one entry from accepts and sign it, as for x402.
  3. Call the tool again with the signed payment in params._meta["x402/payment"].
  4. The result carries the receipt in _meta["x402/payment-response"].
{
  "isError": true,
  "structuredContent": {
    "x402Version": 2,
    "accepts": [{ "scheme": "exact", "network": "eip155:8453", "...": "..." }],
    "extensions": {
      "dna.d3.com/pay": { "payUrl": "https://dna.d3.com/pay?handoff=…", "handoff": {}, "methods": [] }
    }
  },
  "content": [
    { "type": "text", "text": "{…the same JSON…}" },
    { "type": "text", "text": "…" }
  ]
}

The first text item repeats structuredContent, for a client that reads text only. The second says what to do, in words a model can act on.

Pay with DNA instead

extensions["dna.d3.com/pay"] is the body of a Pay with DNA 402: show the person payUrl. Once they approve, send the same call to handoff.fetchUrl, the server's URL with the handoff attached, and it is served and charged. A client that does not know this extension ignores it.

Why the answer is a 200, not a 402

The result rides an HTTP 200, as the binding requires. A client that pays only on an HTTP 402 sees a tool error; an MCP client that implements the binding pays as above.

On this page