关于 tollbooth-authority
Tollbooth Authority 是 DPYC 网络中的运营方认证服务,负责登记运营方、收取预付认证费并签发购买订单证书。它以 Schnorr 签名的 Nostr 事件证明运营方已缴费,但不处理用户向运营方支付的款项。
主要功能
- 01登记并管理服务运营方
- 02通过 Lightning 收取预付认证费
- 03签署 Schnorr 购买订单证书
- 04检查 DPYC 注册状态
- 05提供账本公证与证明工具
适用场景
- 01为 MCP 服务申请并完成运营方认证
- 02为后续购买订单预存认证额度
- 03验证运营方购买额度所需的证书
- 04管理运营方登记与审批请求
MCP 相关
作为 MCP 服务,它向客户端提供运营方生命周期、认证签名及标准支付和身份工具。客户端可通过 Horizon 连接,并以 NIP-98 签名或 OAuth 后完成 Nostr 身份证明。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://tollbooth-authority.fastmcp.app/mcpclaude mcp add --transport http lonniev-tollbooth-authority https://tollbooth-authority.fastmcp.app/mcp{"mcpServers":{"lonniev-tollbooth-authority":{"type":"http","url":"https://tollbooth-authority.fastmcp.app/mcp"}}}在 Cursor 中打开{"servers":{"lonniev-tollbooth-authority":{"type":"http","url":"https://tollbooth-authority.fastmcp.app/mcp"}}}在 VS Code 中打开{"mcpServers":{"lonniev-tollbooth-authority":{"type":"http","url":"https://tollbooth-authority.fastmcp.app/mcp"}}}{"mcpServers":{"lonniev-tollbooth-authority":{"serverUrl":"https://tollbooth-authority.fastmcp.app/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
70| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| npub | string | 是 | 要查询余额的 Nostr 公钥(npub1...)。 |
| dpop_token | string | 是 | 证明调用方持有 npub 的凭据:来自 receive_npub_proof 的授权信封,或由 npub 签名的 kind-27235 Nostr 事件原始 JSON,其中 `u` 标签的值为此工具的名称。 |
详细介绍
收费站管理局
建设基础设施的机构。
本项目的比喻借鉴自 The Phantom Tollbooth ,谨致以敬意。该书由 Norton Juster 创作,Jules Feiffer 绘制插图(1961 年)。Milo、Tock、收费站、Dictionopolis 和 Digitopolis 都出自 Juster 先生非凡的想象。我们只是搭建了支付基础设施。
收费公路管理局
每条收费公路都有一个管理局。它既不是运营收费站的运营方,也不是支付通行费的驾驶者,而是浇筑混凝土、竖立标牌并盖章批准采购订单的机构。
收费站管理局是 Lightning 经济中的马萨诸塞州收费公路管理局。它不运营任何收费站,不接触运营方的 BTCPay 商店,也从不接触用户支付数据。它所做的事更简单,也更重要:
- 它注册运营方,让他们能够在收费公路上运营收费站。
- 它收取适度的认证费用——每笔通行费的 2%,最低 10 sats,须通过 Lightning 预先支付。
- 它盖章批准采购订单——使用 Schnorr 签名的 Nostr 事件证书(kind 30079),证明运营方已在收取通行费前缴纳费用。
- 它绝不接触通行费本身。运营方直接向用户收款。
管理局的签名是收费公路合法性的证明。没有印章,收费站就不会开放。
架构
从 v0.9.0 起,本管理局是 tollbooth-dpyc wheel 的轻量使用方。所有通用管理局代码——入驻状态机、Schnorr 证书签名器、重放跟踪器、Neon 租户配置器,以及完整的管理局工具集——都位于该 wheel 的 tollbooth.authority 包中。此仓库的 server.py 仅提供特定角色的配置:身份名称、面向用户的说明、OperatorRuntime 构建,以及两次 register_*_tools(mcp, runtime) 调用。
# The entire server.py, distilled
from fastmcp import FastMCP
from tollbooth.authority import (
AUTHORITY_TOOL_REGISTRY,
OPERATOR_CREDENTIAL_TEMPLATE,
register_authority_tools,
)
from tollbooth.runtime import OperatorRuntime, register_standard_tools
from tollbooth.tool_identity import STANDARD_IDENTITIES
mcp = FastMCP("tollbooth-authority", instructions="…")
runtime = OperatorRuntime(
tool_registry={**STANDARD_IDENTITIES, **AUTHORITY_TOOL_REGISTRY},
vault_source="env", # Authority arrives with its own Neon
purchase_mode="auto", # derive direct/certified from the registry chain
service_name="Tollbooth Authority",
ots_enabled=True,
operator_credential_template=OPERATOR_CREDENTIAL_TEMPLATE,
)
register_standard_tools(mcp, "authority", runtime, ...)
register_authority_tools(mcp, runtime)
重构历史:
- v0.5.0 引入了
OperatorRuntime,并将标准工具委托给 wheel——代码从约 1,900 行缩减到约 970 行。 - v0.19.0 要求并验证每个提及证明的工具都必须提供证明;本地的
_verify_operator_proof辅助函数被提升到 wheel 侧的tollbooth.identity_proof.require_proof。 - v0.21.0(wheel)将 6 个支持模块(onboarding、nostr_signing、replay、tenant_provisioner、role_migration、settings)从分叉的管理局代码提升至
tollbooth.authority.*。 - v0.22.0(wheel)将 10 个管理局
@tool定义提升至register_authority_tools(mcp, runtime)。 - v0.9.0(此版本)删除了现已冗余的 8 个模块,并将 server.py 从约 970 行精简至约 100 行。NorthAmerica 和 NewEngland 也在各自的
0.4.0版本中进行了同样的调整。
三方协议
收费站生态系统是一个横跨 3 个仓库的三方协议:
| 仓库 | 角色 |
|---|---|
| tollbooth-authority(此仓库) | 机构——收取费用、Schnorr 签名、采购订单认证 |
| tollbooth-dpyc | 收费站——运营方侧的信用账本、BTCPay 客户端、工具访问控制 |
| thebrain-mcp | 第一座城市——由收费站提供支持的 MCP 参考服务 |
DPYC 联盟的更广范围
上面的三方协议是核心,但 Authority 还会认证由独立 MCP 服务组成的更广泛联盟,这些服务均基于同一个 tollbooth-dpyc SDK 构建:
| Repo | 角色 |
|---|---|
| tollbooth-dpyc | 共享 SDK — 加密、保险库、身份验证、定价、审计 |
| dpyc-community | 治理注册表 — members/read-only-lookup-cache.json、GOVERNANCE.md、CI 验证 |
| dpyc-oracle | 免费的社区服务台 — 成员资格、治理、入门答疑 |
| tollbooth-authority | 本仓库 — 认证骨干、Schnorr 证书、费用账本 |
| tollbooth-sample | 新运营方的参考模板 |
| tollbooth-pricing-studio | 定价编辑器 — 原生 iOS、Nostr 私信 |
| cypher-mcp | 收费图数据库问答 — 针对 Neo4j/AuraDB 的命名 Cypher 查询 |
| schwab-mcp | Charles Schwab 经纪业务数据 |
| thebrain-mcp | TheBrain 知识图谱访问 |
| excalibur-mcp | X/Twitter 发帖 |
| taxsort-mcp | 税务分类与归类 |
| optionality-mcp | 期权分析 |
| goodearth-mcp | 小型农场的气候分析 |
| beesknees-mcp | The Bee's Knees 竞速游戏 |
| roastify-mcp | Roastify 咖啡目录与包装插画 |
| ChartRemotely-mcp | 通过配对的 Agent 操作桌面图表 |
| tollbooth-web | 供运营方前端使用的共享浏览器 SDK |
| tollbooth-oauth2-collector | 共享 OAuth2 回调收集器(社区倡导者) |
| tollbooth-shortlinks | URL 缩短工具 |
工作原理
-
接入。 运营方在其自己的 MCP 上调用
request_adoption(authority_npub=..., service_url=..., display_name=...),并使用其 nsec 为请求签名。其服务会将请求发送给 Authority,后者将其记录为待处理状态并通知所有者。所有者使用approve_operator_request批准请求(或使用reject_operator_request拒绝请求);批准后会创建运营方的账本条目、配置其隔离的 Neon schema,并通过 Oracle 注册该运营方。 -
充值。 运营方调用
purchase_credits,指定要预充值的 sats 数量。Authority 会从其自有 BTCPay Server 返回 Lightning 发票。运营方支付发票。结算后,check_payment会为余额充值。 -
认证。 用户想要从运营方购买额度时,运营方的服务会调用
certify_credits。Authority 会扣除 2% 从价费用(通过@runtime.paid_tool装饰器),签署基于 Schnorr 的 Nostr 事件证书,并将其返回。 -
验证。 运营方的 tollbooth-dpyc 库会使用 Authority 的 Nostr npub 验证证书。只有印章有效时,运营方才会为用户创建 Lightning 发票。没有印章,就没有服务。
Nostr 证书格式(kind 30079)
证书是由 Schnorr 签名的 Nostr 事件(NIP-33 参数化可替换事件),而不是 Ed25519 JWT。每个证书都包含一个 p 标签,用于记录运营方的 npub;t/L 标签,用于记录认证金额和协议;一个 expiration 标签;以及用于存放结构化声明数据的 content 字段。验证时,使用 Authority 的 Nostr npub 验证 BIP-340 Schnorr 签名。
DPYC 注册表强制检查
Authority 在认证时会检查 dpyc-community 注册表缓存 members/read-only-lookup-cache.json。运营方必须在注册表中的 "status": "active"。注册表通过 HTTP 缓存,并使用可配置的 TTL。此设计采用失败即关闭策略:如果无法访问注册表,则拒绝认证。
上游拓扑是注册表元数据
父级 Authority 关系存储在 dpyc-community 注册表中——每个 Authority 的 upstream_authority_npub 都指向其赞助方。运营方 MCP 会通过 Oracle(resolve_authority_for(npub))解析为其认证的 Authority;Oracle 会遍历注册表链。无需通过每个 Authority 的环境变量配置上游。Authority 自身的 certify_credits 只需从运营方的预付余额中收取从价费用并签署证书,无需逐笔调用上游。
从价定价
certify_credits 注册为 @runtime.paid_tool,按 amount_sats 参数采用 2% 的从价定价(最低 10 sats)。费用由装饰器扣除,成本从 runtime._last_debit_cost 读取,无需重复计算。
OTS 公证
已启用 OpenTimestamps 公证(在运行时设置 ots_enabled=True)。可使用该 wheel 提供的标准 notarize_ledger 和 get_notarization_proof 工具,对账本状态进行公证和验证。
防重放(ReplayTracker)
每张证书都包含一个唯一的 JTI(JWT ID)。Authority 会在带有基于 TTL 的修剪机制的内存有序字典中追踪已见过的 JTI。即使证书在过期前被截获,也能防止证书重放攻击。
MCP 工具
现在,所有工具都由 wheel 定义,并通过 server.py 中的两个 register_*_tools 调用注册。如需查看规范的完整表格(由 register_authority_tools 挂载的 Authority 工具,以及由 register_standard_tools 挂载的标准工具),请参阅 tollbooth-dpyc README。简要说明:
- Authority 工具(Schnorr 证书签名、运营方生命周期管理、三步 Authority 入驻、注册表成员检查)——
register_authority_tools(mcp, runtime)。这一组还包括所有者的请求队列:receive_adoption_request(接收运营方的收养请求)、list_operator_requests、approve_operator_request和reject_operator_request。队列处理两种请求:收养请求,以及更新运营方注册表条目的请求(运营方调用update_operator,由所有者批准)。deregister_operator无需批准:运营方(退出)或 Authority 的所有者(解除其所属关系)都可以单独调用。repair_operator_schema用于所有者修复租户的表所有权。 - 标准工具(额度/付款、身份、安全信使、npub 证明、定价模型、OpenTimestamps 公证、Oracle 委派)——
register_standard_tools(mcp, "authority", runtime, ...)。
所有接受 npub 的工具都要求连接证明该 npub,并且每个请求只能代表一个 npub。使用该 npub 的 nsec 签署请求(NIP-98)即可完成证明。无密钥客户端以 OAuth 持有者身份连接,并通过 request_npub_proof、回复 DM,然后调用 receive_npub_proof,将 npub 一次性证明到其钱包中。所有者专用工具要求请求证明 Authority 自身的 npub。工具参数中不会传递任何证明。
入门
通过 Horizon MCP 连接
Authority 运行在 Horizon 上。任何 MCP 客户端(Claude Desktop、Cursor 或你自己的 Agent)都可以通过 Horizon 连接:
https://www.fastmcp.cloud/server/lonniev/tollbooth-authority
连接无需 API 密钥。持有密钥的客户端会使用该密钥对每个请求签名(NIP-98)。其他客户端则以持有者身份通过 OAuth 连接;在通过 Nostr DM 向其中证明某个 npub 之前,它不会关联任何 npub。
首次连接流程
连接后,按顺序完成引导流程:
request_adoption(authority_npub="npub1...", service_url="...")— 在你自己的运营方 MCP 上调用,并使用你的运营方 nsec 签名。Authority 的所有者会批准请求(approve_operator_request),从而创建你的账本条目并配置你的 Neon 架构。完成后,你的运营方的adoption_status会显示为provisioned。purchase_credits(amount_sats=1000)— 返回一张 Lightning 发票。使用任意 Lightning 钱包付款。check_payment(invoice_id="...")— 传入步骤 2 中的发票 ID。确认结算并为你的余额充值。check_balance— 确认你的余额已到账。operator_status— 查看你的注册信息、余额、金库后端以及 Authority 的 npub。tollbooth-dpyc 会在验证证书时通过注册表查找该 npub,因此无需将其硬编码。
自托管
要运行自己的 Authority 实例,请设置以下环境变量:
必需
| 变量 | 用途 | 示例 |
|---|---|---|
NEON_DATABASE_URL | 用于持久化运营方账本的 Neon Postgres URL。Authority 是信任根——它从环境变量中读取此值(与通过 Nostr DM 从 Authority 引导获取此值的认证运营方不同)。启动时,Authority 会在连接字符串中注入 search_path=authority,以实现按架构隔离。 | postgresql://... |
TOLLBOOTH_NOSTR_OPERATOR_NSEC | 用于 Schnorr 证书签名和 Secure Courier DM 的 Nostr 私钥(nsec) | nsec1... |
通过 Secure Courier 提供凭据(不是环境变量)
BTCPay 凭据通过 Secure Courier 传送,不作为环境变量设置:
| 凭据 | 说明 |
|---|---|
btcpay_host | 用于收取费用的 Authority BTCPay Server URL |
btcpay_api_key | 具有发票和付款权限的 BTCPay API 密钥 |
btcpay_store_id | Authority 费用商店的 BTCPay 商店 ID |
可选
| 变量 | 用途 | 默认值 |
|---|---|---|
CERTIFICATE_TTL_SECONDS | 签名证书的有效时长 | 600(10 分钟) |
DPYC_ENFORCE_MEMBERSHIP | 在认证时启用注册表强制检查 | true |
DPYC_REGISTRY_CACHE_TTL_SECONDS | DPYC 社区注册表的缓存时长 | 300 |
按运营方隔离架构
每个已注册的运营方都会获得一个隔离的 Neon 架构(op_{hash}),并配有专用的 Postgres LOGIN 角色。Authority 架构(authority)存放 Authority 自己的账本。所有者批准接纳请求后,系统会自动配置运营方架构,并通过基于角色的授权实施访问控制——不可能访问其他运营方的数据。
开发
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
pytest tests/ -q
密钥生成
Nostr 签名密钥(Schnorr 证书)
Authority 使用 Nostr nsec/npub 密钥对为证书签名。使用任意 Nostr 密钥生成器(例如 nak key generate)生成密钥。将 nsec 填入 TOLLBOOTH_NOSTR_OPERATOR_NSEC;npub 会通过 operator_status 提供,以便 tollbooth-dpyc 验证。
DPYC 身份(Nostr npub)
每个 Authority 都有一个 Nostr 密钥对,用于在 DPYC Certification Chain 上标识自身:
pip install nostr-sdk
python -c "from nostr_sdk import Keys; k = Keys.generate(); print(f'npub: {k.public_key().to_bech32()}'); print(f'nsec (back up!): {k.secret_key().to_bech32()}')"
延伸阅读
闪电高速公路上的幻影收费站 — 完整讲述了我们如何将 AI API 变现的过程变现,然后淡出背景。
许可证
Apache License 2.0 — 详情请参阅 LICENSE 和 NOTICE。
因为每条收费公路都需要一个管理机构。不是为了管控道路,只是为了确保印章真实、收费合理。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。