使用说明
沙盒mcp
本地AI代理沙盒。在Mac上运行独立的Linux虚拟机大约需要60毫秒。没有云成本。通过Virtualization.framework实现VM级隔离。与支持本地stdio服务器(Claude Code、Claude Desktop、Cursor)的MCP客户端配合使用。
这是什么
MCP服务器为AI代理提供沙盒Linux环境,使用 苹果集装箱化 (虚拟化框架)。每个沙箱都是一个真正的虚拟机,而不是一个共享内核的容器,它在大约700毫秒内启动,并通过vsock上的持久shell在大约60毫秒内执行命令。
与云沙盒相比(截至2025年初):
| 执行延迟 | 成本 | 隔离 | |
|---|---|---|---|
| 此(本地) | ~60ms | 本地硬件 | VM(虚拟化框架) |
| E2B | ~150ms+网络 | 0.18美元/小时 | 鞭炮微型VM |
| Daytona | ~90ms+网络 | 基于使用 | Docker容器 |
快速演示
注册后,您的MCP客户端可以直接使用沙盒工具:
Agent: exec(command="uname -a")
→ Linux mcp-sb-abc123 6.12.6 #1 SMP aarch64 Linux
Agent: install(packages="python3 py3-pip")
→ Installed python3 py3-pip (1230ms)
Agent: exec(command="python3 -c 'print(sum(range(1000)))'")
→ 499500
Agent: bg(command="python3 -m http.server 8000")
→ Started [bg-a1b2c3] PID 42
Agent: expose(port=8000)
→ Forwarding localhost:8000 → 'default':8000
Open http://localhost:8000
冷启动时间约为700ms,后续命令每次约为60ms。
需求
- 苹果硅Mac(M1+)
- macOS 15红杉+
- Python 3.11+
- 紫外线 (用于包装)
设置
1.安装苹果容器
# Download and install the container CLI
curl -LO https://github.com/apple/containerization/releases/download/v0.9.0/container-v0.9.0.pkg
sudo installer -pkg container-v0.9.0.pkg -target /
# Start the container system (downloads kernel on first run)
container system start
# Verify it works
time container run --rm alpine echo "hello" # ~700ms cold boot
2.构建开发镜像
包括 Containerfile.mcp-dev 构建一个预装了Python、Node.js、Go、Rust和标准构建工具的Alpine映像:
cd sandbox-mcp
container build -t mcp-dev -f Containerfile.mcp-dev .
3.安装MCP服务器
uv sync
4.向您的MCP客户注册
克劳德代码:
claude mcp add sandbox -- uv --directory /path/to/sandbox-mcp run sandbox-mcp
手册(~/.claude.json):
{
"mcpServers": {
"sandbox": {
"type": "stdio",
"command": "/path/to/uv",
"args": ["--directory", "/path/to/sandbox-mcp", "run", "sandbox-mcp"]
}
}
}
5.构建优化的内核(可选)
苹果的容器化仓库包括一个精简的Linux内核配置。自己编译并不能有意义地改善执行延迟——~700ms的下限是VM生命周期开销(Virtualization.framework+EXT4+网络+vminitd),而不是内核引导。真正的胜利是让虚拟机保持温暖,并使用持久的shell exec(~60ms)。
也就是说,如果你想要一个更小的内核:
git clone https://github.com/apple/containerization.git
cd containerization/kernel
make # ~3 min on M-series
container system kernel set --binary ./vmlinux
container system stop && container system start
运作原理
Agent ──MCP/stdio──▶ sandbox_mcp_server.py (FastMCP)
│
├── SandboxManager
│ ├── _sandboxes: dict[name, Sandbox]
│ ├── _port_forwards: dict[port, PortForward]
│ ├── _sync_jobs: dict[id, SyncJob]
│ └── _cleanup_loop (idle TTL + child TTL)
│
├── SandboxCtlServer (per-parent UDS listener)
│ └── NDJSON over /run/sandbox-ctl.sock
│ → spawn, list, exec, destroy, run
│
└── Sandbox (per-VM)
├── PersistentShell (container exec -i <name> sh)
├── _bg_processes: dict[id, Process]
└── _audit_log: deque
延迟细分:
- 冷启动:~700ms(虚拟化框架+EXT4+网络+vminitd)
- 温暖的执行官:~60ms(命令通过vsock管道传输到持久shell)
- 为什么温暖很快:每个沙箱都有一个打开的
container exec -i <name> sh过程。命令以唯一的结束标记写入stdin,读取输出直到标记出现。每个命令没有进程生成开销。
端口转发
苹果容器v0.9.0 -p 端口发布中断(TCP连接但数据从未流动),VM IP无法从主机路由。端口转发通过asyncio TCP代理工作:
expose在上启动本地TCP服务器127.0.0.1:<host_port>- 每个传入连接都会生成
container exec -i <name> nc 127.0.0.1 <container_port> - 数据通过vsock在客户端和nc进程之间双向传输
多沙箱
沙盒已命名(默认值: "default").每个都有独立的卷 /workspace 以及包缓存(apk、pip、npm)。缓存在重置过程中保持不变,以便快速重新安装。沙盒可以通过以下方式按名称相互联系 /etc/hosts 当网络可用时,条目会自动注入。
档案
在中配置每个沙盒名称资源 SANDBOX_PROFILES 在服务器的顶部:
SANDBOX_PROFILES = {
"ml": {"cpus": 4, "memory": "2G"},
"build": {"cpus": 4, "memory": "1G"},
"nested": {"cpus": 2, "memory": "1G", "virtualization": True},
}
这 virtualization 标志启用嵌套虚拟化(--virtualization).苹果容器不支持GPU/Metal passthrough——内核有 CONFIG_DRM_VIRTIO_GPU 禁用,Swift框架不使用 VZVirtioGraphicsDeviceConfiguration.
儿童沙盒
沙盒可以生成子沙盒,由以下方式控制 SPAWN_POLICIES 在服务器的顶部。策略定义了每个父级的限制:最大并发子级、生命周期生成计数、CPU/内存预算、允许的映像和TTL。未列出的沙盒名称无法生成。
子级是轻量级的——它们跳过缓存卷,获得自己的隔离工作区。当TTL到期或其父级重置/销毁时,它们会自动销毁。
设置 child_can_spawn: True 在一项政策中,允许孩子们生育自己的孩子(孙子孙女),深度可达 _MAX_SPAWN_GENERATION (默认值2)。孙子策略是自动派生的——并发/预算限制减半,没有进一步的子生成。树范围的预算检查确保无论生成深度如何,根沙盒的CPU/内存包络都不会被超过。默认情况下,此选项处于关闭状态,不建议用于大多数用例。
API容器(sandbox-ctl)
当沙箱具有生成策略时 inject_ctl: True (默认),服务器装载UDS套接字 sandbox-ctl 将二进制文件导入VM。集 inject_ctl: False 对于VM子启动中不需要的沙盒,跳过注入。然后,在VM内运行的代码可以生成/管理兄弟容器:
sandbox-ctl ping # verify connection
sandbox-ctl spawn --image mcp-dev --cpus 1 --memory 256M # create child
sandbox-ctl list # show children
sandbox-ctl exec <child> -- echo hello # run in child
sandbox-ctl destroy <child> # tear down
sandbox-ctl run -- echo test # ephemeral: spawn + exec + destroy
通信通过安装的套接字使用NDJSON(/run/sandbox-ctl.sock).主机端 SandboxCtlServer 处理请求并委派给 SandboxManager.
状态持久性
沙盒到容器的映射保存到 ~/.local/state/sandbox-mcp/state.json (模式v2)。重新启动时,服务器将重新连接到上一个会话中仍在运行的任何容器。过期的孩子在重新连接时会被清理。
工具(35)
核心
| 工具 | 说明 |
|---|---|
exec |
运行shell命令(~60ms) |
python |
执行Python代码 |
write_file |
将文件写入沙盒 |
read_file |
从沙盒中读取文件 |
batch_write |
在一次传输中写入多个文件 |
install |
通过apk安装软件包 |
env |
管理持久环境变量 |
过程管理
| 工具 | 说明 |
|---|---|
bg |
在后台运行命令 |
logs |
读取后台进程的输出 |
kill |
终止后台进程 |
沙盒生命周期
| 工具 | 说明 |
|---|---|
status |
显示池和沙盒信息 |
health |
在所有沙盒中快速检查活动性/磁盘/内存 |
stats |
显示一个沙盒的CPU/内存/磁盘使用情况 |
reset |
销毁并重新创建(干净状态) |
list_all |
列出所有活动沙盒 |
destroy |
永久杀死沙盒 |
clone |
将正在运行的沙盒克隆为新名称 |
history |
显示最近的命令审核日志 |
文件传输
| 工具 | 说明 |
|---|---|
upload |
将文件从主机复制到沙盒 |
download |
将文件从沙盒复制到主机 |
git_clone |
克隆一个git仓库(带有可选的身份验证令牌) |
sync_start |
监视并实时同步主机目录 |
sync_stop |
停止正在运行的同步作业 |
快照和图像
| 工具 | 说明 |
|---|---|
snapshot |
将沙盒状态保存为可重用映像 |
restore |
从已保存的快照启动 |
list_snapshots |
列出可用快照 |
delete_snapshot |
删除已保存的快照映像 |
build_image |
从Containerfile构建容器映像 |
images |
列出所有可用的容器图像 |
网络
| 工具 | 说明 |
|---|---|
expose |
将沙盒端口转发到localhost(TCP代理) |
unexpose |
阻止端口前进 |
network_info |
显示沙盒之间的IP和连接 |
儿童沙盒
| 工具 | 说明 |
|---|---|
spawn |
在父母的指导下创建一个儿童沙盒 |
children |
列出父级的子沙盒 |
destroy_child |
销毁儿童沙盒 |
文件
| 文件 | 描述 |
|---|---|
sandbox_mcp_server.py |
沙盒类、沙盒管理器、MCP工具定义 |
cmd/sandbox-ctl/ |
用于生成兄弟沙盒的容器内CLI(Go) |
pyproject.toml |
紫外线/孵化包装,入口点 sandbox-mcp |
Containerfile.mcp-dev |
Alpine 3.23开发镜像,包含Python、Node、Go和Rust |
tests/ |
pytest测试套件 |
定制
在顶部编辑常量 sandbox_mcp_server.py:
| 常量 | 默认值 | 描述 |
|---|---|---|
DEFAULT_IMAGE |
"mcp-dev" |
新沙盒的容器映像 |
SANDBOX_CPUS |
2 |
每个沙盒的默认CPU核心 |
SANDBOX_MEMORY |
"512M" |
每个沙盒的默认内存 |
IDLE_TTL |
1800 |
自动销毁空闲沙盒前的几秒钟 |
DEFAULT_TIMEOUT |
30 |
默认命令超时时间(秒) |
MAX_OUTPUT |
50000 |
每个命令的最大输出字节数 |
SPAWN_POLICIES |
{"default": {...}} |
每个沙盒的子生成限制和权限 |
_MAX_SPAWN_GENERATION |
2 |
最大产卵深度(根→ 孩子→ 孙子) |
测试
uv run pytest tests/ -v
持续集成
测试通过GitHub Actions在Python 3.11、3.12和3.13上运行。预推:
uv run pytest tests/ -q && python3 -m compileall sandbox_mcp_server.py tests
