diff --git a/public/__redirects b/public/__redirects index 1fd806d71ba..a169eddad60 100644 --- a/public/__redirects +++ b/public/__redirects @@ -313,6 +313,7 @@ /agents/tools/browser/browse-the-web/ /agents/tools/browser/ 301 /agents/tools/sandbox/codemode/ /agents/tools/codemode/ 301 /agents/tools/payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp-charge-for-http-content/ 301 +/agents/tools/payments/mpp/protect-an-origin/ /agents/tools/payments/mpp-charge-for-http-content/ 301 /agents/agentic-payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp-charge-for-http-content/ 301 # ai-audit diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index c7a5133d215..feb1f2c4e2d 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -5,7 +5,7 @@ sidebar: order: 5 group: hideIndex: false -description: Let AI agents pay for services programmatically using payment protocols like MPP and x402 with Cloudflare's Agents SDK. +description: Let AI agents pay for services with x402 or Machine Payments Protocol (MPP) through Cloudflare's Agents SDK. products: - agents --- @@ -17,11 +17,11 @@ AI agents need to discover, pay for, and consume resources and services programm Cloudflare's [Agents SDK](/agents/) supports agentic payments through two protocols built on the HTTP `402 Payment Required` status code: **x402** and **Machine Payments Protocol (MPP)**. Both follow the same core flow: 1. A client requests a resource or calls a tool. -2. The server responds with `402` and a payment challenge describing what to pay, how much, and where. +2. The server returns a payment Challenge describing what to pay, how much, and where. 3. The client fulfills the payment and retries the request with a payment credential. 4. The server verifies the payment (optionally through a facilitator service) and returns the resource along with a receipt. -No accounts, sessions, or pre-shared API keys are required. Agents handle the entire exchange programmatically. +No pre-created service account or pre-shared API key is required. Agents handle the payment exchange programmatically. ## x402 and Machine Payments Protocol @@ -31,16 +31,16 @@ No accounts, sessions, or pre-shared API keys are required. Agents handle the en The Agents SDK provides first-class x402 integration: -- **Server-side**: `withX402` and `paidTool` for MCP servers, plus `x402-hono` middleware for HTTP Workers. -- **Client-side**: `withX402Client` wraps MCP client connections with automatic 402 handling and optional human-in-the-loop confirmation. +- **Server-side**: `withX402` and `paidTool` for Model Context Protocol (MCP) servers, plus `x402-hono` middleware for HTTP Workers. +- **Client-side**: `withX402Client` wraps MCP connections with automatic `402` handling and optional human approval. ### Machine Payments Protocol -[Machine Payments Protocol (MPP)](https://mpp.dev) is a protocol co-authored by Tempo Labs and Stripe. It extends the HTTP `402` pattern with a formal `WWW-Authenticate: Payment` / `Authorization: Payment` header scheme and is on the IETF standards track. +[Machine Payments Protocol (MPP)](https://mpp.dev) is an open payment protocol. It adds the `WWW-Authenticate: Payment` and `Authorization: Payment` headers to HTTP `402` responses. -MPP supports multiple payment methods beyond blockchain — including cards (via Stripe), Bitcoin Lightning, and stablecoins — and introduces **sessions** for streaming and pay-as-you-go use cases with sub-millisecond latency and sub-cent costs. MPP is backwards-compatible with x402: MPP clients can consume existing x402 services without modification. +MPP supports multiple payment methods beyond blockchains, including cards (via Stripe) and stablecoins. The `mppx` SDK supports one-time, usage-based, and recurring payments. MPP is also backwards-compatible with x402: MPP clients can consume existing x402 services without modification. -## Charge for resources +## Build with agentic payments + + ## Related diff --git a/src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx b/src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx index 17806e9fea1..577f4df735d 100644 --- a/src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx +++ b/src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx @@ -78,31 +78,7 @@ For full configuration options, proxy modes, and Bot Management examples, refer ## Custom Worker endpoints -For more control, add MPP middleware directly to your Worker using Hono: - -```ts -import { Hono } from "hono"; -import { Mppx, tempo } from "mppx/hono"; - -const app = new Hono(); - -const mppx = Mppx.create({ - methods: [ - tempo({ - currency: "0x20c0000000000000000000000000000000000000", - recipient: "0xYourWalletAddress", - }), - ], -}); - -app.get("/premium", mppx.charge({ amount: "0.10" }), (c) => - c.json({ data: "Thanks for paying!" }), -); - -export default app; -``` - -Refer to the [Hono middleware reference](https://mpp.dev/sdk/typescript/middlewares/hono) for the full API, including session payments and payer identification. +To add MPP middleware directly to a Worker, refer to [Accept payments with MPP](/agents/tools/payments/mpp/accept-payments/#charge-for-a-worker-route). ## Related diff --git a/src/content/docs/agents/tools/payments/mpp.mdx b/src/content/docs/agents/tools/payments/mpp.mdx deleted file mode 100644 index 0c916b415af..00000000000 --- a/src/content/docs/agents/tools/payments/mpp.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: MPP (Machine Payments Protocol) -pcx_content_type: overview -sidebar: - order: 9 - group: - hideIndex: false -description: Accept and make payments using the Machine Payments Protocol (MPP) on Cloudflare Workers. -products: - - agents ---- - -import { LinkCard, CardGrid } from "~/components"; - -[Machine Payments Protocol (MPP)](https://mpp.dev) is a protocol for machine-to-machine payments, co-authored by [Tempo Labs](https://tempo.xyz) and [Stripe](https://stripe.com). It standardizes the HTTP `402 Payment Required` status code with a formal authentication scheme proposed to the [IETF](https://paymentauth.org). MPP gives agents, apps, and humans a single interface to pay for any service in the same HTTP request. - -MPP is payment-method agnostic. A single endpoint can accept stablecoins (Tempo), credit cards (Stripe), or Bitcoin (Lightning). - -## How it works - -1. A client requests a resource — `GET /resource`. -2. The server returns `402 Payment Required` with a `WWW-Authenticate: Payment` header containing a payment challenge. -3. The client fulfills the payment — signs a transaction, pays an invoice, or completes a card payment. -4. The client retries the request with an `Authorization: Payment` header containing a payment credential. -5. The server verifies the payment and returns the resource with a `Payment-Receipt` header. - -## Payment methods - -MPP supports multiple payment methods through a single protocol: - -| Method | Description | Status | -| ------------------------------------------------------ | ---------------------------------------------------------------------------- | ---------- | -| [Tempo](https://mpp.dev/payment-methods/tempo) | Stablecoin payments on the Tempo blockchain with sub-second settlement | Production | -| [Stripe](https://mpp.dev/payment-methods/stripe) | Cards, wallets, and other Stripe-supported methods via Shared Payment Tokens | Production | -| [Lightning](https://mpp.dev/payment-methods/lightning) | Bitcoin payments over the Lightning Network | Available | -| [Card](https://mpp.dev/payment-methods/card) | Card payments via encrypted network tokens | Available | -| [Custom](https://mpp.dev/payment-methods/custom) | Build your own payment method using the MPP SDK | Available | - -Servers can offer multiple methods simultaneously. Clients choose the method that works for them. - -## Payment intents - -MPP defines two payment intents: - -- **`charge`** — A one-time payment that settles immediately. Use for per-request billing. -- **`session`** — A streaming payment over a payment channel. Use for pay-as-you-go or per-token billing with sub-cent costs and sub-millisecond latency. - -## Compatibility with x402 - -MPP is backwards-compatible with [x402](/agents/tools/payments/x402/). The core x402 `exact` payment flows map directly onto MPP's `charge` intent, so MPP clients can consume existing x402 services without modification. - -## Charge for resources - - - - - -## SDKs - -MPP provides official SDKs in three languages: - -| SDK | Package | Install | -| ---------- | -------- | ------------------- | -| TypeScript | `mppx` | `npm install mppx` | -| Python | `pympp` | `pip install pympp` | -| Rust | `mpp-rs` | `cargo add mpp` | - -The TypeScript SDK includes framework middleware for [Hono](https://mpp.dev/sdk/typescript/middlewares/hono), [Express](https://mpp.dev/sdk/typescript/middlewares/express), [Next.js](https://mpp.dev/sdk/typescript/middlewares/nextjs), and [Elysia](https://mpp.dev/sdk/typescript/middlewares/elysia), as well as a [CLI](https://mpp.dev/sdk/typescript/cli) for testing paid endpoints. - -## Related - -- [mpp.dev](https://mpp.dev) — Protocol documentation and quickstart guides -- [IETF specification](https://paymentauth.org) — Full Payment HTTP Authentication Scheme specification -- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) — Cloudflare-native monetization for web content diff --git a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx new file mode 100644 index 00000000000..9f6518f5f4d --- /dev/null +++ b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx @@ -0,0 +1,182 @@ +--- +title: Accept payments with MPP +pcx_content_type: how-to +sidebar: + order: 2 +description: Accept Machine Payments Protocol (MPP) payments from an origin, Cloudflare Worker route, or Model Context Protocol (MCP) tool. +products: + - agents +--- + +import { + PackageManagers, + Steps, + TypeScriptExample, + WranglerConfig, +} from "~/components"; + +Use Cloudflare Workers to accept Machine Payments Protocol (MPP) payments. Choose an integration based on the service you want to protect: + +- [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) — Charge for HTTP content without changing your origin code. Refer to [Charge for HTTP content](/agents/tools/payments/mpp-charge-for-http-content/). +- **Worker route** — Add `mppx` payment middleware to a Worker application. +- **MCP tool** — Require payment before an MCP tool returns its result. + +## Prerequisites + +Create a [Cloudflare account](/fundamentals/account/create-account/). You also need a payment recipient and an MPP secret key. + +The examples use a stablecoin payment method on testnet. For other methods, refer to [MPP payment methods](https://mpp.dev/payment-methods/). + +## Charge for a Worker route + +Add `mppx` middleware when you control the Worker application: + + + +1. Install Hono and `mppx` in the Worker project: + + + +2. Store the MPP signing key as a [Worker secret](/workers/configuration/secrets/): + + + +3. Add the payment middleware before the paid route handler: + + + + ```ts + import { env } from "cloudflare:workers"; + import { Hono } from "hono"; + import { Mppx, tempo } from "mppx/hono"; + + const workerEnv = env as Env & { MPP_SECRET_KEY: string }; + const app = new Hono(); + const mppx = Mppx.create({ + methods: [tempo.charge({ testnet: true })], + secretKey: workerEnv.MPP_SECRET_KEY, + }); + + app.get( + "/premium", + mppx.charge({ + amount: "0.01", + currency: "0x20c0000000000000000000000000000000000000", + description: "Premium API access", + recipient: "", + }), + (c) => c.json({ access: "paid" }), + ); + + export default app; + ``` + + + +4. Deploy the Worker: + + + +5. Request the paid route without a payment: + + ```sh + curl -i https://.workers.dev/premium + ``` + + The Worker returns `402 Payment Required` and a `WWW-Authenticate: Payment` header. A paid retry reaches the handler and returns a `Payment-Receipt` header. + + + +## Charge for an MCP tool + +Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/agent-api/): + + + +1. Install the required packages in an Agents project: + + + +2. Bind the `McpAgent` Durable Object in the Wrangler configuration: + + + + ```toml + name = "mpp-server" + main = "src/index.ts" + compatibility_date = "$today" + compatibility_flags = ["nodejs_compat"] + + [[durable_objects.bindings]] + name = "MCP_OBJECT" + class_name = "PaidMCP" + + [[migrations]] + tag = "v1" + new_sqlite_classes = ["PaidMCP"] + ``` + + + +3. Store `MPP_SECRET_KEY` as a Worker secret: + + + +4. Check payment before returning the tool result: + + + + ```ts + import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; + import { McpAgent } from "agents/mcp"; + import { Mppx, tempo, Transport } from "mppx/server"; + import { z } from "zod"; + + type PaymentEnv = Env & { MPP_SECRET_KEY: string }; + + export class PaidMCP extends McpAgent { + server = new McpServer({ name: "paid-search", version: "1.0.0" }); + + async init() { + const mppx = Mppx.create({ + methods: [tempo.charge({ testnet: true })], + secretKey: this.env.MPP_SECRET_KEY, + transport: Transport.mcpSdk(), + }); + + this.server.tool( + "premium_search", + "Search premium content", + { query: z.string() }, + async ({ query }, extra) => { + const payment = await mppx.charge({ + amount: "0.01", + currency: "0x20c0000000000000000000000000000000000000", + description: "Premium search", + recipient: "", + })(extra); + + if (payment.status === 402) throw payment.challenge; + + return payment.withReceipt({ + content: [{ type: "text", text: `Results for: ${query}` }], + }); + }, + ); + } + } + + export default PaidMCP.serve("/mcp"); + ``` + + + +5. Deploy the Worker: + + + + An unpaid `premium_search` call returns an MPP Challenge. A paid retry returns the tool result and an MPP Receipt in `_meta`. + + + +To test both payment flows from a Cloudflare Agent, refer to [Pay from the Agents SDK](/agents/tools/payments/mpp/pay-from-agents-sdk/). For production billing patterns, refer to [MPP payment intents](https://mpp.dev/intents/). diff --git a/src/content/docs/agents/tools/payments/mpp/index.mdx b/src/content/docs/agents/tools/payments/mpp/index.mdx new file mode 100644 index 00000000000..3c653315123 --- /dev/null +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -0,0 +1,68 @@ +--- +title: MPP (Machine Payments Protocol) +pcx_content_type: overview +sidebar: + order: 9 + group: + hideIndex: false +description: Accept and make payments using Machine Payments Protocol (MPP) with Cloudflare Workers and the Agents SDK. +products: + - agents +--- + +import { LinkCard, CardGrid } from "~/components"; + +[Machine Payments Protocol (MPP)](https://mpp.dev) is an open protocol for machine-to-machine payments. It standardizes the HTTP `402 Payment Required` status code with a formal authentication scheme proposed to the [IETF](https://paymentauth.org). MPP gives agents, applications, and people one interface to pay for a service in the same HTTP request. + +MPP is payment-method agnostic. It supports stablecoins, cards through Stripe, and custom payment methods. A service can offer more than one method. + +## How it works + +1. An Agent or HTTP client requests a paid resource. +2. The service returns `402 Payment Required` with a payment Challenge. +3. The client fulfills the payment. +4. The client retries with a payment Credential. +5. The service returns the resource with a payment Receipt. + +HTTP services exchange payment data in authentication headers. Model Context Protocol (MCP) tools use the same flow through JSON-RPC. + +## Payment intents + +MPP defines three payment intents: + +- **`charge`** — Collect a one-time payment. +- **`session`** — Charge for measured usage. +- **`subscription`** — Sell recurring access. + +For more information, refer to [MPP payment intents](https://mpp.dev/intents/). + +## Compatibility with x402 + +MPP is backwards-compatible with [x402](/agents/tools/payments/x402/). MPP clients can consume existing x402 services without changes to those services. + +## Build on Cloudflare + + + + + + +## SDKs + +MPP provides SDKs for TypeScript, Python, Rust, Go, and Ruby. The Cloudflare guides use the TypeScript [`mppx` SDK](https://mpp.dev/sdk/typescript/). + +For current packages and integrations, refer to the [MPP SDK documentation](https://mpp.dev/sdk/). + +## Related + +- [mpp.dev](https://mpp.dev) — Protocol documentation and guides +- [IETF specification](https://paymentauth.org) — Payment HTTP Authentication Scheme +- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) — Cloudflare-native web content monetization diff --git a/src/content/docs/agents/tools/payments/mpp/pay-from-agents-sdk.mdx b/src/content/docs/agents/tools/payments/mpp/pay-from-agents-sdk.mdx new file mode 100644 index 00000000000..cfb9d1fe1a0 --- /dev/null +++ b/src/content/docs/agents/tools/payments/mpp/pay-from-agents-sdk.mdx @@ -0,0 +1,157 @@ +--- +title: Pay from the Agents SDK +pcx_content_type: how-to +sidebar: + order: 3 +description: Configure a Cloudflare Agent to pay HTTP services and Model Context Protocol (MCP) tools with Machine Payments Protocol (MPP). +products: + - agents +--- + +import { PackageManagers, Steps, TypeScriptExample } from "~/components"; + +Use the Cloudflare Agents SDK to pay MPP services. The `mppx` SDK handles payment retries for HTTP requests and Model Context Protocol (MCP) tool calls. + +## Prerequisites + +Create a [Cloudflare Agents project](/agents/getting-started/). Fund an account for the payment method that the service accepts. + +## Configure payments + + + +1. Install the Agents SDK, `mppx`, and `viem`: + + + +2. Store the payment private key as a [Worker secret](/workers/configuration/secrets/): + + + +3. Create the payment method once: + + + + ```ts + import { tempo } from "mppx/client"; + import { privateKeyToAccount } from "viem/accounts"; + + export function createPaymentMethods(privateKey: string) { + const account = privateKeyToAccount(privateKey as `0x${string}`); + + return [tempo.charge({ account })] as const; + } + ``` + + + + + +:::note +For production Agents, use a scoped access key. Apply spending limits and recipient restrictions. For more information, refer to [Manage Agent spend](https://mpp.dev/guides/managing-agent-spend). +::: + +## Pay an HTTP service + +Create a payment-aware client in `onStart()`. Restrict automatic payments to trusted origins: + + + +```ts +import { Agent } from "agents"; +import { Mppx } from "mppx/client"; +import { createPaymentMethods } from "./payments"; + +type PaymentEnv = Env & { MPP_PRIVATE_KEY: string }; + +export class BuyerAgent extends Agent { + methods!: ReturnType; + payments!: ReturnType; + + async onStart() { + this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY); + this.payments = Mppx.create({ + acceptPaymentPolicy: { origins: ["https://api.example.com"] }, + methods: this.methods, + polyfill: false, + }); + } + + async buyReport() { + const response = await this.payments.fetch( + "https://api.example.com/reports/latest", + ); + + if (!response.ok) throw new Error(`Request failed: ${response.status}`); + return response.json(); + } +} +``` + + + +Free endpoints pass through unchanged. Paid endpoints trigger the payment retry and return a `Payment-Receipt` header. + +## Pay an MCP tool + +Connect the Agent with `addMcpServer()`. Wait for the connection before wrapping its client: + + + +```ts +import { Agent } from "agents"; +import { McpClient } from "mppx/mcp/client"; +import { createPaymentMethods } from "./payments"; + +type PaymentEnv = Env & { MPP_PRIVATE_KEY: string }; + +export class BuyerAgent extends Agent { + methods!: ReturnType; + + async onStart() { + this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY); + } + + async paidSearch() { + const connection = await this.addMcpServer( + "premium-search", + "https://mcp.example.com/mcp", + ); + if (connection.state === "authenticating") { + return { authUrl: connection.authUrl }; + } + + await this.mcp.waitForConnections(); + + const server = this.getMcpServers().servers[connection.id]; + const mcpConnection = this.mcp.mcpConnections[connection.id]; + if (server?.state !== "ready" || !mcpConnection) { + throw new Error("MCP server is not ready."); + } + + const client = McpClient.wrap(mcpConnection.client, { + methods: this.methods, + }); + const result = await client.callTool({ + name: "premium_search", + arguments: { query: "Cloudflare Agents" }, + }); + + return { content: result.content, receipt: result.receipt }; + } +} +``` + + + +If `paidSearch()` returns an `authUrl`, send the user to that URL and retry after authorization. + +The wrapper retries a paid tool call with an MPP Credential. The result includes the MPP Receipt as `result.receipt`. + +By default, both clients pay compatible Challenges automatically. Use `onChallenge` for HTTP or `onPaymentRequired` for MCP when a payment needs approval. Challenge amounts are integer base units, not decimal display values. + +## Pay x402 services + +The `mppx` HTTP client also recognizes x402 Challenges. Configure an x402-compatible EVM method next to the MPP method. The service does not need changes. For configuration, refer to [Use MPP with x402](https://mpp.dev/guides/use-mpp-with-x402). + +To accept payments, refer to [Accept payments with MPP](/agents/tools/payments/mpp/accept-payments/). For MCP connection options, refer to the [MCP client API](/agents/model-context-protocol/apis/client-api/).