How It Works
Understanding MCP Guard's security architecture and code execution flow.
Architecture Overview
Security Layers
Layer 1: Code Validation (Pre-Execution)
Before any code runs, MCP Guard validates it for dangerous patterns:
Layer 2: V8 Isolate Sandboxing (Runtime)
Code executes in a Cloudflare Workers V8 isolate:
- Fresh environment per execution
- No Node.js APIs (fs, child_process, etc.)
- No global state persists between runs
- Memory limited (configurable, default 128MB)
- CPU limited (configurable execution timeout)
Layer 3: Network Isolation
By default, the isolate has zero network capability. It cannot:
- Make HTTP requests
- Open WebSocket connections
- Access any external resources
Three-Layer Network Access Enforcement (when network enabled via settings):
-
Layer 1: Runtime Isolation - Dynamic workers ALWAYS have
globalOutbound: null.globalThis.fetchdoes NOT exist natively. -
Layer 2: Module-Level Fetch Wrapper - When network enabled,
generateWorkerCode()injects a wrapper that:- Uses
Object.definePropertyto defineglobalThis.fetch - Adds
X-MCPGuard-Allowed-HostsandX-MCPGuard-Allow-Localhostheaders - Delegates to
env.FETCH_PROXY.fetch()Service Binding
- Uses
-
Layer 3: FetchProxy Service Binding - Runs in parent Worker (has network access):
- Reads allowlist from headers
- Enforces rules (exact match, wildcard
*.github.com, localhost blocking) - Returns 403 JSON error if blocked, otherwise proxies via parent's
fetch()
If you enable Network Access for a specific guarded MCP, MCP Guard uses this three-layer approach to allow controlled fetch() while enforcing a host allowlist (and optional localhost access).
Layer 4: Binding-Based Access Control
The only way to interact with MCP tools is through Service Bindings:
Layer 5: Credential Isolation
- API keys are never exposed to the isolate
- Credentials are managed by the MCP Guard server
- MCP bindings handle authentication transparently
- Even if code tried to access credentials, they don't exist in scope
Code Execution Flow
Step by Step
Here's exactly what happens when the AI generates and executes code:
-
User Request: AI calls
call_mcpwith TypeScript code -
Validation: MCP Guard validates code for dangerous patterns
- If blocked patterns found → Error returned immediately
- If safe → Continue to execution
-
Worker Generation: MCP Guard generates a Worker script containing:
- User code embedded directly
- MCP binding stubs (functions that call
env.MCP.callTool()) - Console output capture
- Metrics tracking
-
Isolate Creation: Wrangler spawns a fresh V8 isolate:
globalOutbound: null(default: no network)- optional per-MCP allowlist may enable outbound
fetch() - Memory and CPU limits applied
- Service Binding injected for MCP access
-
Code Execution: User code runs in the isolate:
- Can call MCP tools via generated stubs
- Cannot access network, filesystem, or environment
- Console output captured
-
MCP Tool Calls: When code calls an MCP tool:
- Stub calls
env.MCP.callTool('search_repositories', input) - Service Binding receives the call (runs in parent Worker)
- Parent Worker calls Node.js RPC server via localhost
- RPC server uses MCP SDK to call actual MCP process
- Results flow back through the chain
- Stub calls
-
Results Return:
- Console output returned to AI
- Metrics recorded (execution time, MCP calls made)
- Isolate disposed (no state persists)
Service Bindings Architecture
The key to MCP Guard's security is the Service Binding pattern:
Key benefits:
- Dynamic workers use native Service Binding calls (not fetch)
- True network isolation for user code
- Only parent Worker can reach the RPC server
- Credentials never exposed to user code
Why This Architecture?
Traditional MCP (Insecure)
MCP Guard (Secure)
The isolation boundary ensures that even if the AI generates malicious code:
- Dangerous patterns are blocked before execution
- The isolate cannot access system resources
- Communication is limited to approved MCP bindings
- Credentials remain hidden from the executing code
Limitations
OAuth MCPs Cannot Be Guarded
Important Limitation
MCP servers that require OAuth authentication cannot be guarded by MCP Guard.
Why? OAuth authentication creates a trust relationship between the IDE and the MCP provider:
When MCP Guard intercepts communication:
- It cannot access the IDE's OAuth tokens
- The MCP server rejects requests without valid tokens
- Re-authentication through MCP Guard would require client registration with every OAuth provider
Solution: Use OAuth MCPs directly through your IDE without guarding. MCP Guard detects OAuth requirements and displays a "Cannot Guard" indicator.
MCPs that work with MCP Guard:
- API key authenticated MCPs (GitHub with PAT, etc.)
- Command-based local MCPs (filesystem, git, etc.)
- URL-based MCPs with header authentication
- Any MCP that doesn't require OAuth