Skip to content

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.