Container Sandboxing
Relevant source files
The following files were used as context for generating this wiki page:
Container Sandboxing is the core security architecture of the MCP Server Code Execution Mode. It provides a robust, production-capable environment for executing untrusted Python code by isolating it within rootless containers. This approach ensures a clear boundary between the sandboxed execution environment and the host system, mitigating risks associated with arbitrary code execution while allowing mediated access to host-managed MCP tools.
The system utilizes either Podman or Docker (rootless) to create ephemeral, strictly constrained environments. Each execution request is handled within a fresh container instance, or a persistent session, featuring comprehensive resource limits, disabled networking, and an immutable root filesystem. Host mediation is achieved through a JSON-framed stdio bridge, allowing the sandbox to interact with external MCP servers without compromising host integrity.
Sources: HISTORY.md:7-11, ARCHITECTURE.md:5-9, README.md:129-135
Architecture and Components
The sandboxing logic is primarily encapsulated in the RootlessContainerSandbox class, which manages the lifecycle of the container and enforces security constraints. The bridge acts as a mediator, forwarding RPC requests between the unprivileged container and host-side MCP clients.
High-Level Execution Flow
The following diagram illustrates the interaction between the MCP Client, the Bridge, and the isolated Container Sandbox.
The bridge prepares a temporary IPC directory on the host, which is mounted into the container at /ipc. This volume contains the generated entrypoint.py script that manages communication and proxy generation inside the sandbox.
Sources: ARCHITECTURE.md:13-35, mcp_server_code_execution_mode.py:465-475
Core Components Table
| Component | Description | File Reference |
|---|---|---|
RootlessContainerSandbox | Manages container lifecycle, runtime detection, and command generation. | mcp_server_code_execution_mode.py:462 |
SandboxInvocation | Prepares per-execution metadata, IPC directories, and handles RPC routing. | mcp_server_code_execution_mode.py:1003 |
entrypoint.py | Generated script running inside the container to rewire stdio and install MCP proxies. | mcp_server_code_execution_mode.py:534 |
| Container Runtime | Podman or Docker (rootless) used to enforce process-level isolation. | mcp_server_code_execution_mode.py:468 |
Security Constraints and Isolation
The sandbox enforces "defense in depth" through multiple layers of isolation. These constraints are applied as arguments to the container runtime command during initialization.
Enforcement Matrix
| Constraint | Implementation | Purpose |
|---|---|---|
| Network | --network none | Completely blocks external and internal host network access. |
| Filesystem | --read-only | Prevents persistence or modification of the base container image. |
| Privileges | --cap-drop ALL, no-new-privileges | Ensures the process cannot escalate or perform system-level actions. |
| User | 65534:65534 | Runs as an unprivileged user (nobody/nogroup). |
| Resources | --memory, --pids-limit, --cpus | Prevents Denial of Service (DoS) attacks via resource exhaustion. |
| Workspace | tmpfs | Provides volatile, non-executable temporary storage at /tmp and /workspace. |
Sources: README.md:465-478, mcp_server_code_execution_mode.py:481-510, ARCHITECTURE.md:113-125
Resource Configuration Defaults
The sandboxing environment uses the following default limits, which can be tuned via environment variables:
- Memory: 512m (configurable via
MCP_BRIDGE_MEMORY) - PIDs: 128 (configurable via
MCP_BRIDGE_PIDS) - Timeout: 30 seconds (configurable via
MCP_BRIDGE_TIMEOUT, hard ceiling at 120s)
Sources: mcp_server_code_execution_mode.py:91-94, GUIDE.md:104-115
Runtime Management
The system dynamically detects and manages the container runtime. It supports Podman and rootless Docker, preferring Podman due to its native user namespace support.
Runtime Lifecycle Diagram
This diagram shows how the bridge manages the state of the container runtime, specifically for Podman.
For Podman, the bridge automatically starts the Podman machine if it is not running and schedules a shutdown after a period of inactivity (default 300 seconds) defined by MCP_BRIDGE_RUNTIME_IDLE_TIMEOUT.
Sources: mcp_server_code_execution_mode.py:808-850, ARCHITECTURE.md:58-62
Host-Mediated Communication (RPC)
Communication between the isolated sandbox and the host is mediated via line-delimited JSON frames over the container's standard I/O streams. This ensures that the sandbox never makes direct system calls or network requests to reach MCP tools.
Communication Flow
- The containerized
entrypoint.pywrapssys.stdoutandsys.stderrto send JSON messages. - When user code calls an
mcp_<alias>tool, the entrypoint sends anrpc_requestframe. - The
SandboxInvocation.handle_rpcmethod on the host receives the frame. - The host validates the request against an allowlist of loaded servers.
- The host performs the actual tool call using a
PersistentMCPClient. - The result is returned to the sandbox as an
rpc_responseframe.
Persistence and Volume Sharing
While the root filesystem is read-only, the sandbox uses persistent volumes for state and shared communication artifacts.
- IPC Volume (
/ipc): A temporary host directory created per invocation to host theentrypoint.py. - Projects Volume (
/projects): Maps to~/MCPs/user_tools/on the host, containinguser_tools.py(forsave_tool) and thememory/directory (forsave_memory).
For Podman on macOS/Linux, the bridge ensures volumes are shared by executing podman machine set --volume or probing the VM via SSH if the volume flag is unsupported.
Sources: mcp_server_code_execution_mode.py:1034-1045, mcp_server_code_execution_mode.py:950-985, README.md:310-318
Container sandboxing in this project prioritizes security by design, transforming untrusted code execution into a mediated, isolated, and resource-constrained operation. By combining rootless container technology with host-side RPC mediation, it provides a safe environment for LLM-driven programming and tool orchestration.