关于 presidio-hardened-x402-mcp
presidio-hardened-x402-mcp 是 x402 Agent 支付的预付款安全关卡,可在签名前筛查并脱敏个人信息、执行支出策略和检测重复支付。它将 presidio-hardened-x402 库封装为三个 MCP 工具,并可生成可离线验证的签名决策记录。
主要功能
- 01筛查并脱敏支付元数据中的个人信息
- 02按支付金额和额度执行策略
- 03检测重复支付
- 04记录审计日志与签名决策
- 05支持本地处理或远程筛查
适用场景
- 01在发送支付元数据前移除个人信息
- 02阻止超出单笔或周期额度的付款
- 03在签名前识别重复支付请求
- 04为支付决策生成可离线验证的证据
MCP 相关
该 MCP 服务封装 presidio-hardened-x402 库,向 MCP 客户端提供支付元数据筛查、支出策略检查和重复支付检查三个预付款工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| reason | string | 否 | |
| entities | any | 否 | |
| description | string | 否 | |
| resource_url | string | 是 |
详细介绍
presidio-hardened-x402-mcp
x402 的付款前安全关卡——Agent 在签名前调用 screen_payment_metadata(...)、check_payment_policy(...) 和 check_payment_replay(...),在元数据或资金离开 Agent 主机前发现个人身份信息(PII)、预算超支和重复付款。
属于 presidio-hardened-* 工具包系列。它是 presidio-hardened-x402 库之上的轻量 MCP(模型上下文协议)适配器,并固定使用父库 0.13.x(presidio-hardened-x402>=0.13.0,<0.14.0)。0.13.0 是首个可将控制项记录为 NOT_EVALUATED 的父库版本,而签名决策证据需要此功能;该版本还包含 0.11.1 中针对百分号编码 PII 脱敏绕过漏洞的修复,这是安全底线。
为什么要开发这个项目
x402 Agent 付款通常会将用户提供的自由文本——描述、备注、查询字符串参数——直接传给商家和支付服务。LLM Agent 生成这些文本时,可能包含用户原本不打算分享的 PII。一旦商家记录了这些信息,是否保留就由商家决定,而不是由你决定。
这个 MCP 服务为 Agent 提供了一个简单的默认拒绝关卡,在付款离开 Agent 主机前进行检查。三个工具公开父库稳定的付款前控制项:PII 脱敏、支出策略和重放检测。从 0.3.0 起,每项决策还可输出为签名的 payment-decision@1 记录,供第三方离线验证(参见签名决策证据)。这些工具旨在与支付执行和端点安全 MCP 服务(x402station、Coinbase x402、Sardis 等)组合使用;父库的其他功能——对传入证据进行 evidence-ref@1 验证、v0.9.1 SLO broker、v0.10.0 settlement-ref@1 treasury binding,以及 v0.11.0 CapabilityEnforcer——仍保留在 Python 库中,除非后续有 MCP 工具明确封装它们。
安装与配置
需要 Python ≥ 3.10。通过 PyPI 分发;建议使用 uvx 调用(无需全局安装)。
Claude Desktop / Claude Code
将以下内容添加到 ~/Library/Application Support/Claude/claude_desktop_config.json(macOS)或你所在平台上的对应文件中:
{
"mcpServers": {
"presidio-x402": {
"command": "uvx",
"args": ["presidio-hardened-x402-mcp"]
}
}
}
Cursor / Windsurf / Continue
配置格式相同——每个 MCP 宿主都接受 command / args / env。配置文件路径请参阅编辑器的 MCP 服务文档。
环境变量
全部为可选项。默认值提供零配置的进程内模式,无配额、无网络连接,也不存储 PII。
| 变量 | 用途 | 默认值 |
|---|---|---|
PRESIDIO_X402_MCP_MODE | regex(零配置)或 nlp(需要 [nlp] 附加组件和 spaCy 模型) | regex |
PRESIDIO_X402_MCP_MAX_PER_CALL_USD | 单笔付款的最高金额(美元)(策略门控) | 未设置 → 不限额 |
PRESIDIO_X402_MCP_DAILY_LIMIT_USD | 滚动时间窗口内的最高金额(美元)(策略门控) | 未设置 → 不限额 |
PRESIDIO_X402_MCP_PER_ENDPOINT_JSON | 各端点的额度上限,例如 '{"api.foo.com": 5.00}' | 未设置 |
PRESIDIO_X402_MCP_WINDOW_SECONDS | 每日限额的滚动时间窗口 | 86400 |
PRESIDIO_X402_MCP_AGENT_ID | 写入审计记录的标签 | 未设置 |
PRESIDIO_X402_MCP_REPLAY_TTL | 指纹缓存 TTL(秒) | 300 |
PRESIDIO_X402_MCP_REDIS_URL | 使用 Redis 存储重放状态,而非内存 | 未设置 |
PRESIDIO_X402_MCP_AUDIT_PATH | 仅追加的 JSON-L 审计日志路径;省略则禁用 | 未设置 |
PRESIDIO_X402_MCP_LOG_LEVEL | DEBUG / INFO / WARNING / ERROR | INFO |
PRESIDIO_X402_MCP_REMOTE_BASE_URL | 为工具 1 启用 HTTP 代理模式 — 参见“模式”。必须为 https://;仅接受指向环回地址的普通 http://,否则拒绝启动 | 未设置 |
PRESIDIO_X402_MCP_REMOTE_API_KEY | 远程筛查服务的 API 密钥 | 未设置 |
PRESIDIO_X402_FINGERPRINT_KEY | 用于跨进程重放检测的 32 字节十六进制密钥 | 未设置(每个进程独立) |
PRESIDIO_X402_CHAIN_KEY | 用于跨进程审计链 HMAC 的 32 字节十六进制密钥 | 未设置(每个进程独立) |
PRESIDIO_X402_REQUIRE_FINGERPRINT_KEY | 若重放密钥缺失或无效,则启动失败 | 未设置 |
PRESIDIO_X402_REQUIRE_CHAIN_KEY | 若审计链密钥缺失或无效,则启动失败 | 未设置 |
PRESIDIO_X402_MCP_EVIDENCE_KEY_FILE | 保存决策签名密钥的文件(首选;优先于环境变量中的密钥) | 未设置 |
PRESIDIO_X402_EVIDENCE_KEY | 决策签名密钥(父级库使用的变量):64 个十六进制字符的 Ed25519 私钥,或 HMAC 密钥 | 未设置 |
PRESIDIO_X402_MCP_DECISION_PATH | 用于保存已签名 payment-decision@1 记录的仅追加 JSON-L 文件 | 未设置 |
PRESIDIO_X402_MCP_EVIDENCE_ALGORITHM | ed25519 或 hmac-sha256 | ed25519 |
PRESIDIO_X402_MCP_EVIDENCE_SIGNER | 签名者身份;信任存储中的密钥验证器会据此查找 | presidio-hardened-x402-mcp |
PRESIDIO_X402_MCP_EVIDENCE_KEY_ID | 可选密钥 ID,写入每条记录(用于轮换) | 未设置 |
PRESIDIO_X402_MCP_REQUIRE_EVIDENCE_KEY | 若未完整配置已签名证据或密钥无法签名,则启动失败 | 未设置 |
使用 openssl rand -hex 32 生成跨进程密钥。
工具
screen_payment_metadata(resource_url, description, reason, entities?)
检测并删改付款元数据中的 PII。无副作用 — 可安全重复调用。
// Input
{
"resource_url": "https://api.foo.com/u/[email protected]",
"description": "monthly fee for [email protected]",
"reason": ""
}
// Output
{
"redacted_resource_url": "https://api.foo.com/u/<EMAIL_ADDRESS>",
"redacted_description": "monthly fee for <EMAIL_ADDRESS>",
"redacted_reason": "",
"entities_found": [
{ "entity_type": "EMAIL_ADDRESS", "field": "resource_url", "count": 1 },
{ "entity_type": "EMAIL_ADDRESS", "field": "description", "count": 1 }
],
"mode": "in_process"
// + "decision_ref": "<64 hex>" when signed decision evidence is enabled
}
entities(可选的 Presidio 实体类型列表)可将检测范围缩小至白名单。字段长度上限与 screening-api 线协议一致,并在父级版本 0.7.x 中保持稳定:resource_url ≤ 2048、description ≤ 4096、reason ≤ 4096 个字符。输入超出上限时会引发 ValueError。
check_payment_policy(resource_url, amount_usd, prior_decision_refs?)
支出策略门禁。成功时会记录支出——请在付款前立即调用,且仅调用一次。若检查成功后未实际付款,每日限额账本中的支出会被虚增,直到统计窗口滚动。
系统会先筛查 URL,只有脱敏后的 URL 会传到策略引擎,因此原始 URL 不会进入父级的日志。单个端点的限额会与该脱敏 URL 匹配;配置的端点前缀中请勿包含 PII。如果筛查失败,门禁会拒绝请求,且不记录支出。
// Input
{ "resource_url": "https://api.foo.com/x", "amount_usd": 1.50 }
// Output (allowed)
{ "allowed": true }
// Output (denied — over per-call limit of $5.00)
{ "allowed": false, "reason": "...", "limit_usd": 5.00, "amount_usd": 6.00 }
启用签名证据后,两种输出也都会携带 decision_ref。prior_decision_refs(可选,最多 8 个)会将此服务先前为同一笔付款返回的引用(通常是 screen_payment_metadata 返回的引用)关联到签名记录中;如果某个引用并非由当前进程签发,则会在记录任何支出之前拒绝请求。
check_payment_replay(resource_url, pay_to, amount, currency, deadline_seconds, prior_decision_refs?)
通过规范字段的 HMAC-SHA256 指纹进行重复付款门禁。成功时会记录指纹——请在付款前立即调用,且仅调用一次。
amount 是字符串,用于保留精度。跨进程检测需要设置 PRESIDIO_X402_FINGERPRINT_KEY(以及可选的 PRESIDIO_X402_MCP_REDIS_URL);否则,每个 MCP 服务进程都会维护自己的内存存储。
// Input
{
"resource_url": "https://api.foo.com/x",
"pay_to": "0xabc...",
"amount": "1.50",
"currency": "USDC",
"deadline_seconds": 1700000000
}
// Output (first seen)
{ "is_replay": false, "fingerprint": "29aaf60f..." }
// Output (duplicate within TTL)
{ "is_replay": true, "fingerprint": "29aaf60f..." }
decision_ref 和 prior_decision_refs 的行为与 check_payment_policy 相同。
签名决策证据
审计日志(PRESIDIO_X402_MCP_AUDIT_PATH)采用 HMAC 链式签名:持有 PRESIDIO_X402_CHAIN_KEY 的人可以检测篡改,其他人则不能。从 0.3.0 起,每项工具决策(无论允许还是阻止)也可以写入一条签名的 payment-decision@1 记录。该记录由父级库构建并签名(build_payment_decision_content、build_decision_evidence),任何持有公钥的人都可以验证(verify_decision_ref)。审计日志仍会写入;这些记录会与其并存,而不会取代它。
# One-time: an Ed25519 key pair for the signer (hex private key, 0600).
python - <<'PY'
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
sk = Ed25519PrivateKey.generate()
open("evidence.key", "w").write(sk.private_bytes_raw().hex())
print(sk.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw).hex()) # -> trust store
PY
chmod 600 evidence.key
"env": {
"PRESIDIO_X402_MCP_EVIDENCE_KEY_FILE": "/etc/presidio/evidence.key",
"PRESIDIO_X402_MCP_DECISION_PATH": "/var/log/presidio/x402-mcp-decisions.jsonl",
"PRESIDIO_X402_MCP_REQUIRE_EVIDENCE_KEY": "1"
}
可使用父级 CLI 对照固定了签名者名称及其公钥的信任存储进行离线验证:
echo '{"presidio-hardened-x402-mcp": {"alg": "ed25519", "public_key": "<public hex>"}}' > trust.json
python -m presidio_x402.decision_ref /var/log/presidio/x402-mcp-decisions.jsonl trust.json
未设置密钥时,服务的行为与 0.2.x 完全相同——仅写入审计日志——并在启动时记录一条 WARNING,说明签名证据已禁用。未设置 PRESIDIO_X402_MCP_DECISION_PATH、密钥文件不可读,或签名者拒绝该密钥时,都会记录 ERROR,且不会生成证据。设置 PRESIDIO_X402_MCP_REQUIRE_EVIDENCE_KEY=1,即可在上述任一情况下拒绝启动。服务运行后,如果写入失败,会记录错误,但门禁的判定结果不变:决策记录不会推翻决策本身。
记录内容。 payment-decision@1 始终包含全部五项控制(pii → trusted_wallet → policy → replay → mpa)。每条记录只会为其工具实际运行的检查保存真实判定,其余项均为 NOT_EVALUATED:每种工具都会筛查 URL(pii),check_payment_policy 还会执行 policy,check_payment_replay 还会执行 replay;此处不会评估 trusted_wallet 和 mpa。NOT_EVALUATED 不会导致决策失败,也不代表通过,因此仅凭控制项区块就能看出是哪道门禁作出了决策。通过 prior_decision_refs 将这三项关联起来,即可为每笔付款形成一组相互链接的记录。
记录中绝不会包含的内容。 原始 resource_url、description 或 reason;只会包含 URL 的协议和主机、发现的实体类型标签,以及哈希值(策略快照、重放指纹、付款详情)。门禁会检查传入 URL 中的 PII,但会原样支付,因此其 PII 判定为 PII_WARNED;screen_payment_metadata 会返回脱敏字符串,并记录 PII_REDACTED。MCP 工具无法获取的字段——付款方钱包、网络、原始 402 报价——会记录为 unspecified / not-presented。记录不包含能力链 parents,因此不会设置 ADR-0002 顶层的 parents 字段。
模式
进程内(默认)。 在 MCP 服务所在的同一进程中封装本地 presidio-hardened-x402 库。无需网络、API 密钥或配额。PII 不会离开 Agent 主机。除非有具体理由,否则请使用此模式。
HTTP 代理。 设置 PRESIDIO_X402_MCP_REMOTE_BASE_URL 和 PRESIDIO_X402_MCP_REMOTE_API_KEY 后,screen_payment_metadata 会调用所配置主机上的 /v1/screen(例如 https://screen.presidio-group.eu),以便集中审计。如果发生身份验证、配额或网络故障,则返回结构化内容 { "error": "auth_error" | "rate_limit" | "unavailable", "detail": ..., "mode": "remote" },绝不会静默回退到进程内模式。工具 2 和 3 始终在进程内运行。
可组合性
专为与支付执行和端点安全 MCP 服务配合使用的 Agent 工作流而设计:
agent intent: pay https://api.foo.com/x with 1.50 USDC
│
├─ x402station preflight(url) ← is the ENDPOINT safe? (decoys, dead, traps)
│
├─ presidio-x402 screen_payment_metadata ← is the PAYLOAD safe? (PII)
├─ presidio-x402 check_payment_policy ← within budget?
├─ presidio-x402 check_payment_replay ← not a duplicate?
│
└─ pay()
screen_payment_metadata 为只读工具,可安全地穿插在任何位置。策略门控和重放门控会在调用时记录状态;请将它们安排在支付操作之前立即执行。
这些门控都无法看到的内容:Agent 编造的请求正文。 这三个工具会检查 402 挑战的元数据和支出,但看不到 Agent 发送到 POST 路由的正文。对 x402 和 MPP 目录进行的独立测量(probe402,MCRI #001,2026 年 9 月 1 日)发现,在列出的 8,056 个 POST 路由中,有 1,521 个(18.9%)没有发布可用的请求示例;其中 72% 仍会在门槛处返回可支付报价。这样的路由虽然已列出、已定价,但根据已发布的契约无法通过机器执行。如果 Agent 通过合成正文来填补空缺,那就是在猜测,而猜测出的正文正是用户数据未经检查进入请求的地方。应采取的做法是:如果目录条目没有请求示例或架构,就停在 402 报价处并将其呈现出来;不要为了越过门槛而编造正文。请将此规则写入 Agent 的指令中——这是 Agent 在这些工具运行之前就要作出的决定。
组合代码片段:预检 → 检查 → 支付
端点安全和载荷安全是相互独立的信号;签名前实际需要做的是同时调用两者。并排配置这两个 MCP 服务:
{
"mcpServers": {
"x402station": { "command": "npx", "args": ["-y", "x402station-mcp"],
"env": { "AGENT_PRIVATE_KEY": "0x…" } },
"presidio-x402": { "command": "uvx", "args": ["presidio-hardened-x402-mcp"] }
}
}
签署支付前的 Agent 工作流(伪代码——每个步骤都是一次 MCP 工具调用):
# 1. endpoint safety: is the URL trustworthy? (x402station-mcp)
pf = preflight(url)
if not pf["ok"]:
abort(reason=pf["warnings"]) # decoy / zombie / dead / price-trap
# 2. payload safety: redact PII before it leaves the host (presidio-x402)
s = screen_payment_metadata(resource_url=url, description=description, reason="")
url, description = s["redacted_resource_url"], s["redacted_description"]
# 3. spend gates: record-on-success, call exactly once each (presidio-x402)
if not check_payment_policy(url, amount_usd)["allowed"]:
abort(reason="policy")
if check_payment_replay(url, pay_to, amount, currency, deadline_seconds)["is_replay"]:
abort(reason="replay")
# 4. sign + pay
pay(url, amount, description=description)
这两个服务有意独立开发——关键就在于保持信号之间不相关。请参阅 x402station-mcp,了解预检工具的完整输出架构和警告目录。
开发者须知
- 日志输出到 stderr(MCP 客户端会捕获 stderr)。stdout 保留用于 JSON-RPC 帧。
- 此包是一个轻量适配器。所有安全逻辑都位于
presidio-hardened-x402中——请阅读其文档,了解实体类型目录、策略语义、证据引用验证、SLO broker 和审计链详情。 - 此 MCP 版本公开的三个工具与
0.1.1相同。0.3.0 新增了由这些工具发出的签名payment-decision@1,以及两个门控上的可选prior_decision_refs参数;父库其余的 SLO/证据/能力接口未纳入 MCP。 - 使用
mcp-inspector --cli测试时,裸数字--tool-arg amount=1.50会被自动转换为浮点数,并被架构拒绝。实际 MCP 客户端会发送正确的 JSON 类型;工具的amount参数是字符串,以保留精度。 - 本地开发:
uv venv && uv pip install -e ".[dev]" && pytest tests/。
许可证
MIT。请参阅 LICENSE。
链接
- 本仓库:https://github.com/presidio-v/presidio-hardened-x402-mcp
- 问题反馈:https://github.com/presidio-v/presidio-hardened-x402-mcp/issues
- 父库:https://github.com/presidio-v/presidio-hardened-x402
- PyPI 上的库:https://pypi.org/project/presidio-hardened-x402/
- 需求:PRESIDIO-REQ.md
- 安全策略:SECURITY.md
- MCP 规范:https://modelcontextprotocol.io
- x402:https://x402.org
SDLC
本仓库采用 PRESIDIO 强化系列 SDLC 的开源基线 (报告 · PDF)。 针对本仓库测量的控制项及任何尚未解决的差距,详见适用性矩阵中对应的条目。
路线图(未来 12 个月)
- 当前/进行中 — 达到 OpenSSF Best Practices 银级,并将 Scorecard 提升至 7 分以上:
治理文档、与 Bandit 并行运行的真实 CodeQL 作业、遵循最小权限原则的工作流令牌,以及对配置验证器进行 Atheris 模糊测试。解决
SECURITY-AUDIT.md中剩余的问题。 - 下一步 — 对 CI 依赖项进行哈希固定,最好作为整个系列的变更,而非仅修改本仓库。
- 稍后 (评估中) — 发布带有签名和构建来源证明的版本;随着 MCP 规范趋于稳定,持续跟进;如果 Agent 的需求足以证明增加接口的合理性,则将父级库的
capability-grant@1强制执行机制作为第四个工具开放。
治理、架构、安全
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。