-
Notifications
You must be signed in to change notification settings - Fork 12.3k
[Agents] Expand x402 documentation into dedicated section #28398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: production
Are you sure you want to change the base?
Changes from 6 commits
a4824bf
ffc510f
3c258d1
1ca40ec
b01c839
5c827e0
a3cba08
c538c1c
1d2d346
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| --- | ||
| title: Charge for HTTP content | ||
| pcx_content_type: how-to | ||
| sidebar: | ||
| order: 1 | ||
| description: Gate HTTP endpoints with x402 payments using a Cloudflare Worker proxy. | ||
| --- | ||
|
|
||
| The x402-proxy template is a Cloudflare Worker that sits in front of any HTTP backend. When a request hits a protected route, the proxy returns a 402 response with payment instructions. After the client pays, the proxy verifies the payment and forwards the request to your origin. | ||
|
|
||
| [](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/x402-proxy-template) | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - A [Cloudflare account](https://dash.cloudflare.com/sign-up) | ||
| - An HTTP backend to gate | ||
| - A wallet address to receive payments | ||
|
|
||
| ## Configuration | ||
|
|
||
| Define protected routes in `wrangler.jsonc`: | ||
|
|
||
| ```json | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: the text says "Define protected routes in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. goign json here on the body type - but actually simplified this significantly |
||
| { | ||
| "vars": { | ||
| "PAY_TO": "0xYourWalletAddress", | ||
| "NETWORK": "base-sepolia", | ||
| "PROTECTED_PATTERNS": [ | ||
| { | ||
| "pattern": "/api/premium/*", | ||
| "price": "$0.10", | ||
| "description": "Premium API access" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| :::note | ||
| `base-sepolia` is a test network. Change to `base` for production. | ||
| ::: | ||
|
|
||
| ## Selective gating with Bot Management | ||
|
|
||
| With [Bot Management](/bots/), the proxy can charge crawlers while keeping the site free for humans: | ||
|
|
||
| ```json | ||
| { | ||
| "pattern": "/content/*", | ||
| "price": "$0.10", | ||
| "description": "Content access", | ||
| "bot_score_threshold": 30, | ||
| "except_detection_ids": [117479730] | ||
| } | ||
| ``` | ||
|
|
||
| Requests with a bot score below `bot_score_threshold` see the paywall. Use `except_detection_ids` to allowlist specific crawlers by [detection ID](/ai-crawl-control/reference/bots/). | ||
Oxyjun marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Deploy | ||
|
|
||
| Clone the template, edit `wrangler.jsonc`, and deploy: | ||
|
|
||
| ```sh | ||
| git clone https://github.com/cloudflare/templates | ||
| cd templates/x402-proxy-template | ||
| npm install | ||
| npx wrangler deploy | ||
| ``` | ||
|
|
||
| For full configuration options and Bot Management examples, see the [template README](https://github.com/cloudflare/templates/tree/main/x402-proxy-template). | ||
Oxyjun marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Custom Worker endpoints | ||
|
|
||
| For more control, add x402 middleware directly to your Worker using Hono: | ||
|
|
||
| ```ts | ||
| import { Hono } from "hono"; | ||
| import { paymentMiddleware } from "x402-hono"; | ||
|
|
||
| const app = new Hono<{ Bindings: Env }>(); | ||
|
|
||
| app.use( | ||
| paymentMiddleware( | ||
| process.env.SERVER_ADDRESS as `0x${string}`, | ||
threepointone marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| { | ||
| "/premium": { | ||
| price: "$0.10", | ||
| network: "base-sepolia", | ||
| config: { description: "Premium content" }, | ||
| }, | ||
| }, | ||
| { url: "https://x402.org/facilitator" }, | ||
| ), | ||
| ); | ||
|
|
||
| app.get("/premium", (c) => c.json({ message: "Thanks for paying!" })); | ||
|
|
||
| export default app; | ||
| ``` | ||
|
|
||
| See the [x402 Workers example](https://github.com/cloudflare/agents/tree/main/examples/x402) for a complete implementation. | ||
Oxyjun marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Related | ||
|
|
||
| - [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) — Native Cloudflare monetization without custom code | ||
| - [Charge for MCP tools](/agents/x402/charge-for-mcp-tools/) — Charge per tool call instead of per request | ||
| - [x402.org](https://x402.org) — Protocol specification | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| --- | ||
| title: Charge for MCP tools | ||
| pcx_content_type: how-to | ||
| sidebar: | ||
| order: 2 | ||
| description: Charge per tool call in an MCP server using paidTool. | ||
| --- | ||
|
|
||
| The Agents SDK provides `paidTool`, a drop-in replacement for `tool` that adds x402 payment requirements. Clients pay per tool call, and you can mix free and paid tools in the same server. | ||
|
|
||
| ## Setup | ||
|
|
||
| Wrap your `McpServer` with `withX402` and use `paidTool` for tools you want to charge for: | ||
|
|
||
| ```ts | ||
| import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; | ||
| import { McpAgent } from "agents/mcp"; | ||
| import { withX402, type X402Config } from "agents/x402"; | ||
| import { z } from "zod"; | ||
|
|
||
| const X402_CONFIG: X402Config = { | ||
| network: "base", | ||
| recipient: env.MCP_ADDRESS, | ||
threepointone marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| facilitator: { url: "https://x402.org/facilitator" }, // Payment facilitator URL | ||
| // To learn more about facilitators: https://x402.gitbook.io/x402/core-concepts/facilitator | ||
| }; | ||
|
|
||
| export class PaidMCP extends McpAgent<Env> { | ||
| server = withX402( | ||
| new McpServer({ name: "PaidMCP", version: "1.0.0" }), | ||
| X402_CONFIG, | ||
| ); | ||
|
|
||
| async init() { | ||
| // Paid tool — $0.01 per call | ||
| this.server.paidTool( | ||
| "square", | ||
| "Squares a number", | ||
| 0.01, // USD | ||
| { number: z.number() }, | ||
| {}, | ||
| async ({ number }) => { | ||
| return { content: [{ type: "text", text: String(number ** 2) }] }; | ||
| }, | ||
| ); | ||
|
|
||
| // Free tool | ||
| this.server.tool( | ||
| "echo", | ||
| "Echo a message", | ||
| { message: z.string() }, | ||
| async ({ message }) => { | ||
| return { content: [{ type: "text", text: message }] }; | ||
| }, | ||
| ); | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| | Field | Description | | ||
| | ------------- | ------------------------------------------------------------ | | ||
| | `network` | `base` for production, `base-sepolia` for testing | | ||
| | `recipient` | Wallet address to receive payments | | ||
| | `facilitator` | Payment facilitator URL (use `https://x402.org/facilitator`) | | ||
|
|
||
| ## paidTool signature | ||
|
|
||
| ```ts | ||
| this.server.paidTool( | ||
| name, // Tool name | ||
| description, // Tool description | ||
| price, // Price in USD (e.g., 0.01) | ||
| inputSchema, // Zod schema for inputs | ||
| annotations, // MCP annotations | ||
| handler, // Async function that executes the tool | ||
| ); | ||
| ``` | ||
|
|
||
| When a client calls a paid tool without payment, the server returns 402 with payment requirements. The client pays via x402, retries with payment proof, and receives the result. | ||
|
|
||
| ## Testing | ||
|
|
||
| Use `base-sepolia` and get test USDC from the [Circle faucet](https://faucet.circle.com/). | ||
|
|
||
| For a complete working example, see [x402-mcp on GitHub](https://github.com/cloudflare/agents/tree/main/examples/x402-mcp). | ||
Oxyjun marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Related | ||
|
|
||
| - [Pay from Agents SDK](/agents/x402/pay-from-agents-sdk/) — Build clients that pay for tools | ||
| - [Charge for HTTP content](/agents/x402/charge-for-http-content/) — Gate HTTP endpoints | ||
| - [MCP server guide](/agents/guides/remote-mcp-server/) — Build your first MCP server | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are we deploying here? Can we add in a sentence to explicitly describe?