Skip to content

RFC: Native Token Metering, Session Budgets, and Payment Tracking (x402) for MCP #3229

Description

@sophieamoure2026-ui

RFC: Native Token Metering, Session Budgets, and Payment Tracking (x402) for MCP

Context

As the Model Context Protocol (MCP) rapidly scales to become the standard interface for autonomous agents, a critical vulnerability in the unit economics of the Agentic Web has emerged.

Currently, MCP provides no native protocol-level mechanism for payment tracking, session budget caps, or token metering. As highlighted in recent ecosystem discussions (e.g., google-gemini/gemini-cli#4472), developers are experiencing massive, unexpected API bills (e.g., $2,800 in 60 seconds) because autonomous agents can enter infinite loops or aggressively poll paid resources with zero proactive financial guardrails.

Simultaneously, open-source MCP server creators are struggling to host their servers publicly because they absorb the inference and database COGS without a standardized way to bill the agent operator per-transaction.

Proposal

We propose introducing x402 (inspired by the HTTP 402 Payment Required status code)—a standardized protocol extension for MCP that introduces native capabilities for token metering, live margin tracking, and proactive session budget firewalls.

1. The capabilities Extension

Servers should be able to advertise their metering and billing requirements during the initialization handshake.

{
  "protocolVersion": "2024-11-05",
  "capabilities": {
    "prompts": {},
    "resources": {},
    "tools": {},
    "x402_metering": {
      "supported": true,
      "currency": "usd",
      "enforces_budget_caps": true
    }
  },
  "serverInfo": {
    "name": "Acme Database Server",
    "version": "1.0.0"
  }
}

2. Standardized JSON-RPC Error: 4020 Payment Required

Currently, if an MCP server wants to block a transaction because the client has insufficient funds or has exceeded their session budget, they must return a generic -32000 Server Error.

We propose adding a standardized 4020 JSON-RPC error code to explicitly signal that a transaction was blocked due to financial guardrails.

{
  "jsonrpc": "2.0",
  "id": 4,
  "error": {
    "code": -4020,
    "message": "x402: Session budget of $10.00 USD exceeded.",
    "data": {
      "projected_cost_usd": 0.05,
      "remaining_budget_usd": 0.01
    }
  }
}

3. Per-Transaction Cost Headers (Metadata)

When an MCP Server responds to a tool call or resource read, it should optionally include x402 metadata indicating the cost of that specific transaction. This allows the client (the agent runner) to maintain a live ledger of its own spend.

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "..."
      }
    ],
    "_x402": {
      "cost_usd": 0.05,
      "input_tokens": 1200,
      "output_tokens": 400
    }
  }
}

Why this belongs at the Protocol Level

If billing and metering are pushed to the API gateway layer or handled via ad-hoc SDK decorators (like neuforge-pay), the ecosystem will fracture. Agents will not know how to automatically handle 402 responses or parse cost metadata if every server implements it differently.

By standardizing x402 in the core protocol:

  1. Developers are protected: Agents can natively halt themselves if a server returns a -4020 error.
  2. Creators can monetize: Open-source developers can safely host their MCP servers, knowing the protocol enforces their required take-rate and tracks the exact token usage.

Reference Implementation

Our team has built a working reference implementation of this logic at the Python SDK level (NeuForge Pay), demonstrating 1-ms latency ledger validation and proactive blocking. We would love to contribute this architecture upstream to the core MCP specification.

Looking forward to the community's thoughts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions