Skip to content
0%

How to add x402 payments to an MCP server: a builder's guide to agent payments

Alchemy headshot

Written by Alchemy

Published on August 26, 202614 min read

Adding x402 payments

Most APIs charge by making you sign up first: create an account, get a key, get billed later. x402 skips all of that. A server can charge per request instead, with no signup, key, or invoice. And it's already running in production: Coinbase shipped it in May 2025, Cloudflare wired it into its Agents SDK, and our agent gateway uses it to charge agents for RPC and data access.

This guide is for anyone building either side of that exchange: an MCP server or API that wants to charge per call, or an agent that needs to pay one. We'll walk through the request and response loop, then show real code for charging for a tool call, metering and settling per call in USDC, giving an agent a wallet to pay with, and where other payment protocols like AP2 fit in.

What does x402 actually do?

HTTP 402 Payment Required has existed in the HTTP spec since the 1990s and was never implemented. x402 is the protocol that finally uses it:

  • A server responds to an unpaid request with status 402 and a machine-readable price
  • The client attaches a signed payment and retries
  • The server verifies, settles, and returns the resource in the same exchange

There is no session, stored card, or dashboard, and the wallet is the account. In x402 v2, relevant information is stored in HTTP headers:

Header
Direction
Carries

PAYMENT-REQUIRED

Server to client

Price, destination address, network, and accepted payment schemes, base64-encoded

PAYMENT-SIGNATURE

Client to server

The signed payment payload, base64-encoded

PAYMENT-RESPONSE

Server to client

The settlement result, base64-encoded

The three headers never change. What changes is the scheme field inside the JSON that PAYMENT-REQUIRED carries, which tells the client which billing model this particular call is using. In every scheme, the same third party does the checking and the money-moving: a facilitator, a service that verifies the client's signed payment and submits the onchain settlement, so neither the seller nor the client has to do either themselves. What differs scheme to scheme is only what the facilitator is checking and when it settles.

Most calls use exact: the price is fixed and known upfront, so the client signs for that exact amount and it settles for that exact amount. The payload looks like this, trimmed to the fields that matter. amount is 10,000 atomic units, which is $0.01 USDC:

json
Copied
{ "accepts": [{ "scheme": "exact", "amount": "10000", "asset": "0x036C...F7e", "payTo": "0x2096...87C" }] }

Some calls cost a variable amount only known after the work is done, like LLM output billed by tokens generated. For those, the server uses upto. The payload looks almost identical, but amount now means a ceiling the client agrees to, not a price. Here that ceiling is $5.00:

json
Copied
{ "accepts": [{ "scheme": "upto", "amount": "5000000", "asset": "0x036C...F7e", "payTo": "0x2096...87C" }] }

The client signs once against that ceiling. After the server does the work, the facilitator settles the real amount (say $1.20 of actual usage) and checks that it's at or below the signed ceiling before moving any money. The client never signs twice; only the settlement step fills in the real number.

A third scheme, batch-settlement, is for high-frequency, sub-cent charges where paying gas fees on every call would cost more than the call itself. In the x402 scheme, the buyer deposits once into an escrow contract, signs off-chain vouchers per request, and sellers redeem in batches onchain. Circle Gateway uses a related nanopayments pattern for the same job.

The facilitator never holds funds itself; it only checks signed instructions and executes them. x402.org runs a free public facilitator for development and testnet only, and Coinbase's CDP runs a hosted production facilitator with compliance screening. You can point your code at either one.

How does the x402 request and response loop work?

The handshake is nine steps:

  1. The client requests a resource with no payment attached.
  2. The server responds 402 Payment Required with a price, a destination address, and the payment schemes it accepts.
  3. The client signs a payment for one of the accepted schemes and retries the request with the signature attached.
  4. The server asks the facilitator to verify the signed payment against its declared requirements.
  5. The facilitator returns a verification result.
  6. The server does the work (runs the query, calls the model, generates the report).
  7. The server asks the facilitator to settle the payment onchain.
  8. The facilitator returns the settlement result.
  9. The server returns the resource, along with the settlement receipt.

Over HTTP, that loop is executed via HTTP headers (PAYMENT-REQUIRED, PAYMENT-SIGNATURE, PAYMENT-RESPONSE). Over MCP, those same nine steps run over JSON instead:

  • A call with no payment returns a result with isError: true and a PaymentRequired payload (equivalent to PAYMENT-REQUIRED)
  • The client retries the same call with the signed payment attached at _meta["x402/payment"] (equivalent to PAYMENT-SIGNATURE)
  • The server returns the real result with settlement info at _meta["x402/payment-response"] (equivalent to PAYMENT-RESPONSE)

How do I add x402 payments to an MCP server?

This example mirrors a common real-world case: an MCP server with a mix of paid and free tools, like a research or data server that gives free basic lookups but charges for a deeper generated report.

In this example, generate_report costs $0.01 per call and ping stays free, built on the open x402 Foundation SDKs (facilitator-agnostic, so you can start against the free public facilitator and swap in a commercial one later) with a Wallet APIs smart account as the address that receives payment.

First, provision the wallet that gets paid. @alchemy/wallet-apis (v5) gives you a smart account address without touching a private key on your server:

tsx
Copied
// wallet.ts import { createServerSigner } from "@account-kit/signer"; import { createSmartWalletClient, alchemyWalletTransport } from "@alchemy/wallet-apis"; import { baseSepolia } from "viem/chains"; const signer = await createServerSigner({ auth: { accessKey: process.env.ALCHEMY_ACCESS_KEY! }, connection: { apiKey: process.env.ALCHEMY_API_KEY! }, }); const walletClient = createSmartWalletClient({ transport: alchemyWalletTransport({ apiKey: process.env.ALCHEMY_API_KEY! }), chain: baseSepolia, signer, }); export const receiverAccount = await walletClient.requestAccount(); // receiverAccount.address is the payTo address for every quote you issue below

Now wire that address into an x402-gated MCP tool. @x402/core builds and verifies payment requirements, @x402/evm implements the exact scheme for EVM chains, and @x402/mcp wraps a tool handler so a plain function becomes a paid one:

tsx
Copied
// server.ts import { createServer } from "node:http"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { x402ResourceServer } from "@x402/core/server"; import { HTTPFacilitatorClient } from "@x402/core/facilitator"; import { createPaymentWrapper } from "@x402/mcp"; import { ExactEvmScheme } from "@x402/evm/exact/server"; import { z } from "zod"; import { receiverAccount } from "./wallet"; // Base Sepolia for testing; swap to eip155:8453 for Base mainnet const NETWORK = "eip155:84532"; // Start against the free public facilitator, then swap the url for a // commercial facilitator (compliance screening, higher throughput, an // SLA) for production. const facilitator = new HTTPFacilitatorClient({ url: "https://x402.org/facilitator", }); const resourceServer = new x402ResourceServer(facilitator); resourceServer.register(NETWORK, new ExactEvmScheme()); await resourceServer.initialize(); const accepts = await resourceServer.buildPaymentRequirements({ scheme: "exact", network: NETWORK, payTo: receiverAccount.address, price: "$0.01", }); const paid = createPaymentWrapper(resourceServer, { accepts }); const server = new McpServer({ name: "paid-report-server", version: "1.0.0", }); server.tool( "generate_report", "Generate a research report on a topic. Costs $0.01 in USDC.", { topic: z.string() }, paid(async ({ topic }) => ({ content: [ { type: "text", text: "Report on " + topic + ": trending up, no anomalies.", }, ], })), ); server.tool("ping", "Free health check", {}, async () => ({ content: [{ type: "text", text: "pong" }], })); const transport = new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, }); await server.connect(transport); createServer((req, res) => { const path = new URL(req.url ?? "/", "http://localhost").pathname; if (path === "/mcp") { void transport.handleRequest(req, res); return; } res.writeHead(404).end(); }).listen(3000);

server.connect(transport) only attaches the protocol to the transport. The Node HTTP listener is what actually opens port 3000 and forwards /mcp into transport.handleRequest(...), which is the endpoint the client below calls.

Everything you did not wrap in paid(...) stays free, so you can mix priced and unpriced tools on the same server. Test it with curl or any MCP client without payment attached first: you should get back a payment-required result instead of the report, which confirms the gate is live before you wire up a paying client.

If you would rather not run a facilitator relationship yourself at all, and want to accept x402 alongside other emerging agent-payment protocols without picking one, that is what AgentPay is for: point it at your existing endpoint and it handles protocol translation across x402, ACP, MPP, and AP2 from one integration.

How do I meter and charge agents per call?

A single flat price per call is the base case. Production servers also need to track who paid and how much, and shouldn't rely on the facilitator's settlement report as the only proof that money actually moved. To verify, keep track of:

  • Pricing shape. Use exact for a flat per-call price, the pattern above. Use upto when the cost varies by call (a longer report costs more tokens than a short one) and you want to authorize a ceiling up front but settle the real usage. Use batch-settlement when calls are frequent and cheap enough that settling each one onchain individually would cost more than the call itself.
  • Attribution and ledgering. The payment payload the client signs includes the paying address. Log it against the tool name, price, and settlement result every time a call settles, and you have a per-agent usage ledger for free:
tsx
Copied
const paid = createPaymentWrapper(resourceServer, { accepts, hooks: { onAfterSettlement: async ({ toolName, settlement }) => { await usageLedger.record({ payer: settlement.payer, tool: toolName, amountUsd: 0.01, txHash: settlement.transaction, settledAt: new Date(), }); }, }, });

Do not stop at trusting the settlement response as your only signal. A facilitator can report settled: true while a request still returns a non-200, or vice versa; check both before you count revenue. For a periodic reconciliation pass, our Transfers API lets you independently confirm what actually landed at your receiving address, which catches the rare case where a facilitator's settlement report and onchain reality disagree:

tsx
Copied
const res = await fetch("https://base-sepolia.g.alchemy.com/v2/" + apiKey, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", method: "alchemy_getAssetTransfers", params: [{ toAddress: receiverAccount.address, category: ["erc20"], contractAddresses: [USDC_ADDRESS], withMetadata: true, }], id: 1, }), }); const { result } = await res.json(); // result.transfers is the ground truth for what actually arrived onchain, // independent of what any single facilitator reported settling

How do I give an agent a USDC wallet to pay with?

An agent that needs to pay a paywalled endpoint, yours or anyone else's, needs a funded wallet and code (or a CLI) that can sign a payment when it hits a 402.

For a human-operated or locally tested agent, the fastest path is the Alchemy CLI. It creates a scoped wallet session that the agent can use without ever touching a private key:

bash
Copied
npm i -g "@alchemy/cli@latest" alchemy auth alchemy wallet connect --mode session --instance-name "my-agent" # decode a quote without paying anything, useful for a first look at an unfamiliar endpoint alchemy x402 request "https://api.example.com/report" --estimate # pay it for real, with a hard spend cap; required for any non-interactive run alchemy --json --no-interactive x402 request "https://api.example.com/report" --max-payment 0.01

--max-payment sets the most the CLI will ever pay, and nothing the server sends back can push that number higher. If you run the command with no human there to approve it (--no-interactive) and forget to set --max-payment, the CLI just stops instead of paying, because the price in a 402 response comes from a server you don't control, and nothing should pay it without your limit checking it first. See the x402 payments CLI docs for the full command surface.

For a fully autonomous backend agent that needs to pay without a human approving each session, wrap fetch (or your MCP client) with a payment handler backed by a signer. If the agent is calling paid HTTP endpoints, use @x402/fetch:

tsx
Copied
import { x402Client } from "@x402/core/client"; import { wrapFetchWithPayment } from "@x402/fetch"; import { registerExactEvmScheme } from "@x402/evm/exact/client"; import { privateKeyToAccount } from "viem/accounts"; const signer = privateKeyToAccount(process.env.AGENT_WALLET_KEY as `0x${string}`); const client = new x402Client(); registerExactEvmScheme(client, { signer }); const fetchWithPayment = wrapFetchWithPayment(fetch, client); const response = await fetchWithPayment("https://api.example.com/report");

If the agent is calling paid tools on an MCP server instead of a plain HTTP endpoint, wrap the MCP client the same way instead of fetch. CDP documents the same pattern for MCP buyers:

tsx
Copied
import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { x402Client } from "@x402/core/client"; import { wrapMCPClientWithPayment } from "@x402/mcp"; import { registerExactEvmScheme } from "@x402/evm/exact/client"; import { privateKeyToAccount } from "viem/accounts"; const signer = privateKeyToAccount( process.env.AGENT_WALLET_KEY as `0x${string}`, ); const paymentClient = new x402Client(); registerExactEvmScheme(paymentClient, { signer }); const mcp = wrapMCPClientWithPayment( new Client( { name: "my-agent", version: "1.0.0" }, { capabilities: {} }, ), paymentClient, { autoPayment: true }, ); await mcp.connect( new StreamableHTTPClientTransport( new URL("http://localhost:3000/mcp"), ), ); const report = await mcp.callTool({ name: "generate_report", arguments: { topic: "USDC on Base" }, });

A raw private key in an environment variable can be fine for a first test on testnet, but it is unacceptable in production. For a production agent, put a Wallet APIs smart account or an Agent Wallet session behind the same signer interface instead, so the agent can sign under rules you set without ever holding the private key itself.

How do I settle in USDC without making agents hold gas?

Every onchain transaction needs gas: a native token like ETH, held by whoever sends the transaction, to pay the network to process it. That's a problem for an agent paying per API call. It can't stop and go acquire a gas token before every $0.01 payment, and holding a stockpile of it just in case defeats the point of an automated flow.

USDC settlement gets around this with EIP-3009 (transferWithAuthorization): it lets the agent sign a transfer without itself submitting a transaction or holding any gas token. The agent only signs; the facilitator is the one who submits that transaction onchain and pays its gas. exact and upto settlements typically use EIP-3009 for USDC and Permit2 for any other ERC-20 that doesn't support EIP-3009. batch-settlement still has the agent sign per request, then the seller redeems a batch onchain later instead of settling each call alone. Circle Gateway uses a related nanopayments pattern for that same high-frequency case. USDC being priced in dollars also keeps things simple on top of that: neither side has to do exchange-rate math on a $0.01 charge.

That covers the payment itself. If your receiving address is a plain externally-owned wallet, that's the whole story: it just receives USDC, no deployment step involved. If it's a smart account like the one built earlier in this guide, it still touches gas at two other moments outside the x402 flow: once to deploy onchain the first time it receives funds, and again whenever you sweep collected USDC out to a treasury wallet. Our Gas Manager can sponsor gas for those two moments; either way, it isn't involved in settling the x402 payment itself, since the facilitator already covers that.

Base is the default network in most tooling, since that is where the original reference facilitator runs and where most existing x402 integrations already live, but x402 v2 is not Base-only. It also covers any EVM chain (including Ethereum mainnet and Polygon) plus Solana, TON, Algorand, Stellar, Aptos, Hedera, Keeta, NEAR, Concordium, and XRPL, with more chains expected as facilitators add support. Whether "pay in USDC on Ethereum" specifically works for you today depends on whether your chosen facilitator has implemented that network, not on the protocol itself.

Where does x402 fit in the wider agent payments stack?

x402 is one protocol in a fast-moving field, not the only one.

  • Stripe and Tempo built MPP as a version of the same 402 pattern that is not locked to stablecoins, where a seller can accept cards or stablecoins under the same flow (and MPP is backwards compatible with x402's exact flow, so a client built for one can usually talk to a server built for the other).
  • OpenAI and Stripe's ACP covers a different slice: checkout for AI-driven shopping rather than per-request API payments.
  • Google's AP2 covers a different problem entirely: proving a user authorized an agent to spend, using signed Checkout and Payment mandates, regardless of whether the payment method is a card, a bank transfer, or a stablecoin. AP2 isn't a competing settlement rail; when an AP2 flow needs to settle in stablecoins, it does so through the A2A x402 extension that Google built with Coinbase, the Ethereum Foundation, and MetaMask, so x402 is the crypto rail underneath it rather than an alternative to it.
Protocol
Steward
Payment type
Primary job
Settles per request?

x402

x402 Foundation (originally Coinbase)

Onchain stablecoins

Pay per API call, tool call, or piece of content over HTTP or MCP

Yes

MPP

Stripe and Tempo

Cards or stablecoins, same flow

Pay per request, payment-method-agnostic

Yes

ACP

OpenAI and Stripe

Cards (via Stripe checkout)

Agent-driven shopping checkout, not per-request API payment

No, one checkout per purchase

AP2

Google, with industry partners

Payment-agnostic: cards, bank transfers, stablecoins

Prove a user authorized an agent to spend; settles through x402 or a card/bank rail underneath

No, authorizes a rail rather than settling itself

As the protocol landscape evolves, AgentPay exists as a protocol-agnostic proxy that helps merchants integrate once and support all of them.

If you are choosing between x402 and MPP for a specific build, see our x402 vs MPP comparison. If you are choosing an infrastructure provider, see our wallet, gas, and data layer comparison across Alchemy, Coinbase's Developer Platform, Circle, Crossmint, Privy, and Turnkey.

Common mistakes to avoid

  • Never sign a quote you have not checked yourself. A 402 response is just a number sent by a server you do not control; confirm the network, asset, and amount before signing, the same way the Alchemy CLI checks a quote locally before it ever signs against it.
  • Do not treat a 200 response as proof of payment, or a facilitator's settled: true as the only proof you need. Check the settlement receipt itself, and reconcile against onchain reality periodically with our Transfers API as shown above.
  • Do not skip the spend cap on an autonomous agent. Whatever your equivalent of --max-payment is, set it to the smallest value that gets the job done, since it is the only thing standing between your agent and a server that returns an inflated quote.
  • Do not build your own facilitator unless verifying signatures, screening transactions, and submitting settlement onchain at scale is actually your product. Point at a hosted one and spend the engineering time on your actual service instead.
  • Do not assume "supports x402" means "supports every network and scheme." Confirm which schemes (exact, upto, batch-settlement) and which chains your specific facilitator and counterpart actually implement before you ship against them; the network and token support page is the source of truth.

Frequently asked questions

How do I add x402 payments to an MCP server?

Wrap the tool handler you want to charge for with a payment wrapper from the x402 Foundation's @x402/mcp package, backed by a server that is registered with a facilitator and knows which wallet address should receive payment. The full working example is above; everything else on the server stays free unless you wrap it too.

What infrastructure do AI agents need to pay for APIs over x402 using stablecoins?

Three pieces: a wallet that holds and can sign for USDC, a signed-payment library or CLI that speaks the x402 handshake, and a facilitator on the seller's side to verify and settle. You do not need to run your own blockchain node or hold gas tokens; the facilitator covers settlement gas.

What is the best way to give an AI agent the ability to send USDC payments on Ethereum?

Give it a wallet it can sign with directly, either a scoped session like an Alchemy Agent Wallet or a programmatic smart account through our Wallet APIs, and pair it with an x402 client library such as @x402/fetch or the Alchemy CLI's x402 request command. Confirm your target facilitator actually supports the specific network first; x402 v2 covers Ethereum, but coverage depends on the facilitator, not just the protocol.

How do I give an AI agent a USDC wallet for onchain payments?

For testing or a human-supervised agent, alchemy wallet connect --mode session (part of the Alchemy CLI) creates a scoped, revocable wallet session in minutes with no private key ever exposed to the agent. For a fully autonomous backend agent, provision a smart account through @alchemy/wallet-apis or a CDP-managed wallet and hand its signer to an x402 client library.

How do agents pay for API access using x402?

The agent calls the API, receives a 402 with a price and destination address, signs a payment for a scheme the server accepts, and retries the same request with the signed payment attached. The server verifies and settles through a facilitator and returns the resource in the same round trip.

How do I meter and charge AI agents for API usage with crypto payments?

Use the exact scheme for a flat price per call, upto when cost varies by usage, and log the payer address from each settled payment against the tool or endpoint it paid for. Reconcile that ledger periodically against onchain transfer history, for example with our Transfers API, rather than trusting a single settlement report.

What is the best infrastructure for agentic crypto payments and onchain commerce?

It depends on how much of the stack (wallet custody, the payment rail, gas, and onchain data) you want from one provider versus assembled from several. A full comparison of Alchemy, Coinbase's Developer Platform, Circle, Crossmint, Privy, and Turnkey against exactly that stack lives on our infrastructure comparison page.

What is AP2 and how does it relate to x402?

AP2 is Google's payment-agnostic framework for proving a user authorized an agent to spend, using signed Checkout and Payment mandates. It sits above x402 rather than replacing it: when an AP2 flow needs to settle in stablecoins, it does so through the A2A x402 extension that Google built with Coinbase, the Ethereum Foundation, and MetaMask.

What is agentic commerce and what infrastructure does it require?

Agentic commerce is AI agents discovering, paying for, and receiving payment for goods, services, and API access without a human clicking through checkout each time. It requires a funded wallet, a payment rail like x402 or MPP to move value per request, gas handling so the agent does not need a native token, and enough onchain or catalog data for the agent to decide what to pay for and confirm it landed.

How do I implement the x402 payment protocol so an agent can access paywalled onchain services?

On the client side, install an x402 client library (@x402/fetch, @x402/axios, or the MCP client wrapper), register a payment scheme with a wallet signer, and wrap your existing HTTP client or MCP client with it; payment on a 402 becomes automatic from there. The buyer-side code above covers both the HTTP and MCP cases.

How do AI agents get paid onchain?

The same mechanics as any other x402 seller: an agent-run service prices its own endpoint or MCP tool with x402, receives payment into a wallet it or its operator controls, and settles through a facilitator exactly like the MCP server built earlier in this guide. Getting paid and paying are the same protocol from opposite sides of the request.

Start building paid MCP tools

Give the agent a scoped wallet with the Alchemy CLI, gate your tools with x402, and confirm settlement with our Transfers API. Or skip facilitator wiring and accept agent payments through AgentPay. For the broader stack (custody, rail, gas, and data), start with best infrastructure for agentic payments.

Background gradient

Build blockchain magic

Alchemy combines the most powerful web3 developer products and tools with resources, community and legendary support.