← All projects

mcp-warden

Runtime security gateway for MCP

Tang Yijia (Tom)

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.

Web demoScanner catching tool poisoning
Web demoProxy replay blocking an injection

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.

Scenarios

Message JSON
Findings

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

ClassWhereRuleSeverity
Tool poisoningtools/list responseInstruction-like phrases (9 patterns), or zero-width / Unicode tag characters, in a tool's name, description or input schemacritical
Rug pulltools/list responseA tool's SHA-256 no longer matches warden.lock.json; a tool that was never pinned is reported separatelycritical / warning
Prompt injectiontools/call resultThe same phrases in returned text; invisible characters in resultscritical / warning
Data exfiltrationtools/call arguments and results, other response bodiesAWS access key IDs, GitHub, Slack, OpenAI and Google API keys, private key blocks, JWTscritical

How the proxy decides

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.