Picture an agent session over twenty-four hours. You wrap three local servers for filesystem, github, and postgres. Across 142 tool calls, the proxy logs every tool call locally. It flags a hidden instruction tucked inside a read_file tool description. It catches three separate attempts by the agent to call delete_repo on the github server, an unknown tool missing from the server manifest.
Inspection takes zero trust.
a local firewall
I built mcp-guard to place an explicit verification layer between your AI client and your local MCP servers. It is an open source proxy under the MIT license, built for Python 3.10 or newer with zero runtime dependencies. It wraps stdio servers in place, records argument names, flags poisoned tool descriptions, and blocks rule violations when enforce mode is active.
Installation takes two commands.
pip install mcp-integrity
mcp-guard init
Restart your client and check status.
mcp-guard status
mode: audit (nothing is blocked; run 'mcp-guard enforce' to block)
servers: filesystem, github, postgres
last 24h: 142 calls, 0 would-block, 1 suspicious description, 0 changed tools
would block:
github delete_repo unknown_tool x3
suspicious:
filesystem read_file hidden_instruction
changed tools: none
Audit mode is the default. Nothing breaks. The proxy logs every tool invocation to ~/.mcp-guard/audit.jsonl with argument names only, never values. You inspect the stream with mcp-guard log, which prints entries in structured format and supports tail or follow flags. When you want active enforcement, run mcp-guard enforce to reject violating calls with an MCP error response. Run mcp-guard audit to return to passive logging. You can also wrap an individual server manually with mcp-guard run -- <server_command>.
four structural rules
The engine checks four concrete rules across the wire.
The unknown_tool check catches calls to tools missing from the server manifest and blocks them in enforce mode. The extra_argument check flags calls containing arguments not defined in the tool schema and blocks them in enforce mode. The tool_changed check detects rug-pull attacks where a server silently altered a tool schema or description after the first run, comparing against pinned hashes in ~/.mcp-guard/pins. When a tool update is legitimate, you inspect and accept the new hash with mcp-guard pin –accept. The suspicious_description check scans descriptions for prompt injection heuristics like hidden instructions, sensitive paths, exfiltration targets, invisible unicode, and cross-tool references.
Because heuristic scanners generate false positives, suspicious descriptions only warn.
explicit boundaries
Every security tool needs clear operational boundaries.
The proxy does not see your chat messages, so it cannot verify whether arguments match what the user requested. That verification exists in the underlying research and will ship as a library API for developers who run their own agent loop. The proxy does not inspect tool results returned by the server. It does not protect remote HTTP or SSE servers yet. The heuristic scanner can miss novel attacks.
If you decide to remove protection, mcp-guard uninstall restores each client configuration from its original backup file. Clean rollback matters.
the empirical foundation
I grounded this tool in concrete research data. In FAULTLINE P8, we evaluated client-side provenance contracts on the MCPTox benchmark. That contract cut pooled attack success from 30% down to 7% across six models. The mcp-guard proxy implements the subset of that contract that operates without inspecting user chat turns.
You can run the proxy today from mcp-guard or audit the repository on GitHub. Code beats blind trust.
