← Создание агентов на Cloudflare / agents / tools / payments / mpp
Принимайте платежи с помощью MPP
Используйте Cloudflare Workers для приёма платежей по протоколу Machine Payments Protocol (MPP). Выберите интеграцию в зависимости от сервиса, который нужно защитить:
mpp-proxy↗ : Взимайте плату за HTTP-контент без изменения кода источника. См. Плата за HTTP-контент.- маршрут Worker : Добавьте
mppxплатёжный middleware в приложение Worker. - MCP-инструмент : требуйте оплату до того, как инструмент MCP вернёт результат.
Предварительные требования
Создайте Аккаунт Cloudflare. Вам также понадобится получатель платежа и секретный ключ MPP.
Примеры используют способ оплаты в стейблкоинах в testnet. Для других способов см. Способы оплаты MPP ↗.
Плата за Worker route
Добавить mppx middleware, если вы контролируете приложение Worker:
-
Установите Hono и
mppxв проекте Worker:npm i hono mppx -
Сохраните подписывающий ключ MPP как Секрет Worker:
npx wrangler secret put MPP_SECRET_KEY -
Добавьте платёжный middleware перед обработчиком платного маршрута:
src/index.jsimport { env } from "cloudflare:workers"; import { Hono } from "hono"; import { Mppx, tempo } from "mppx/hono"; const workerEnv = env; 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;src/index.tsimport { 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; -
Разверните Worker:
npx wrangler deploy -
Запросите платный маршрут без оплаты:
curl -i https://<YOUR_WORKER>.workers.dev/premiumWorker возвращает
402 Payment RequiredиWWW-Authenticate: Paymentзаголовок. Платный повтор доходит до обработчика и возвращаетPayment-Receiptзаголовок.
Плата за инструмент MCP
Добавьте транспорт MPP в McpAgent:
-
Установите необходимые пакеты в проекте Agents:
npm i agents mppx @modelcontextprotocol/sdk zod -
Привяжите
McpAgentDurable Object в конфигурации Wrangler:{ "$schema": "./node_modules/wrangler/config-schema.json", "name": "mpp-server", "main": "src/index.ts", // Set this to today's date "compatibility_date": "2026-08-28", "compatibility_flags": [ "nodejs_compat" ], "durable_objects": { "bindings": [ { "name": "MCP_OBJECT", "class_name": "PaidMCP" } ] }, "migrations": [ { "tag": "v1", "new_sqlite_classes": [ "PaidMCP" ] } ] }name = "mpp-server" main = "src/index.ts" # Set this to today's date compatibility_date = "2026-08-28" compatibility_flags = ["nodejs_compat"] [[durable_objects.bindings]] name = "MCP_OBJECT" class_name = "PaidMCP" [[migrations]] tag = "v1" new_sqlite_classes = ["PaidMCP"] -
Сохраните
MPP_SECRET_KEYкак секрет Worker:npx wrangler secret put MPP_SECRET_KEY -
Перед возвратом результата инструмента проверьте оплату:
src/index.jsimport { 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( "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");src/index.tsimport { 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"); -
Разверните Worker:
npx wrangler deployНеоплаченный
premium_searchвызов возвращает MPP Challenge. Оплаченная повторная попытка возвращает результат инструмента и MPP Receipt в_meta.
Чтобы протестировать оба сценария оплаты из Cloudflare Agent, см. Оплата из Agents SDK. Для схем биллинга в production см. Платёжные намерения MPP ↗.