Security sidecar for MCP servers: prompt-injection scan, Ed25519 verify, tools/list drift. 10 tools.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Part of the StudioMeyer MCP Stack β Built in Mallorca π΄ Β· β if you use it
Drop-in Rust sidecar that wraps any MCP server. Scans tool calls for prompt injection, validates Ed25519 manifest signatures (with TOFU keystore + Sigstore Rekor bridge since v0.2), exports OTLP gRPC telemetry (on opentelemetry 0.30 since v0.4 β closes the shutdown-hang class), blocks marketplace-poisoning vectors, strips loader-class env keys from spawned children (LD_PRELOAD, NODE_OPTIONS, β¦ β new in v0.3), folds Unicode confusables to detect homoglyph evasion (Cyrillic ΡgnΠΎrΠ΅ β ignore β new in v0.3), strips ANSI/terminal escape sequences and flags tool-name homoglyph collisions on tools/call (both new in v0.7), and β new in v0.8 β scans every tools/list catalog for tool-description / full-schema poisoning (model-directed instructions hidden in a tool's description or its parameter schema β the first-sight poisoning Layer 7 drift can't see) plus a directory-traversal argument pattern. Single signed binary, p99 budget under 5 ms (enforced in CI).
Anthropic has classified the underlying MCP-design issues (auto-invoke, marketplace tool-list trust, no manifest signing) as out-of-scope for the spec. mcp-armor implements the runtime defenses they declined to spec.
mcp-armor sits between an MCP client (Claude Desktop, Windsurf, Cursor) and an upstream server. JSON-RPC traffic flows through a four-stage scanner (Aho-Corasick prefilter β regex stage β NFKC + zero-width + Bidi + tag-unicode strip β re-scan β UTS-39 confusable skeleton fold β re-scan). Block decisions are recorded to an in-memory ring buffer, and the read-only control-plane MCP server surfaces the audit history back to the client. On wrap, loader-class env keys (LD_PRELOAD, NODE_OPTIONS, PYTHONPATH, β¦) are stripped from the child process before spawn().
Sister project: studiomeyer-io/ai-shield β TypeScript policy engine that mcp-armor's evasion patterns are ported from (Round 4 zero-width + tag-unicode work).
We have been building tools and systems for ourselves for the past two years. The fact that this repo is small and has few stars is not because it is new. It is because we only just decided to share what we have built. It is not a fresh experiment, it is a long story with a recent commit.
We love building things and sharing them. We do not love social media tactics, growth hacks, or chasing stars and followers. So this repo is small. The code is real, it gets used, issues get answered. Judge for yourself.
If it helps you, sharing, testing, and feedback help us. If it could be better, an issue is more useful. If you build something with it, tell us at hello@studiomeyer.io. That genuinely makes our day.
From a small studio in Palma de Mallorca.
Pre-built binaries (signed via cosign):
Or from source:
Note: the
audit-dbfeature flag was removed in v0.2.0 (a Lumina-class empty flag that pulledrusqliteinto the dep graph but was never wired into any code path). It will return in a future release alongside the actual SQLite-backedScanHistoryimplementation.
MSRV: Rust 1.89 (1.75 -> 1.85 in v0.1.1 for edition = "2024" deps; -> 1.89 in v0.7 because the icu 2.2.0 family via regex/idna needs 1.86 and rmcp 1.7 uses let-chains stabilised in 1.88). Cargo.toml rust-version, .clippy.toml msrv, and the CI matrix are all pinned to 1.89 β a cargo install on 1.86-1.88 will not build despite the older docs claiming 1.85.
Wrap any stdio MCP server:
Scan a single payload from CLI:
Verify a signed manifest (stateless):
v0.2 TOFU-aware verify β cross-check against the pinned key for this server name:
v0.2 TOFU keystore management:
v0.2 Sigstore Rekor bridge (offline bundle parse + online inclusion lookup):
Show the active policy:
v0.2 SIGHUP-driven runtime reload (Unix):
Run the read-only control-plane MCP server (for inspection by Claude Desktop or MCP Inspector):
The mcp-armor mcp-control server exposes 11 read-only tools (6 from v0.1 + 3 from v0.2 + 1 added in v0.5 + 1 added in v0.8). All have readOnlyHint: true and destructiveHint: false. The control plane speaks MCP spec 2025-11-25 since v0.7 (was 2025-06-18 v0.1 through v0.6).
| Tool | Description |
|---|---|
armor_scan_payload | Scan an arbitrary payload, return verdict + matched patterns + CVE refs + latency |
armor_verify_manifest | Ed25519 verify over canonical-JSON form of a tools/list response |
armor_list_blocked | Read recent blocked tool calls from the in-memory ring buffer |
armor_get_policy | Return policy file path, rules, fail mode, scan flags, version |
armor_check_cve | Look up a server name (+ optional version) in the curated CVE feed |
armor_simulate_attack | Run the static simulate_payload for a CVE through the scanner. Never spawns the upstream binary |
armor_get_keystore | v0.2 β List pinned TOFU maintainer public keys (server_name + fingerprint + pinned_at_iso) |
armor_verify_bundle | v0.2 β Parse a cosign sigstore.json bundle and structurally verify the Rekor SET shape. Offline |
armor_rekor_lookup | v0.2 β Query the Sigstore Rekor transparency log for inclusion of a manifest's artifact hash. Requires --features sigstore-bridge |
armor_get_drift_history | v0.5 β Inspect the tools-list schema-drift baselines (Layer 7). Read-only, optional program filter, no caller-supplied path |
armor_scan_tools_list | v0.8 β Scan a captured tools/list (object or JSON string, 2 MiB cap) for tool-description / full-schema poisoning (Layer 8). Returns per-field findings. Never spawns the upstream |
The control plane runs by default as a hand-rolled JSON-RPC stdio server (no extra crate deps). Operators who want the official Anthropic MCP Rust SDK on the wire can compile in the parallel rmcp 1.5 control plane via --features rmcp-control (v0.7 finally wires this; v0.2 through v0.6 shipped it as a stub that advertised tools but refused calls). Both planes share one dispatcher β same 11 tools, same semantics, same protocolVersion.
Hot-path is four stages (since v0.3), all in-process:
\x1b[β¦, OSC hyperlinks, the 8-bit C1 introducers β new in v0.7, closes terminal-escape "line-jumping" injection), zero-width (U+200Bβ¦U+200F, U+2060β¦U+2064, U+FEFF), Bidi formatting (U+202Aβ¦U+202E, U+2066β¦U+2069), and tag-unicode (U+E0000β¦U+E007F), apply NFKC, re-run stages 1 and 2. Gated by policy.scan_unicode.src/scanner/confusable.rs), then re-run stages 1 and 2. Catches ΡgnΠΎrΠ΅ previous instructions where i / o / e are Cyrillic. Cheap pre-gate via has_confusables() keeps the p99 budget intact for pure-ASCII payloads. Gated by policy.scan_confusable.No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/mcp-armor)<a href="https://allmcps.com/mcp/mcp-armor"><img src="https://allmcps.com/api/badge/mcp-armor?style=directory" alt="MCP Armor on AllMCPs" /></a>