mcpField
M
mpp

mpp

github.com/tenequm开发4070 次安装5 天前更新
代码仓库

关于 mpp

用于实现 Machine Payments Protocol 的技能,该协议为机器间请求规范 HTTP 402 支付。内容涵盖支付客户端与服务端、多种支付方式、会话及 MCP 传输。

主要功能

  1. 01HTTP 402 挑战、凭证与收据流程
  2. 02多种支付方式与意图
  3. 03TypeScript、Python 和 Rust SDK 指南
  4. 04按使用量付费的支付会话
  5. 05支持支付感知型 MCP 客户端与服务端
  6. 06用于请求、账户和服务发现的 CLI

适用场景

  1. 01对 API 请求或内容访问收费
  2. 02为 LLM 流式输出或高频 API 调用计费
  3. 03要求 MCP 工具调用先行支付
  4. 04为现有 API 添加支付门控

MCP 相关

通过 MCP 客户端和服务端封装器支持需付费的 MCP 工具调用。MCP-over-HTTP 支付挑战可在支付感知型请求流程中处理。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tenequm/skills --skill mpp

安装后在 Claude Code 中输入/mpp确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
LICENSE.txt
references/
cli.md
custom-methods.md
discovery-and-proxy.md
lightning-method.md
production-gotchas.md
protocol-spec.md
python-sdk.md
rust-sdk.md
sessions.md
stripe-method.md
subscriptions.md
tempo-method.md
transports.md
typescript-sdk.md

详细介绍

MPP - 机器支付协议

MPP 是一种开放协议(由 Tempo 和 Stripe 联合编写),用于标准化机器间支付所用的 HTTP 402 Payment Required。客户端在同一个 HTTP 请求中完成支付,无需账户、API 密钥或结账流程。

核心协议规范已作为支付 HTTP 身份验证方案提交给 IETF。

本技能中的代码使用占位符令牌名称(<USDC_TEMPO_MAINNET>、<PATHUSD_TESTNET>);真实地址见 Tempo 文档和 references/tempo-method.md。

核心架构

每笔 MPP 支付都由三个基本要素构成:

  1. Challenge - 服务端发出的支付要求(位于 WWW-Authenticate: Payment 标头中)
  2. Credential - 客户端提交的支付凭证(位于 Authorization: Payment 标头中)
  3. Receipt - 服务端对支付成功的确认(位于 Payment-Receipt 标头中)

支付方式与意图

MPP 不依赖特定支付方式。每种方式都定义自己的结算通道:

方式通道SDK 包状态
TempoTempo 链上的 TIP-20 稳定币mppx(内置)生产就绪
Stripe卡/钱包(SPT)+ 链上加密货币存款mppx(内置)生产就绪
EVMEIP-3009 稳定币授权(兼容 x402-exact)mppx(内置)生产就绪
Lightning通过 Lightning Network 支付的比特币@buildonspark/lightning-mpp-sdk生产就绪
StellarStellar 上的 SEP-41 代币,支持 charge + channel@stellar/mpp生产就绪(channel 线路规范仍在起草中,可能变更)
SolanaSolana 原生 charge + session(SOL、SPL、Token-2022)@solana/mpp生产就绪
MonadMonad charge(ERC-3009、结算模式)@monad-crypto/mpp生产就绪
NEAR Intents通过 1Click 存款地址进行跨链 charge@defuse-protocol/nearintents-mpp-sdk生产就绪(不具备无信任性 - 通过结算后端进行路由,标记为 methodDetails.settlementBackend: "near-intents",以便按方式制定风险策略)
RedotPayRedotPay 余额(rdt)或稳定币凭证,仅支持 charge@redotpay/mpp生产就绪
Card加密网络令牌(Visa)mpp-card生产就绪
自定义任意通道Method.from() + Method.toClient/toServer可扩展

各支付方式的详细说明:references/tempo-method.md、references/stripe-method.md、references/lightning-method.md、references/custom-methods.md。

意图模式最适用场景
charge每个请求进行一次性支付API 调用、内容访问、固定价格端点
session通过支付通道按使用量付费大模型流式传输、计量计费、高频 API
subscription通过授权密钥定期访问(Tempo)- 参见 references/subscriptions.md访问权限与按请求计费分离的套餐/层级

快速开始:服务端(TypeScript)

import { Mppx, tempo } from 'mppx/server'

const mppx = Mppx.create({
  methods: [tempo({
    currency: '<PATHUSD_TESTNET>', // pathUSD testnet
    recipient: '0xYourAddress',
  })],
})

export async function handler(request: Request) {
  const result = await mppx.charge({ amount: '0.01' })(request)
  if (result.status === 402) return result.challenge
  return result.withReceipt(Response.json({ data: '...' }))
}

安装:npm install mppx viem(mppx 0.8.15 要求 viem >= 2.54.0)。

使用 npx mppx validate http://localhost:3000 对完成的服务端进行端到端验证。

快速入门:客户端(TypeScript)

import { privateKeyToAccount } from 'viem/accounts'
import { Mppx, tempo } from 'mppx/client'

// Polyfills globalThis.fetch to handle 402 automatically
Mppx.create({
  methods: [tempo({ account: privateKeyToAccount('0x...') })],
})

const res = await fetch('https://api.example.com/paid')
// Payment happens transparently when server returns 402

在浏览器中,mppx 0.6.0 更改了默认行为:polyfilled fetch 只会向同源端点发送 Accept-Payment,因此跨域付费 API 需要设置 acceptPaymentPolicy('always' / { origins: [...] })。客户端 fetch 会针对递增式挑战重试,最多重试 maxPaymentRetries 次(默认为 3)。有关非全局替代方案(Fetch.from/polyfill/restore、Mppx.restore()),请参阅 references/typescript-sdk.md。

快速入门:服务端(Python)

from fastapi import FastAPI
from mpp import Credential, Receipt
from mpp.server import Mpp
from mpp.methods.tempo import tempo, ChargeIntent

app = FastAPI()
server = Mpp.create(method=tempo(
    currency="<PATHUSD_TESTNET>",
    recipient="0xYourAddress", intents={"charge": ChargeIntent()},
))

@app.get("/resource")
@server.pay(amount="0.50")
async def get_resource(request, credential: Credential, receipt: Receipt):
    return {"data": "paid content", "payer": credential.source}

安装:pip install "pympp[tempo]"。完整用法请参阅 references/python-sdk.md。

快速入门:服务端(Rust)

安装:cargo add mpp --features tempo,server。完整用法请参阅 references/rust-sdk.md。

框架中间件(TypeScript)

每个框架都有自己的导入路径(mppx/nextjs、mppx/hono、mppx/express、mppx/elysia):

// Next.js
import { Mppx, tempo } from 'mppx/nextjs'
const mppx = Mppx.create({ methods: [tempo({ currency: '<PATHUSD_TESTNET>', recipient: '0x...' })] })
export const GET = mppx.charge({ amount: '0.1' })(() => Response.json({ data: '...' }))

// Hono
import { Mppx, tempo } from 'mppx/hono'
app.get('/resource', mppx.charge({ amount: '0.1' }), (c) => c.json({ data: '...' }))

Express 和 Elysia 示例请参阅 references/typescript-sdk.md。

会话:按需付费流式传输

会话只需打开一次支付通道,之后每个请求都使用链下凭证,不必为每个请求发起区块链交易。延迟低于 100 ms,每次请求的费用几乎为零。

会话 v2(自 mppx 0.7.0 起为默认版本): tempo.session() 是 TIP-1034 预编译通道流程;较早的托管合约实现为会话 v1,仍可通过已弃用的 tempo.sessionLegacy 使用。期望使用 v2 的客户端会拒绝 v1 会话,并回退到 charge 流程,因此客户端和服务端应使用匹配的流程。客户端有两种 API:tempo.session({ account, maxDeposit }) 会通过 Mppx.create() 注册该方法(通过 fetch 透明处理 402),而 tempo.session.manager({ account, maxDeposit }) 会返回一个托管客户端,以便直接控制生命周期(.sse()、.close())。

// Server - session endpoint with automatic settlement
const mppx = Mppx.create({
  methods: [tempo.session({
    currency: '<PATHUSD_TESTNET>', recipient: '0x...',
    store: Store.redis(redis),
    settlementSchedule: { amount: '1.00', intervalMs: 300_000 },
    bootstrap: true, // let returning clients recover their channel on this route
  })],
})
const result = await mppx.session({ amount: '0.001', unitType: 'token' })(request)
if (result.status === 402) return result.challenge
return result.withReceipt(Response.json({ data: '...' }))
// Server - SSE streaming with per-word billing
export const GET = mppx.session({ amount: '0.001', unitType: 'word' })(
  async () => async function* (stream) {
    for (const word of ['hello', 'world']) {
      await stream.charge()
      yield word
    }
  }
)

// Client - session with auto-managed channel
Mppx.create({ methods: [tempo({ account, maxDeposit: '1' })] })
const res = await fetch('http://localhost:3000/api/resource')
// 1st request: opens channel on-chain; 2nd+: off-chain vouchers

会话还可以通过 Ws.serve() 使用 WebSocket 进行流式传输。有关完整生命周期、结算、存储、SSE 和 WebSocket 用法,以及通道恢复,请参阅 references/sessions.md。

多方法支持

在同一个端点上接受 Tempo 稳定币、Stripe 卡和 Lightning Bitcoin:

const mppx = Mppx.create({
  methods: [
    tempo({ currency: '<PATHUSD_TESTNET>', recipient: '0x...' }),
    stripe.charge({ client: new Stripe(key), networkId: 'profile_...', paymentMethodTypes: ['card'] }),
    spark.charge({ mnemonic: process.env.MNEMONIC! }),
  ],
})

使用 Mppx.compose() 在单个 402 响应中提供多种方法,并按路由定价。在挑战处理处和验证处理处应用相同的分支,否则 402 公布的选项会少于服务端接受的选项。请参阅 references/typescript-sdk.md。

支付链接(HTML)

在支付方法配置中设置 html: true,用户通过浏览器访问 402 端点时便会显示适合浏览器的支付页面,并支持主题设置、多方法组合标签页和 Solana 钱包。服务工作线程会处理凭证提交,随后页面重新加载并显示已付款的响应。

可通过 mppx/html 导出项(Config、Text、Theme)进行自定义,并使用 Html.init(methodName) 构建自定义方法的支付链接。

零金额身份验证(证明凭证)

无需付款即可验证 Agent 身份。客户端会针对挑战 ID 签署 EIP-712 证明,而不是创建交易,因此无需消耗 Gas,也不会转移资金。

// Server - zero-dollar charge, with a store for replay protection
const mppx = Mppx.create({
  methods: [tempo.charge({ currency: '<PATHUSD_TESTNET>', recipient: '0x...', store })],
})
const result = await mppx.charge({ amount: '0' })(request)

自 mppx 0.8.0 起,这些证明会绑定到付款方钱包:EIP-712 Proof 类型化数据(通过 tempo.Proof 暴露)在域版本 3 中包含 account 字段,因此针对一个账户签署的证明无法再通过另一个账户的验证。

使用场景:身份验证、长时间运行的作业轮询、付费解锁后免费持续访问、多步骤 Agent 工作流。请参阅 mpp.dev/advanced/identity。

支付代理

在现有 API 前设置 MPP 支付门槛:

// import { openai, Proxy } from 'mppx/proxy' - a service inside Proxy.create({ services: [...] })
openai({
  apiKey: process.env.OPENAI_API_KEY,
  routes: {
    'POST /v1/chat/completions': mppx.charge({ amount: '0.05' }),
    'GET /v1/models': true, // literal `true` marks a free route
  },
})

内置预设包括 openai()、anthropic()、stripe(),以及适用于任意上游的 custom()。有关 Proxy.create()、其提供的发现端点,以及适用于非代理服务端的 discovery() 辅助函数,请参阅 references/discovery-and-proxy.md。

MCP 传输

MCP 工具调用可能需要付款,使用 JSON-RPC 错误代码 -32042(服务端也可能发出 -32043):

// Server - import tempo from mppx/server, NOT mppx/tempo
import { McpServer } from 'mppx/mcp/server'
import { tempo } from 'mppx/server'
const server = McpServer.wrap(baseServer, { methods: [tempo.charge({ /* ... */ })], secretKey })

// Client - payment-aware MCP client (import tempo from mppx/client)
import { McpClient } from 'mppx/mcp/client'
import { tempo } from 'mppx/client'
const mcp = McpClient.wrap(client, { methods: [tempo({ account })] })
const result = await mcp.callTool({ name: 'premium_tool', arguments: {} })

MCP-over-HTTP 挑战会在同一个支持付款的 fetch 中完成结算,且双方的传输方式均可通过 Transport.from/http/mcp/mcpSdk 插拔。参见 references/transports.md。

Privy 服务端钱包

来自 @privy-io/node/viem 的 createViemAccount(需要 @privy-io/node >= 0.20.0)会返回一个由 Privy 服务端钱包支持的 viem Account,因此可像本地账户一样,在任何需要传入账户的地方使用 tempo({ account })。

服务端签名适用于应用所有的服务端钱包;用户所有的嵌入式钱包则需要授权密钥或密钥法定人数。完整设置和手动构建 toAccount() 的方法,请参见 references/typescript-sdk.md。

测试与 CLI

# Create an account (stored in keychain), then fund it on testnet
npx mppx account create
npx mppx account fund --network testnet

# Make a paid request
npx mppx http://localhost:3000/resource

# Parse a challenge without signing it
npx mppx sign --dry-run --challenge '<www-authenticate value>'

# Validate a server implementation end-to-end
npx mppx validate http://localhost:3000

CLI 还支持 init、sessions(列出/查看/关闭)、discover、services、mcp add 和 skills add。配置来自 MPPX_CONFIG 或显式指定的 --config——不会从工作目录自动发现配置。完整参考:references/cli.md。

SDK 包

语言包安装
TypeScriptmppxnpm install mppx
Pythonpympppip install "pympp[tempo]"
Rustmppcargo add mpp --features tempo,client,server
Rubympp-rb(官方,由 Stripe 提供)查看代码库了解 gem 名称
Gompp-go(官方,由 Tempo 提供)go get github.com/tempoxyz/mpp-go
Elixirmpp(社区)hex.pm/packages/mpp
Swiftmpp-swift(社区)查看代码库

功能说明依据 SDK 源码核对,而非文档中的功能矩阵(上游发布的两份矩阵彼此不一致):

  • Session 意图:仅 TypeScript 和 Rust 支持。
  • Proof Credentials(零金额认证):TypeScript、Rust 和 Ruby 支持。pympp 不支持——Python Tempo 方法仅实现 hash 和 transaction 负载类型。
  • Stripe、MCP 和事件处理:TypeScript、Python、Rust 和 Ruby 支持。官方 mpp-go 不支持,它提供客户端/服务端/收费/费用赞助/Proof 功能,以及 net/http、Gin、Echo 和 Chi 中间件。另有一个独立的社区 Go mppx(cp0x)。

Go 和 Ruby 的官方 SDK 文档页面分别见 mpp.dev/sdk/go 和 mpp.dev/sdk/ruby。

始终从与使用场景匹配的子路径导入 Mppx 和 tempo(mppx/server、mppx/client 或框架子路径)。注意:Mppx 和 tempo 不会从 mppx/tempo 导出——该子路径仅导出 Session 和 Ws。权威的子路径表见 references/typescript-sdk.md。

核心概念

  • 挑战/凭证/收据:三个协议原语。挑战 ID 通过 HMAC-SHA256 绑定,以防篡改。请参阅 references/protocol-spec.md
  • 拆分付款:在单笔交易中向多个收款方支付一笔费用(1–10 个拆分项,每项可添加备注,使用 expectedRecipients)。请参阅 references/tempo-method.md
  • 费用赞助:服务代表客户端支付 Gas,并受 maxInFlightReservations / maxInFlightTotalFee 限制
  • 中继:通过 tempo.charge({ relay }) 将凭证验证和广播委托给 Tempo API 或兼容的中继
  • 推送/拉取模式:客户端广播交易(推送),或由服务广播(拉取)
  • 客户端链固定:tempo.charge({ expectedChainId }) 会拒绝面向错误 Tempo 网络的挑战
  • 可复用客户端通道:传入 channelStore,即可跨进程持久化并复用付款方会话通道
  • x402 互操作:evm.charge({ x402: { facilitator } }) 可通过单一路由提供原生 MPP 和 x402“exact”挑战;客户端会优先选择 Payment 身份验证挑战
  • 自定义方式:使用 Method.from() 实现任意支付渠道。请参阅 references/custom-methods.md

支付钩子

无需修改处理程序,即可添加日志记录、指标或追踪。在 Mppx.create() 返回的对象上注册;每次注册都会返回一个取消订阅函数。

  • 服务端(mppx/server):onChallengeCreated、onPaymentSuccess、onPaymentFailed、onSessionSettlement、on('*')
  • 客户端(mppx/client):onChallengeReceived、onCredentialCreated、onPaymentResponse、onPaymentFailed

服务端处理程序会在请求流程中以内联方式等待执行,因此应保持快速。onPaymentFailed 是查看不透明 402 背后实际错误的实用方式。请参阅 references/typescript-sdk.md 和 mpp.dev/advanced/payment-hooks。

管理 Agent 支出

使用 Tempo 访问密钥限制 Agent 的付款权限——这类委托签名密钥内置支出控制,拥有独立的过期时间和撤销途径。

import { Expiry } from 'accounts'
import { numberToHex, parseUnits } from 'viem'
import { Scopes } from 'viem/tempo'

const accessKey = {
  expiry: Expiry.days(7),
  limits: [{ token: usdc, limit: numberToHex(parseUnits('10', 6)), period: 86_400 }], // 10 USDC/day
  scopes: [Scopes.tip20(usdc).transfer({ recipients: [recipientAddress] })],
}
// Authorize: provider.request({ method: 'wallet_connect', params: [{ capabilities: { authorizeAccessKey: accessKey } }] })

Mppx.create({
  methods: [tempo({
    account: provider.getAccount(),
    ...provider.getMppxParameters({ accessKey: accessKeyAddress }),
  })],
})

支出限额采用 十六进制编码——传入 numberToHex(parseUnits(...)),不要传入原始 bigint。为每个应用/工具/部署使用单独的密钥,可隔离各个受委托的运行时。请参阅 mpp.dev/guides/managing-agent-spend 和 Tempo 访问密钥。

生产环境注意事项

以下故障模式最耗费时间。详情请参阅 references/production-gotchas.md:

  • Tempo 没有原生 Gas 代币。 设置 feeToken 或调用 setUserToken,否则交易会因 gas_limit: 0 而失败。“Fund with ETH”错误实际表示“使用稳定币费用代币充值”
  • 会话不会自行结算。 配置 settlementSchedule,或运行自己的 tempo.settle() / tempo.settleBatch() 扫描任务,并配合空闲通道的关闭策略——否则收入会以未兑换凭证的形式累积,通道会一直保持开启并锁定付款方的存款
  • 费用会在处理程序运行前结算。 如果付款应取决于工作是否成功,请使用 validateCredential,然后再调用 broadcastCredential。挑战默认在 5 分钟后过期
  • 生产环境中切勿使用 Store.memory()。 通道状态丢失会导致存款无限期处于预留状态
  • 明确设置 realm。 环境变量的优先级高于每个请求的主机名,而 Kubernetes 的 HOSTNAME 会在每次部署时轮换,从而破坏 mppscan 归因
  • 会话凭证、close 和 topUp 凭证均为无请求体的 POST 请求,因此,在 mppx.session() 之前运行的请求体验证器会以无端的 400 错误拒绝它们。读取请求体前先克隆请求,否则 mppx 会看到空请求体并返回 402
  • 较大的 402 响应头会超出 nginx 默认的 4k 缓冲区,并表现为 502

参考资料

文件内容
references/protocol-spec.md挑战/凭证/收据、状态码、安全性
references/typescript-sdk.mdmppx:服务端、客户端、中间件、传输方式、存储
references/cli.mdmppx CLI:请求、验证、签名、账户、配置
references/production-gotchas.md经实战验证的故障模式及其修复方法
references/sessions.md通道、凭证券、结算、SSE/WS、恢复
references/subscriptions.md订阅意图:激活、续订、取消
references/tempo-method.mdTempo:费用、中继、推送/拉取、拆分、会话
references/stripe-method.mdStripe:SPT 法币流程、加密货币存款、Elements
references/discovery-and-proxy.md代理服务、发现文档、注册表
references/transports.mdHTTP、MCP 和 WebSocket 传输绑定
references/python-sdk.mdpympp:@server.pay、异步客户端、收费意图
references/rust-sdk.mdmpp Rust:服务端/客户端、功能、会话
references/lightning-method.mdLightning:BOLT11 收费、持有者会话、Spark
references/custom-methods.mdMethod.from、toClient、toServer 模式

官方资源

评论

支持 Markdown