Autonomous agents are powerful and unnerving for the same reason: you cannot see what they are about to do until it is already done. Foreguard sits between any MCP host and its tool server. Read-only calls pass straight through. Mutating calls are intercepted and previewed, showing the concrete effect rather than a bare verdict.
cargo install foreguard
Then put it in front of the tool server your agent already uses. No agent changes, no prompt changes.
{
"mcpServers": {
"filesystem": {
"command": "foreguard",
"args": ["proxy", "--", "npx", "-y",
"@modelcontextprotocol/server-filesystem", "/path"]
}
}
}
Most defenses scan text, trying to recognise a malicious instruction by how it reads. That is
an arms race against natural language. Foreguard ignores what the text says and tracks
where it came from. With --taint, output from untrusted sources such as a
web fetch, an inbox read, or RAG retrieval is marked. If that data later turns up inside a
mutating call, it has violated Meta's Agents "Rule of Two", and the call stops for a human.
⛔ RULE-OF-TWO VIOLATION this mutation carries untrusted data (`attacker@evil.com`); forcing human approval. ⚠ `send_email` (high risk) · sends to attacker@evil.com Execute this for real? [y/N] ✗ denied, dry-run, nothing executed
Approve instead, and the exact call you previewed is what executes. Nothing is re-planned or re-generated between the preview and the action.
Sit between host and tool server. Mutations are previewed with their concrete effect and never executed.
Each mutation pauses for a decision on your terminal. Only an explicit yes runs it.
Track provenance. Untrusted data reaching a mutating call forces approval automatically.
Append a JSON line per call: what was asked, how it was judged, and what happened.
Replay a recorded ledger against a live server, running the same calls you already reviewed.
Score a batch of proposed tool calls offline and get a Mutation Plan, with JSON output.
Taint tracking is best-effort, not sound, and saying so is the point. Foreguard sees tool inputs and outputs, not the model's hidden reasoning, so data the model paraphrases or re-encodes can slip a substring match. What it reliably catches is the common, un-laundered path from untrusted input to mutating action.
Where it is uncertain, it fails safe. A tainted mutation with no terminal attached is denied rather than executed. The ledger is an audit log, not a tamper-proof one.
A security tool that overstates its guarantee is worse than one that draws the boundary clearly and then holds it.
Foreguard does not reinvent the engine, it extracts one. The fail-safe, deny-wins tool classifier comes from kedge, a deterministic AI-agent harness. Same code, one source of truth, published as a dependency rather than forked.