@vet402/mcp-server
MCP tools for checking vet402 trust scores from Claude
Desktop, Cursor, or any MCP client — so an agent can ask "is this wallet safe
to pay?" before it pays.
Published on npm. No clone, no build: your MCP client launches it with npx.
npm install -g @vet402/mcp-server
Tools
check_agent_trust | Score by agent ID (optional wallet verification) |
check_wallet_trust | Score by wallet (x402 payer path) |
check_payee_trust | Buyer-side: score a payment recipient before paying it (score + dataDepth + recommendation + degraded / signalsUnavailable) |
explain_trust_score | Human-readable score breakdown (includes x402 + dataCoverage) |
attest_x402_payment | Write settlement attestation after payment verification |
pay_if_trusted | ETHOnline 2026 window (2026-09-05) — the same gate as check_resource_decision, but it holds the signer. On anything other than ALLOW the payment module is never loaded, so no signature can exist. Refusals are machine-readable and happen before a signature. Delegates the payment itself to payOrRefuse in @vet402/sdk. Signing requires VOUCH_PAYER_PRIVATE_KEY and viem; without them the gate still runs and refuses with payer_not_configured. Settlement is reported as settle_claimed — never settled, which only an on-chain re-read may write. Since 2026-09-06 it also takes policy (requireVet402Allow, evidence.source / minSubgraphReceipts / minL1Deliveries), forwarded to payOrRefuse unchanged: source: "subgraph" reads The Graph's x402 Base subgraph (key from GRAPH_API_KEY) and returns that read on decision_record.evidence[]. A seller outside the catalogue (/decision 404) is judged too when resource is given: the SDK reads the 402's payTo, that address's payee score and the caller's floors (reason_codes carries resource_uncatalogued); without resource a 404 refuses with evidence_unavailable |
check_resource_decision | 0.2.0 — Product spec §9.1: pre-payment decision for one x402 resource (resourceId = sha256 hex from /api/v1/resolve?q=<url>). Returns decision (ALLOW_PAY | REFUSE), safe_to_pay, refuse_reasons, and the full measurement body (L0–L2 facts, reason_codes, freshness, evidence, rules_version). role=payee + payer asks the seller-side question instead. Since 2026-09-07 it also takes your own policy — amountUsd, maxPerTxUsd (default 1), minL1Deliveries, requireVet402Allow (default true; false waives a WARN and needs minL1Deliveries ≥ 1) — which the server applies and returns as measurement.caller_policy in the SDK's words (price_above_ceiling, evidence_unavailable, payee_recommendation_block, payee_recommendation_not_allow, insufficient_delivery_evidence); a caller_policy REFUSE makes the tool REFUSE with those words in refuse_reasons |
Reading a check_payee_trust result
The tool returns the API body verbatim. Two of its fields override
recommendation, and the tool description tells the model so:
degraded: true — an input could not be read at all; the body is a refusal,
not a measurement.
signalsUnavailable non-empty — some inputs were not measured
(wallet_metrics, native_drain, usdc_drain, outcome_history); the view
is partial.
Either one means the payee was not fully checked, and an unchecked payee is not
a safe one. The same goes for a tool error, including lookup_timeout: no
answer is not an ALLOW.
Setup — Claude Desktop
Get a key at vet402.com/dashboard/keys,
then add this to ~/Library/Application Support/Claude/claude_desktop_config.json
(%APPDATA%\Claude\claude_desktop_config.json on Windows) and restart the app:
{
"mcpServers": {
"vouch": {
"command": "npx",
"args": ["-y", "@vet402/mcp-server"],
"env": {
"VOUCH_API_URL": "https://vet402.com/api/v1",
"VOUCH_API_KEY": "vouch_live_your_key_here"
}
}
}
}
Setup — Cursor
Same block in ~/.cursor/mcp.json (or a project-local .cursor/mcp.json):
{
"mcpServers": {
"vouch": {
"command": "npx",
"args": ["-y", "@vet402/mcp-server"],
"env": {
"VOUCH_API_URL": "https://vet402.com/api/v1",
"VOUCH_API_KEY": "vouch_live_your_key_here"
}
}
}
}
Confirm it starts before wiring it into a client:
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}' \
| VOUCH_API_KEY=vouch_live_your_key_here npx -y @vet402/mcp-server
A serverInfo line comes back on stdout. The package also installs a
vet402-mcp binary, if you prefer npx -p @vet402/mcp-server vet402-mcp.
Environment
VOUCH_API_KEY | — | Optional since 2026-09-07: check_resource_decision and pay_if_trusted read /decision key-less (10/min per IP, then 429 rate_limited). The score and attest tools still need one (the API answers missing_api_key). Create one here. |
VOUCH_API_URL | https://vet402.com/api/v1 | API base URL. Override only to point at another deployment. |
GRAPH_API_KEY | — | Graph Gateway key for pay_if_trusted when policy.evidence.source is "subgraph" or "both". Read from env only — never from tool input, so it never enters the model's context. Without it such a call refuses with graph_key_not_configured before reading anything (2026-09-06). |
VOUCH_TIMEOUT_MS | 10000 | Per-request timeout. Cannot be disabled — a lookup that never returns cannot be failed closed on. A malformed value falls back to the default rather than breaking every tool call. |
0.1.0 defaults VOUCH_API_URL to http://localhost:3000/api/v1 — a
development default that shipped by accident. The configs above set it
explicitly, so they are correct on every version; 0.1.1 and later default to
the hosted API.
Example prompts
- "Check trust for agent 42 on Base"
- "Is wallet 0xabc... safe to accept x402 payment from?"
- "Is it safe to pay wallet 0xdef...? Check its payee trust first"
- "Explain the trust score for agent 7"
Building from the repo (contributors)
git clone https://github.com/kzmttkc/vet402.git
cd agent-trust/packages/mcp-server && npm install && npm run build
Links
MIT · vet402