presidio-hardened-x402-mcp
A pre-payment safety gate for x402 that screens payment metadata for PII, enforces spending policies, and detects replay attacks before signing.
README
presidio-hardened-x402-mcp
<!-- mcp-name: io.github.presidio-v/presidio-hardened-x402-mcp -->
Pre-payment safety gate for x402 — agents call screen_payment_metadata(...), check_payment_policy(...), and check_payment_replay(...) before signing, catching PII, budget overruns, and duplicate payments before metadata or money leaves the agent host.
Part of the presidio-hardened-* toolkit family. Thin MCP (Model Context Protocol) adapter over the presidio-hardened-x402 library, pinned for parent 0.9.x compatibility (presidio-hardened-x402>=0.9.1,<0.10.0).
Why this exists
x402 agentic payments routinely carry user-supplied free text — descriptions, memos, query-string parameters — straight through to merchants and facilitators. When an LLM agent generates that text, it can include PII the user never intended to share. Once the merchant logs it, retention is their decision, not yours.
This MCP server gives agents a small default-deny gate before payment leaves the agent host. Three tools expose the parent library's stable pre-payment controls: PII redaction, spending policy, and replay detection. They are designed to compose with payment-execution and endpoint-safety MCP servers (x402station, Coinbase x402, Sardis, ...), while newer parent-library surfaces such as evidence-ref@1 verification and the v0.9.1 SLO broker stay in the Python library unless an MCP tool explicitly wraps them later.
Install & configure
Requires Python ≥ 3.10. Distributed on PyPI; recommended invocation via uvx (no global install).
Claude Desktop / Claude Code
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your platform:
{
"mcpServers": {
"presidio-x402": {
"command": "uvx",
"args": ["presidio-hardened-x402-mcp"]
}
}
}
Cursor / Windsurf / Continue
Same shape — every MCP host accepts command / args / env. See your editor's MCP-server docs for the config-file path.
Environment variables
All optional. Defaults give a zero-config in-process mode with no quota, no network, and no PII storage.
| Variable | Purpose | Default |
|---|---|---|
PRESIDIO_X402_MCP_MODE |
regex (zero-setup) or nlp (needs [nlp] extra + a spaCy model) |
regex |
PRESIDIO_X402_MCP_MAX_PER_CALL_USD |
Max USD per single payment (policy gate) | unset → no limit |
PRESIDIO_X402_MCP_DAILY_LIMIT_USD |
Max USD per rolling window (policy gate) | unset → no limit |
PRESIDIO_X402_MCP_PER_ENDPOINT_JSON |
Per-endpoint cap, e.g. '{"api.foo.com": 5.00}' |
unset |
PRESIDIO_X402_MCP_WINDOW_SECONDS |
Rolling window for the daily limit | 86400 |
PRESIDIO_X402_MCP_AGENT_ID |
Label written into audit records | unset |
PRESIDIO_X402_MCP_REPLAY_TTL |
Fingerprint cache TTL (seconds) | 300 |
PRESIDIO_X402_MCP_REDIS_URL |
Use Redis for replay state instead of in-memory | unset |
PRESIDIO_X402_MCP_AUDIT_PATH |
Append-only JSON-L audit log path; omit to disable | unset |
PRESIDIO_X402_MCP_LOG_LEVEL |
DEBUG / INFO / WARNING / ERROR |
INFO |
PRESIDIO_X402_MCP_REMOTE_BASE_URL |
Enable HTTP-proxy mode for tool 1 — see Modes | unset |
PRESIDIO_X402_MCP_REMOTE_API_KEY |
API key for the remote screening service | unset |
PRESIDIO_X402_FINGERPRINT_KEY |
32-byte hex key for cross-process replay detection | unset (per-process) |
PRESIDIO_X402_CHAIN_KEY |
32-byte hex key for cross-process audit-chain HMAC | unset (per-process) |
PRESIDIO_X402_REQUIRE_FINGERPRINT_KEY |
Fail startup if replay key is absent or invalid | unset |
PRESIDIO_X402_REQUIRE_CHAIN_KEY |
Fail startup if audit-chain key is absent or invalid | unset |
Generate cross-process keys with openssl rand -hex 32.
Tools
screen_payment_metadata(resource_url, description, reason, entities?)
Detects and redacts PII in payment metadata. No side effects — safe to call repeatedly.
// Input
{
"resource_url": "https://api.foo.com/u/jane@example.com",
"description": "monthly fee for jane@example.com",
"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"
}
entities (optional list of Presidio entity types) narrows detection to a whitelist. Field-length caps mirror the screening-api wire contract that remains stable through parent 0.7.x: resource_url ≤ 2048, description ≤ 4096, reason ≤ 4096 characters. Oversized inputs raise ValueError.
check_payment_policy(resource_url, amount_usd)
Spending-policy gate. Records the spend on success — call exactly once, immediately before payment. Skipping the actual payment after a successful check inflates the daily-limit ledger until the window rolls over.
// 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 }
check_payment_replay(resource_url, pay_to, amount, currency, deadline_seconds)
Duplicate-payment gate via HMAC-SHA256 fingerprint of the canonical fields. Records the fingerprint on success — call exactly once, immediately before payment.
amount is a string to preserve precision. Cross-process detection requires PRESIDIO_X402_FINGERPRINT_KEY (and optionally PRESIDIO_X402_MCP_REDIS_URL); otherwise each MCP server process keeps its own in-memory store.
// 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..." }
Modes
In-process (default). Wraps the local presidio-hardened-x402 library in the same process as the MCP server. No network, no API key, no quota. PII never leaves the agent host. Use this unless you have a specific reason not to.
HTTP-proxy. When both PRESIDIO_X402_MCP_REMOTE_BASE_URL and PRESIDIO_X402_MCP_REMOTE_API_KEY are set, screen_payment_metadata calls /v1/screen on the configured host (e.g. https://screen.presidio-group.eu) for centralized audit. On auth / quota / network failure, returns a structured { "error": "auth_error" | "rate_limit" | "unavailable", "detail": ..., "mode": "remote" } — never silently falls back to in-process. Tools 2 and 3 always stay in-process.
Composability
Designed to slot into agent flows alongside payment-execution and endpoint-safety MCP servers:
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 is read-only and safe to interleave anywhere. The policy and replay gates record state on call — sequence them immediately before payment.
Combined snippet: preflight → screen → pay
Endpoint-safety and payload-safety are independent signals — calling both is what you actually want before signing. Configure the two MCP servers side-by-side:
{
"mcpServers": {
"x402station": { "command": "npx", "args": ["-y", "x402station-mcp"],
"env": { "AGENT_PRIVATE_KEY": "0x…" } },
"presidio-x402": { "command": "uvx", "args": ["presidio-hardened-x402-mcp"] }
}
}
Agent flow before signing a payment (pseudocode — each step is one MCP tool call):
# 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)
The two servers are developed independently, on purpose — keeping the signals uncorrelated is the point. See x402station-mcp for the preflight tool's full output schema and warning catalog.
Notes for developers
- Logs go to stderr (MCP clients capture stderr). stdout is reserved for JSON-RPC frames.
- The package is a thin adapter. All security logic lives in
presidio-hardened-x402— read its docs for the entity-type catalog, policy semantics, evidence-ref verification, SLO broker, and audit-chain details. - This MCP release intentionally exposes the same three tools as
0.1.1; the compatibility update is dependency and metadata alignment with parent0.7.x, not a promotion of the full parent SLO/evidence surface into MCP. - When testing via
mcp-inspector --cli, bare numeric--tool-arg amount=1.50is auto-coerced to a float and rejected by the schema. Real MCP clients send proper JSON types; the tool'samountargument is a string to preserve precision. - Local dev:
uv venv && uv pip install -e ".[dev]" && pytest tests/.
License
MIT. See LICENSE.
Links
- This repo: https://github.com/presidio-v/presidio-hardened-x402-mcp
- Issues: https://github.com/presidio-v/presidio-hardened-x402-mcp/issues
- Parent library: https://github.com/presidio-v/presidio-hardened-x402
- Library on PyPI: https://pypi.org/project/presidio-hardened-x402/
- Requirements: PRESIDIO-REQ.md
- Security policy: SECURITY.md
- MCP spec: https://modelcontextprotocol.io
- x402: https://x402.org
SDLC
This repository is developed under the Presidio hardened-family SDLC: https://github.com/presidio-v/presidio-hardened-docs/blob/main/sdlc/sdlc-report.md.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。