Skip to content
Draft
173 changes: 0 additions & 173 deletions src/content/docs/agents/x402.mdx

This file was deleted.

107 changes: 107 additions & 0 deletions src/content/docs/agents/x402/charge-for-http-content.mdx
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.

[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/main/x402-proxy-template)
Copy link
Contributor

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?


## 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: the text says "Define protected routes in wrangler.jsonc" but the code block language is ```json. Since JSONC supports comments and the file extension is .jsonc, consider using ```jsonc for accuracy — though note jsonc may not be in the supported languages list for syntax highlighting (check if it falls back to txt). Alternatively, the <WranglerConfig> component could be used here for consistency with other docs, but since this is a template-specific vars fragment rather than a full Wrangler config, the raw block is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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/).

## 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).

## 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}`,
{
"/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.

## 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
93 changes: 93 additions & 0 deletions src/content/docs/agents/x402/charge-for-mcp-tools.mdx
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,
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).

## 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
Loading
Loading