The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Devmcp listing page.
Listed on the official MCP Registry as io.github.rudranaresh0201/verimcp and io.github.rudranaresh0201/devmcp.
Watch the console → — a recorded session replaying in the browser: three verified calls, five caught lies, one honest backend error.
MCP tool calls are trusted by default, in two different ways that both bite in production agent workflows:
isError: false only means the tool didn't crash, not that it did what it claimed. An agent wired up to git, CI, or infrastructure through MCP is one confidently-wrong tool response away from acting on a lie.tools/call after an ambiguous response (a timeout, a dropped connection), nothing in MCP stops the backend from just running it again — a second commit, a second CI run, a second charge. The protocol has no concept of "didn't I already do this?"verimcp is a transparent proxy that sits between an MCP Host and a backend server and forwards every message unchanged, except for two independent checks around each call:
--idempotent-replay, see Proof below.devmcp is the backend it's proven against — a real git/CI MCP server, deliberately built with the full protocol surface (tools, resources, prompts, roots, sampling), because a proxy is only as convincing as what it's shown catching.
Both are independently installable and have no import dependency on each other — verimcp works in front of any MCP backend (proven against the official mcp-server-git too, not just devmcp), and devmcp works with any Host directly, unproxied.
Two runnable benchmarks, real subprocess pipes, no mocks — the numbers below are what they actually print, gaps included:
Claim-acceptance — a real MCP Host with no verification layer accepts 100% of fabricated results by construction; that's not a benchmark artifact, it's the actual gap in the protocol:
The 79%, not 100%, is deliberate and stated in the script's own output: 3 of the 14 scenarios exploit documented, principled gaps in specific verifiers (e.g. a hash-exists check can't tell this call created the hash vs an old one) — named plainly rather than hidden, because a tool claiming a perfect score on its own benchmark is the real red flag.
Retry-duplication — same idea applied to --idempotent-replay, against 5 realistic non-idempotent side effects (a counter bump, a notification send, an invoice increment, an audit entry, a two-step pipeline):
scripts/demo.py is the smaller, narrative version of the same proof — one fabricated commit hash caught, one real write confirmed and passed through unchanged. tests/test_adversarial_corpus.py and tests/test_proxy_integration.py run the same claims through the real proxy pipe in CI on every commit, not just on demand.
write_file (disk hash-compare), git_commit/git_branch (re-derived from real git state), run_ci_pipeline (self-consistency + re-execution of steps marked safe to re-run), plus resource reads (repo://status, repo://log, repo://file/{path}). New verifiers are a plugin system (importlib.metadata.entry_points, the same mechanism pytest/Black use) — see docs/writing-a-verifier.md.--idempotent-replay) — a retried tools/call is only ever answered from cache if the previous identical call was independently verified true by the checks above; a key match with no prior verified success is a cache miss, not a false dedupe. Adapted from arXiv:2608.02645, moved to the proxy layer so it works for any Host/backend pair verimcp fronts, not just one agent framework's own retry wrapper.elicitation/create).verimcp://audit MCP resource; verimcp replay re-runs recorded traffic against a new policy to backtest "would this have changed anything."Deeper design reasoning (why prompts/roots get no verifier on principle, why policy is a separate concept from verification, etc.) lives in docs/adr/ for anyone who wants to go that deep — the summary above is everything needed to use or evaluate the project.
As a user — install straight from PyPI:
Note on names: the PyPI distribution is
devmcp-server(devmcpwas blocked by PyPI's typosquat-similarity check against an unrelated existing package), but the Python import and CLI command are both still plaindevmcp— nothing above changes if you're reading devmcp's own source.
Use it with Claude Desktop, Claude Code, or Cursor — after pip install,
add devmcp as an MCP server the normal way, just point its command at
verimcp instead of devmcp directly:
claude_desktop_config.json (macOS:
~/Library/Application Support/Claude/claude_desktop_config.json, Windows:
%APPDATA%\Claude\claude_desktop_config.json).claude mcp add devmcp -- verimcp --root /path/to/your/repo -- devmcp --repo-path /path/to/your/repoFrom then on your assistant sees write_file, git_commit, git_branch,
run_ci_pipeline, sqlite_*, and docker_* as normal tools — no prompting
change needed — except every claim those tools make gets independently
re-checked before the assistant is told it succeeded.
In Docker — no local Python/git needed:
As a contributor — editable installs from this repo:
Omitting --otel-exporter entirely means zero telemetry overhead — the default, same as every other opt-in flag here.
The console reads the audit log verimcp already writes and streams it to a browser — verdict, tool, arguments, and the evidence each verdict rests on.
verimcp-console.onrender.com replays a recorded session. It is a recording, not a live agent, and the UI says so: the log it serves was produced by scripts/demo_audit_log.py driving the real proxy in front of the real devmcp server and the adversarial fixture, so every event on screen came from the code path a real run uses. A dashboard screenshot of invented events would be exactly the kind of unearned claim this project exists to catch. (Free instance — the first load after an idle spell takes ~30s to wake.)
Against your own session:
The console never talks to the proxy directly. verimcp speaks MCP over stdio to exactly one Host, and a second reader on that pipe would corrupt the session, so the audit log is the supported out-of-band surface (ADR 0004) — reading a file cannot perturb what it observes, which matters for a tool whose whole claim is that it does not interfere.
Send the same tools/call twice in a row (same tool, same arguments, new request id — exactly what a client resending after a timeout looks like on the wire). The first call runs for real; the second is answered from the confirmed result without touching the backend again. Omit the flag for the unchanged default: every retry is re-executed, same as before this existed.
See CONTRIBUTING.md — dev setup, how to add a verifier, this project's ADR discipline, and commit/PR conventions. See CHANGELOG.md for release history.
MIT — see LICENSE.