- Category
- AI & MCP
- Platform
- CLI · macOS / Linux / Windows
- License
- MIT
A security gateway and scanner for Model Context Protocol servers. It sits between an MCP client and server, inspects the JSON-RPC traffic, and blocks a message when a critical rule fires. Fully offline: no LLM, no telemetry.
Try it in your browser
The detection rules below are a JavaScript port of the Go rules, running locally in your browser. Nothing you paste leaves the page. The sample data is made up, and the credentials in it are documentation examples or obviously fake.
Paste or edit an MCP message and the rules run as you type. Pick a scenario to start.
Pin the tool set you approved, then let the server change a tool behind your back. Re-scanning compares SHA-256 hashes of each tool against the pin.
A short session replayed through warden proxy. Each message is inspected on its way through; a critical finding stops it at the gateway.
Why runtime, not only static
The common MCP attacks are well known: tool poisoning (hidden instructions in a tool's metadata), rug pulls (an approved tool silently changing its definition), prompt injection delivered through tool results, and credential exfiltration. Existing open-source scanners inspect configs and metadata at install time, so they don't see what actually flows at call time. Gateways mostly handle routing, auth and governance. mcp-warden covers the runtime part: it inspects live traffic in both directions and can stop a message before it reaches the model or the server.
What it checks
| Class | Where | Rule | Severity |
|---|---|---|---|
| Tool poisoning | tools/list response | Instruction-like phrases (9 patterns), or zero-width / Unicode tag characters, in a tool's name, description or input schema | critical |
| Rug pull | tools/list response | A tool's SHA-256 no longer matches warden.lock.json; a tool that was never pinned is reported separately | critical / warning |
| Prompt injection | tools/call result | The same phrases in returned text; invisible characters in results | critical / warning |
| Data exfiltration | tools/call arguments and results, other response bodies | AWS access key IDs, GitHub, Slack, OpenAI and Google API keys, private key blocks, JWTs | critical |
How the proxy decides
- With
blockOnCriticalon, any critical finding replaces the message with a JSON-RPC error (-32001, "blocked by mcp-warden security policy"). If the request is the problem, the server never sees the call. - Warnings are forwarded and recorded in the JSONL audit log.
warden scanexits non-zero on a critical finding, so it can gate CI.
warden pin https://my-mcp-server.example.com/mcp --out warden.lock.json
warden scan https://my-mcp-server.example.com/mcp --lock warden.lock.json
warden proxy --config warden.json # point the client at the proxy instead Offline, zero dependencies
It uses only the Go standard library, with nothing in go.mod. Detectors are pure functions,
so the same input always gives the same findings, and no inspected traffic leaves the process.
Tool hashes are SHA-256 over the JSON of name, description and input schema with sorted keys,
so reordering schema keys doesn't trigger a false rug pull.
Status
Early development (v0.1.0); APIs and rules will change. The proxy only speaks Streamable HTTP for now (no stdio), SSE bodies are scanned as plain text, and pattern matching catches known shapes rather than novel obfuscation. Treat it as one layer of defense, not a guarantee.
About this demo
The phrases, regexes, invisible-character ranges, severities and hashing follow the Go source. The port was run side by side with the Go detectors on a shared set of fixtures, including the repo's own test cases, and produced identical findings and identical tool hashes. Two parts exist only on this page: the diff view in the rug-pull tab (the real lockfile stores only hashes) and the abridged audit log.