Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/__redirects
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@
/agents/tools/browser/browse-the-web/ /agents/tools/browser/ 301
/agents/tools/sandbox/codemode/ /agents/tools/codemode/ 301
/agents/tools/payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp-charge-for-http-content/ 301
/agents/tools/payments/mpp/protect-an-origin/ /agents/tools/payments/mpp-charge-for-http-content/ 301
/agents/agentic-payments/mpp/charge-for-http-content/ /agents/tools/payments/mpp-charge-for-http-content/ 301

# ai-audit
Expand Down
28 changes: 19 additions & 9 deletions src/content/docs/agents/tools/payments/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
---
Expand All @@ -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.
Comment thread
parvahuja marked this conversation as resolved.
3. The client fulfills the payment and retries the request with a payment credential.
4. The server verifies the payment (optionally through a facilitator service) and returns the resource along with a receipt.

No accounts, sessions, or pre-shared API keys are required. Agents handle the entire exchange programmatically.
No pre-created service account or pre-shared API key is required. Agents handle the payment exchange programmatically.

## x402 and Machine Payments Protocol

Expand All @@ -31,16 +31,16 @@ No accounts, sessions, or pre-shared API keys are required. Agents handle the en

The Agents SDK provides first-class x402 integration:

- **Server-side**: `withX402` and `paidTool` for MCP servers, plus `x402-hono` middleware for HTTP Workers.
- **Client-side**: `withX402Client` wraps MCP client connections with automatic 402 handling and optional human-in-the-loop confirmation.
- **Server-side**: `withX402` and `paidTool` for Model Context Protocol (MCP) servers, plus `x402-hono` middleware for HTTP Workers.
- **Client-side**: `withX402Client` wraps MCP connections with automatic `402` handling and optional human approval.

### Machine Payments Protocol

[Machine Payments Protocol (MPP)](https://mpp.dev) is a protocol co-authored by Tempo Labs and Stripe. It extends the HTTP `402` pattern with a formal `WWW-Authenticate: Payment` / `Authorization: Payment` header scheme and is on the IETF standards track.
[Machine Payments Protocol (MPP)](https://mpp.dev) is an open payment protocol. It adds the `WWW-Authenticate: Payment` and `Authorization: Payment` headers to HTTP `402` responses.

MPP supports multiple payment methods beyond blockchain — including cards (via Stripe), Bitcoin Lightning, and stablecoins — and introduces **sessions** for streaming and pay-as-you-go use cases with sub-millisecond latency and sub-cent costs. MPP is backwards-compatible with x402: MPP clients can consume existing x402 services without modification.
MPP supports multiple payment methods beyond blockchains, including cards (via Stripe) and stablecoins. The `mppx` SDK supports one-time, usage-based, and recurring payments. MPP is also backwards-compatible with x402: MPP clients can consume existing x402 services without modification.

## Charge for resources
## Build with agentic payments

<CardGrid>
<LinkCard
Expand All @@ -50,9 +50,19 @@ MPP supports multiple payment methods beyond blockchain — including cards (via
/>
<LinkCard
title="HTTP content (MPP)"
description="Gate APIs, web pages, and files with a Worker proxy"
description="Gate APIs, web pages, and files with the mpp-proxy Worker"
href="/agents/tools/payments/mpp-charge-for-http-content/"
/>
<LinkCard
title="Accept payments (MPP)"
description="Accept MPP from an origin, Worker route, or MCP tool"
href="/agents/tools/payments/mpp/accept-payments/"
/>
<LinkCard
title="Pay from the Agents SDK"
description="Give an Agent MPP-aware HTTP fetch and MCP clients"
href="/agents/tools/payments/mpp/pay-from-agents-sdk/"
/>
</CardGrid>

## Related
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
78 changes: 0 additions & 78 deletions src/content/docs/agents/tools/payments/mpp.mdx

This file was deleted.

182 changes: 182 additions & 0 deletions src/content/docs/agents/tools/payments/mpp/accept-payments.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
---
title: Accept payments with MPP
pcx_content_type: how-to
sidebar:
order: 2
description: Accept Machine Payments Protocol (MPP) payments from an origin, Cloudflare Worker route, or Model Context Protocol (MCP) tool.
products:
- agents
---

import {
PackageManagers,
Steps,
TypeScriptExample,
WranglerConfig,
} from "~/components";

Use Cloudflare Workers to accept Machine Payments Protocol (MPP) payments. Choose an integration based on the service you want to protect:

- [`mpp-proxy`](https://github.com/cloudflare/mpp-proxy) — Charge for HTTP content without changing your origin code. Refer to [Charge for HTTP content](/agents/tools/payments/mpp-charge-for-http-content/).
- **Worker route** — Add `mppx` payment middleware to a Worker application.
- **MCP tool** — Require payment before an MCP tool returns its result.

## Prerequisites

Create a [Cloudflare account](/fundamentals/account/create-account/). You also need a payment recipient and an MPP secret key.

The examples use a stablecoin payment method on testnet. For other methods, refer to [MPP payment methods](https://mpp.dev/payment-methods/).

## Charge for a Worker route

Add `mppx` middleware when you control the Worker application:

<Steps>

1. Install Hono and `mppx` in the Worker project:

<PackageManagers pkg="hono mppx" />

2. Store the MPP signing key as a [Worker secret](/workers/configuration/secrets/):

<PackageManagers type="exec" pkg="wrangler" args="secret put MPP_SECRET_KEY" />

3. Add the payment middleware before the paid route handler:

<TypeScriptExample filename="src/index.ts">

```ts
import { env } from "cloudflare:workers";
import { Hono } from "hono";
import { Mppx, tempo } from "mppx/hono";

const workerEnv = env as Env & { MPP_SECRET_KEY: string };
const app = new Hono();
const mppx = Mppx.create({
methods: [tempo.charge({ testnet: true })],
secretKey: workerEnv.MPP_SECRET_KEY,
});

app.get(
"/premium",
mppx.charge({
amount: "0.01",
currency: "0x20c0000000000000000000000000000000000000",
description: "Premium API access",
recipient: "<YOUR_WALLET_ADDRESS>",
}),
(c) => c.json({ access: "paid" }),
);

export default app;
```

</TypeScriptExample>

4. Deploy the Worker:

<PackageManagers type="exec" pkg="wrangler" args="deploy" />

5. Request the paid route without a payment:

```sh
curl -i https://<YOUR_WORKER>.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.

</Steps>

## Charge for an MCP tool

Add the MPP transport to an [`McpAgent`](/agents/model-context-protocol/apis/agent-api/):

<Steps>

1. Install the required packages in an Agents project:

<PackageManagers pkg="agents mppx @modelcontextprotocol/sdk zod" />

2. Bind the `McpAgent` Durable Object in the Wrangler configuration:

<WranglerConfig>

```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"]
```

</WranglerConfig>

3. Store `MPP_SECRET_KEY` as a Worker secret:

<PackageManagers type="exec" pkg="wrangler" args="secret put MPP_SECRET_KEY" />

4. Check payment before returning the tool result:

<TypeScriptExample filename="src/index.ts">

```ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { McpAgent } from "agents/mcp";
import { Mppx, tempo, Transport } from "mppx/server";
import { z } from "zod";

type PaymentEnv = Env & { MPP_SECRET_KEY: string };

export class PaidMCP extends McpAgent<PaymentEnv> {
server = new McpServer({ name: "paid-search", version: "1.0.0" });

async init() {
const mppx = Mppx.create({
methods: [tempo.charge({ testnet: true })],
secretKey: this.env.MPP_SECRET_KEY,
transport: Transport.mcpSdk(),
});

this.server.tool(
"premium_search",
"Search premium content",
{ query: z.string() },
async ({ query }, extra) => {
const payment = await mppx.charge({
amount: "0.01",
currency: "0x20c0000000000000000000000000000000000000",
description: "Premium search",
recipient: "<YOUR_WALLET_ADDRESS>",
})(extra);

if (payment.status === 402) throw payment.challenge;

return payment.withReceipt({
content: [{ type: "text", text: `Results for: ${query}` }],
});
},
);
}
}

export default PaidMCP.serve("/mcp");
```

</TypeScriptExample>

5. Deploy the Worker:

<PackageManagers type="exec" pkg="wrangler" args="deploy" />

An unpaid `premium_search` call returns an MPP Challenge. A paid retry returns the tool result and an MPP Receipt in `_meta`.

</Steps>

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