Sandboxing & Isolation

Process-level sandbox architecture, resource limits, network and filesystem isolation, and platform-specific capabilities.

The MCP Client executes every MCP server inside a lightweight process-level sandbox. This is not VM-level isolation – it uses operating system primitives to constrain what a running process can access and consume. The depth of isolation depends on the host platform.

Sandbox Architecture

When mcp run launches an MCP server, the following isolation layers are applied in order:

1. Process Creation
   └─ Fork a new process for the MCP server

2. Resource Limits
   ├─ Memory limit (cgroups v2 / rlimits / Job Objects)
   ├─ CPU limit (cgroups v2 / rlimits / Job Objects)
   ├─ PID limit (cgroups v2 / rlimits)
   └─ File descriptor limit (rlimits)

3. Network Isolation (Linux only)
   └─ Network namespace with default-deny

4. Filesystem Isolation
   ├─ Linux: bind mounts + Landlock LSM
   ├─ macOS: UNIX file permissions (best-effort)
   └─ Windows: NTFS ACLs (best-effort)

5. Subprocess Control
   ├─ Linux: seccomp BPF filters
   ├─ macOS: process monitoring (limited)
   └─ Windows: not available

6. Environment Filtering
   └─ Only allowed env vars passed to process

7. STDIO Transport
   └─ Communication via stdin/stdout only

Resource limits are mandatory – they cannot be disabled, only adjusted. The default limits are designed to be generous enough for typical MCP servers while preventing runaway resource consumption.

Resource Limits

Every MCP server process runs with enforced resource limits. These limits apply regardless of platform.

Default Limits

ResourceDefaultFlag OverrideConfig Key
Memory256 MB--max-memoryexecutor.resource_limits.max_memory
CPU1.0 cores--max-cpuexecutor.resource_limits.max_cpu
PIDs64--max-pidsexecutor.resource_limits.max_pids
File Descriptors256--max-fdsexecutor.resource_limits.max_fds
Execution Timeout5 minutes--timeoutexecutor.default_timeout

How Limits Are Enforced

ResourceLinuxmacOSWindows
Memorycgroups v2 memory.maxRLIMIT_ASJob Object JobObjectExtendedLimitInformation
CPUcgroups v2 cpu.maxRLIMIT_CPU (time-based)Job Object JobObjectCpuRateControlInformation
PIDscgroups v2 pids.maxRLIMIT_NPROCNot available (Job Object has no PID limit)
File DescriptorsRLIMIT_NOFILERLIMIT_NOFILENot applicable (handles are different)

Behavior When Limits Are Exceeded

  • Memory exceeded: On Linux, the kernel OOM killer terminates the process (exit code 137). On macOS, the process receives a SIGKILL. On Windows, the Job Object terminates the process.
  • CPU exceeded: On Linux, the process is throttled (not killed). On macOS, a SIGXCPU signal is sent. On Windows, the process is throttled.
  • PID limit exceeded: On Linux, fork() calls fail with EAGAIN. On macOS, fork() calls fail. On Windows, not enforced.
  • FD limit exceeded: open() calls fail with EMFILE on all UNIX platforms.
  • Timeout exceeded: The client sends SIGTERM, waits 5 seconds, then sends SIGKILL. Exit code is 124.

Adjusting Limits

# Generous limits for a heavy workload
mcp run acme/[email protected] \
  --max-memory 2g \
  --max-cpu 4.0 \
  --max-pids 256 \
  --max-fds 1024 \
  --timeout 30m

Or configure globally:

# ~/.mcp/config.yaml
executor:
  default_timeout: "30m"
  resource_limits:
    max_memory: "2g"
    max_cpu: 4.0
    max_pids: 256
    max_fds: 1024

Network Isolation

Network isolation prevents MCP servers from making unauthorized outbound connections. This defends against data exfiltration, SSRF, and covert channels.

Linux (Production-Ready)

On Linux, the client creates a dedicated network namespace for the MCP server process. By default, the namespace has:

  • No network interfaces (not even loopback in the strictest mode)
  • No routing table entries
  • No DNS resolution

This means the MCP server cannot make any network connections unless explicitly allowed.

To allow network access:

mcp run acme/[email protected] --network allow

macOS and Windows

Network isolation is not available on macOS or Windows. The MCP server process inherits the host’s full network stack. The --network deny flag is accepted but has no effect on these platforms.

$ mcp doctor
...
Network Isolation: NOT AVAILABLE (macOS does not support network namespaces)
...

Filesystem Isolation

Filesystem isolation confines the MCP server process to a specific working directory, preventing it from reading or writing files outside its sandbox.

Linux (Production-Ready)

On Linux, the client uses two mechanisms:

  1. Bind mounts: The MCP server’s root filesystem is a minimal set of bind-mounted directories. Only the working directory is mounted read-write.

  2. Landlock LSM: If the kernel supports Landlock (Linux 5.13+), additional filesystem access restrictions are applied at the kernel level. This provides mandatory access control that the MCP server cannot bypass even with elevated privileges within its namespace.

The effective filesystem view:

/                      (read-only, minimal)
├── usr/lib/           (read-only, shared libraries)
├── lib/               (read-only, shared libraries)
├── tmp/               (read-write, temporary files)
└── workspace/         (read-write, MCP working directory)

macOS (Best-Effort)

On macOS, the client sets UNIX file permissions on the working directory and relies on the operating system’s permission model. This is a best-effort approach – a determined process with knowledge of the filesystem layout can potentially access files outside the sandbox.

Windows (Best-Effort)

On Windows, the client uses NTFS ACLs to restrict directory access. Similar to macOS, this is best-effort and does not provide the same guarantees as Linux bind mounts and Landlock.

Subprocess Control

Subprocess control restricts whether the MCP server can fork or execute child processes.

Linux (seccomp)

On Linux, the client installs a seccomp BPF filter on the MCP server process. This filter intercepts system calls at the kernel level:

  • fork(), vfork(), clone(): Blocked (returns EPERM)
  • execve(), execveat(): Blocked (returns EPERM)

This is a kernel-level enforcement that cannot be bypassed from user space.

When allow_subprocess is true in the policy configuration, these syscalls are permitted but the child processes still inherit all resource limits from the parent cgroup.

macOS (Limited)

On macOS, subprocess control is implemented via process monitoring. The client watches for child process creation and sends termination signals. This is a reactive mechanism (kill after detection) rather than a preventive one (block the syscall), and there is a brief window where a child process can execute before being terminated.

Windows (Not Available)

Subprocess control is not implemented on Windows. MCP servers can spawn child processes without restriction.

Platform Comparison

FeatureLinuxmacOSWindows
Resource Limitscgroups v2 + rlimitsrlimits onlyJob Objects
Memory EnforcementHard kill (OOM)Soft signalHard kill
CPU EnforcementThrottlingTime-based signalThrottling
PID LimitsEnforced (cgroups)Enforced (rlimits)Not available
FD LimitsEnforced (rlimits)Enforced (rlimits)Not applicable
Network IsolationNetwork namespaces (full)Not availableNot available
Filesystem IsolationBind mounts + LandlockUNIX perms (best-effort)NTFS ACLs (best-effort)
Subprocess Controlseccomp BPF (preventive)Process monitoring (reactive)Not available
Audit LoggingFullFullFull
Production ReadyYesNoNo

Understanding mcp doctor Output

The mcp doctor command reports the status of each sandbox capability on your system.

Status Indicators

IndicatorMeaning
OKCapability is fully available and production-ready
PARTIALCapability is available with limitations
LIMITEDCapability exists but has known bypass vulnerabilities
NOT AVAILABLECapability is not supported on this platform

Reading the Overall Assessment

AssessmentMeaning
PRODUCTION READYAll critical sandbox capabilities are available. Safe for untrusted MCPs.
DEVELOPMENT ONLYSome capabilities are missing. Safe for trusted MCPs from verified publishers. Not suitable for untrusted code.

Common mcp doctor Results

Linux with cgroups v2:

Overall: PRODUCTION READY

All features available. This is the recommended setup.

Linux without cgroups v2:

Resource Limits: PARTIAL (rlimits only, cgroups v2 not available)
Overall: DEVELOPMENT ONLY

Upgrade to a kernel with cgroups v2 support, or ensure the cgroups v2 hierarchy is mounted.

macOS (any version):

Resource Limits:    PARTIAL (rlimits only, no cgroups)
Network Isolation:  NOT AVAILABLE
Filesystem:         PARTIAL (best-effort UNIX permissions)
Subprocess Ctrl:    LIMITED
Overall:            DEVELOPMENT ONLY

This is expected on macOS. Use for development and testing only.

Production vs Development Recommendations

Production Environments

For production workloads, especially those running untrusted or community MCP servers:

  • Use Linux with cgroups v2 enabled
  • Set min_cert_level to at least 2 (Security Certified)
  • Restrict allowed_origins to Official and Verified
  • Keep network_default at deny
  • Keep allow_subprocess at false
  • Enable audit logging
  • Consider running the MCP Client inside a Docker container for additional isolation

Development Environments

For local development and testing with trusted packages:

  • Any platform is acceptable (Linux, macOS, Windows)
  • min_cert_level: 0 for flexibility
  • network_default: allow if the MCP server needs network access
  • allow_subprocess: true if needed for your development workflow
  • Audit logging optional but recommended

Docker as an Additional Layer

For maximum isolation on any platform, run the MCP Client inside a Docker container:

docker run --rm -it \
  -v ~/.mcp:/home/mcp/.mcp \
  -e MCP_REGISTRY_TOKEN=$MCP_REGISTRY_TOKEN \
  mcphub/mcp-client:latest \
  run acme/[email protected]

This provides Docker’s container isolation (namespaces, cgroups, seccomp) as a foundation, with the MCP Client’s own sandbox as an additional layer inside the container.