{"id":"4cf54ddd-2b71-4df2-9dec-a49ec0cdbcba","slug":"mcp-box","kind":"mcp","name":"mcp-box","summary":"Highly isolated Linux container environments optimized specifically for mcp-servers. Secure AI agent tool execution.","owner":"lowcache","repoUrl":"https://github.com/lowcache/mcp-box","license":"MIT","licenseTier":"permissive","trust":"community","stars":14,"match":null,"fewStars":false,"format":"mcp","createdAt":null,"addedAt":"2026-10-14T05:05:26.820Z","logoUrl":"https://avatars.githubusercontent.com/u/101915753?u=5998d309d73674ffa3a948ff3126755ae31f01fb&v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["cloud-infra","memory-knowledge"],"tags":["ai-agent","ai-security","claude","container-security","devtools","docker","golang","isolation"],"runtime":"binary","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-14T07:57:16.056Z","sample":false,"url":"https://conduits.dev/tools/mcp-box","language":"Go","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# mcp-box\n\n[![CI](https://github.com/lowcache/mcp-box/actions/workflows/ci.yml/badge.svg)](https://github.com/lowcache/mcp-box/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Go](https://img.shields.io/badge/Go-1.22%2B-00ADD8.svg)](src/go/go.mod)\n\n![mcp-box sandbox demo](docs/demo.gif)\n\n**Your AI agent's tools run with your permissions.** When an MCP server can call `run_command` or write files, \na buggy prompt or a malicious instruction can reach your home directory, your SSH keys, and your cloud credentials. \n`mcp-box` puts every MCP server inside a locked-down Docker sandbox with a read-only root filesystem, explicit writable mounts, \ndropped Linux capabilities, and per-profile network policy. Only the folders you mount are writable; the rest of your host stays out of reach.\n\n> ### mcp-box is the boringly reliable way to run MCP servers safely: inspectable, reproducible, and default-deny by design.\n\n**mcp-box** is a single, portable **Go** binary that launches turnkey, immutable, strictly-isolated\ncontainer sandboxes for Model Context Protocol (MCP) servers. Nix is used for deterministic image builds \nwhen present, but it is **entirely optional**. Without Nix, `mcp-box` pulls the same pinned OCI image definitions\nfrom GHCR and runs them under the same Docker isolation model. Docker is the only hard requirement.\n\n> ### Same server, same hardening, same sandbox boundary — only the image source changes.\n\n\n## Security Audit Checks\n\nYou can audit the sandbox boundary directly by overriding the container command with -- bash -c '...'. \nThese checks prove the boundary itself, not just the MCP server running inside it. \nThe hardening (read-only root, no network, dropped capabilities, host UID mapping) applies to *any* process in the box:\n\n1. **Read-only filesystem** — writes outside `/workspace` are rejected:\n   ```bash\n   ./mcp-box run shell -- bash -c 'touch /etc/naughty'\n   # => touch: cannot touch '/etc/naughty': Read-only file system   (exit 1)\n   ```\n2. **Network isolation** — with the default `--network none`, DNS/egress fail:\n   ```bash\n   ./mcp-box run shell -- bash -c 'curl -I https://google.com'\n   # => curl: (6) Could not resolve host: google.com               (exit 6)\n   ```\n3. **No privilege escalation** — `sudo` is not even present in the image:\n   ```bash\n   ./mcp-box run shell -- bash -c 'sudo -l'\n   # => bash: line 1: sudo: command not found                       (exit 127)\n   ```\n4. **Host UID/GID mapping** — the process is *you*, not root:\n   ```bash\n   ./mcp-box run shell -- bash -c 'id'\n   # => uid=<your uid> gid=<your gid> ...   (files in /workspace are owned by you)\n   ```\n\n---\n\n## Key Features\n\n1. **Strict Sandboxing**:\n   - **Immutable Root (`--read-only`)**: The entire root filesystem is mounted read-only.\n   - **Transient State (`--tmpfs`)**: Writable spaces (`/tmp` and `/run`) exist solely in RAM and disappear once the container stops.\n   - **Zero Capabilities (`--cap-drop=ALL`)**: The running processes have no special Linux kernel capabilities.\n   - **No Privilege Escalation (`no-new-privileges:true`)**: Prevents elevation to root inside the sandbox.\n   - **Per-Profile Network Policy**:\n      - Most sandboxes default to `--network none`.\n      - Networked profiles are explicit and opt-in, so a server only gets egress when its job genuinely requires it.\n      - The `fetch` profile is the exception by design: it uses a controlled network mode for web access, while still keeping the container boundary intact.\n   - **Scoped Workspaces**: Only specifically mounted host directories (`--workspace`) are visible to the server at `/workspace`.\n2. **Correct File Ownership**:\n   - Containers run mapped to your host UID/GID (`-u $(id -u):$(id -g)`), ensuring that files written to mounted workspaces are owned by you (not `root`) and don't trigger host-side permission errors.\n3. **Painless Integration**:\n   - Built-in configuration generator (`mcp-box config <server>`) prints out paste-ready JSON snippets to plug directly into `claude_desktop_config.json` or OpenClaw configurations.\n4. **Zero-Dependency Nix Autonomy**:\n   - If Nix is installed, running a sandbox automatically triggers a local rebuild and load of the OCI image.\n   - If Nix is absent, `mcp-box` automatically detects this and falls back to pulling pre-built, identical, and secure OCI images directly from the GitHub Container Registry (`ghcr.io/lowcache`), making Nix entirely optional for the end-user.\n\n---\n\n## CLI Surface\n\n`mcp-box` is designed to be inspectable, scriptable, and auditable.\n\n- `mcp-box run <server>` — launch a sandboxed MCP server\n- `mcp-box stop <id>` — stop a running sandbox\n- `mcp-box ps` — list active sandboxes\n- `mcp-box inspect <id>` — show the full sandbox spec and policy\n- `mcp-box logs <id>` — read audit logs\n- `mcp-box logs --follow` — stream live events\n- `mcp-box config <server>` — print paste-ready client config\n- `mcp-box build <server>` — rebuild or refresh an OCI image\n\n---\n\n## Quickstart\n\n```bash\n# 1. Get the binary (Docker is the only dependency)\ncurl -sSL https://github.com/lowcache/mcp-box/releases/latest/download/mcp-box-linux-amd64 -o mcp-box\nchmod +x mcp-box && mv mcp-box ~/.local/bin/\n\n# 2. Prove the sandbox holds — this write MUST fail\nmcp-box run shell --workspace /tmp/demo -- bash -c 'touch /etc/naughty'\n# => touch: cannot touch '/etc/naughty': Read-only file system\n\n# 3. Wire it into your AI client (paste the output into claude_desktop_config.json)\nmcp-box config sqlite\n```\n\n---\n\n## Pre-Packaged Sandboxes\n\n| Server Name | Language | Included Utilities | Network Mode | Primary Purpose |\n| :--- | :--- | :--- | :--- | :--- |\n| **`sqlite`** | Python | `sqlite3` CLI, `fastmcp` SDK | `none` | High-performance, isolated database querying. |\n| **`shell`** | Python | `bash`, `ripgrep`, `fd`, `git`, `curl`, `jq`, `sqlite`, `tar` | `none` | Safe, sandboxed script running and file operations. |\n| **`filesystem`** | Node.js | `ripgrep`, `fd`, `git` | `none` | Scoped filesystem read/write and code searching. |\n| **`fetch`** | Node.js | `curl` | `bridge` | Safe, isolated web fetching and scraping. |\n\n---\n\n## Policy, Compose, and Auditability\n\n`mcp-box` is not just a runner — it is a trust layer for MCP execution.\n\nPlanned core platform features:\n- **Policy profiles** for common trust levels: `readonly`, `dev`, `trusted`, `internet-off`, `internet-on`\n- **Compose-style specs** for multi-server setups\n- **Append-only audit logs** for sandbox lifecycle and denied actions\n- **`ps` / `inspect` / `logs`** so every sandbox can be checked after launch\n- **Pinned image digests** for reproducible, reviewable execution\n\n---\n\n## Dependencies\n\nDepending on your installation path, `mcp-box` has distinct dependency requirements:\n\n*   **Runtime Boundary (All Users)**:\n    - **Docker Engine** (Must be active and running locally on the host system).\n*   **Local Image Building (Source Flow with Nix)**:\n    - **Nix** (with experimental `flakes` and `nix-command` enabled).\n*   **CLI Compilation (Source Flow with Go)**:\n    - **Go** compiler v1.22 or higher (only required if building the executable from source without using Nix).\n*   **Zero-Dependency Fallback Flow**:\n    - **None**. The pre-compiled CLI binary runs standalone and automatically pulls the pre-built, multi-arch OCI images straight from GHCR into your local Docker daemon.\n\n---\n\n## Architecture\n\n```mermaid\ngraph TD\n    subgraph Host [Host Environment]\n        Agent[AI Agent / Claude Desktop] <-->|stdio piping| CLI[mcp-box CLI]\n        CLI -->|Checks for Nix| NixDetect{Nix Installed?}\n        \n        NixDetect -->|Yes: Source Flow| NixBuild[nix build .#server]\n        NixBuild -->|Stream tarball| DockerLoad[docker load]\n        \n        NixDetect -->|No: Registry Flow| DockerPull[docker pull ghcr.io]\n        DockerPull -->|Tag locally| DockerLoad\n        \n        DockerLoad -->|Loads image| Docker[Docker Engine]\n    end\n    \n    subgraph Sandbox [Docker Sandbox]\n        Server[MCP Server]\n        Tools[Isolated Tools: git, rg, sqlite3, curl]\n        Workspace[Mounted Workspace: /workspace]\n    end\n    \n    Docker -->|spawns with strict isolation| Sandbox\n    CLI <-->|stdio piping| Server\n```\n\n---\n\n## Installation\n\nDepending on your host environment, you can install and run `mcp-box` with three different avenues:\n\n### Option A: Pre-built Go Binary (No Nix / Docker-only)\nFor systems that only have Docker installed:\n1. **Download the compiled CLI binary** (pick the asset matching your OS/arch — `linux`/`darwin`, `amd64`/`arm64`):\n   ```bash\n   curl -sSL https://github.com/lowcache/mcp-box/releases/latest/download/mcp-box-linux-amd64 -o mcp-box\n   chmod +x mcp-box\n   ```\n2. **Move to PATH** (Optional):\n   ```bash\n   mv mcp-box ~/.local/bin/  # Or another folder in your PATH\n   ```\n*On first execution, `mcp-box` will automatically detect the absence of Nix and pull the pre-built OCI images from `ghcr.io/lowcache` into your local Docker daemon.*\n\n### Option B: From Source via Nix Flake (Nix/NixOS)\nFor systems running Nix/NixOS:\n*   **Run directly without installing**:\n    ```bash\n    nix run github:lowcache/mcp-box -- list\n    ```\n*   **Install to your user profile**:\n    ```bash\n    nix profile install github:lowcache/mcp-box\n    ```\n*   **Declarative Installation (NixOS / Home Manager)**:\n    Add the flake input and package to your configuration:\n    ```nix\n    # flake.nix inputs:\n    inputs.mcp-box.url = \"github:lowcache/mcp-box\";\n    \n    # In systemPackages or home.packages:\n    inputs.mcp-box.packages.${pkgs.system}.default\n    ```\n*On first execution, `mcp-box` will build the Go binary and OCI images purely from source and load them directly into your local Docker daemon.*\n\n### Option C: Compile from Source (Go Compiler)\nIf you want to compile the CLI binary manually without Nix:\n1. **Clone the repository**:\n   ```bash\n   git clone https://github.com/lowcache/mcp-box.git\n   cd mcp-box\n   ```\n2. **Compile the binary** (the Go module lives in `src/go`):\n   ```bash\n   cd src/go\n   go build -o ../../mcp-box .\n   ```\n*You can now run `./mcp-box` directly, which will pull OCI layers from the registry or build locally using Nix based on your host environment.*\n\n---\n\n## Usage Guide\n\n### 1. Show Help & Supported Servers\n```bash\n./mcp-box help\n./mcp-box list\n```\n\n### 2. Run a Sandbox Interactively\nYou can launch any server interactively to test its behavior and tools:\n```bash\n./mcp-box run sqlite --workspace /tmp/sandbox-db -- --db /workspace/test.db\n```\n\n### 3. Build/Force-Update an OCI Image\nIf you want to manually rebuild or force-update a Nix-built image:\n```bash\n./mcp-box build sqlite\n```\n\n### 4. Integration with AI Clients\n\n`mcp-box config <server>` prints a ready-to-paste `mcpServers` JSON block (with an\nabsolute path to the binary). The same block works for both Claude Desktop and\nClaude Code.\n\n```bash\n./mcp-box config sqlite\n```\n\n#### Claude Code (CLI)\n\nClaude Code does **not** use `claude_desktop_config.json`. Add the server with one\ncommand — note the nested `--` (the first separates `claude`'s flags from the\nsubprocess; the second is consumed by `mcp-box` to forward server args):\n\n```bash\n# user scope (available in every project); drop -s user for the current project only\nclaude mcp add -s user mcp-box-sqlite -- \\\n  mcp-box run sqlite --workspace /abs/path/to/workspace -- --db /workspace/db.sqlite\n```\n\nOr, to commit a shareable config to your repo, drop the `mcp-box config` JSON block\nstraight into a project-root **`.mcp.json`** — it uses the exact `{\"mcpServers\": …}`\nshape that `config` emits.\n\nVerify with `claude mcp list`.\n\n#### Claude Desktop\n\nPaste the `config` block into `claude_desktop_config.json`. Its location is\nOS-specific:\n\n| OS | Path |\n| :--- | :--- |\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\n---\n\n"}