The committed fs-git run, replayed: a public issue taints the agent context, and your private folder leaves through git.push. The transcript is in docs/live-evidence/.
One run
Config in, route out, grant revoked.
One run, end to end: the config goes in, the query names the route tool by tool, and one revoked grant closes it. Every line below is copied from the committed run in docs/live-evidence/.
config fs-git · A public issue steers the agent through the private folder out to a public repo
graph scan_fs-git · 11 nodes · 9 edges · ready
01 · config in
LEAK PATHS
1 4 hops project folder → filesystem.read → context → git.push → public repo
1 route found — every one of them is a permission you granted.
02 · route found
FIX · CALL algo.maxFlow on FalkorDB
max-flow 2
cut write side · git.push → public repo
revoke git.push
verified 0 of 1 routes remain (leak query re-run without git.push)
tasks 3 of 4 keep working
03 · cut verified
Why this matters
The leak needs no bug, only the arrangement.
When an AI agent can read text a stranger wrote, read your private data, and send data somewhere public, a hidden instruction can make it leak that data. Simon Willison calls this the lethal trifecta.
It has happened with real tools. A malicious GitHub issue made an agent copy private-repo contents into a public pull request (Invariant Labs, May 2025), and a support ticket made a Cursor agent paste database tokens back into the ticket (General Analysis, July 2025). Neither needed a bug in the server; Invariant notes GitHub “cannot resolve this vulnerability through server-side patches.”
The same pattern appears without an attacker. In a controlled study of multi-server MCP agents, depending on the model, 11.5–41.3% of runs passed credentials across server boundaries even when the task left room to redact them (MCPHunt, arXiv 2604.27819). Meta’s Agents Rule of Two and OWASP’s LLM06 Excessive Agency point to the same remedy: don’t give one agent session all three abilities, and remove permissions it doesn’t need.
How it works
LethalPath turns your MCP config into a graph of tools, data and the agent’s context. One Cypher query lists every route from untrusted input, through the context, from private data to a public destination. FalkorDB’s max-flow then picks the cheapest permissions to remove, weighted by the workflows you declare, and the same query is re-run to confirm zero routes are left. You get a list of grants to revoke, not a score.
Limitations
- Tool labels come from 35 name-based rules and built-in tool lists for 11 common servers. They are not verified against server code; unknown tools are named as unlabelled, not trusted.
- The test results below are on synthetic configs we generated. Accuracy on real users’ setups is not measured yet.
- The runtime guard is a demo: it answers with simulated tool results and does not sit in front of real servers yet.
- It finds structural routes. It does not detect malicious packages or predict whether a model will be fooled.
- Prior work: MSCC also maps cross-server paths, Snyk Agent Scan flags each risky capability, and CaMeL gives stronger guarantees by redesigning the agent. LethalPath adds the computed, verified minimum fix. See Limits.
Test results (synthetic)
40 configs from a seeded generator, ground truth known by construction.
Both suites ran against FalkorDB 6.0.2. The JSON is committed at packages/eval/results/*.json. This shows the engine is consistent, not that it is accurate on real setups.
seeded scan cases — every planted route found
detection.json
fixes verified — route closed, expected tasks kept
fix-quality.json
clean synthetic configs answered with zero routes
detection.json
Install
Run it locally.
The packages are not on npm. You need a clone of the repo, Docker (for FalkorDB), Node 20 or newer, and pnpm 9. Build once, then scan.
Apache-2.0 · pinned to falkordb/falkordb:6.0.2 · the guard is a demo with simulated tool calls
# clone, start FalkorDB, build git clone https://github.com/bhanu-dev82/lethalpath && cd lethalpath docker compose up -d pnpm install && pnpm build # find every leak path, then the grants that close them node packages/cli/dist/index.js scan node packages/cli/dist/index.js fix # guard demo: simulated tool calls, no real servers behind it pnpm --filter @lethalpath/guard demo