关于 mpp
用于实现 Machine Payments Protocol 的技能,该协议为机器间请求规范 HTTP 402 支付。内容涵盖支付客户端与服务端、多种支付方式、会话及 MCP 传输。
主要功能
- 01HTTP 402 挑战、凭证与收据流程
- 02多种支付方式与意图
- 03TypeScript、Python 和 Rust SDK 指南
- 04按使用量付费的支付会话
- 05支持支付感知型 MCP 客户端与服务端
- 06用于请求、账户和服务发现的 CLI
适用场景
- 01对 API 请求或内容访问收费
- 02为 LLM 流式输出或高频 API 调用计费
- 03要求 MCP 工具调用先行支付
- 04为现有 API 添加支付门控
MCP 相关
通过 MCP 客户端和服务端封装器支持需付费的 MCP 工具调用。MCP-over-HTTP 支付挑战可在支付感知型请求流程中处理。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tenequm/ skills --skill mpp安装后在 Claude Code 中输入/mpp确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
CHANGELOG.mdLICENSE.txtreferences/cli.mdcustom-methods.mddiscovery-and-proxy.mdlightning-method.mdproduction-gotchas.mdprotocol-spec.mdpython-sdk.mdrust-sdk.mdsessions.mdstripe-method.mdsubscriptions.mdtempo-method.mdtransports.mdtypescript-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 支付都由三个基本要素构成:
- Challenge - 服务端发出的支付要求(位于
WWW-Authenticate: Payment标头中) - Credential - 客户端提交的支付凭证(位于
Authorization: Payment标头中) - Receipt - 服务端对支付成功的确认(位于
Payment-Receipt标头中)
支付方式与意图
MPP 不依赖特定支付方式。每种方式都定义自己的结算通道:
| 方式 | 通道 | SDK 包 | 状态 |
|---|---|---|---|
| Tempo | Tempo 链上的 TIP-20 稳定币 | mppx(内置) | 生产就绪 |
| Stripe | 卡/钱包(SPT)+ 链上加密货币存款 | mppx(内置) | 生产就绪 |
| EVM | EIP-3009 稳定币授权(兼容 x402-exact) | mppx(内置) | 生产就绪 |
| Lightning | 通过 Lightning Network 支付的比特币 | @buildonspark/lightning-mpp-sdk | 生产就绪 |
| Stellar | Stellar 上的 SEP-41 代币,支持 charge + channel | @stellar/mpp | 生产就绪(channel 线路规范仍在起草中,可能变更) |
| Solana | Solana 原生 charge + session(SOL、SPL、Token-2022) | @solana/mpp | 生产就绪 |
| Monad | Monad charge(ERC-3009、结算模式) | @monad-crypto/mpp | 生产就绪 |
| NEAR Intents | 通过 1Click 存款地址进行跨链 charge | @defuse-protocol/nearintents-mpp-sdk | 生产就绪(不具备无信任性 - 通过结算后端进行路由,标记为 methodDetails.settlementBackend: "near-intents",以便按方式制定风险策略) |
| RedotPay | RedotPay 余额(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 包
| 语言 | 包 | 安装 |
|---|---|---|
| TypeScript | mppx | npm install mppx |
| Python | pympp | pip install "pympp[tempo]" |
| Rust | mpp | cargo add mpp --features tempo,client,server |
| Ruby | mpp-rb(官方,由 Stripe 提供) | 查看代码库了解 gem 名称 |
| Go | mpp-go(官方,由 Tempo 提供) | go get github.com/tempoxyz/mpp-go |
| Elixir | mpp(社区) | hex.pm/packages/mpp |
| Swift | mpp-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 中间件。另有一个独立的社区 Gomppx(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.md | mppx:服务端、客户端、中间件、传输方式、存储 |
references/cli.md | mppx CLI:请求、验证、签名、账户、配置 |
references/production-gotchas.md | 经实战验证的故障模式及其修复方法 |
references/sessions.md | 通道、凭证券、结算、SSE/WS、恢复 |
references/subscriptions.md | 订阅意图:激活、续订、取消 |
references/tempo-method.md | Tempo:费用、中继、推送/拉取、拆分、会话 |
references/stripe-method.md | Stripe:SPT 法币流程、加密货币存款、Elements |
references/discovery-and-proxy.md | 代理服务、发现文档、注册表 |
references/transports.md | HTTP、MCP 和 WebSocket 传输绑定 |
references/python-sdk.md | pympp:@server.pay、异步客户端、收费意图 |
references/rust-sdk.md | mpp Rust:服务端/客户端、功能、会话 |
references/lightning-method.md | Lightning:BOLT11 收费、持有者会话、Spark |
references/custom-methods.md | Method.from、toClient、toServer 模式 |
官方资源
- 网站:mpp.dev - 大模型文档:llms-full.txt - 规范:paymentauth.org
- GitHub:wevm/mppx(TypeScript SDK)、tempoxyz/mpp(文档)、tempoxyz/mpp-specs(规范)
- IETF 草案:draft-ryan-httpauth-payment-01(标准轨道)
- Stripe MPP 文档 - Tempo 文档 - x402 互操作 - mpp 与 x402 - 治理
- Agent 钱包:mpp.dev/tools/wallet - 合作伙伴集成:Cloudflare Agents、Vercel AI SDK、MCP SDK、OpenClaw - 社区扩展
- 文档 MCP:
claude mcp add --transport http mpp https://mpp.dev/api/mcp(8 个工具:list_pages、read_page、search_docs、search_source、list_sources、list_source_files、read_source_file、get_file_tree)。服务 MCP:mpp.dev/mcp/services - 上游发布了自己的机器可读技能,位于
mpp.dev/.well-known/agent-skills/mppx/SKILL.md;可通过npx skills add tempoxyz/mpp -g或mppx skills add安装