Open source · runs locally · powered by FalkorDB

The leak is a path.
Close it with the fewest permissions.

An agent that reads a public GitHub issue, can read your private files, and can push to a public repo can be steered into publishing those files. LethalPath finds that route in your MCP config, then the smallest set of permissions to remove, weighted by the workflows you tell it you need.

Install the CLI See an example scan

What goes wrong

read issue read files publish each one, you would approve
Fine alone. Read a public issue. Read your folder. Publish. Three ordinary grants.
issue agent notes public one sentence is the instruction the folder is the payload
Dangerous together. A stranger’s sentence rides into the agent’s notes, and your files leave with it. No tool misbehaved.
revoke publish 3 of 4 tasks keep working
Turn off the fewest. On the committed run, revoking git.push closes the route. The other work stays.

Why it matters: switching every tool off stops the leak and also stops the agent. The useful answer is the smallest set to switch off, then a second query that shows the leak is gone.

lethalpath scan · live path FalkorDB 6.0.2
1 · A STRANGER 2 · YOUR AGENT 3 · YOUR DATA public issue github read agent context filesystem write private files git push public repo
Route closed. The files stay private.
0 / 7

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/.

scan

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

path

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

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.

Four published incidents, replayed as fixtures
published incidentroutes foundcomputed cut (revoke)tasks kept
GitHub MCP, 2025-05-261github.create_pull_request2 of 3
Supabase MCP, 2025-07-082supabase.execute_sql0 of 1
WhatsApp MCP, 2025-04-071whatsapp.send_message2 of 3
Postmark npm, 2025-09-25Out of scope: a malicious package that copied every email with no injection involved. A scan does not detect it; the fix is removing the package.

Reconstructions from the write-ups, not reproductions. Each fixture is in data/fixtures/incidents/, with commands and limits in docs/incident-replay.md. Tasks kept counts workflows declared in each fixture.

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.

40 of 40 seeded scan cases passed

seeded scan cases — every planted route found

detection.json

40 of 40 fixes verified

fixes verified — route closed, expected tasks kept

fix-quality.json

8 of 8 clean configs answered with zero routes

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

terminal
# 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