Architecture
How it works
Two components, both required:
MCP-Shield sits between the AI client (Cursor, Claude Code, any MCP host) and the target MCP server. Every JSON-RPC frame passes through it. It validates capability certificates, checks HMAC signatures, tracks per-server call history and evaluates it against configurable sequence rules, scans tool arguments against a regex blacklist, scans code payloads with an AST walker, enforces tool namespace locks, and sanitizes server outputs before they reach the LLM context.
The sequence-tracking stage (session-aware, multi-turn evaluation) is the suite's original contribution beyond per-request checks — see Session Tracking for how it works and what it catches that single-request evaluation misses.
MCP-Box handles code execution. When Shield clears an execute_code call, it dispatches the payload to Box rather than running it directly. Box spins up a one-shot Alpine container with no network access, a 128MB memory cap, and a 2-second watchdog. The container is force-removed after every execution regardless of outcome.
%%{init: {'theme': 'base', 'themeVariables': {'loopTextColor': 'var(--md-default-fg-color)'}}}%%
sequenceDiagram
participant Client as AI Client
participant Shield as MCP-Shield
participant Sandbox as MCP-Box
participant Server as Target MCP Server
Client->>Shield: JSON-RPC tools/call
Note over Shield: HMAC → Sequence → Attestation → Regex → AST → Namespace
alt Policy violation
Shield-->>Client: JSON-RPC error (-32602 / -32601)
else Code execution
Shield->>Sandbox: execute(code)
Note over Sandbox: Alpine container, network_mode=none, 2s timeout
Sandbox-->>Shield: {exit_code, logs, status, duration_ms}
Shield-->>Client: result
else Standard tool call
Shield->>Server: forward request
Server-->>Shield: response
Note over Shield: Output sanitizer, namespace filter
Shield-->>Client: sanitized response
end
Stdio mode
Shield can run as a stdio proxy wrapping any MCP server subprocess:
python -m mcp_shield.src.stdio_proxy -- npx -y @modelcontextprotocol/server-filesystem /home/user
Everything after -- is the server command. The proxy intercepts both directions: client requests are validated before forwarding, server responses are sanitized before returning. JSON-RPC error frames are written to stdout on block so the AI client never hangs.