Give a model a wallet, a spending cap, and twelve merchants. Each tool call pays an upstream x402 route and hands back the artifact — with the receipt attached.
git clone https://github.com/nirholas/x402-mcp-commerce && npm install && npm run mcp| Route | Price | What you get back |
|---|---|---|
MCP: | upstream | The merchant's artifact plus the decoded payment receipt and the exact price paid. Twelve tools, generated from config/tools.json. |
MCP: | free | What this agent can do, what it has spent, and any x402 service's manifest. |
GET /attest | $0.001 | Signed attestation of the tool registry, payment rails, spending caps and remaining budget — proof of what this agent can spend, without taking its word for it. |
GET /tools · GET /ledger · POST /tools/:name · POST /verify | free | The registry, the spending ledger, an HTTP bridge for non-MCP agents, and signature verification. |
Call a paid route. The server answers 402 Payment Required with an accepts array holding both rails.
The 402 offers two rails — USDC on Base and USDC on Solana. This server picks one per call: from config, from a per-tool override, or from the model itself.
That rail's facilitator verifies and settles on-chain. The server holds no key and pays no gas.
The merchant's artifact comes back in the tool result, with the settlement receipt and the exact price beside it.
npm install npm run mcp # the MCP server, over stdio npm run dev # the inspector on :4039 # rehearse the whole toolbox against the sandbox for a fraction of a cent X402_TOOLS_CONFIG=./config/tools.sandbox.json npx tsx examples/agent-client.ts
| Rail | Network | Asset | Pays to | Facilitator |
|---|---|---|---|---|
| EVM | base-sepolia (default) · base | USDC | 0x40252CFDF8B20Ed757D61ff157719F33Ec332402 | x402.org/facilitator |
| Solana | solana (default) · solana-devnet | USDC | WwwuGbqHrwF5RG89KhUbmRWEvjnRH9k5kVM5p7T3WwW | facilitator.payai.network |
Both entries appear in every 402. Pay in USDC on Base or Solana — your client picks the rail. Set PAY_TO_ADDRESS / SOLANA_PAY_TO_ADDRESS to receive the funds yourself.
Every suite merchant offers USDC on Base and USDC on Solana in the same 402. Which one gets signed is layered — later wins:
| Layer | Where | Example |
|---|---|---|
| Registry default | config/tools.json → defaults.rail | "rail": "auto" |
| Server-wide | environment | X402_RAIL=solana |
| Per tool, in config | the tool's rail field | "rail": "evm" |
| Per tool, from env | environment | X402_RAIL_BOOK_TABLE=evm |
| Per call | the model | book_table({…, rail: "solana"}) |
auto takes a rail this process holds a key for, EVM first. If a chosen rail isn't in the upstream's accepts, the call fails with RAIL_UNAVAILABLE rather than quietly paying on the other one.
Checked before any payment is signed, against the real price in the upstream's 402 — so a runaway loop stops at the ledger, not at the chain.
| Env | Default | Meaning |
|---|---|---|
MAX_PER_CALL_USD | 0.05 | Most this agent will pay for any single tool call. |
MAX_SESSION_USD | 1 | Total this process may spend before it refuses. |
MAX_CALLS | 200 | Total paid calls this process may make. |
ALLOWED_TOOLS | all | Comma-separated allowlist. |
A blocked call returns the cap that stopped it and the current spending state, so the model can explain itself — or escalate to a human with x402-approval-page.
Agents find this service via skill.md and the machine-readable /.well-known/x402 manifest — indexable by x402scan.com, the x402 Bazaar, and agentic.market. Questions: nichxbt@gmail.com.