Native Sandbox Isolation (Linux, no Docker)
MCPProxy can isolate a stdio MCP server without Docker using the Linux
Landlock LSM plus resource
limits (setrlimit). This is the sandbox isolation mode (MCP-34), built for
hosts where Docker is unavailable or broken — notably Ubuntu 24.04 with
snap-installed Docker under AppArmor. Unlike bubblewrap / user-namespace
sandboxes, Landlock does not require unprivileged user namespaces, so it is
not blocked by kernel.apparmor_restrict_unprivileged_userns=1 (default on
Ubuntu 23.10+).
Enabling
Set the isolation mode to sandbox, globally or per server:
{
"docker_isolation": { "mode": "sandbox" },
"mcpServers": [
{ "name": "obsidian", "command": "uvx", "args": ["obsidian-mcp"],
"isolation": { "mode": "sandbox" } }
]
}
A per-server isolation.mode wins over the global mode. The legacy
docker_isolation.enabled boolean still maps to docker/none for
back-compat; mode supersedes it (see MCP-34.2).
What it enforces
- Filesystem write allowlist. Reads stay broad (the runtime can load
interpreters,
node_modules, andsite-packagesfrom anywhere), but writes are denied outside a small allowlist: the server'sworking_dir, the OS temp dir, and the common package caches (~/.npm,~/.cache,~/.local/share). Tightening reads is deferred — a read allowlist breaks tool discovery. - Resource limits. Core dumps are disabled (
RLIMIT_CORE=0, so in-memory secrets can't spill to disk) and the descriptor table is capped (RLIMIT_NOFILE). - Process-group cleanup. Reuses the existing
Setpgidgroup teardown, so a sandboxed server and its children are killed together on disconnect.
Confinement is applied by a tiny re-exec wrapper (mcpproxy __sandbox_exec) that
calls Landlock/setrlimit and then execs the real command — so the server's
stdin/stdout pass straight through with no intervening multiplexer.
Honest limits
- No uid/gid separation by default. The wrapper performs a best-effort
privilege drop only when it is running as root with a non-root real user. In
the personal edition mcpproxy runs as your user (not root), so this is a
documented no-op — real uid/gid separation needs root or
CAP_SETUID. - Reads are not confined (write-allowlist only; see above).
- Graceful degrade. If the kernel lacks Landlock (pre-5.13, or LSM disabled),
the server still starts but runs unconfined, and the host log records a
DEGRADED/unconfineddiagnostic. This favors availability; usedockermode when you need a hard guarantee.
Platform support
| Platform | mode: sandbox behavior |
|---|---|
| Linux (kernel 5.13+ with Landlock) | Enforced: write-allowlist + rlimits |
| Linux (no Landlock) | Degraded → runs unconfined, logged |
| macOS / Windows | Documented no-op → effective none (Landlock is Linux-only) |
See also: Docker Isolation for the Docker mode, and the non-Docker sandbox spike for the mechanism evaluation.