Skip to content

Commit d5cdb72

Browse files
Merge pull request #476 from basementstudio/canary
v0.6.1
2 parents d11ff69 + 0b14e83 commit d5cdb72

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+3854
-193
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: "HTTP 402 Payment Not Found"
3+
description: "Pay-per-use monetization for MCP tools with x402."
4+
summary: "Pay-per-use monetization for MCP tools with x402."
5+
category: "engineering"
6+
date: "2026-01-20"
7+
order: 2
8+
featured: false
9+
previewImage: "/textures/text6.png"
10+
authors:
11+
- fveiras_
12+
---
13+
14+
HTTP 402 Payment Required has been in the spec since 1999, reserved for future use. 25 years later, [Coinbase built x402](https://docs.cdp.coinbase.com/x402/docs/welcome): a protocol that finally gives it a purpose.
15+
16+
MCP tools can now charge per request using crypto micropayments. No subscriptions, no license keys, no accounts. Just pay and use.
17+
18+
## Why crypto for payments
19+
20+
Traditional monetization requires setup. Users create accounts, enter payment methods, manage subscriptions. That friction makes sense for SaaS products, but not for API calls that cost fractions of a cent.
21+
22+
With x402, a client sends a signed payment, the server verifies it, the tool executes. No accounts, no payment processors, no recurring billing.
23+
24+
## How x402 works
25+
26+
[x402](https://www.x402.org/) implements HTTP 402 using USDC on Base. When a client calls a paid tool:
27+
28+
1. The server responds with payment requirements
29+
2. The client signs a payment authorization
30+
3. The request continues with proof of payment
31+
4. Payment settles on-chain after execution
32+
33+
![x402 payment flow](https://j2fbnka41vq9pfap.public.blob.vercel-storage.com/images/x402-diagram.svg)
34+
35+
The payment requirements include everything the client needs to construct a valid payment:
36+
37+
```json
38+
{
39+
"error": "Payment required",
40+
"accepts": [{
41+
"scheme": "exact",
42+
"network": "eip155:8453",
43+
"amount": "50000",
44+
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
45+
"payTo": "0x..."
46+
}]
47+
}
48+
```
49+
50+
The `amount` is in atomic units (6 decimals for USDC), so `50000` equals $0.05. The client signs an authorization, attaches it to the retry request, and the server verifies it with a facilitator before executing the tool.
51+
52+
No accounts. No API keys. No subscriptions. Just pay-per-use.
53+
54+
## Enabling agentic commerce
55+
56+
It's not crazy to think that in the near future, agents will have their own wallets and budgets. They'll discover tools at runtime, decide if the price is worth it, and pay on the spot.
57+
58+
One agent needs a capability it doesn't have. It finds another that does, pays for the call, and moves on. No human approving each transaction. That future needs payment infrastructure that works at machine speed. x402 is a step in that direction.
59+
60+
## Making it work with xmcp
61+
62+
We built an [x402 plugin](/docs/integrations/x402) that handles all of this at the transport layer. You don't need to think about payment verification, signature validation, or settlement. Just wrap your tools.
63+
64+
```typescript title="src/middleware.ts"
65+
import { x402Provider } from "@xmcp-dev/x402";
66+
67+
export default x402Provider({
68+
wallet: process.env.X402_WALLET,
69+
defaults: {
70+
price: 0.01,
71+
currency: "USDC",
72+
network: "base",
73+
},
74+
});
75+
```
76+
77+
```typescript title="src/tools/paid-tool.ts"
78+
import { paid } from "@xmcp-dev/x402";
79+
80+
export default paid(async function paidTool({ input }) {
81+
return `Processed: ${input}`;
82+
});
83+
```
84+
85+
That's it. The middleware intercepts requests, validates payments, and settles transactions. Your tool code stays clean.
86+
87+
## Per-tool pricing
88+
89+
Not every tool costs the same. Some are simple lookups, others call expensive APIs or run heavy compute.
90+
91+
```typescript
92+
export default paid(
93+
{ price: 0.05 },
94+
async function expensiveTool({ input }) {
95+
// This one costs 5 cents
96+
return result;
97+
}
98+
);
99+
```
100+
101+
Tools without `paid()` stay free. Mix and match as needed.
102+
103+
## Why stablecoins
104+
105+
Micropayments need stable value. Charging $0.01 for a tool call doesn't work if the currency swings 10% overnight. USDC is pegged to USD, so prices stay predictable for both sides.
106+
107+
Base keeps fees low enough that charging fractions of a cent makes sense. For testing, use `base-sepolia`. For production, use `base`.
108+
109+
## Testing the integration
110+
111+
You can test your paid tools using the [x402 AI Starter](https://github.com/vercel-labs/x402-ai-starter), a Next.js client that consumes paid tools.
112+
113+
1. Clone the repo
114+
2. Sign into the [Coinbase CDP portal](https://portal.cdp.coinbase.com/)
115+
3. Following `.env.example`, set the following environment variables in `.env.local`:
116+
- `CDP_API_KEY_ID`
117+
- `CDP_API_KEY_SECRET`
118+
- `CDP_WALLET_SECRET`
119+
4. Get an OIDC token by running `vc link` then `vc env pull`. An API key can be obtained from the AI Gateway dashboard.
120+
5. Connect your MCP server in `api/chat/route`
121+
6. Run `pnpm dev`
122+
123+
The template runs on `base-sepolia` by default, so you can test with fake currency before going to production.
124+
125+
## Looking forward
126+
127+
Micropayments have been "almost here" for decades. High fees and slow settlement made them impractical. Low-cost L2s finally changed that. x402 provides the protocol. xmcp makes it easy to implement.
128+
129+
If you're building MCP servers that charge per request, check out our [monetization guide](/docs/guides/monetization) or join us on [Discord](https://discord.gg/d9a7JBBxV9).
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"title": "Adapters",
3-
"pages": ["nextjs", "express"],
3+
"pages": ["nextjs", "nestjs", "express"],
44
"defaultOpen": true,
55
"root": true
66
}

0 commit comments

Comments
 (0)