跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

通过 Agents SDK 付款

最后更新 查看 MarkdownAgent 设置

使用 Cloudflare Agents SDK 向 MPP 服务付款。mppx SDK 负责处理 HTTP 请求和模型上下文协议(MCP)工具调用的支付重试。

前提条件

创建 Cloudflare Agents 项目。为服务接受的支付方式对应的账户充值。

配置支付

  1. 安装 Agents SDK、mppx 和 viem:

    npm i agents mppx viem
  2. 将支付私钥存储为 Worker 密钥:

    npx wrangler secret put MPP_PRIVATE_KEY
  3. 创建一次支付方式:

    src/payments.jsjs
    import { tempo } from "mppx/client";
    import { privateKeyToAccount } from "viem/accounts";
    
    export function createPaymentMethods(privateKey) {
    	const account = privateKeyToAccount(privateKey);
    
    	return [tempo.charge({ account })];
    }
    src/payments.tsts
    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;
    }

向 HTTP 服务付款

在 onStart() 中创建支持支付的客户端。将自动付款限制为受信任的源站:

src/agent.jsjs
import { Agent } from "agents";
import { Mppx } from "mppx/client";
import { createPaymentMethods } from "./payments";

export class BuyerAgent extends Agent {
	methods;
	payments;

	async onStart() {
		this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
		this.payments = Mppx.create({
			acceptPaymentPolicy: { origins: ["https://api.example.com"] },
			methods: this.methods,
			polyfill: false,
		});
	}

	async buyReport() {
		const response = await this.payments.fetch(
			"https://api.example.com/reports/latest",
		);

		if (!response.ok) throw new Error(`Request failed: ${response.status}`);
		return response.json();
	}
}
src/agent.tsts
import { Agent } from "agents";
import { Mppx } from "mppx/client";
import { createPaymentMethods } from "./payments";

type PaymentEnv = Env & { MPP_PRIVATE_KEY: string };

export class BuyerAgent extends Agent<PaymentEnv> {
	methods!: ReturnType<typeof createPaymentMethods>;
	payments!: ReturnType<typeof Mppx.create>;

	async onStart() {
		this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
		this.payments = Mppx.create({
			acceptPaymentPolicy: { origins: ["https://api.example.com"] },
			methods: this.methods,
			polyfill: false,
		});
	}

	async buyReport() {
		const response = await this.payments.fetch(
			"https://api.example.com/reports/latest",
		);

		if (!response.ok) throw new Error(`Request failed: ${response.status}`);
		return response.json();
	}
}

免费端点的请求会直接通过。付费端点会触发支付重试,并返回 Payment-Receipt 标头。

向 MCP 工具付款

使用 addMcpServer() 连接 Agent。等待连接完成后再包装其客户端:

src/agent.jsjs
import { Agent } from "agents";
import { McpClient } from "mppx/mcp/client";
import { createPaymentMethods } from "./payments";

export class BuyerAgent extends Agent {
	methods;

	async onStart() {
		this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
	}

	async paidSearch() {
		const connection = await this.addMcpServer(
			"premium-search",
			"https://mcp.example.com/mcp",
		);
		if (connection.state === "authenticating") {
			return { authUrl: connection.authUrl };
		}

		await this.mcp.waitForConnections();

		const server = this.getMcpServers().servers[connection.id];
		const mcpConnection = this.mcp.mcpConnections[connection.id];
		if (server?.state !== "ready" || !mcpConnection) {
			throw new Error("MCP server is not ready.");
		}

		const client = McpClient.wrap(mcpConnection.client, {
			methods: this.methods,
		});
		const result = await client.callTool({
			name: "premium_search",
			arguments: { query: "Cloudflare Agents" },
		});

		return { content: result.content, receipt: result.receipt };
	}
}
src/agent.tsts
import { Agent } from "agents";
import { McpClient } from "mppx/mcp/client";
import { createPaymentMethods } from "./payments";

type PaymentEnv = Env & { MPP_PRIVATE_KEY: string };

export class BuyerAgent extends Agent<PaymentEnv> {
	methods!: ReturnType<typeof createPaymentMethods>;

	async onStart() {
		this.methods = createPaymentMethods(this.env.MPP_PRIVATE_KEY);
	}

	async paidSearch() {
		const connection = await this.addMcpServer(
			"premium-search",
			"https://mcp.example.com/mcp",
		);
		if (connection.state === "authenticating") {
			return { authUrl: connection.authUrl };
		}

		await this.mcp.waitForConnections();

		const server = this.getMcpServers().servers[connection.id];
		const mcpConnection = this.mcp.mcpConnections[connection.id];
		if (server?.state !== "ready" || !mcpConnection) {
			throw new Error("MCP server is not ready.");
		}

		const client = McpClient.wrap(mcpConnection.client, {
			methods: this.methods,
		});
		const result = await client.callTool({
			name: "premium_search",
			arguments: { query: "Cloudflare Agents" },
		});

		return { content: result.content, receipt: result.receipt };
	}
}

如果 paidSearch() 返回 authUrl,将用户引导至该 URL,并在授权后重试。

包装器携带 MPP 凭证重试付费工具调用。结果通过 result.receipt 包含 MPP 收据。

默认情况下,两个客户端都会自动支付兼容的质询。付款需要审批时,HTTP 使用 onChallenge,MCP 使用 onPaymentRequired。质询金额使用整数形式的基础单位,而非用于显示的小数值。

向 x402 服务付款

mppx HTTP 客户端也能识别 x402 质询。在 MPP 支付方式之外配置兼容 x402 的 EVM 支付方式即可,无需修改服务。有关配置,请参阅将 MPP 与 x402 配合使用 ↗。

要接受付款,请参阅使用 MPP 收款。有关 MCP 连接选项,请参阅 MCP 客户端 API。

这篇文档对您有帮助吗?