nanosandbox-mcp
An MCP server that lets an AI agent run commands in a
nanosandbox sandbox. It speaks MCP over stdio and
offers one tool, run_command.
Install
npx -y nanosandbox-mcp --help # npm, nothing to install first
uvx nanosandbox-mcp --help # PyPI, via uv
cargo install nanosandbox-mcp # crates.io, builds from source
Prebuilt binaries cover macOS (Apple silicon and Intel) and Linux (x86_64 and aarch64, glibc 2.17+). Linux and macOS only. Windows isn't supported yet: the sandbox there is a resource limiter, not a security boundary.
Use
Add it to an MCP client's configuration (Claude Desktop, Cursor, Zed, ...):
{
"mcpServers": {
"sandbox": {
"command": "npx",
"args": ["-y", "nanosandbox-mcp", "--workspace", "/path/to/project"]
}
}
}
(With uvx: "command": "uvx", "args": ["nanosandbox-mcp", "--workspace", ...]. With a
cargo installed binary: "command": "nanosandbox-mcp".)
The agent can now run programs, with their files limited to that workspace and no network.
Who decides what the sandbox may do
You do, when you launch the server. The model chooses what to run; it never chooses what the
sandbox may touch. The tool takes only command, args and stdin. There is no parameter for
paths, network, memory or time, so a model can't ask for more than you allowed. An extra argument
is refused.
| Option | Meaning | Default |
|---|---|---|
--workspace <DIR> |
Working directory and the only place commands can write. Required. | |
--read-only <PATH>, --writable <PATH> |
Also allow reading / writing a path (repeatable) | |
--deny-read <PATH>, --no-hide-home |
Hide a path; stop hiding the home directory | home hidden |
--allow-network <HOST> |
Allow these hosts, comma-separated or repeated; *.example.com works |
network off |
--host-network |
Unrestricted network. Use with care. | |
--memory <SIZE>, --timeout <SECS> |
Per-command limits | 512M, 30 s |
--cpu <N>, --max-pids <N> |
Linux only | pids: 128 on Linux |
--max-output <SIZE>, --max-concurrent <N> |
Output cap; commands running at once | CPU count |
--env <KEY=VALUE> |
Environment variable for commands (repeatable) | clean environment |
--host-uid, --host-gid, --no-seccomp |
Linux only | |
--log-io |
Also log stdin/stdout/stderr bodies | off |
Run nanosandbox-mcp --help for the full text. A limit this platform can't enforce (for example
--max-pids on macOS) makes the server refuse to start, rather than run without it.
The tool
run_command runs one program in a fresh sandbox and returns:
{ "stdout": "...", "stderr": "...", "exit_code": 0, "duration_ms": 15,
"timed_out": false, "out_of_memory": false, "cpu_limit_hit": false,
"tmp_limit_hit": false, "output_truncated": false, "blocked_hosts": [] }
A command that runs and fails (non-zero exit, killed by a limit) is a normal result, so the model
can read the output and react. Only a call that couldn't run at all comes back with isError.
There is no shell: args is the argument vector. For pipes or &&, run sh with
["-c", "..."]. Every call is a new sandbox; files in the workspace are what carry over.
Calls run in parallel up to --max-concurrent. A client cancelling a call stops its reply, but the
command runs until it ends or hits the time limit.
One line per call goes to stderr (command, exit code, duration, which limit hit, blocked hosts).
Stdin and output are only logged with --log-io, since they can contain secrets.
Protocol
Stdio transport, tools only. Both generations of the protocol are served on the same stream: the
stateless 2026-07-28 revision (server/discover, per-request _meta) and the earlier initialize
handshake (2025-11-25 down to 2024-11-05). HTTP, OAuth, resources, prompts and sampling are not
offered: a local command runner has no use for them.
What this isn't
This is a process-level sandbox on a shared kernel, suited to one developer's agent or one trusted service. It is not isolation between mutually distrusting tenants. Read the threat model before relying on it, including the platform differences: macOS is structurally weaker than Linux.
Running as root on Linux, commands run as nobody unless --host-uid/--host-gid say otherwise,
and the workspace must be writable by that user; the server says so at startup if it isn't.
On Ubuntu 23.10+ under AppArmor's unprivileged_userns restriction, --allow-network is refused
at startup, and /var/tmp and /dev/shm are the host's shared paths.
Metadata
Release files for nanosandbox-mcp 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| nanosandbox_mcp-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| nanosandbox_mcp-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| nanosandbox_mcp-0.3.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| nanosandbox_mcp-0.3.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 4.9 MB
Release files / nanosandbox_mcp-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | nanosandbox_mcp-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 1.9 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
7a3632b0a4fbea4b655224eab40404495856391728cd6e9ce58bea91f9559aeb
|
|
BLAKE2b-256 checksum How to use checksums |
47be8963137646276d8ae1a88b3ff12079acbe880b8a962707872ee6e3e9fb5b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / nanosandbox_mcp-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | nanosandbox_mcp-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 1.8 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
340e8053aa952af5ed74174fc2ffc796b225e628df66752df5199416311a462b
|
|
BLAKE2b-256 checksum How to use checksums |
56632ce4b83d7e35e1ce45c7e7b41d1df9b8027e764e282ab7fe4517c67a143d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / nanosandbox_mcp-0.3.0-py3-none-macosx_11_0_arm64.whl
| Download URL | nanosandbox_mcp-0.3.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 649.0 kB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
8c6bfaee4d6d11e2e0aafea89e6d8877f2b3762a56ad215d3077f554b847b0f5
|
|
BLAKE2b-256 checksum How to use checksums |
7e172d284bf19dd0dadb798f9bb4a1177f16c901e6d803c924a61c2d43c31ced
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|
Release files / nanosandbox_mcp-0.3.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | nanosandbox_mcp-0.3.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 661.0 kB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
8b3509f7f617f137657d374edbb5034b3d22bbc6555a28087800a2010be951b2
|
|
BLAKE2b-256 checksum How to use checksums |
47652f355b4b93fb8208092ac062cdde5655a25621c368a2fd38b103ed21c489
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
maturin/1.15.0
|