cd /news/ai-safety/kevlar-mcp-firewall-for-llm-s · home › topics › ai-safety › article
[ARTICLE · art-156995] src=github.com ↗ pub= topic=ai-safety verified=true sentiment=↑ positive

Kevlar = MCP Firewall for LLM's

Ablation-Tool released Kevlar, an open-source proxy firewall for the Model Context Protocol (MCP) that sits between an LLM client and MCP servers to block tool-poisoning and prompt-injection attacks. Kevlar strips every tool `description` field to an empty string on `tools/list` responses, scans `tools/call` results against roughly 60 injection indicators sourced from published prompt-injection research, blocks outbound calls carrying credentials, and in strict mode locks the tool registry after the initial handshake so servers cannot inject new tools mid-session. The tool requires Python 3.10+ and runs on Linux and macOS only, with strict, lenient and audit modes whose reject thresholds are scores of 40, 80 and never-block respectively.

read3 min views3 publishedOct 24, 2026
Kevlar = MCP Firewall for LLM's
Image: Michielbdejong (auto-discovered)

Kevlar is a proxy firewall for Model Context Protocol

LLM  [ KEVLAR ]  MCP

It sits between (you) and (everyone else)

MCP servers control their own tools.

Those tools (good or bad) go into your LLM blindly, due to trust.

Any MCP server can exploit this to redirect the model, pull credentials, or add any tools they want.

The MCP spec does not prevent any of this.

You do not control what an MCP server puts in its messages.

TL;DR #

Kevlar sits between client and server and does four things:

  1. Strips all tool descriptions before they reach the LLM. No exceptions.
  2. Scans tool call responses for injection payloads and either redacts matched spans or blocks the response entirely.
  3. Blocks outbound calls carrying credentials in their arguments, even if the LLM has already been compromised.
  4. Locks the tool registry after the initial handshake so the server cannot inject new tools mid-session.

CDR on tools/list #

Kevlar strips every description field to "" unconditionally on every tools/list response, before the message reaches the client. The LLM sees name and inputSchema only. inputSchema is rebuilt from an allowlist: prose fields like description, title, examples, and $comment are stripped there too, and enum values, property keys, $ref targets, and type values are validated against the MCP spec. Score 0 on this pass cannot be achieved by adding description text back, because description text is never forwarded regardless of score.

Analysis on tools/call responses #

Tool call results cannot be stripped without breaking functionality. Kevlar scans them against ~60 indicators sourced from published prompt injection research. Responses scoring above the mode threshold are quarantined (matched spans replaced with [KEVLAR:<ID>] tokens) or rejected (replaced with an isError block). Unicode bypass attempts using characters that normalize to injection text under NFKC are detected before normalization and redacted after.

Egress DLP #

Outbound tools/call arguments are scanned before the call is forwarded to the server. If the LLM has already been compromised and is trying to exfiltrate credentials, the call is blocked at the proxy layer. The server never receives it. Runs in all three modes.

Tool registry lock (strict mode) #

After the initial tools/list handshake, the set of callable tool names is frozen. notifications/tools/list_changed from the server is dropped, not forwarded. Any call to a tool not in the CDR-sanitized set is blocked with a synthetic isError response regardless of call content.

Install #

git clone https://github.com/Ablation-Tool/kevlar.git
cd kevlar
pip install .

Requires Python 3.10+. Linux and macOS only. Depends on os.killpg and asyncio.connect_read_pipe.

Quickstart #

kevlar --mode strict -- npx -y @modelcontextprotocol/server-filesystem /tmp
kevlar --mode audit --log /tmp/kevlar.jsonl -- uvx mcp-server-git

Claude Desktop integration #

In ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "filesystem": {
      "command": "kevlar",
      "args": [
        "--mode", "strict",
        "--log", "/tmp/kevlar-filesystem.jsonl",
        "--",
        "npx", "-y", "@modelcontextprotocol/server-filesystem",
        "/Users/you/Documents"
      ]
    }
  }
}

Modes #

Mode Reject threshold Tool registry list_changed
strict score ≥ 40 Locked at handshake Dropped
lenient score ≥ 80 Dynamic updates allowed Forwarded
audit Never blocks Dynamic Forwarded

Use strict in production. Use audit to profile a new server before tightening the threshold. --log produces a JSONL file with every policy decision, indicator ID, score, and masked value snippet.

Architecture #

Two files: policy.py is a pure CDR engine with no I/O, directly unit-testable. kevlar.py is the async stdio proxy. No runtime dependencies, stdlib only. kevlar.py spawns the server with start_new_session=True and kills the process group on shutdown, so npx/ uvx child processes don't linger.

See docs/architecture.md for the full design: proxy lifecycle, CDR pipeline per message type, scoring arithmetic, indicator registries, and audit log format.

Tests #

pip install -e ".[dev]"
pytest

149 tests. tests/test_proxy.py runs integration tests against real subprocess pairs. tests/test_policy.py covers the pure policy engine in unit tests.

── more in #ai-safety 4 stories · sorted by recency
── more on @kevlar 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/kevlar-mcp-firewall-…] indexed:0 read:3min 2026-10-24 · —