@routescore/mcp
v0.3.5
Published
Read-only pre-sign evidence — a "pre-sign journal" — for onchain agents. Free check_swap MCP server for Claude, Codex, Cursor & any MCP-capable agent.
Maintainers
Readme
@routescore/mcp
The read-only pre-sign evidence layer — a "pre-sign journal" — for onchain agents.
Before an agent (or you) signs a swap onchain, check_swap returns a modeled
read of route quality, MEV/execution exposure, and token-registry recognition as
a clear / caution / unsupported verdict with its caveats — and persists a
hash-verifiable record of exactly what was known before signing, re-verifiable
offline. That record is the pre-sign journal. It is read-only: it never signs,
executes, routes funds, or custodies assets.
An MCP server (and a keyed REST API) for Claude, Codex, Cursor, and any MCP-capable agent — a thin, stateless wrapper around the Routescore public API, storing no request or response data locally.
check_swap is free. A free account runs 100 pre-sign checks/day (Pro
1,000/day, Power 10,000/day), shared across its keys; each key also has a
per-minute burst limit. The modeled premium-estimate tools,
simulate_scenario, and persisted-record retrieval are Power-tier. Generate a
key at Account → Developer → API & MCP access (/account) — free to mint on
any plan. Keys look like rs_live_… and are shown once.
See how these modeled reads have tracked measured on-chain outcomes on the public calibration surface — Routescore publishes its own accuracy (Brier score, ECE, coverage), re-derivable from a bound source manifest.
Setup
Add the server to your MCP client config and set your key in the env block.
Claude Desktop (claude_desktop_config.json) / Cursor (.cursor/mcp.json):
{
"mcpServers": {
"routescore": {
"command": "npx",
"args": ["-y", "@routescore/mcp@latest"],
"env": {
"ROUTESCORE_API_KEY": "rs_live_your_key_here"
}
}
}
}Claude Code (CLI):
claude mcp add routescore --env ROUTESCORE_API_KEY=rs_live_... -- npx -y @routescore/mcp@latestOptional env:
ROUTESCORE_API_URL— override the API base (defaulthttps://www.routescore.io). Useful for local development:http://localhost:3000.
The server checks the key at startup: if ROUTESCORE_API_KEY is missing or
does not match the minted key shape (rs_live_ followed by 64 lowercase hex
characters), it exits immediately with an actionable error instead of
failing on the first tool call. The configured value is never echoed. This
is a shape check only — real key verification stays server-side (run the
whoami tool).
Hosted HTTP endpoint (no install)
For registries, hosted agents, and evaluation harnesses that can't spawn a local
process, the same server is available over Streamable HTTP at
https://www.routescore.io/api/mcp — no npx, no install. Send JSON-RPC over
POST; discovery (initialize, tools/list) needs no key, and tools/call
takes your key in the Authorization header:
curl -s -X POST https://www.routescore.io/api/mcp \
-H 'content-type: application/json' \
-H 'authorization: Bearer rs_live_...' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_swap","arguments":{"notional_usd":1000,"chain_id":1}}}'Same tools, tiers, and quotas as the stdio package. It is stateless and read-only — it never signs, executes, or holds keys.
Tools
check_swap is the primary tool — the pre-sign check an agent runs right
before it signs. The other tools support it: retrieve its record, verify your
key, or add Power-tier modeling. MCP clients surface check_swap first.
| Tool | What it does |
|---|---|
| ⭐ check_swap | Primary — call before signing an onchain swap. Modeled route quality, price-impact / slippage band, modeled MEV/execution exposure where observable, and a token registry read (recognized vs unverified), as a clear / caution / unsupported verdict. Supports Ethereum (1) and Robinhood Chain (4663). Recognition is not safety, sellability, rights, redemption, liquidity, or investment-quality verification. Decision support, not execution. Every keyed call also attempts to persist a hash-verifiable evidence record and returns its record_id, evidence_bundle_id, and record_output_hash — null, with a record_persistence_failed caveat, if the record store is unavailable. |
| get_preflight_record | Fetch one persisted preflight evidence record by record_id (owner-scoped to the configured key's account). The record embeds the original check response verbatim plus a canonical-JSON SHA-256 integrity hash so the evidence can be re-verified offline. Read-only evidence: record creation rejects known execution-material keys (calldata, transaction payloads, signing material) and drops identity-shaped labels from the actor context. |
| whoami | Confirm the key works and report its plan tier. |
| get_detector_manifest | Latest public MEV-detector run manifest (version hash + universe). |
| quote_mev_cover | (Power) Modeled premium estimate for MEV-sandwich exposure on a swap (modeled premium, expected/CVaR loss). |
| quote_bridge_refund | (Power) Modeled premium estimate for cross-chain bridge execution failure vs a modeled SLA expectation. |
| quote_lrt_slashing | (Power) Modeled premium estimate for slashing risk on an LRT position given AVS exposure. |
| simulate_scenario | (Power) What-if Monte Carlo: modeled expected premium vs refund/loss over a horizon. |
Each tool also carries MCP annotations: only check_swap is marked non-read-only
and non-idempotent (it persists a record); every other tool is a read.
All quote_* tool results are modeled, point-in-time premium estimates —
decision support only, not a live cover, insurance, refund, or
premium-acceptance offer. Routescore does not underwrite risk.
Output contract
Routescore MCP is decision support, not execution infrastructure. check_swap,
quote, and scenario tool results preserve the same trust envelope as the REST API, and the
wrapper marks output as degraded if the upstream API ever omits required trust
fields.
check_swap answers verdict: unsupported as an HTTP 422 with a full
evaluated body — an answer, not an error. The wrapper relays those evaluated
422 bodies as normal structured tool results (gap-state fields, caveats, and
record linkage included) so agents receive "not evaluated" as first-class
evidence; true errors (400/401/403/404/429/5xx and non-evaluated 422 error
envelopes) still surface as tool errors.
Downstream agents and dashboards should render the trust-envelope fields by default (abbreviated example):
{
"score_state": "partial",
"source_freshness": {
"state": "partial",
"checked_at": "2026-06-21T00:00:00.000Z",
"sources": [
{ "name": "routescore_backend", "freshness_state": "fresh" },
{ "name": "bridge_risk_labels", "freshness_state": "unknown" }
]
},
"methodology_version": "routescore.public_api.v1",
"confidence_band": { "low": null, "high": null, "unit": "bps" },
"caveats": [
"Modeled, point-in-time decision support. Not an execution guarantee.",
"Unsupported or stale inputs widen uncertainty instead of hiding risk."
],
"commercial_disclosure": {
"paid_placement": false,
"score_influenced_by_partner": false
}
}Integration patterns
Routescore sits between an agent's plan and its executor. It is read-only —
it never signs, routes funds, or holds keys — so it drops into an existing
agent without changing the execution path. The shape is always
plan → check_swap → (the agent decides) → execute → record.
1. Virtuals (GAME / ACP) planner → Routescore → executor
A Virtuals agent proposes a swap; before the executor signs, it calls
check_swap and relays the verdict. The executor is unchanged.
// the planner calls this before handing the swap to the executor
{
"tool": "check_swap",
"arguments": {
"notional_usd": 25000,
"chain_id": 4663, // Robinhood Chain
"route": "uniswap-v3-rho",
"token_out": "0x…" // RHC tokenized asset address
}
}// check_swap returns — relay verdict + reasons + caveats verbatim
{
"verdict": "caution",
"reasons": ["price_impact_above_band", "token_unverified"],
"caveats": ["Modeled, point-in-time decision support. Not an execution guarantee."],
"record_id": "…",
"record_output_hash": "…"
}The agent decides whether to proceed and keeps record_id as evidence of what
it knew before signing.
2. Coinbase AgentKit action → Routescore record
Expose check_swap as an AgentKit action provider inside the agent's action
loop. On each proposed swap the action returns the verdict; because every call
persists a hash-verifiable record, the agent's action history carries a
reviewable pre-sign trail. Fetch any entry later with get_preflight_record.
3. DEX aggregator (e.g. 1inch) route → Routescore evidence → wallet signing
After the aggregator returns a route but before the wallet signs, call
check_swap with the chosen route and token_out. Surface a
caution / unsupported verdict next to the signing prompt — the wallet
signing path stays exactly as it was.
Routescore is one element of the agentic stack, not the executor: it produces a reviewable record of what was known before signing, and the agent still owns the decision.
Local development
npm install
npm run build
ROUTESCORE_API_KEY=rs_live_... ROUTESCORE_API_URL=http://localhost:3000 node dist/index.jsThen point MCP Inspector at the command, or wire it into a client config as above.
Public Reddit research utility
The retail-research workflow includes a standard-library parser for a saved, publicly rendered old Reddit thread. It extracts public handles, comment counts, IDs, and permalinks without logging in or attempting to recover deleted authors:
python3 scripts/scrape_reddit_public_handles.py /path/to/thread.html \
--csv work/reddit-public-handles.csv \
--json work/reddit-public-handles.jsonThe input must be HTML already obtained from a public old.reddit.com thread.
The parser does not fetch pages or bypass Reddit access controls.
Notes
- Scenario and quote outputs are modeled decision-support, not investment advice.
- MCP does not custody assets, execute transactions, route funds, or guarantee outcomes.
- Daily
check_swapquotas apply per account; per-minute burst limits apply per key. Responses carryX-RateLimit-*andX-RateLimit-Daily-*headers.
