From 9f363736f3107dfecf618fab47f1e3057d48bdc1 Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Mon, 20 Jul 2026 13:01:22 -0700 Subject: [PATCH 1/9] [Agents] Expand MPP payment documentation --- public/__redirects | 5 +- .../docs/agents/tools/payments/index.mdx | 21 +- .../payments/mpp-charge-for-http-content.mdx | 110 --------- .../docs/agents/tools/payments/mpp.mdx | 78 ------- .../tools/payments/mpp/accept-payments.mdx | 216 ++++++++++++++++++ .../docs/agents/tools/payments/mpp/index.mdx | 102 +++++++++ .../payments/mpp/pay-from-agents-sdk.mdx | 193 ++++++++++++++++ 7 files changed, 527 insertions(+), 198 deletions(-) delete mode 100644 src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx delete mode 100644 src/content/docs/agents/tools/payments/mpp.mdx create mode 100644 src/content/docs/agents/tools/payments/mpp/accept-payments.mdx create mode 100644 src/content/docs/agents/tools/payments/mpp/index.mdx create mode 100644 src/content/docs/agents/tools/payments/mpp/pay-from-agents-sdk.mdx diff --git a/public/__redirects b/public/__redirects index 1fd806d71ba..db84efb46cf 100644 --- a/public/__redirects +++ b/public/__redirects @@ -312,8 +312,9 @@ /agents/communication-channels/slack/slack-agent/ /agents/examples/slack-agent/ 301 /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/agentic-payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp-charge-for-http-content/ 301 +/agents/tools/payments/mpp-charge-for-http-content/ /agents/tools/payments/mpp/accept-payments/ 301 +/agents/tools/payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp/accept-payments/ 301 +/agents/agentic-payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp/accept-payments/ 301 # ai-audit /ai-audit/features/detect-ai-crawlers/ /ai-crawl-control/features/analyze-ai-crawlers/ 301 diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index c7a5133d215..a8780b26846 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -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. A protocol may still use durable sessions or subscriptions after the first payment. ## x402 and Machine Payments Protocol @@ -36,11 +36,11 @@ The Agents SDK provides first-class x402 integration: ### 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 protocol for machine-to-machine payments. It extends the HTTP `402` pattern with a formal `WWW-Authenticate: Payment` / `Authorization: Payment` header scheme and is on the IETF standards track. -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 blockchain — including cards through Stripe, Bitcoin Lightning, and stablecoins — and provides **charges**, **sessions**, and **subscriptions** for fixed-price, usage-based, and recurring billing. With an EVM charge method configured, `mppx` can also handle x402 `exact` payment Challenges. -## Charge for resources +## Build with agentic payments + 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 deleted file mode 100644 index 17806e9fea1..00000000000 --- a/src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Charge for HTTP content -pcx_content_type: how-to -sidebar: - order: 1 -description: Gate HTTP endpoints with MPP payments using the mpp-proxy template on Cloudflare Workers. -products: - - agents ---- - -The [mpp-proxy](https://github.com/cloudflare/mpp-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 an MPP payment challenge. After the client pays, the proxy verifies the payment, forwards the request to your origin, and issues a 1-hour session cookie. - -Deploy the mpp-proxy template to your Cloudflare account: - -[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/mpp-proxy) - -## 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`: - -```jsonc -{ - "vars": { - "PAY_TO": "0xYourWalletAddress", - "TEMPO_TESTNET": false, - "PAYMENT_CURRENCY": "0x20c000000000000000000000b9537d11c60e8b50", - "PROTECTED_PATTERNS": [ - { - "pattern": "/premium/*", - "amount": "0.01", - "description": "Access to premium content for 1 hour" - } - ] - } -} -``` - -:::note -Set `TEMPO_TESTNET` to `true` and `PAYMENT_CURRENCY` to `0x20c0000000000000000000000000000000000000` for testnet development. -::: - -## Selective gating with Bot Management - -With [Bot Management](/bots/), the proxy can charge crawlers while keeping the site free for humans: - -```jsonc -{ - "pattern": "/content/*", - "amount": "0.25", - "description": "Content access for 1 hour", - "bot_score_threshold": 30, - "except_detection_ids": [120623194, 117479730] -} -``` - -Requests with a bot score at or below `bot_score_threshold` are directed to 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/mpp-proxy -cd mpp-proxy -npm install -npx wrangler secret put JWT_SECRET -npx wrangler secret put MPP_SECRET_KEY -npx wrangler deploy -``` - -For full configuration options, proxy modes, and Bot Management examples, refer to the [mpp-proxy README](https://github.com/cloudflare/mpp-proxy). - -## 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. - -## Related - -- [mpp.dev](https://mpp.dev) — Protocol specification -- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) — Cloudflare-native monetization without custom code 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..5998f0a9051 --- /dev/null +++ b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx @@ -0,0 +1,216 @@ +--- +title: Accept payments with MPP +pcx_content_type: how-to +sidebar: + order: 1 +description: Accept MPP payments from an existing origin, a custom Worker endpoint, or an MCP tool. +products: + - agents +--- + +import { + PackageManagers, + Steps, + TypeScriptExample, + WranglerConfig, +} from "~/components"; + +Choose the integration that matches the service you want to sell: + +| Service | Integration | +| -------------------------- | ---------------------------------------------------------------------------------- | +| Existing website or API | Put [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) in front of the origin. | +| New or existing Worker API | Add `mppx` middleware directly to a route. | +| MCP server | Add the MPP MCP transport inside a tool handler. | + +All three approaches return a payment Challenge, verify the retry Credential, and attach a Receipt to the paid response. + +## Gate an existing origin with `mpp-proxy` + +[`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) is a Cloudflare Worker that adds MPP to an existing HTTP backend. Unprotected traffic passes through. A paid request receives an MPP Challenge, and a verified request reaches the origin. The proxy also issues a secure cookie that reuses access for one hour. + + + +1. Deploy the template to your Cloudflare account: + + [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/mpp-proxy) + +2. Set the recipient, payment currency, and protected routes in `wrangler.jsonc`: + + + + ```jsonc + { + "vars": { + "PAY_TO": "0xYourWalletAddress", + "TEMPO_TESTNET": false, + "PAYMENT_CURRENCY": "0x20c000000000000000000000b9537d11c60e8b50", + "PROTECTED_PATTERNS": [ + { + "pattern": "/premium/*", + "amount": "0.01", + "description": "Access to premium content for 1 hour" + } + ] + } + } + ``` + + + + For testnet development, set `TEMPO_TESTNET` to `true` and use `0x20c0000000000000000000000000000000000000` as the payment currency. + +3. Store the two required secrets: + + + + + +4. Request `/__mpp/protected` or another protected route. An unpaid request should return `402 Payment Required` with a `WWW-Authenticate: Payment` header. + + + +The proxy supports DNS-based origins, external origin URLs, and [service bindings](/workers/runtime-apis/bindings/service-bindings/). Refer to the [`mpp-proxy` README](https://github.com/cloudflare/mpp-proxy) for the full configuration. + +### Charge crawlers with Bot Management + +With [Bot Management](/bots/), a protected pattern can charge automated traffic while leaving the same content free for people: + + + +```jsonc +{ + "vars": { + "PROTECTED_PATTERNS": [ + { + "pattern": "/content/*", + "amount": "0.25", + "description": "Content access for 1 hour", + "bot_score_threshold": 30, + "except_detection_ids": [120623194, 117479730] + } + ] + } +} +``` + + + +Requests with a bot score at or below `bot_score_threshold` reach the paywall. Use `except_detection_ids` to allow specific crawlers by [detection ID](/ai-crawl-control/reference/bots/). + +## Charge for a Worker route + +Use the Hono middleware when you control the Worker application. + + + +Store the MPP signing key as a [Worker secret](/workers/configuration/secrets/): + + + +Then add `mppx.charge` before the route handler: + + + +```ts +import { env } from "cloudflare:workers"; +import { Hono } from "hono"; +import { Mppx, tempo } from "mppx/hono"; + +const app = new Hono(); + +const mppx = Mppx.create({ + methods: [tempo.charge()], + secretKey: env.MPP_SECRET_KEY, +}); + +app.get( + "/premium", + mppx.charge({ + amount: "0.10", + currency: "0x20c000000000000000000000b9537d11c60e8b50", + description: "Premium API access", + recipient: "0xYourWalletAddress", + }), + (c) => c.json({ data: "Thanks for paying!" }), +); + +export default app; +``` + + + +You can parse the verified Credential to read the payer DID, offer several methods from the same `Mppx` instance, or set different prices on different routes. + +## Charge for an MCP tool + +MPP carries its Challenge, Credential, and Receipt as MCP JSON-RPC data. Add `Transport.mcpSdk()` to an [`McpAgent`](/agents/model-context-protocol/apis/agent-api/) and check payment inside the tool handler: + + + + + +```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"; + +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( + "search", + "Search the web", + { query: z.string() }, + async ({ query }, extra) => { + const payment = await mppx.charge({ + amount: "0.01", + currency: "0x20c0000000000000000000000000000000000000", + description: "Web search query", + recipient: "0xYourWalletAddress", + })(extra); + + if (payment.status === 402) throw payment.challenge; + + return payment.withReceipt({ + content: [{ type: "text", text: `Results for: ${query}` }], + }); + }, + ); + } +} + +export default PaidMCP.serve("/mcp"); +``` + + + +Free tools do not call `mppx.charge`. Paid tools can set different prices, and the returned Receipt is attached to the tool result in `_meta`. + +## Add other billing patterns + +Use the same server architecture for more than one-time charges: + +| Pattern | Server API | Production requirement | +| ---------------------------- | --------------------------------------- | --------------------------------------------------------------------- | +| Usage-based access | `mppx.session()` | An atomic store that persists the payment channel across requests. | +| Recurring access | `mppx.subscription()` | An atomic store for subscription state and a stable subscription key. | +| Native MPP and x402 together | `evm.charge()` with an x402 facilitator | An EVM asset, recipient, and facilitator configuration. | +| Zero-dollar payer proof | `mppx.charge({ amount: "0" })` | An atomic store if proofs must be single-use across Worker instances. | + +Use `Store.memory()` only for local development. Use a durable implementation such as `Store.cloudflare()` for concurrent Worker deployments. Refer to the [session intent](https://mpp.dev/intents/session), [subscription guide](https://mpp.dev/guides/subscription-payments), and [MPP with x402 guide](https://mpp.dev/guides/use-mpp-with-x402) for complete configurations. + +## Related resources + +- [Pay from the Agents SDK](/agents/tools/payments/mpp/pay-from-agents-sdk/) +- [Monetize an MCP server](https://mpp.dev/guides/monetize-mcp-server) +- [Hono middleware reference](https://mpp.dev/sdk/typescript/middlewares/hono) +- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) 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..cd6d39ed643 --- /dev/null +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -0,0 +1,102 @@ +--- +title: MPP (Machine Payments Protocol) +pcx_content_type: overview +sidebar: + order: 9 + group: + hideIndex: false +description: Accept and make HTTP and MCP payments with MPP and the Cloudflare Agents SDK. +products: + - agents +--- + +import { CardGrid, LinkCard } from "~/components"; + +[Machine Payments Protocol (MPP)](https://mpp.dev) is an open protocol for machine-to-machine payments. It turns HTTP `402 Payment Required` into a complete Challenge, Credential, and Receipt flow for agents, apps, and people. + +MPP is payment-method agnostic. The same endpoint can offer stablecoins, cards, Bitcoin Lightning, or custom payment methods. + + + + + + +## What MPP can do + +| Use case | MPP capability | +| ------------------------------ | ----------------------------------------------------------------------------------------------------- | +| Charge once | Set a fixed price for an HTTP request or MCP tool call. | +| Meter usage | Use sessions for streamed tokens, bytes, or other pay-as-you-go usage. | +| Sell recurring access | Use subscriptions for paid plans, memberships, recurring MCP tools, and usage bundles. | +| Gate an existing application | Put [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) in front of an origin without changing it. | +| Identify the payer | Read the payer DID from the verified MPP Credential. | +| Offer several payment methods | Publish multiple Challenges and let the client select a compatible method. | +| Support native MPP and x402 | Add an EVM charge method and x402 facilitator alongside native MPP methods. | +| Let an Agent pay automatically | Use `Mppx.create` for HTTP requests and `McpClient.wrap` for MCP tool calls. | + +## How it works + +1. A client requests a resource or calls a tool. +2. The server returns a payment Challenge. HTTP uses `402` and `WWW-Authenticate: Payment`; MCP uses JSON-RPC error code `-32042`. +3. The client selects a supported method and creates a payment Credential. +4. The client retries with the Credential. +5. The server verifies and settles the payment, then returns the result with a Receipt. + +## Payment intents + +MPP provides three billing patterns: + +| Intent | Use it for | +| ------------------ | --------------------------------------------------------------------------------------------------- | +| **`charge`** | One-time, fixed-price payments that settle immediately. | +| **`session`** | Usage-based payments whose cost changes during a request, such as streamed tokens or bytes. | +| **`subscription`** | Recurring access with a fixed price per billing period, such as paid plans, memberships, or quotas. | + +Sessions and subscriptions keep state across requests. Back them with a durable, atomic store in production. + +## Payment methods + +Servers can offer several methods at the same time. Clients choose a compatible Challenge. + +| Method | Description | +| ------------------------------------------------------ | ----------------------------------------------------------------------- | +| [Stablecoins](https://mpp.dev/payment-methods/tempo) | Stablecoin payments with fast settlement, sessions, and subscriptions. | +| [Stripe](https://mpp.dev/payment-methods/stripe) | Cards, wallets, and other Stripe methods through Shared Payment Tokens. | +| [Lightning](https://mpp.dev/payment-methods/lightning) | Bitcoin payments over the Lightning Network. | +| [Card](https://mpp.dev/payment-methods/card) | Card payments through encrypted network tokens. | +| [Custom](https://mpp.dev/payment-methods/custom) | A custom payment method implemented with an MPP SDK. | + +## Compatibility with x402 + +MPP and x402 both use the `402 Payment Required` pattern, but use different Challenge and Credential encodings. `mppx` can handle native MPP and x402 `exact` flows through one payment-aware HTTP client when you register both the native method and an EVM charge method. Servers can expose both formats from one endpoint by configuring the EVM method with an x402 facilitator. + +Refer to [use MPP with x402](https://mpp.dev/guides/use-mpp-with-x402) for the shared client and server setup. + +## SDKs + +MPP has official client and server SDKs in five languages: + +| Language | SDK | +| ---------- | ---------------------------------------- | +| TypeScript | [`mppx`](https://mpp.dev/sdk/typescript) | +| Python | [`pympp`](https://mpp.dev/sdk/python) | +| Rust | [`mpp`](https://mpp.dev/sdk/rust) | +| Go | [`mpp-go`](https://mpp.dev/sdk/go) | +| Ruby | [`mpp-rb`](https://mpp.dev/sdk/ruby) | + +The TypeScript SDK includes middleware for [Hono](https://mpp.dev/sdk/typescript/middlewares/hono), Express, Next.js, and Elysia, an MCP transport, a payment-aware fetch client, and an [`mppx` CLI](https://mpp.dev/sdk/typescript/cli). + +## Related resources + +- [Cloudflare Agents integration](https://mpp.dev/partner-integrations/cloudflare-agents) +- [MPP protocol documentation](https://mpp.dev) +- [Payment HTTP Authentication specification](https://paymentauth.org) +- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) 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..d78e7e479f6 --- /dev/null +++ b/src/content/docs/agents/tools/payments/mpp/pay-from-agents-sdk.mdx @@ -0,0 +1,193 @@ +--- +title: Pay from the Agents SDK +pcx_content_type: how-to +sidebar: + order: 2 +description: Give a Cloudflare Agent payment-aware HTTP fetch and MCP clients with mppx. +products: + - agents +--- + +import { PackageManagers, Steps, TypeScriptExample } from "~/components"; + +Use [`Mppx.create`](https://mpp.dev/sdk/typescript/client/Mppx.create) for paid HTTP requests and [`McpClient.wrap`](https://mpp.dev/sdk/typescript/client/McpClient.wrap) for paid MCP tool calls. Free requests pass through unchanged. When a paid service returns a compatible Challenge, `mppx` creates a Credential, retries the call, and returns the result with its Receipt. + +## Set up payment methods + + + +1. Install the Agents SDK, `mppx`, and `viem`: + + + +2. Store the Agent's private key as a [Worker secret](/workers/configuration/secrets/): + + + +3. Create the payment methods once and reuse them for HTTP and MCP: + + + + ```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 +The examples use an environment private key for brevity. For a long-running Agent, use a scoped access key with spending limits, call scopes, recipient restrictions, and independent revocation. Refer to [managing agent spend](https://mpp.dev/guides/managing-agent-spend). +::: + +## Pay for HTTP requests + +Create a scoped payment-aware fetch inside `onStart()`. Setting `polyfill: false` keeps the wrapper local to this Agent instance. `acceptPaymentPolicy` restricts which origins can receive the Agent's `Accept-Payment` header and trigger automatic payment. + + + +```ts +import { Agent } from "agents"; +import { Mppx } from "mppx/client"; +import { createPaymentMethods } from "./payments"; + +export class BuyerAgent extends Agent { + payments!: ReturnType; + + async onStart() { + this.payments = Mppx.create({ + acceptPaymentPolicy: { + origins: ["https://api.example.com"], + }, + methods: createPaymentMethods(this.env.MPP_PRIVATE_KEY), + 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(); + } +} +``` + + + +If your runtime should make every later `fetch` payment-aware, omit `polyfill: false` and call `Mppx.create` once before those requests. The returned `payments.fetch` is easier to scope and test in an Agent. + +### Require approval before HTTP payment + +Use `onChallenge` to enforce an application policy or request human approval before creating a Credential: + + + +```ts +const payments = Mppx.create({ + methods, + onChallenge: async (challenge, { createCredential }) => { + if (Number(challenge.request.amount) > 0.1) { + throw new Error("Payment requires approval"); + } + + return createCredential(); + }, + polyfill: false, +}); +``` + + + +## Pay for MCP tools + +First connect the Agent with `addMcpServer()`. Then wrap the MCP client stored on that connection. Calls through the same client become payment-aware without replacing the Cloudflare MCP connection. + + + +```ts +import { Agent } from "agents"; +import { McpClient } from "mppx/mcp/client"; +import { createPaymentMethods } from "./payments"; + +export class BuyerAgent extends Agent { + async onStart() { + const { id } = await this.addMcpServer( + "premium-search", + "https://mcp.example.com/mcp", + ); + + const client = McpClient.wrap(this.mcp.mcpConnections[id].client, { + methods: createPaymentMethods(this.env.MPP_PRIVATE_KEY), + onPaymentRequired: async (challenge) => { + return Number(challenge.request.amount) <= 0.1; + }, + }); + + const result = await client.callTool({ + name: "premium_search", + arguments: { query: "Cloudflare Agents" }, + }); + + console.log(result.content, result.receipt); + } +} +``` + + + +`onPaymentRequired` runs before the wrapper creates a Credential. Return `false` to decline. You can also pass a different approval callback in the options for an individual `callTool` request. + +## Pay MPP and x402 endpoints + +Add an EVM charge method next to your MPP methods when the Agent calls HTTP APIs that may return either MPP or x402 `exact` Challenges: + + + +```ts +import { env } from "cloudflare:workers"; +import { evm } from "mppx/client"; +import { privateKeyToAccount } from "viem/accounts"; +import { createPaymentMethods } from "./payments"; + +const account = privateKeyToAccount(env.MPP_PRIVATE_KEY as `0x${string}`); + +const methods = [ + ...createPaymentMethods(env.MPP_PRIVATE_KEY), + evm.charge({ + account, + currencies: [evm.assets.baseSepolia.USDC], + maxAmount: "1.00", + }), +] as const; +``` + + + +The payment-aware HTTP client reads native MPP `WWW-Authenticate` Challenges and x402 `PAYMENT-REQUIRED` Challenges, then retries with the matching header. The MCP wrapper handles MPP's MCP transport; it does not convert an x402 HTTP service into an MCP service. + +## Know which calls are covered + +| Agent call surface | Add payment handling with | What it covers | +| -------------------------------- | ------------------------- | -------------------------------------------------- | +| HTTP `fetch` | `Mppx.create` | Native MPP and configured x402 HTTP Challenges. | +| Agents SDK MCP connection | `McpClient.wrap` | MPP Challenges returned by MCP tool calls. | +| Another library's private client | Its transport adapter | Only calls made through that library's own client. | + +Configuring payment-aware fetch does not automatically wrap an MCP client that the Agents SDK already owns. Configure both surfaces when the same Agent pays HTTP APIs and MCP tools. + +## Related resources + +- [Accept payments with MPP](/agents/tools/payments/mpp/accept-payments/) +- [Cloudflare Agents integration](https://mpp.dev/partner-integrations/cloudflare-agents) +- [MCP client API](/agents/model-context-protocol/apis/client-api/) +- [Manage agent spend](https://mpp.dev/guides/managing-agent-spend) From e99bc21b0a91ed28b5727ad6d838c6d4b8cca5ce Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Mon, 20 Jul 2026 16:04:58 -0700 Subject: [PATCH 2/9] [Agents] Refine MPP payment how-to guides --- .../docs/agents/tools/payments/index.mdx | 12 +- .../tools/payments/mpp/accept-payments.mdx | 212 ++++++++++-------- .../docs/agents/tools/payments/mpp/index.mdx | 86 +++---- .../payments/mpp/pay-from-agents-sdk.mdx | 40 ++-- 4 files changed, 185 insertions(+), 165 deletions(-) diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index a8780b26846..c06deab1595 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 --- @@ -21,7 +21,7 @@ Cloudflare's [Agents SDK](/agents/) supports agentic payments through two protoc 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 pre-created service account or pre-shared API key is required. Agents handle the payment exchange programmatically. A protocol may still use durable sessions or subscriptions after the first payment. +No pre-created service account or pre-shared API key is required. Agents handle the payment exchange. They can reuse sessions or subscriptions after the first payment. ## x402 and Machine Payments Protocol @@ -31,14 +31,14 @@ No pre-created service account or pre-shared API key is required. Agents handle 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 an open protocol for machine-to-machine payments. 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 through Stripe, Bitcoin Lightning, and stablecoins — and provides **charges**, **sessions**, and **subscriptions** for fixed-price, usage-based, and recurring billing. With an EVM charge method configured, `mppx` can also handle x402 `exact` payment Challenges. +On Cloudflare, MPP can protect Worker routes, origins, and MCP tools. Cloudflare Agents can also pay MPP services through HTTP or MCP. The `mppx` SDK supports one-time, usage-based, and recurring payments. ## Build with agentic payments diff --git a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx index 5998f0a9051..900492b22d7 100644 --- a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx +++ b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx @@ -3,7 +3,7 @@ title: Accept payments with MPP pcx_content_type: how-to sidebar: order: 1 -description: Accept MPP payments from an existing origin, a custom Worker endpoint, or an MCP tool. +description: Accept payments through Machine Payments Protocol (MPP) from a Cloudflare Worker, origin proxy, or Model Context Protocol (MCP) tool. products: - agents --- @@ -15,19 +15,25 @@ import { WranglerConfig, } from "~/components"; -Choose the integration that matches the service you want to sell: +Use Cloudflare Workers to accept Machine Payments Protocol (MPP) payments. Protect an existing origin, a Worker route, or a Model Context Protocol (MCP) tool. -| Service | Integration | +## Prerequisites + +[Create a Cloudflare account](/fundamentals/account/create-account/), if you have not already. The examples also require a payment recipient and an MPP secret key. + +Choose a Cloudflare integration for the service: + +| Service | Cloudflare integration | | -------------------------- | ---------------------------------------------------------------------------------- | | Existing website or API | Put [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) in front of the origin. | -| New or existing Worker API | Add `mppx` middleware directly to a route. | -| MCP server | Add the MPP MCP transport inside a tool handler. | +| New or existing Worker API | Add `mppx` middleware to a Worker route. | +| MCP server | Add the MPP transport to an `McpAgent` tool handler. | -All three approaches return a payment Challenge, verify the retry Credential, and attach a Receipt to the paid response. +Each workflow challenges unpaid requests. It verifies the payment retry and returns an MPP Receipt. ## Gate an existing origin with `mpp-proxy` -[`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) is a Cloudflare Worker that adds MPP to an existing HTTP backend. Unprotected traffic passes through. A paid request receives an MPP Challenge, and a verified request reaches the origin. The proxy also issues a secure cookie that reuses access for one hour. +Deploy [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) when you cannot change the origin code. The Worker passes unprotected requests to the origin. It challenges paid paths and verifies payment before forwarding. A secure cookie reuses access for one hour. @@ -66,15 +72,17 @@ All three approaches return a payment Challenge, verify the retry Credential, an -4. Request `/__mpp/protected` or another protected route. An unpaid request should return `402 Payment Required` with a `WWW-Authenticate: Payment` header. +4. Request `/__mpp/health` to confirm that the Worker is available. Then request `/__mpp/protected` or another paid route. The unpaid request returns `402 Payment Required` with a `WWW-Authenticate: Payment` header. -The proxy supports DNS-based origins, external origin URLs, and [service bindings](/workers/runtime-apis/bindings/service-bindings/). Refer to the [`mpp-proxy` README](https://github.com/cloudflare/mpp-proxy) for the full configuration. +The Worker now protects matching routes before forwarding them. It supports DNS origins, external URLs, and [service bindings](/workers/runtime-apis/bindings/service-bindings/). + +For all settings, refer to the [`mpp-proxy` README](https://github.com/cloudflare/mpp-proxy). ### Charge crawlers with Bot Management -With [Bot Management](/bots/), a protected pattern can charge automated traffic while leaving the same content free for people: +With [Cloudflare Bot Management](/bots/), a paid pattern can target automated traffic. The same content remains free for people: @@ -100,115 +108,139 @@ Requests with a bot score at or below `bot_score_threshold` reach the paywall. U ## Charge for a Worker route -Use the Hono middleware when you control the Worker application. +Add `mppx` middleware when you control the Worker application: - + -Store the MPP signing key as a [Worker secret](/workers/configuration/secrets/): +1. Install Hono and `mppx` in the Worker project: - + -Then add `mppx.charge` before the route handler: +2. Store the MPP signing key as a [Worker secret](/workers/configuration/secrets/): - + -```ts -import { env } from "cloudflare:workers"; -import { Hono } from "hono"; -import { Mppx, tempo } from "mppx/hono"; +3. Add `mppx.charge` before the paid route handler: -const app = new Hono(); + -const mppx = Mppx.create({ - methods: [tempo.charge()], - secretKey: env.MPP_SECRET_KEY, -}); + ```ts + import { env } from "cloudflare:workers"; + import { Hono } from "hono"; + import { Mppx, tempo } from "mppx/hono"; -app.get( - "/premium", - mppx.charge({ - amount: "0.10", - currency: "0x20c000000000000000000000b9537d11c60e8b50", - description: "Premium API access", - recipient: "0xYourWalletAddress", - }), - (c) => c.json({ data: "Thanks for paying!" }), -); + const app = new Hono(); -export default app; -``` + const mppx = Mppx.create({ + methods: [tempo.charge()], + secretKey: env.MPP_SECRET_KEY, + }); - + app.get( + "/premium", + mppx.charge({ + amount: "0.10", + currency: "0x20c000000000000000000000b9537d11c60e8b50", + description: "Premium API access", + recipient: "0xYourWalletAddress", + }), + (c) => c.json({ data: "Thanks for paying!" }), + ); -You can parse the verified Credential to read the payer DID, offer several methods from the same `Mppx` instance, or set different prices on different routes. + export default app; + ``` + + + +4. Request `/premium` without payment. The Worker returns `402 Payment Required` and an MPP Challenge. + + + +After payment, the Worker runs the route handler and returns a Receipt. You can also read the decentralized identifier (DID) for the payer. ## Charge for an MCP tool -MPP carries its Challenge, Credential, and Receipt as MCP JSON-RPC data. Add `Transport.mcpSdk()` to an [`McpAgent`](/agents/model-context-protocol/apis/agent-api/) and check payment inside the tool handler: - - - - - -```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"; - -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( - "search", - "Search the web", - { query: z.string() }, - async ({ query }, extra) => { - const payment = await mppx.charge({ - amount: "0.01", - currency: "0x20c0000000000000000000000000000000000000", - description: "Web search query", - recipient: "0xYourWalletAddress", - })(extra); - - if (payment.status === 402) throw payment.challenge; - - return payment.withReceipt({ - content: [{ type: "text", text: `Results for: ${query}` }], - }); - }, - ); - } -} +Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/agent-api/): -export default PaidMCP.serve("/mcp"); -``` + + +1. Install the Agents SDK, `mppx`, MCP SDK, and Zod: + + + +2. Store `MPP_SECRET_KEY` as a [Worker secret](/workers/configuration/secrets/): - + -Free tools do not call `mppx.charge`. Paid tools can set different prices, and the returned Receipt is attached to the tool result in `_meta`. +3. Add `Transport.mcpSdk()` and check payment in the tool handler: + + + + ```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"; + + 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( + "search", + "Search the web", + { query: z.string() }, + async ({ query }, extra) => { + const payment = await mppx.charge({ + amount: "0.01", + currency: "0x20c0000000000000000000000000000000000000", + description: "Web search query", + recipient: "0xYourWalletAddress", + })(extra); + + if (payment.status === 402) throw payment.challenge; + + return payment.withReceipt({ + content: [{ type: "text", text: `Results for: ${query}` }], + }); + }, + ); + } + } + + export default PaidMCP.serve("/mcp"); + ``` + + + +4. Call the `search` tool without payment. The MCP server returns an MPP Challenge through JSON-RPC. + + + +After payment, the tool result includes the MPP Receipt in `_meta`. Free tools do not call `mppx.charge`. ## Add other billing patterns -Use the same server architecture for more than one-time charges: +After a one-time Worker flow succeeds, add another billing pattern: | Pattern | Server API | Production requirement | | ---------------------------- | --------------------------------------- | --------------------------------------------------------------------- | | Usage-based access | `mppx.session()` | An atomic store that persists the payment channel across requests. | | Recurring access | `mppx.subscription()` | An atomic store for subscription state and a stable subscription key. | -| Native MPP and x402 together | `evm.charge()` with an x402 facilitator | An EVM asset, recipient, and facilitator configuration. | +| Native MPP and x402 together | `evm.charge()` with an x402 facilitator | An Ethereum Virtual Machine (EVM) asset, recipient, and facilitator. | | Zero-dollar payer proof | `mppx.charge({ amount: "0" })` | An atomic store if proofs must be single-use across Worker instances. | -Use `Store.memory()` only for local development. Use a durable implementation such as `Store.cloudflare()` for concurrent Worker deployments. Refer to the [session intent](https://mpp.dev/intents/session), [subscription guide](https://mpp.dev/guides/subscription-payments), and [MPP with x402 guide](https://mpp.dev/guides/use-mpp-with-x402) for complete configurations. +Use `Store.memory()` only for local development. Concurrent Workers need a durable implementation such as `Store.cloudflare()`. + +For complete configurations, refer to the [session intent](https://mpp.dev/intents/session), [subscription guide](https://mpp.dev/guides/subscription-payments), and [MPP with x402 guide](https://mpp.dev/guides/use-mpp-with-x402). -## Related resources +## Next steps - [Pay from the Agents SDK](/agents/tools/payments/mpp/pay-from-agents-sdk/) - [Monetize an MCP server](https://mpp.dev/guides/monetize-mcp-server) diff --git a/src/content/docs/agents/tools/payments/mpp/index.mdx b/src/content/docs/agents/tools/payments/mpp/index.mdx index cd6d39ed643..86e5c64c898 100644 --- a/src/content/docs/agents/tools/payments/mpp/index.mdx +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -5,16 +5,14 @@ sidebar: order: 9 group: hideIndex: false -description: Accept and make HTTP and MCP payments with MPP and the Cloudflare Agents SDK. +description: Use Machine Payments Protocol (MPP) with Cloudflare Workers and the Agents SDK to accept and make payments. products: - agents --- import { CardGrid, LinkCard } from "~/components"; -[Machine Payments Protocol (MPP)](https://mpp.dev) is an open protocol for machine-to-machine payments. It turns HTTP `402 Payment Required` into a complete Challenge, Credential, and Receipt flow for agents, apps, and people. - -MPP is payment-method agnostic. The same endpoint can offer stablecoins, cards, Bitcoin Lightning, or custom payment methods. +[Machine Payments Protocol (MPP)](https://mpp.dev) adds payments to HTTP requests and Model Context Protocol (MCP) tool calls. Use it with Cloudflare Workers to sell access. Use it with the Agents SDK to pay for services. -## What MPP can do - -| Use case | MPP capability | -| ------------------------------ | ----------------------------------------------------------------------------------------------------- | -| Charge once | Set a fixed price for an HTTP request or MCP tool call. | -| Meter usage | Use sessions for streamed tokens, bytes, or other pay-as-you-go usage. | -| Sell recurring access | Use subscriptions for paid plans, memberships, recurring MCP tools, and usage bundles. | -| Gate an existing application | Put [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) in front of an origin without changing it. | -| Identify the payer | Read the payer DID from the verified MPP Credential. | -| Offer several payment methods | Publish multiple Challenges and let the client select a compatible method. | -| Support native MPP and x402 | Add an EVM charge method and x402 facilitator alongside native MPP methods. | -| Let an Agent pay automatically | Use `Mppx.create` for HTTP requests and `McpClient.wrap` for MCP tool calls. | - -## How it works +## Choose a Cloudflare workflow -1. A client requests a resource or calls a tool. -2. The server returns a payment Challenge. HTTP uses `402` and `WWW-Authenticate: Payment`; MCP uses JSON-RPC error code `-32042`. -3. The client selects a supported method and creates a payment Credential. -4. The client retries with the Credential. -5. The server verifies and settles the payment, then returns the result with a Receipt. +Choose a workflow based on where payment happens: -## Payment intents +| Goal | Cloudflare integration | +| -------------------------- | ---------------------------------------------------------------- | +| Protect an existing origin | Deploy `mpp-proxy` as a Worker in front of the origin. | +| Charge for a Worker route | Add `mppx` middleware to a Hono route. | +| Charge for an MCP tool | Add the MPP transport to an `McpAgent` tool handler. | +| Pay an HTTP endpoint | Create a payment-aware client in the Agent lifecycle. | +| Pay for an MCP tool | Wrap the MCP connection created by the Agents SDK. | -MPP provides three billing patterns: +## How payments move through Cloudflare -| Intent | Use it for | -| ------------------ | --------------------------------------------------------------------------------------------------- | -| **`charge`** | One-time, fixed-price payments that settle immediately. | -| **`session`** | Usage-based payments whose cost changes during a request, such as streamed tokens or bytes. | -| **`subscription`** | Recurring access with a fixed price per billing period, such as paid plans, memberships, or quotas. | +1. An Agent or HTTP client requests a paid resource. +2. The Worker or MCP server returns an MPP Challenge. +3. The client creates a payment Credential. +4. The client retries the same request. +5. The server verifies payment and returns a Receipt. -Sessions and subscriptions keep state across requests. Back them with a durable, atomic store in production. +HTTP services return the Challenge with `402 Payment Required`. MCP tools return the same payment data through JSON-RPC. -## Payment methods +## Add billing beyond one request -Servers can offer several methods at the same time. Clients choose a compatible Challenge. +Choose an MPP intent based on the billing model: -| Method | Description | -| ------------------------------------------------------ | ----------------------------------------------------------------------- | -| [Stablecoins](https://mpp.dev/payment-methods/tempo) | Stablecoin payments with fast settlement, sessions, and subscriptions. | -| [Stripe](https://mpp.dev/payment-methods/stripe) | Cards, wallets, and other Stripe methods through Shared Payment Tokens. | -| [Lightning](https://mpp.dev/payment-methods/lightning) | Bitcoin payments over the Lightning Network. | -| [Card](https://mpp.dev/payment-methods/card) | Card payments through encrypted network tokens. | -| [Custom](https://mpp.dev/payment-methods/custom) | A custom payment method implemented with an MPP SDK. | +| Intent | Cloudflare use case | +| ------------------ | -------------------------------------------------------- | +| **`charge`** | Set a fixed price for a Worker route or MCP tool. | +| **`session`** | Meter streamed tokens, bytes, or other changing usage. | +| **`subscription`** | Sell recurring access, plans, memberships, or allowances. | -## Compatibility with x402 +Sessions and subscriptions keep state across requests. Use a durable, atomic store for production Workers. -MPP and x402 both use the `402 Payment Required` pattern, but use different Challenge and Credential encodings. `mppx` can handle native MPP and x402 `exact` flows through one payment-aware HTTP client when you register both the native method and an EVM charge method. Servers can expose both formats from one endpoint by configuring the EVM method with an x402 facilitator. +## Choose a payment method -Refer to [use MPP with x402](https://mpp.dev/guides/use-mpp-with-x402) for the shared client and server setup. +MPP separates the payment protocol from the payment method. A Worker can offer one or more compatible methods. The examples use one stablecoin method so that the code remains executable. -## SDKs +For other methods, refer to [MPP payment methods](https://mpp.dev/payment-methods). -MPP has official client and server SDKs in five languages: +## Pay MPP and x402 services -| Language | SDK | -| ---------- | ---------------------------------------- | -| TypeScript | [`mppx`](https://mpp.dev/sdk/typescript) | -| Python | [`pympp`](https://mpp.dev/sdk/python) | -| Rust | [`mpp`](https://mpp.dev/sdk/rust) | -| Go | [`mpp-go`](https://mpp.dev/sdk/go) | -| Ruby | [`mpp-rb`](https://mpp.dev/sdk/ruby) | +The same `mppx` HTTP client can pay MPP and x402 services. Add an x402-compatible charge method beside the native MPP method. -The TypeScript SDK includes middleware for [Hono](https://mpp.dev/sdk/typescript/middlewares/hono), Express, Next.js, and Elysia, an MCP transport, a payment-aware fetch client, and an [`mppx` CLI](https://mpp.dev/sdk/typescript/cli). +For the shared setup, refer to [use MPP with x402](https://mpp.dev/guides/use-mpp-with-x402). ## Related resources - [Cloudflare Agents integration](https://mpp.dev/partner-integrations/cloudflare-agents) - [MPP protocol documentation](https://mpp.dev) -- [Payment HTTP Authentication specification](https://paymentauth.org) - [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) 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 index d78e7e479f6..9c354b2dd99 100644 --- 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 @@ -3,16 +3,20 @@ title: Pay from the Agents SDK pcx_content_type: how-to sidebar: order: 2 -description: Give a Cloudflare Agent payment-aware HTTP fetch and MCP clients with mppx. +description: Configure a Cloudflare Agent to pay HTTP requests and Model Context Protocol (MCP) tools with Machine Payments Protocol (MPP). products: - agents --- import { PackageManagers, Steps, TypeScriptExample } from "~/components"; -Use [`Mppx.create`](https://mpp.dev/sdk/typescript/client/Mppx.create) for paid HTTP requests and [`McpClient.wrap`](https://mpp.dev/sdk/typescript/client/McpClient.wrap) for paid MCP tool calls. Free requests pass through unchanged. When a paid service returns a compatible Challenge, `mppx` creates a Credential, retries the call, and returns the result with its Receipt. +Use the Cloudflare Agents SDK with Machine Payments Protocol (MPP) services. An Agent can pay for HTTP requests and Model Context Protocol (MCP) tools. The `mppx` SDK handles the payment retry and returns a Receipt. -## Set up payment methods +## Prerequisites + +Create a [Cloudflare Agents project](/agents/getting-started/). Configure a funded account for the selected MPP payment method. + +## Configure Agent payments @@ -20,7 +24,7 @@ Use [`Mppx.create`](https://mpp.dev/sdk/typescript/client/Mppx.create) for paid -2. Store the Agent's private key as a [Worker secret](/workers/configuration/secrets/): +2. Store the payment private key as a [Worker secret](/workers/configuration/secrets/): @@ -44,12 +48,12 @@ Use [`Mppx.create`](https://mpp.dev/sdk/typescript/client/Mppx.create) for paid :::note -The examples use an environment private key for brevity. For a long-running Agent, use a scoped access key with spending limits, call scopes, recipient restrictions, and independent revocation. Refer to [managing agent spend](https://mpp.dev/guides/managing-agent-spend). +The examples use an environment private key. For production Agents, use a scoped access key with spending limits and recipient restrictions. Refer to [managing agent spend](https://mpp.dev/guides/managing-agent-spend). ::: ## Pay for HTTP requests -Create a scoped payment-aware fetch inside `onStart()`. Setting `polyfill: false` keeps the wrapper local to this Agent instance. `acceptPaymentPolicy` restricts which origins can receive the Agent's `Accept-Payment` header and trigger automatic payment. +Create a scoped payment-aware client inside `onStart()`. Setting `polyfill: false` keeps the wrapper local to this Agent. `acceptPaymentPolicy` limits which origins can request automatic payment. @@ -84,11 +88,13 @@ export class BuyerAgent extends Agent { -If your runtime should make every later `fetch` payment-aware, omit `polyfill: false` and call `Mppx.create` once before those requests. The returned `payments.fetch` is easier to scope and test in an Agent. +Call `buyReport()` to test the client. Free endpoints pass through unchanged. Paid endpoints trigger the MPP payment retry. + +To wrap every later `fetch`, omit `polyfill: false`. The scoped `payments.fetch` remains easier to test in an Agent. ### Require approval before HTTP payment -Use `onChallenge` to enforce an application policy or request human approval before creating a Credential: +Use `onChallenge` to require approval before creating a Credential: @@ -110,7 +116,7 @@ const payments = Mppx.create({ ## Pay for MCP tools -First connect the Agent with `addMcpServer()`. Then wrap the MCP client stored on that connection. Calls through the same client become payment-aware without replacing the Cloudflare MCP connection. +Connect the Agent with `addMcpServer()`. Then wrap the client stored on that connection. This keeps the Cloudflare MCP connection and adds payment handling. @@ -145,11 +151,13 @@ export class BuyerAgent extends Agent { -`onPaymentRequired` runs before the wrapper creates a Credential. Return `false` to decline. You can also pass a different approval callback in the options for an individual `callTool` request. +Call the tool to test the wrapper. `onPaymentRequired` runs before payment. Return `false` to decline the payment. + +You can pass another approval callback to an individual `callTool` request. ## Pay MPP and x402 endpoints -Add an EVM charge method next to your MPP methods when the Agent calls HTTP APIs that may return either MPP or x402 `exact` Challenges: +Add an Ethereum Virtual Machine (EVM) charge method for x402. Keep it beside the native MPP method: @@ -173,19 +181,21 @@ const methods = [ -The payment-aware HTTP client reads native MPP `WWW-Authenticate` Challenges and x402 `PAYMENT-REQUIRED` Challenges, then retries with the matching header. The MCP wrapper handles MPP's MCP transport; it does not convert an x402 HTTP service into an MCP service. +The HTTP client recognizes MPP and x402 Challenges. It retries each request with the matching header. The MCP wrapper only handles the MPP transport. ## Know which calls are covered +The following table shows where to add payment handling: + | Agent call surface | Add payment handling with | What it covers | | -------------------------------- | ------------------------- | -------------------------------------------------- | | HTTP `fetch` | `Mppx.create` | Native MPP and configured x402 HTTP Challenges. | | Agents SDK MCP connection | `McpClient.wrap` | MPP Challenges returned by MCP tool calls. | -| Another library's private client | Its transport adapter | Only calls made through that library's own client. | +| Private client from another SDK | Its transport adapter | Only calls made through that client. | -Configuring payment-aware fetch does not automatically wrap an MCP client that the Agents SDK already owns. Configure both surfaces when the same Agent pays HTTP APIs and MCP tools. +Payment-aware fetch does not wrap an existing MCP client. Configure both surfaces when an Agent pays HTTP APIs and MCP tools. -## Related resources +## Next steps - [Accept payments with MPP](/agents/tools/payments/mpp/accept-payments/) - [Cloudflare Agents integration](https://mpp.dev/partner-integrations/cloudflare-agents) From c752c32ed25cf70b0ead723c9418d320d025421c Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Mon, 20 Jul 2026 17:19:50 -0700 Subject: [PATCH 3/9] [Agents] Tighten MPP payment guides --- .../docs/agents/tools/payments/index.mdx | 4 +- .../tools/payments/mpp/accept-payments.mdx | 188 ++++++------------ .../docs/agents/tools/payments/mpp/index.mdx | 90 ++++----- .../payments/mpp/pay-from-agents-sdk.mdx | 128 ++++-------- 4 files changed, 135 insertions(+), 275 deletions(-) diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index c06deab1595..a7bdbc8117a 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -38,7 +38,7 @@ The Agents SDK provides first-class x402 integration: [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. -On Cloudflare, MPP can protect Worker routes, origins, and MCP tools. Cloudflare Agents can also pay MPP services through HTTP or MCP. The `mppx` SDK supports one-time, usage-based, and recurring payments. +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. ## Build with agentic payments @@ -50,7 +50,7 @@ On Cloudflare, MPP can protect Worker routes, origins, and MCP tools. Cloudflare /> - -1. Deploy the template to your Cloudflare account: - - [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/mpp-proxy) - -2. Set the recipient, payment currency, and protected routes in `wrangler.jsonc`: - - - - ```jsonc - { - "vars": { - "PAY_TO": "0xYourWalletAddress", - "TEMPO_TESTNET": false, - "PAYMENT_CURRENCY": "0x20c000000000000000000000b9537d11c60e8b50", - "PROTECTED_PATTERNS": [ - { - "pattern": "/premium/*", - "amount": "0.01", - "description": "Access to premium content for 1 hour" - } - ] - } - } - ``` - - - - For testnet development, set `TEMPO_TESTNET` to `true` and use `0x20c0000000000000000000000000000000000000` as the payment currency. - -3. Store the two required secrets: - - - - - -4. Request `/__mpp/health` to confirm that the Worker is available. Then request `/__mpp/protected` or another paid route. The unpaid request returns `402 Payment Required` with a `WWW-Authenticate: Payment` header. - - - -The Worker now protects matching routes before forwarding them. It supports DNS origins, external URLs, and [service bindings](/workers/runtime-apis/bindings/service-bindings/). - -For all settings, refer to the [`mpp-proxy` README](https://github.com/cloudflare/mpp-proxy). - -### Charge crawlers with Bot Management - -With [Cloudflare Bot Management](/bots/), a paid pattern can target automated traffic. The same content remains free for people: - - - -```jsonc -{ - "vars": { - "PROTECTED_PATTERNS": [ - { - "pattern": "/content/*", - "amount": "0.25", - "description": "Content access for 1 hour", - "bot_score_threshold": 30, - "except_detection_ids": [120623194, 117479730] - } - ] - } -} -``` - - - -Requests with a bot score at or below `bot_score_threshold` reach the paywall. Use `except_detection_ids` to allow specific crawlers by [detection ID](/ai-crawl-control/reference/bots/). +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 @@ -120,7 +37,7 @@ Add `mppx` middleware when you control the Worker application: -3. Add `mppx.charge` before the paid route handler: +3. Add the payment middleware before the paid route handler: @@ -129,22 +46,22 @@ Add `mppx` middleware when you control the Worker application: 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()], - secretKey: env.MPP_SECRET_KEY, + methods: [tempo.charge({ testnet: true })], + secretKey: workerEnv.MPP_SECRET_KEY, }); app.get( "/premium", mppx.charge({ - amount: "0.10", - currency: "0x20c000000000000000000000b9537d11c60e8b50", + amount: "0.01", + currency: "0x20c0000000000000000000000000000000000000", description: "Premium API access", - recipient: "0xYourWalletAddress", + recipient: "", }), - (c) => c.json({ data: "Thanks for paying!" }), + (c) => c.json({ access: "paid" }), ); export default app; @@ -152,11 +69,19 @@ Add `mppx` middleware when you control the Worker application: -4. Request `/premium` without payment. The Worker returns `402 Payment Required` and an MPP Challenge. +4. Deploy the Worker: - + + +5. Request the paid route without a payment: -After payment, the Worker runs the route handler and returns a Receipt. You can also read the decentralized identifier (DID) for the payer. + ```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 @@ -164,15 +89,36 @@ Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/age -1. Install the Agents SDK, `mppx`, MCP SDK, and Zod: +1. Install the required packages in an Agents project: -2. Store `MPP_SECRET_KEY` as a [Worker secret](/workers/configuration/secrets/): +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: -3. Add `Transport.mcpSdk()` and check payment in the tool handler: +4. Check payment before returning the tool result: @@ -182,7 +128,9 @@ Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/age import { Mppx, tempo, Transport } from "mppx/server"; import { z } from "zod"; - export class PaidMCP extends McpAgent { + type PaymentEnv = Env & { MPP_SECRET_KEY: string }; + + export class PaidMCP extends McpAgent { server = new McpServer({ name: "paid-search", version: "1.0.0" }); async init() { @@ -193,15 +141,15 @@ Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/age }); this.server.tool( - "search", - "Search the web", + "premium_search", + "Search premium content", { query: z.string() }, async ({ query }, extra) => { const payment = await mppx.charge({ amount: "0.01", currency: "0x20c0000000000000000000000000000000000000", - description: "Web search query", - recipient: "0xYourWalletAddress", + description: "Premium search", + recipient: "", })(extra); if (payment.status === 402) throw payment.challenge; @@ -219,30 +167,12 @@ Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/age -4. Call the `search` tool without payment. The MCP server returns an MPP Challenge through JSON-RPC. +5. Deploy the Worker: - - -After payment, the tool result includes the MPP Receipt in `_meta`. Free tools do not call `mppx.charge`. - -## Add other billing patterns - -After a one-time Worker flow succeeds, add another billing pattern: + -| Pattern | Server API | Production requirement | -| ---------------------------- | --------------------------------------- | --------------------------------------------------------------------- | -| Usage-based access | `mppx.session()` | An atomic store that persists the payment channel across requests. | -| Recurring access | `mppx.subscription()` | An atomic store for subscription state and a stable subscription key. | -| Native MPP and x402 together | `evm.charge()` with an x402 facilitator | An Ethereum Virtual Machine (EVM) asset, recipient, and facilitator. | -| Zero-dollar payer proof | `mppx.charge({ amount: "0" })` | An atomic store if proofs must be single-use across Worker instances. | + An unpaid `premium_search` call returns an MPP Challenge. A paid retry returns the tool result and an MPP Receipt in `_meta`. -Use `Store.memory()` only for local development. Concurrent Workers need a durable implementation such as `Store.cloudflare()`. - -For complete configurations, refer to the [session intent](https://mpp.dev/intents/session), [subscription guide](https://mpp.dev/guides/subscription-payments), and [MPP with x402 guide](https://mpp.dev/guides/use-mpp-with-x402). - -## Next steps + -- [Pay from the Agents SDK](/agents/tools/payments/mpp/pay-from-agents-sdk/) -- [Monetize an MCP server](https://mpp.dev/guides/monetize-mcp-server) -- [Hono middleware reference](https://mpp.dev/sdk/typescript/middlewares/hono) -- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) +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 index 86e5c64c898..3c653315123 100644 --- a/src/content/docs/agents/tools/payments/mpp/index.mdx +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -5,76 +5,64 @@ sidebar: order: 9 group: hideIndex: false -description: Use Machine Payments Protocol (MPP) with Cloudflare Workers and the Agents SDK to accept and make payments. +description: Accept and make payments using Machine Payments Protocol (MPP) with Cloudflare Workers and the Agents SDK. products: - agents --- -import { CardGrid, LinkCard } from "~/components"; +import { LinkCard, CardGrid } from "~/components"; -[Machine Payments Protocol (MPP)](https://mpp.dev) adds payments to HTTP requests and Model Context Protocol (MCP) tool calls. Use it with Cloudflare Workers to sell access. Use it with the Agents SDK to pay for services. +[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. - - - - - -## Choose a Cloudflare workflow - -Choose a workflow based on where payment happens: +MPP is payment-method agnostic. It supports stablecoins, cards through Stripe, and custom payment methods. A service can offer more than one method. -| Goal | Cloudflare integration | -| -------------------------- | ---------------------------------------------------------------- | -| Protect an existing origin | Deploy `mpp-proxy` as a Worker in front of the origin. | -| Charge for a Worker route | Add `mppx` middleware to a Hono route. | -| Charge for an MCP tool | Add the MPP transport to an `McpAgent` tool handler. | -| Pay an HTTP endpoint | Create a payment-aware client in the Agent lifecycle. | -| Pay for an MCP tool | Wrap the MCP connection created by the Agents SDK. | - -## How payments move through Cloudflare +## How it works 1. An Agent or HTTP client requests a paid resource. -2. The Worker or MCP server returns an MPP Challenge. -3. The client creates a payment Credential. -4. The client retries the same request. -5. The server verifies payment and returns a Receipt. +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. -HTTP services return the Challenge with `402 Payment Required`. MCP tools return the same payment data through JSON-RPC. +## Payment intents -## Add billing beyond one request +MPP defines three payment intents: -Choose an MPP intent based on the billing model: +- **`charge`** — Collect a one-time payment. +- **`session`** — Charge for measured usage. +- **`subscription`** — Sell recurring access. -| Intent | Cloudflare use case | -| ------------------ | -------------------------------------------------------- | -| **`charge`** | Set a fixed price for a Worker route or MCP tool. | -| **`session`** | Meter streamed tokens, bytes, or other changing usage. | -| **`subscription`** | Sell recurring access, plans, memberships, or allowances. | +For more information, refer to [MPP payment intents](https://mpp.dev/intents/). -Sessions and subscriptions keep state across requests. Use a durable, atomic store for production Workers. +## Compatibility with x402 -## Choose a payment method +MPP is backwards-compatible with [x402](/agents/tools/payments/x402/). MPP clients can consume existing x402 services without changes to those services. -MPP separates the payment protocol from the payment method. A Worker can offer one or more compatible methods. The examples use one stablecoin method so that the code remains executable. +## Build on Cloudflare -For other methods, refer to [MPP payment methods](https://mpp.dev/payment-methods). + + + + -## Pay MPP and x402 services +## SDKs -The same `mppx` HTTP client can pay MPP and x402 services. Add an x402-compatible charge method beside the native MPP method. +MPP provides SDKs for TypeScript, Python, Rust, Go, and Ruby. The Cloudflare guides use the TypeScript [`mppx` SDK](https://mpp.dev/sdk/typescript/). -For the shared setup, refer to [use MPP with x402](https://mpp.dev/guides/use-mpp-with-x402). +For current packages and integrations, refer to the [MPP SDK documentation](https://mpp.dev/sdk/). -## Related resources +## Related -- [Cloudflare Agents integration](https://mpp.dev/partner-integrations/cloudflare-agents) -- [MPP protocol documentation](https://mpp.dev) -- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) +- [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 index 9c354b2dd99..c3ccd374451 100644 --- 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 @@ -3,20 +3,20 @@ title: Pay from the Agents SDK pcx_content_type: how-to sidebar: order: 2 -description: Configure a Cloudflare Agent to pay HTTP requests and Model Context Protocol (MCP) tools with Machine Payments Protocol (MPP). +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 with Machine Payments Protocol (MPP) services. An Agent can pay for HTTP requests and Model Context Protocol (MCP) tools. The `mppx` SDK handles the payment retry and returns a Receipt. +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/). Configure a funded account for the selected MPP payment method. +Create a [Cloudflare Agents project](/agents/getting-started/). Fund an account for the payment method that the service accepts. -## Configure Agent payments +## Configure payments @@ -28,7 +28,7 @@ Create a [Cloudflare Agents project](/agents/getting-started/). Configure a fund -3. Create the payment methods once and reuse them for HTTP and MCP: +3. Create the payment method once: @@ -48,12 +48,12 @@ Create a [Cloudflare Agents project](/agents/getting-started/). Configure a fund :::note -The examples use an environment private key. For production Agents, use a scoped access key with spending limits and recipient restrictions. Refer to [managing agent spend](https://mpp.dev/guides/managing-agent-spend). +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 for HTTP requests +## Pay an HTTP service -Create a scoped payment-aware client inside `onStart()`. Setting `polyfill: false` keeps the wrapper local to this Agent. `acceptPaymentPolicy` limits which origins can request automatic payment. +Create a payment-aware client in `onStart()`. Restrict automatic payments to trusted origins: @@ -62,15 +62,17 @@ import { Agent } from "agents"; import { Mppx } from "mppx/client"; import { createPaymentMethods } from "./payments"; -export class BuyerAgent extends Agent { +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: createPaymentMethods(this.env.MPP_PRIVATE_KEY), + acceptPaymentPolicy: { origins: ["https://api.example.com"] }, + methods: this.methods, polyfill: false, }); } @@ -88,35 +90,11 @@ export class BuyerAgent extends Agent { -Call `buyReport()` to test the client. Free endpoints pass through unchanged. Paid endpoints trigger the MPP payment retry. - -To wrap every later `fetch`, omit `polyfill: false`. The scoped `payments.fetch` remains easier to test in an Agent. - -### Require approval before HTTP payment - -Use `onChallenge` to require approval before creating a Credential: +Free endpoints pass through unchanged. Paid endpoints trigger the payment retry and return a `Payment-Receipt` header. - +## Pay an MCP tool -```ts -const payments = Mppx.create({ - methods, - onChallenge: async (challenge, { createCredential }) => { - if (Number(challenge.request.amount) > 0.1) { - throw new Error("Payment requires approval"); - } - - return createCredential(); - }, - polyfill: false, -}); -``` - - - -## Pay for MCP tools - -Connect the Agent with `addMcpServer()`. Then wrap the client stored on that connection. This keeps the Cloudflare MCP connection and adds payment handling. +Connect the Agent with `addMcpServer()`. Wait for the connection before wrapping its client: @@ -125,79 +103,43 @@ import { Agent } from "agents"; import { McpClient } from "mppx/mcp/client"; import { createPaymentMethods } from "./payments"; -export class BuyerAgent extends Agent { +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 { id } = await this.addMcpServer( "premium-search", "https://mcp.example.com/mcp", ); + await this.mcp.waitForConnections(); const client = McpClient.wrap(this.mcp.mcpConnections[id].client, { - methods: createPaymentMethods(this.env.MPP_PRIVATE_KEY), - onPaymentRequired: async (challenge) => { - return Number(challenge.request.amount) <= 0.1; - }, + methods: this.methods, }); - const result = await client.callTool({ name: "premium_search", arguments: { query: "Cloudflare Agents" }, }); - console.log(result.content, result.receipt); + return { content: result.content, receipt: result.receipt }; } } ``` -Call the tool to test the wrapper. `onPaymentRequired` runs before payment. Return `false` to decline the payment. - -You can pass another approval callback to an individual `callTool` request. - -## Pay MPP and x402 endpoints - -Add an Ethereum Virtual Machine (EVM) charge method for x402. Keep it beside the native MPP method: - - - -```ts -import { env } from "cloudflare:workers"; -import { evm } from "mppx/client"; -import { privateKeyToAccount } from "viem/accounts"; -import { createPaymentMethods } from "./payments"; - -const account = privateKeyToAccount(env.MPP_PRIVATE_KEY as `0x${string}`); - -const methods = [ - ...createPaymentMethods(env.MPP_PRIVATE_KEY), - evm.charge({ - account, - currencies: [evm.assets.baseSepolia.USDC], - maxAmount: "1.00", - }), -] as const; -``` - - - -The HTTP client recognizes MPP and x402 Challenges. It retries each request with the matching header. The MCP wrapper only handles the MPP transport. - -## Know which calls are covered - -The following table shows where to add payment handling: +The wrapper retries a paid tool call with an MPP Credential. The result includes the MPP Receipt as `result.receipt`. -| Agent call surface | Add payment handling with | What it covers | -| -------------------------------- | ------------------------- | -------------------------------------------------- | -| HTTP `fetch` | `Mppx.create` | Native MPP and configured x402 HTTP Challenges. | -| Agents SDK MCP connection | `McpClient.wrap` | MPP Challenges returned by MCP tool calls. | -| Private client from another SDK | Its transport adapter | Only calls made through that client. | +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. -Payment-aware fetch does not wrap an existing MCP client. Configure both surfaces when an Agent pays HTTP APIs and MCP tools. +## Pay x402 services -## Next steps +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). -- [Accept payments with MPP](/agents/tools/payments/mpp/accept-payments/) -- [Cloudflare Agents integration](https://mpp.dev/partner-integrations/cloudflare-agents) -- [MCP client API](/agents/model-context-protocol/apis/client-api/) -- [Manage agent spend](https://mpp.dev/guides/managing-agent-spend) +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/). From 114065de9b1328cc730e82c2aa6350d0193911c7 Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Mon, 20 Jul 2026 18:01:54 -0700 Subject: [PATCH 4/9] [Agents] Restore MPP origin proxy guide --- .../docs/agents/tools/payments/index.mdx | 2 +- .../tools/payments/mpp/accept-payments.mdx | 26 ++++- .../docs/agents/tools/payments/mpp/index.mdx | 5 + .../payments/mpp/pay-from-agents-sdk.mdx | 2 +- .../tools/payments/mpp/protect-an-origin.mdx | 97 +++++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 src/content/docs/agents/tools/payments/mpp/protect-an-origin.mdx diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index a7bdbc8117a..a2312130f05 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -50,7 +50,7 @@ MPP supports multiple payment methods beyond blockchains, including cards (via S /> + + + + ## Prerequisites diff --git a/src/content/docs/agents/tools/payments/mpp/index.mdx b/src/content/docs/agents/tools/payments/mpp/index.mdx index 3c653315123..847e10aff81 100644 --- a/src/content/docs/agents/tools/payments/mpp/index.mdx +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -43,6 +43,11 @@ MPP is backwards-compatible with [x402](/agents/tools/payments/x402/). MPP clien ## Build on Cloudflare + + +1. Deploy the `mpp-proxy` template to your Cloudflare account: + + [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/mpp-proxy) + +2. In `wrangler.jsonc`, configure the external origin and protected routes: + + + + ```toml + [vars] + ORIGIN_URL = "https://api.example.com" + PAY_TO = "" + PAYMENT_CURRENCY = "0x20c0000000000000000000000000000000000000" + TEMPO_TESTNET = true + + [[vars.PROTECTED_PATTERNS]] + pattern = "/premium/*" + amount = "0.01" + description = "Access to premium content" + ``` + + + +3. Store the cookie and MPP signing keys as [Worker secrets](/workers/configuration/secrets/): + + + + + +4. Deploy the configured Worker: + + + +5. Request a protected route without payment: + + ```sh + curl -i https:///premium/report + ``` + + The Worker returns `402 Payment Required` with a `WWW-Authenticate: Payment` header. A paid retry returns the origin response, a `Payment-Receipt` header, and an `auth_token` cookie valid for one hour. + + + +## Choose an origin mode + +The proxy supports three origin modes: + +| Origin | Configuration | +| -------------------------- | -------------------------------------------------------------------------------------------- | +| Cloudflare DNS origin | Leave `ORIGIN_URL` unset. | +| External service | Set `ORIGIN_URL` to the service URL. | +| Worker in the same account | Add an `ORIGIN_SERVICE` [service binding](/workers/runtime-apis/bindings/service-bindings/). | + +For all settings, refer to the [`mpp-proxy` README](https://github.com/cloudflare/mpp-proxy#readme). + +## Charge automated traffic + +With [Cloudflare Bot Management](/bots/), a protected pattern can charge likely automated traffic while allowing people and selected crawlers through: + + + +```toml +[[vars.PROTECTED_PATTERNS]] +pattern = "/content/*" +amount = "0.25" +description = "Content access" +bot_score_threshold = 30 +except_detection_ids = [120623194, 117479730] +``` + + + +Requests at or below `bot_score_threshold` receive the payment challenge. Use `except_detection_ids` to allow crawlers by [detection ID](/ai-crawl-control/reference/bots/). + +To pay the protected route from an Agent, refer to [Pay from the Agents SDK](/agents/tools/payments/mpp/pay-from-agents-sdk/). From d22328675b22a51060d01726abcd101a4d37497f Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Tue, 21 Jul 2026 09:15:24 -0700 Subject: [PATCH 5/9] [Agents] Refine MPP guide navigation --- public/__redirects | 6 ++--- .../tools/payments/mpp/accept-payments.mdx | 26 ++++--------------- ...origin.mdx => charge-for-http-content.mdx} | 4 +-- .../docs/agents/tools/payments/mpp/index.mdx | 4 +-- 4 files changed, 12 insertions(+), 28 deletions(-) rename src/content/docs/agents/tools/payments/mpp/{protect-an-origin.mdx => charge-for-http-content.mdx} (95%) diff --git a/public/__redirects b/public/__redirects index db84efb46cf..6e049fbbfb9 100644 --- a/public/__redirects +++ b/public/__redirects @@ -312,9 +312,9 @@ /agents/communication-channels/slack/slack-agent/ /agents/examples/slack-agent/ 301 /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/accept-payments/ 301 -/agents/tools/payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp/accept-payments/ 301 -/agents/agentic-payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp/accept-payments/ 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 /ai-audit/features/detect-ai-crawlers/ /ai-crawl-control/features/analyze-ai-crawlers/ 301 diff --git a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx index 25793d95020..e757fc42f22 100644 --- a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx +++ b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx @@ -9,33 +9,17 @@ products: --- import { - CardGrid, - LinkCard, PackageManagers, Steps, TypeScriptExample, WranglerConfig, } from "~/components"; -Use Cloudflare Workers to accept Machine Payments Protocol (MPP) payments. Protect an origin with a proxy, or add `mppx` to a Worker route or Model Context Protocol (MCP) tool. - - - - - - +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 diff --git a/src/content/docs/agents/tools/payments/mpp/protect-an-origin.mdx b/src/content/docs/agents/tools/payments/mpp/charge-for-http-content.mdx similarity index 95% rename from src/content/docs/agents/tools/payments/mpp/protect-an-origin.mdx rename to src/content/docs/agents/tools/payments/mpp/charge-for-http-content.mdx index f76f1dd04ba..22f0eaea18e 100644 --- a/src/content/docs/agents/tools/payments/mpp/protect-an-origin.mdx +++ b/src/content/docs/agents/tools/payments/mpp/charge-for-http-content.mdx @@ -1,9 +1,9 @@ --- -title: Protect an origin with MPP +title: Charge for HTTP content pcx_content_type: how-to sidebar: order: 1 -description: Deploy an MPP payment-gated Cloudflare Worker in front of an existing website, API, or service. +description: Charge for access to an existing website, API, or service with an MPP payment-gated Cloudflare Worker. products: - agents --- diff --git a/src/content/docs/agents/tools/payments/mpp/index.mdx b/src/content/docs/agents/tools/payments/mpp/index.mdx index 847e10aff81..156980c8a90 100644 --- a/src/content/docs/agents/tools/payments/mpp/index.mdx +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -44,9 +44,9 @@ MPP is backwards-compatible with [x402](/agents/tools/payments/x402/). MPP clien Date: Tue, 21 Jul 2026 11:24:10 -0700 Subject: [PATCH 6/9] [Agents] Restore HTTP content guide placement --- public/__redirects | 6 +- .../docs/agents/tools/payments/index.mdx | 5 + .../payments/mpp-charge-for-http-content.mdx | 110 ++++++++++++++++++ .../tools/payments/mpp/accept-payments.mdx | 2 +- .../payments/mpp/charge-for-http-content.mdx | 97 --------------- .../docs/agents/tools/payments/mpp/index.mdx | 5 - 6 files changed, 119 insertions(+), 106 deletions(-) create mode 100644 src/content/docs/agents/tools/payments/mpp-charge-for-http-content.mdx delete mode 100644 src/content/docs/agents/tools/payments/mpp/charge-for-http-content.mdx diff --git a/public/__redirects b/public/__redirects index 6e049fbbfb9..a169eddad60 100644 --- a/public/__redirects +++ b/public/__redirects @@ -312,9 +312,9 @@ /agents/communication-channels/slack/slack-agent/ /agents/examples/slack-agent/ 301 /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 +/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 /ai-audit/features/detect-ai-crawlers/ /ai-crawl-control/features/analyze-ai-crawlers/ 301 diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index a2312130f05..649b29f58fd 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -48,6 +48,11 @@ MPP supports multiple payment methods beyond blockchains, including cards (via S description="Gate APIs, web pages, and files with a Worker proxy" href="/agents/tools/payments/x402/charge-for-http-content/" /> + + 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. + +## Related + +- [mpp.dev](https://mpp.dev) — Protocol specification +- [Pay Per Crawl](/ai-crawl-control/features/pay-per-crawl/) — Cloudflare-native monetization without custom code diff --git a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx index e757fc42f22..3447a69a672 100644 --- a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx +++ b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx @@ -17,7 +17,7 @@ import { 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/). +- **[`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. 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 deleted file mode 100644 index 22f0eaea18e..00000000000 --- a/src/content/docs/agents/tools/payments/mpp/charge-for-http-content.mdx +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Charge for HTTP content -pcx_content_type: how-to -sidebar: - order: 1 -description: Charge for access to an existing website, API, or service with an MPP payment-gated Cloudflare Worker. -products: - - agents ---- - -import { PackageManagers, Steps, WranglerConfig } from "~/components"; - -Use [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) to add Machine Payments Protocol (MPP) payments without changing origin code. The Worker challenges protected routes, verifies payments, and forwards authorized requests. - -## Prerequisites - -Create a [Cloudflare account](/fundamentals/account/create-account/). Choose an origin and a payment recipient. - -## Deploy the proxy - - - -1. Deploy the `mpp-proxy` template to your Cloudflare account: - - [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/mpp-proxy) - -2. In `wrangler.jsonc`, configure the external origin and protected routes: - - - - ```toml - [vars] - ORIGIN_URL = "https://api.example.com" - PAY_TO = "" - PAYMENT_CURRENCY = "0x20c0000000000000000000000000000000000000" - TEMPO_TESTNET = true - - [[vars.PROTECTED_PATTERNS]] - pattern = "/premium/*" - amount = "0.01" - description = "Access to premium content" - ``` - - - -3. Store the cookie and MPP signing keys as [Worker secrets](/workers/configuration/secrets/): - - - - - -4. Deploy the configured Worker: - - - -5. Request a protected route without payment: - - ```sh - curl -i https:///premium/report - ``` - - The Worker returns `402 Payment Required` with a `WWW-Authenticate: Payment` header. A paid retry returns the origin response, a `Payment-Receipt` header, and an `auth_token` cookie valid for one hour. - - - -## Choose an origin mode - -The proxy supports three origin modes: - -| Origin | Configuration | -| -------------------------- | -------------------------------------------------------------------------------------------- | -| Cloudflare DNS origin | Leave `ORIGIN_URL` unset. | -| External service | Set `ORIGIN_URL` to the service URL. | -| Worker in the same account | Add an `ORIGIN_SERVICE` [service binding](/workers/runtime-apis/bindings/service-bindings/). | - -For all settings, refer to the [`mpp-proxy` README](https://github.com/cloudflare/mpp-proxy#readme). - -## Charge automated traffic - -With [Cloudflare Bot Management](/bots/), a protected pattern can charge likely automated traffic while allowing people and selected crawlers through: - - - -```toml -[[vars.PROTECTED_PATTERNS]] -pattern = "/content/*" -amount = "0.25" -description = "Content access" -bot_score_threshold = 30 -except_detection_ids = [120623194, 117479730] -``` - - - -Requests at or below `bot_score_threshold` receive the payment challenge. Use `except_detection_ids` to allow crawlers by [detection ID](/ai-crawl-control/reference/bots/). - -To pay the protected route from an Agent, refer to [Pay from the Agents SDK](/agents/tools/payments/mpp/pay-from-agents-sdk/). diff --git a/src/content/docs/agents/tools/payments/mpp/index.mdx b/src/content/docs/agents/tools/payments/mpp/index.mdx index 156980c8a90..3c653315123 100644 --- a/src/content/docs/agents/tools/payments/mpp/index.mdx +++ b/src/content/docs/agents/tools/payments/mpp/index.mdx @@ -43,11 +43,6 @@ MPP is backwards-compatible with [x402](/agents/tools/payments/x402/). MPP clien ## Build on Cloudflare - Date: Tue, 21 Jul 2026 12:13:37 -0700 Subject: [PATCH 7/9] [Agents] Link to the MPP Worker guide --- .../payments/mpp-charge-for-http-content.mdx | 26 +------------------ 1 file changed, 1 insertion(+), 25 deletions(-) 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 From 6c02ef9c822d5d986ef8d55b02bab7c360d9b48c Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:37:21 -0700 Subject: [PATCH 8/9] [Agents] Address MPP guide feedback --- src/content/docs/agents/tools/payments/index.mdx | 4 ++-- .../tools/payments/mpp/accept-payments.mdx | 2 +- .../tools/payments/mpp/pay-from-agents-sdk.mdx | 16 ++++++++++++++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index 649b29f58fd..6428321de85 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -59,8 +59,8 @@ MPP supports multiple payment methods beyond blockchains, including cards (via S href="/agents/tools/payments/mpp/accept-payments/" /> diff --git a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx index 3447a69a672..9f6518f5f4d 100644 --- a/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx +++ b/src/content/docs/agents/tools/payments/mpp/accept-payments.mdx @@ -17,7 +17,7 @@ import { 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/). +- [`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. 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 index e15753230d3..cfb9d1fe1a0 100644 --- 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 @@ -113,13 +113,23 @@ export class BuyerAgent extends Agent { } async paidSearch() { - const { id } = await this.addMcpServer( + 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 client = McpClient.wrap(this.mcp.mcpConnections[id].client, { + 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({ @@ -134,6 +144,8 @@ export class BuyerAgent extends Agent { +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. From 0566dd2b8e1e4c0764e386dcc1d452b2b2326e31 Mon Sep 17 00:00:00 2001 From: Parv Ahuja <17094219+parvahuja@users.noreply.github.com> Date: Thu, 23 Jul 2026 12:15:26 -0700 Subject: [PATCH 9/9] [Agents] Clarify payment flow reuse --- src/content/docs/agents/tools/payments/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/docs/agents/tools/payments/index.mdx b/src/content/docs/agents/tools/payments/index.mdx index 6428321de85..feb1f2c4e2d 100644 --- a/src/content/docs/agents/tools/payments/index.mdx +++ b/src/content/docs/agents/tools/payments/index.mdx @@ -21,7 +21,7 @@ Cloudflare's [Agents SDK](/agents/) supports agentic payments through two protoc 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 pre-created service account or pre-shared API key is required. Agents handle the payment exchange. They can reuse sessions or subscriptions after the first payment. +No pre-created service account or pre-shared API key is required. Agents handle the payment exchange programmatically. ## x402 and Machine Payments Protocol