Persistent, container-backed sandboxes over MCP (HTTP + SSE)
mcp-sandboxd is an MCP-compatible server that allows running arbitrary commands inside isolated sandboxes in Docker or Kubernetes.
The core idea is simple: an identifier (e.g. a conversation id) maps to a long-running sandbox environment reused across runs. This makes agent workflows feel like a "real machine", without exposing your host.
- Long-running sandboxes: install deps once, iterate fast.
- IDE integration: run test/lint/build from your editor through MCP without polluting your machine.
- Agent execution backend: give an agent a place to run shell commands.
- Artifact proxying: generate files inside
/artifactsand download them via the server HTTP endpoint.
run_sandbox: run one or more commands in a sandbox keyed byidentifier.delete_sandbox: delete a sandbox environment.restart_sandbox: recreate a fresh sandbox for an identifier.
Write files inside the sandbox under /artifacts. After a run completes, the server copies artifacts out of the sandbox into ARTIFACTS_DIR and serves them over HTTP.
From an MCP client’s point of view this is the same for local Docker, Docker-in-Docker, and the Kubernetes-native backend: clients always download via GET /artifacts/... and never talk to the sandbox filesystem directly.
- By run id:
GET /artifacts/<identifier>/<run_id>/<path> - Convenience alias:
GET /artifacts/<identifier>/latest/<path>
make docker-build-sandbox
cp .env.example .env
make devThis starts the server on http://localhost:8080.
- MCP JSON-RPC endpoint:
http://localhost:8080/mcp - SSE stream (per run):
http://localhost:8080/mcp/events?run_id=...
Below are example configs for connecting to a running server over HTTP + SSE.
OpenCode
// ~/.config/opencode/config.json
{
"mcpServers": {
"mcp-sandboxd": {
"type": "sse",
"url": "http://localhost:8080/mcp"
}
}
}Claude / Claude Desktop (Remote MCP connector)
Add a custom connector and point it at your running server.
- URL:
http://localhost:8080/mcp(or your deployedhttps://.../mcp)
Run via Docker (talking to host Docker socket)
Starts mcp-sandboxd on http://localhost:8080/mcp.
{
"mcpServers": {
"mcp-sandboxd": {
"type": "stdio",
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-p",
"8080:8080",
"-e",
"PORT=8080",
"-e",
"MCP_PATH=/mcp",
"-e",
"SANDBOX_BACKEND=docker",
"-e",
"SANDBOX_IMAGE=ghcr.io/jeliasson/mcp-sandboxd-sandbox:latest",
"-v",
"/var/run/docker.sock:/var/run/docker.sock",
"ghcr.io/jeliasson/mcp-sandboxd:latest"
]
}
}
}General
- Architecture: Protocol surface and internals.
- Configuration: Environment variables and defaults.
- Images: Published container images and tags.
- Observability: Prometheus metrics.
- Security
- Tools: Tool schemas and parameters.
Backend
- Development: Local workflow and make targets.
- Docker: Docker socket setup and DinD pattern.
- Kubernetes: Kubernetes-native backend and DinD sidecar.
no-new-privilegesis enabled by default;sudowon’t work inside the sandbox.- Use
run_sandbox.options.as_user="root"for administrative operations. - Prefer running
mcp-sandboxdin a dedicated namespace with default-deny egress.
