内容
# X402-Algorand-MCP
远程 [MCP](https://modelcontextprotocol.io) 服务器,允许任何代理 **发现 Algorand 上的 x402 支付网关端点并支付费用** —— 而无需向服务器提供密钥。
```
┌─────────────────────┐
代理 ◄──MCP──►│ X402-Algorand-MCP │──── 发现 ───► 中介目录
│ │ (无密钥) │──── 付费调用 ───► 商家端点
│ └─────────────────────┘
│
└── "签名这些字节" ──► 代理拥有的任意签名者
(AC2 配对钱包 · 钱包 MCP · 本地密钥)
```
## 功能
**发现。** 每个 x402 支付都通过中介验证和结算,因此中介观察到网络中的每个商家和每个付费端点。这使得其目录成为一个发现索引,该索引源自实际的支付流量,而不是自愿注册。该服务器将其作为 MCP 工具公开,因此代理可以回答:
- *"有哪些商家可用?"* → `list_merchants`
- *"这个商家提供什么?"* → `list_endpoints({ merchant_id })`
- *"这个端点的费用是多少,它需要什么作为输入?"* → `describe_endpoint`
**支付。** 当代理调用付费端点并收到 HTTP 402 时,该服务器构建支付所需的 Algorand 交易组,然后 **停止** 并返回需要签名的确切字节,以及对签名授权的纯语言描述。代理使用其设置的签名方式进行签名,并提交签名以完成调用。
## 服务器无密钥
这是核心设计约束,这使得服务器可以作为共享的远程服务部署。
因此,支付分为两个步骤:
| 步骤 | 工具 | 操作 |
|---|---|---|
| 1 | `prepare_payment` | 调用端点。免费?您将获得响应。HTTP 402?您将获得可签名的字节 + 描述。 |
| 2 | `submit_payment` | 您返回原始 Ed25519 签名;请求完成,您将获得资源。 |
在这两个步骤之间,**字节如何签名完全由代理决定。** 服务器故意保持中立:
- AC2 配对钱包,人类在自己的设备上批准支付,签名委托回代理;
- 已经授权签署支付交易的钱包 MCP;
- 测试环境中的本地密钥对。
所有这些都满足相同的合同:*接收字节和描述,返回 64 字节的 Ed25519 签名。* 该代码库中没有任何内容导入 AC2 SDK,也不知道对方使用的是哪种方式。
> 签名请求与 AC2 `SigningRequest` 正文(`description`、`payload`、`schema`、`sig_hint`) cleanly 映射,因此 AC2 路径是直接字段映射 — 但这是一种方便,而不是耦合。
### 为什么是两步而不是一步
Algorand 交易组使用固定的有效性轮次和组 ID 构建。无法使用相同的交易组 ID 重建它,因此流程无法在签名后重新启动 — 它必须 **暂停**。`prepare_payment` 将正在进行的支付挂在内存中,直到其签名到达或超时(默认为 5 分钟;有效性窗口使任何更长的时间都变得无用)。
## 工具
| 工具 | 用途 |
|---|---|
| `list_merchants` | 在 Algorand 上销售 x402 端点的商家。按搜索、类别、网络过滤。 |
| `list_endpoints` | 具有描述和定价的端点。传递 `merchant_id` 以限定为一个商家。 |
| `describe_endpoint` | 一个端点的完整详细信息:定价、资产及其声明的输入/输出模式。 |
| `prepare_payment` | 调用端点;返回 402 时,返回签名的字节。 |
| `submit_payment` | 提供签名,获取付费资源。 |
| `get_payment_config` | 中介、默认网络和生效的支出限制。 |
发现结果仅限于 Algorand:目录涵盖中介服务的每个链,该服务器只能在 Algorand 上支付。
## 快速开始
```sh
pnpm install
cp .env.example .env # 可选;如果没有它,默认情况下会应用合理的默认值
pnpm build
pnpm start # 流式 HTTP 在 :3000/mcp
```
## 选择网络
网络 **按调用** 选择,而不是在部署中硬编码。传递 `network` 给任意工具,值为 `"mainnet"`、`"testnet"` 或完整的 CAIP-2 ID:
```jsonc
{ "url": "https://…", "payer_address": "XJCC…", "network": "testnet" }
```
如果端点不接受您指定的网络,则调用 **失败** 而不是在不同链上支付:
```
端点不接受 algorand:SGO1GKSz… 上的支付
它接受: algorand:wGHE2Pwd…
```
省略 `network`,服务器使用 `X402_DEFAULT_NETWORK` 作为 **首选**,并回落到端点提供的网络。目前,目录中包含约 643 个 MainNet 和约 37 个 TestNet 端点;TestNet 端点以 TestNet USDC(ASA `10458941`)定价,因此执行它们不会产生实际成本。
## 本地测试
服务器通过 stdio 运行,因此您可以将其附加到任意桌面 MCP 客户端作为本地服务器。
**Claude 代码:**
```sh
pnpm build
claude mcp add x402-algorand -e MCP_TRANSPORT=stdio -- node "$PWD/dist/index.js"
```
**Claude 桌面** — 添加到 `claude_desktop_config.json`:
```jsonc
{
"mcpServers": {
"x402-algorand": {
"command": "node",
"args": ["/absolute/path/to/X402-Algorand-MCP/dist/index.js"],
"env": { "MCP_TRANSPORT": "stdio" }
}
}
}
```
然后询问类似 *"Algorand 上有哪些 x402 商家可用?"* 或 *"商家 X 提供什么?"* 的问题。
> MCP 客户端使用其自己的工作目录启动服务器,因此不会读取 `.env` 文件。请通过客户端的 `env` 块传递配置。`pnpm start` 和 `pnpm start:stdio` 读取 `.env`,因为它们从项目根目录运行。
**无需客户端**,可以直接与实时目录进行端到端测试。该测试在生成可签名字节时停止,因此永远不会花费:
```sh
pnpm build && pnpm smoke
# 或指定网络和端点:
node scripts/smoke.mjs <payerAddress> https://gateway-x402.vercel.app/discover
```
任何语法有效的 Algorand 地址都适用于 `prepare_payment` — 交易组已构建但从未签名或提交。
### 测试真实支付
完成支付需要一个签名者,而该服务器故意不具备。 要在 TestNet 上完成循环:取 `signing_requests[].payload_base64`,使用 Ed25519 和 TestNet 密钥(从 [dispenser](https://bank.testnet.algorand.network/) 资助并选择 ASA `10458941`)签署原始字节,然后使用 base64 签名调用 `submit_payment`。 **直接** 签名字节 — 不要用交易重新包装。
## 配置
参见 [`.env.example`](./.env.example)。值得注意的值:
| 变量 | 默认值 | 备注 |
|---|---|---|
| `X402_FACILITATOR_URL` | `https://facilitator.goplausible.xyz` | 支持所有发现。 |
| `X402_DEFAULT_NETWORK` | Algorand MainNet CAIP-2 | 仅作为 **默认值** — 调用者按请求覆盖它。标准 base64 genesis hash:包含 `/` 和尾随 `=`,不是 URL 安全变体。 |
| `ALGOD_URL` | AlgoNode MainNet | 用于 `X402_DEFAULT_NETWORK`;其他网络回落到公共 AlgoNode 端点。 |
| `X402_MAX_AMOUNT_ATOMIC` | `1000000` | 服务器端支出上限,以原子单位为单位。 |
| `X402_ALLOWED_ASSETS` | *(任意)* | 以逗号分隔的 ASA ID 列表。 |
| `X402_PENDING_TTL_MS` | `300000` | 已准备的支付等待签名的时间。 |
支出防护措施是 **后备措施,而不是主要控制措施**。签名者强制执行其自己的策略,并且是唯一可以实际授权支出的一方。
## 部署
服务器在 `prepare_payment` 和 `submit_payment` 之间将已准备的支付保存在内存中,因此 MCP 会话必须持续访问相同的实例。运行单个实例,或在负载均衡器后面使用粘性会话。
它没有本地依赖项,不需要 WebRTC,因此可以在 Node 20+ 运行的任何地方运行。
## 开发
```sh
pnpm typecheck
pnpm test
```
## 许可证
Apache-2.0。参见 [LICENSE](./LICENSE)。