关于 mcp-l402-gate
mcp-l402-gate 为服务运营者提供中间件和工具封装,在 MCP 工具运行前同时要求 Lightning 付款和 DoI 评分。它将 L402 付款检查与按公钥计算的身份评分结合起来。
主要功能
- 01每次调用均要求 L402 付款
- 02设定最低 DoI 评分
- 03封装 Express 中间件或 MCP 工具
- 04拒绝重复使用或无效的 macaroon
- 05配置预言机故障时的行为
适用场景
- 01限制高成本 MCP 工具调用
- 02在付款之外要求身份评分
- 03为不同端点设置不同评分门槛
MCP 相关
提供中间件和封装器,通过 L402 付款及 DoI 评分检查来限制 MCP 工具调用。调用方提供 Nostr 公钥,工具运行前会向配置的预言机查询评分。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @powforge/mcp-l402-gatePOW_GATE_URLPowForge L402 gate base URL. Defaults to public production endpoint when running via npx; override for self-hosted or local dev.ORACLE_URLPowForge Depth-of-Identity oracle base URL. Used by l402_gate_score for pubkey lookups. Defaults to public production endpoint.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
3收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
@powforge/mcp-l402-gate
面向 MCP 服务运营者、基于身份评分的 Lightning 付费墙。
L402 只能证明调用方支付了 10 sats。它无法证明调用方有声誉、存在时间超过 10 分钟,也无法证明对某个工具调用定价会改变其经济成本。新钱包支付的 10 sats 与真实用户支付的金额相同。
此包在 L402 发票之上增加了身份深度(DoI)检查。在 MCP 工具前接入此包后,调用方必须 (a) 结清 Lightning 发票,并且 (b) DoI 评分高于你设定的阈值,工具主体才会运行。廉价的女巫攻击者仍要支付通行费,但通行费加上按公钥计算的声誉要求,比单独使用其中任何一项都更难刷取。
效果演示
可克隆并运行的示例服务位于 github.com/zekebuilds-lab/mcp-l402-gate-example。它提供一个工具 bitcoin_data,用于从 mempool.space 获取 BTC/USD 价格和 mempool 手续费,并由 L402 + DoI 进行访问控制。克隆项目、填写你的 LNBits 凭据、运行 npm start,即可在本地启动一个由 Lightning 控制访问的 MCP 服务。
存在的缺口
Sats4AI 自己的文档直言不讳地指出了这一局限:
“自主 Agent 无法建立声誉,也无法在不同会话间获得优待。”
@powforge/mcp-l402-gate 将 L402 付费访问控制与 DoI 预言机的复合身份评分结合起来,填补了这一缺口。付费的调用方也是已知的调用方,其按公钥计算的声誉会在不同会话间保留,且伪造需要付出不可逆的成本。
为什么不只用 L402
L402 是优秀的线缆格式,但滥用防护能力较弱。近期的 MCP 计费工具(sats4ai-mcp、invinoveritas、l402-kit、402-mcp、coinopai-mcp)都采用相同的 402 -> macaroon -> paid -> tool body 流程,攻击者可以每分钟从一个新节点重放该流程。coinopai-mcp 的作者自己也说过:“x402 只是支付传输方式。它不处理 Agent 身份、费率协商、多 Agent 分摊或声誉。”
PowForge 一直在提供缺失的部分。位于 https://identity.powforge.dev 的 DoI 预言机会为任意 Nostr 公钥返回 Schnorr 签名的评分,该评分根据四个维度(社交、访问、背书、经济)中的可观测不可逆工作计算得出。此包将该评分接入 L402 流程,让付费的调用方同时也是难以伪造的调用方。
要求
- Node >= 18
- 一个 LNBits 钱包(Lightning 部分需要 URL + 发票/读取 API 密钥)
- 一个可访问的 PowForge 预言机 URL(默认值:
https://identity.powforge.dev)
5 行集成(Express)
const express = require('express');
const { mcpL402Middleware } = require('@powforge/mcp-l402-gate');
const app = express();
app.use('/tools/expensive', mcpL402Middleware({
secret: process.env.GATE_HMAC_SECRET,
lnbitsUrl: process.env.LNBITS_URL,
lnbitsApiKey: process.env.LNBITS_INVOICE_KEY,
satsAmount: 10,
minScore: 10, // composite >= 10 means "emerging" tier on the oracle
}));
app.post('/tools/expensive', (req, res) => {
// Reached only when L402 paid AND req.doiScore >= 10
res.json({ ok: true, doiScore: req.doiScore, l402: req.l402Token });
});
调用方通过 X-Caller-Pubkey 标头或 ?pubkey= 查询字符串传递其公钥。v0.1.0 将其视为调用方自述;v0.2.0 将通过 NIP-98 以密码学方式绑定公钥。
包装 MCP 工具
const { mcpL402Tool } = require('@powforge/mcp-l402-gate');
const expensiveTool = mcpL402Tool({
secret: process.env.GATE_HMAC_SECRET,
lnbitsUrl: process.env.LNBITS_URL,
lnbitsApiKey: process.env.LNBITS_INVOICE_KEY,
satsAmount: 10,
minScore: 10,
}, {
name: 'image_render',
description: 'Render an image. 10 sats. Requires DoI score >= 10.',
inputSchema: {
type: 'object',
properties: {
prompt: { type: 'string' },
pubkey: { type: 'string' },
auth: { type: 'object', properties: { macaroon: { type: 'string' }, preimage: { type: 'string' } } },
},
required: ['prompt', 'pubkey'],
},
}, async (args, ctx) => {
// Runs only when paid AND ctx.doiScore >= 10
return { image_url: `https://example/r/${args.prompt}`, billed_to: ctx.doiScore };
});
// Register expensiveTool with your MCP server. On first call without args.auth,
// the tool returns { paid: false, challenge: { macaroon, invoice, ... } }.
// The MCP client pays the invoice, then re-calls with args.auth set.
配置参考
| 字段 | 默认值 | 说明 |
|---|---|---|
secret | 必填 | 用于 macaroon 签名的 HMAC 密钥。请定期轮换。 |
lnbitsUrl | 必填 | LNBits 基础 URL。 |
lnbitsApiKey | 必填 | LNBits 发票/读取密钥。绝不要传入管理员密钥。 |
satsAmount | 10 | 每次调用的发票金额。 |
minScore | 10 | 拒绝综合评分低于此值的付费调用者。 |
failClosed | true | 如果预言机出错,则拒绝调用。设为 false 时会继续执行,并附带 req.doiScoreError。 |
oracleUrl | https://identity.powforge.dev | 自托管预言机的覆盖地址。 |
scope | mcp-l402-gate:call | L402 macaroon 作用域。 |
ttlSeconds | 600 | Macaroon 有效期。 |
scoreField | composite | 要与 minScore 比较的信封字段。 |
callerPubkeyHeader | x-caller-pubkey | 携带调用者声明公钥的 HTTP 标头。 |
oracleAuth | 可选 | 如果预言机本身受 L402 付费墙保护,则使用 {macaroon, preimage}。 |
createInvoiceFn | 可选 | 测试接口。异步函数 (memo) => {payment_hash, bolt11}。 |
checkPaidFn | 可选 | 测试接口。异步函数 (payment_hash) => boolean。 |
lookupScoreFn | 可选 | 测试接口。异步函数 (pubkey) => {composite, rank, depth}。 |
评分阈值(综合评分)
与预言机报告为 rank 的分档相同:
| 阈值 | 等级 | 适用场景 |
|---|---|---|
| 0 | 未知 | 只想按次付费调用时使用。跳过此软件包,直接使用 L402。 |
| 10 | 新兴 | 首次调用滥用会造成损失。适用于大多数公开 MCP 工具的默认值。 |
| 40 | 活跃 | 工具会消耗实际 GPU 资源,或产生高昂的副作用。 |
| 100 | 已建立 | 对合规性敏感或采用单租户 SaaS 模式的端点。 |
| 200 | 可信 | 高信任级别的管理工具。 |
故障模式
| 状态 | 响应体 | 含义 |
|---|---|---|
| 402 | {error: "payment required", macaroon, invoice, payment_hash} | 首次调用。支付发票,然后使用 Authorization: L402 <macaroon>:<preimage> 重试。 |
| 401 | {error: "invalid macaroon", reason} | Macaroon 格式错误、已过期、作用域错误或签名无效。 |
| 401 | {error: "preimage does not match payment hash"} | Preimage 未通过与 macaroon 的 payment hash 进行的 sha256 校验。 |
| 409 | {error: "macaroon already redeemed"} | 重放防护已触发。请生成新的 macaroon。 |
| 400 | {error: "caller_pubkey_required"} | 缺少 X-Caller-Pubkey 标头或 ?pubkey= 查询参数。 |
| 403 | {error: "score_too_low", score, min, rank} | 调用者已付款,但 DoI 评分低于阈值。 |
| 503 | {error: "oracle_unavailable", mode: "fail_closed"} | 预言机出错,且 failClosed 已开启(默认值)。 |
| 502 | {error: "invoice provider unavailable"} | 首次调用生成发票时无法访问 LNBits。 |
为什么要将其作为独立软件包
L402 macaroon 的生成和验证代码、LNBits 客户端以及预言机客户端都已包含在其他 PowForge 软件包中并投入使用。@powforge/mcp-l402-gate 的目的是简化组合:一个工厂函数、一个配置对象,以及一个中间件或工具包装器。运营人员无需手动组合三个软件包,就能构建受保护的端点。
测试
npm test
16 个单元测试,不进行真实网络访问。Macaroon HMAC 使用真实实现;LNBits 和预言机则使用存根。
许可证
MIT。
链接
- PowForge 预言机(在线):https://identity.powforge.dev
- Identity SDK:npm 上的 @powforge/identity
- MCP 身份工具:npm 上的 @powforge/mcp-identity
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。