How to charge for an MCP server or tool
An MCP server charges for a tool by answering the tool call with a price instead of a result. The agent sends tools/call, the server replies with a tool result carrying isError: true and a PaymentRequired object listing what it accepts, the agent signs a stablecoin payment and repeats the identical tools/call with the signed payload in _meta["x402/payment"], and the server verifies that payment, runs the tool, settles the transfer through a facilitator, and returns the real result with the transaction hash in _meta["x402/payment-response"]. No account is created, no API key is issued, and no subscription is signed. That flow is the x402 MCP transport, and on top of an MCP server you already run it is roughly thirty lines of code.
What is an MCP tool, and what is MCP tooling?
The Model Context Protocol "is an open-source standard for connecting AI applications to external systems" (modelcontextprotocol.io). A server built on it exposes three kinds of thing, and only one of them is a sensible unit to bill.
| Building block | Who decides to use it | Protocol methods |
|---|---|---|
| Tools | the model | tools/list, tools/call |
| Resources | the host application | resources/list, resources/templates/list, resources/read |
| Prompts | the user | prompts/list, prompts/get |
A tool is a named function with a JSON Schema for its arguments. "MCP tooling" usually means that set of functions plus the schemas and descriptions the model reads to pick between them. Tools are the billable unit because the model chooses them deliberately and the MCP specification already expects a consent step around them: "Tools may require user consent prior to execution, helping to ensure users maintain control over actions taken by a model" (MCP docs, Understanding MCP servers). A payment prompt slots into a decision point that exists already.
Resources and prompts are different. The host may read a resource to fill context without the model asking, so a per-read charge bills work nobody requested.
How does payment work over a tool call?
HTTP has always had a slot for this. RFC 9110 section 15.5.3 says only: "The 402 (Payment Required) status code is reserved for future use." x402 is the standard that took it. It "is built around the HTTP 402 Payment Required status code and allows clients to programmatically pay for resources without accounts, sessions, or credential management" (x402 documentation), and the rule over plain HTTP is simple: "If a request arrives without payment, the server responds with HTTP 402, prompting the client to pay and retry" (x402.org).
MCP is JSON-RPC, not HTTP semantics, so there is no status code to return. The x402 MCP transport maps the same handshake onto tool results: "When a tool requires payment, servers MUST return a tool result with isError: true containing the PaymentRequired data" (x402 MCP transport specification). The isError route exists for a concrete reason, documented in the reference package: "The MCP TypeScript SDK v1 converts McpError exceptions to tool results with isError: true, losing the error.data field" (@x402/mcp). So the payment terms go in structuredContent and are repeated JSON-encoded in content[0].text, and a client reads whichever it can.
Note the ordering. Verification proves a payment can settle. Only settlement proves it did, which is why the merchant rule is "Deliver the paid resource after success: true, not after verify" (Neuronto Payments developer reference).
Worked example: turn one free tool into a paid tool
This is the server half, using @x402/mcp on top of the official MCP SDK. The wallet address is yours. The facilitator does the chain work, so your process holds no private key.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { createPaymentWrapper, x402ResourceServer } from "@x402/mcp";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { ExactEvmScheme } from "@x402/evm/exact/server";
import { z } from "zod";
const mcpServer = new McpServer({ name: "premium-api", version: "1.0.0" });
const resourceServer = new x402ResourceServer(
new HTTPFacilitatorClient({ url: "https://pay.neuronto.com" }),
);
resourceServer.register("eip155:8453", new ExactEvmScheme());
await resourceServer.initialize();
const accepts = await resourceServer.buildPaymentRequirements({
scheme: "exact",
network: "eip155:8453",
payTo: "0xYourWallet",
price: "$0.01",
});
const paid = createPaymentWrapper(resourceServer, { accepts });
// Paid: wrap the handler.
mcpServer.tool(
"financial_analysis",
"Deep analysis of one ticker. Costs $0.01.",
{ ticker: z.string() },
paid(async ({ ticker }) => ({
content: [{ type: "text", text: await analyse(ticker) }],
})),
);
// Free: no wrapper. Discovery and health checks must stay free.
mcpServer.tool("ping", "Health check", {}, async () => ({
content: [{ type: "text", text: "pong" }],
}));The unwrapped ping tool matters as much as the wrapped one. tools/list and cheap probes have to stay free, because an agent that cannot afford to look will never learn the paid tool exists.
Here is what the second call looks like on the wire, which is also what you inspect when something goes wrong:
{ "jsonrpc": "2.0", "id": 7, "method": "tools/call",
"params": { "name": "financial_analysis", "arguments": { "ticker": "AAPL" },
"_meta": { "x402/payment": { "x402Version": 2,
"accepted": { "scheme": "exact", "network": "eip155:8453",
"amount": "10000", "payTo": "0xYourWallet", "maxTimeoutSeconds": 60 },
"payload": { "signature": "0x...", "authorization": { "from": "0x...", "value": "10000" } } } } } }"10000" is not ten thousand dollars. USDC carries six decimals, so it is one cent. Amounts travel as integer strings in the asset's own units, never as floats.
What the price and the fees actually are
x402 itself takes nothing: "x402 as a standard has 0 fees built in" (x402 documentation). The real floor is the gas of the on-chain transfer, which the facilitator pays and prices. Neuronto Payments publishes that figure as JSON rather than a sales page: the credit unit is $0.001, the margin is 3000 basis points over measured gas, a Base settlement is currently estimated at $0.00211, testnets are free, and any change is announced with fourteen days of notice (pay.neuronto.com/pricing).
So a tool priced at one cent gives up about a fifth of a cent to settlement, and a tool priced at a tenth of a cent gives up twice its own price, which means it should not be a paid tool at all. Timing has a ceiling too: a settlement answers within about 25 seconds or returns errorReason: "settlement_pending" with the transaction hash and continues in the background.
Test the client half first. https://pay.neuronto.com/echo is a live merchant that charges $0.001 and refunds it in the same request, so a paying agent can be exercised end to end at no cost.
When charging per tool call is the wrong model
Per-call pricing is the wrong shape more often than the enthusiasm suggests.
- The call is cheap and frequent. If settlement costs a meaningful fraction of the price, batch the work into a coarser tool, or sell a prepaid balance, rather than writing a chain transaction for every lookup.
- The model, not the user, decides how many calls happen. A user asking one question cannot predict whether the agent calls your tool twice or forty times.
@x402/mcpships a default cap of$1per payment for exactly this reason, and you should assume clients tighten it further. Price per unit of work the user recognises. - Retries would double-charge. Agent frameworks retry on timeouts and truncated streams. The agentic payments model in IETF work "uses an idempotency key to associate retries with one task, a single-use nonce to reject credential replay, and a receipt linking the task to operator-controlled authority and settlement records" (draft-king-yew-choo-agentic-payments). If your billing path lacks an idempotency identity, do not bill per call.
- You already have accounts. MCP has an OAuth 2.1 authorization story for servers that sit behind existing tenants. Adding a second, parallel billing rail for the same customers buys inconsistency.
- Latency matters more than money. A verify and settle round trip inside a tight agent loop is a bad trade for a fraction of a cent.
- The value is stateful. If the worth is in an accumulated session, a long analysis, or a stored artifact, charge once for the job and return a handle the agent can read for free.
- You expect refunds or disputes. Settlement is final. There is no chargeback to fall back on, so any refund is a second transfer you have to build and fund yourself.
Questions people actually ask
Can I manually call a paid MCP tool to test it?
Post JSON-RPC directly. tools/list is free, and a tools/call without _meta["x402/payment"] returns the PaymentRequired terms, which is the cheapest way to confirm your pricing is wired up.
Can I charge for MCP resources and prompts too?
The transport can carry it, but resources are read by the host application and prompts are chosen by the user, so neither is a deliberate model decision. Keep billing on tools.
How much do I have to modify my MCP server?
One wrapper around the handlers you want paid. Tool names, schemas and descriptions do not change, so existing clients keep working and simply meet a price.
How do agents find a paid MCP server?
Through a catalogue rather than a search engine. A facilitator that implements the bazaar extension exposes what has been paid for through it, terms and shapes included, at GET /discovery/resources.
What happens if settlement fails after the tool already ran?
The transport is explicit: return the payment error and withhold the tool's content. That is the reason to keep expensive side effects behind an idempotency key.
Does a failed or unpaid call cost the caller anything?
No. Refusals before the chain call, including a payer that emptied its wallet between verification and broadcast, create no transaction and charge nobody.
Sources
- RFC 9110, HTTP Semantics, section 15.5.3: https://www.rfc-editor.org/rfc/rfc9110.html
- Model Context Protocol: https://modelcontextprotocol.io/
- Understanding MCP servers: https://modelcontextprotocol.io/docs/2026-07-28/learn/server-concepts
- x402 documentation: https://docs.x402.org/
- x402 specification site: https://www.x402.org/
- x402 MCP transport specification: https://github.com/x402-foundation/x402/blob/main/specs/transports-v2/mcp.md
@x402/mcppackage reference: https://github.com/x402-foundation/x402/blob/main/typescript/packages/mcp/README.md- IETF draft, a model for agentic payments: https://datatracker.ietf.org/doc/draft-king-yew-choo-agentic-payments/
- Neuronto Payments developer reference: https://pay.neuronto.com/developers
- Neuronto Payments pricing: https://pay.neuronto.com/pricing
- Neuronto Payments integration guide: https://pay.neuronto.com/integrate