Skip to content

Commit a4ded22

Browse files
committed
Mount the sandbox as an MCP server; default to unsandboxed host tools
Pion now has exactly two execution modes: - off (new default): bash/read/write/edit run directly on the host — no Docker startup, no warning banner. - mcp: Pion spawns its own "pion mcp" child and mounts it like any other MCP server. The default toolset becomes sandbox__bash/read/write/edit executed in the hardened Docker container; host default tools are not registered. The parent preflights the Docker daemon (fail-closed) and forwards sandbox settings via PION_SANDBOX_* env vars. The new "pion mcp" command serves the full default toolset over stdio (mcp.server.lowlevel), so any MCP client (Claude Code, Cursor, ...) can mount pion's sandbox: non-root container, cap-drop ALL, no docker.sock, read-only .git, secret masking, orphan cleanup. The integrated in-process Docker backend is removed: SandboxBackend is now "off" | "mcp" (default "off"), legacy "docker" config values migrate to "mcp", and --sandbox docker works as a deprecated alias. Docker is no longer required for a default launch. Tests: end-to-end stdio tests for the server (tests/test_mcp_server.py), MCP-backend wiring + preflight tests, config migration, updated default backend expectations. README (en/zh-CN) rewritten for the two modes with external-client mounting examples.
1 parent 6948686 commit a4ded22

10 files changed

Lines changed: 619 additions & 120 deletions

File tree

README.md

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,30 +122,52 @@ variables are inherited. Environment values are redacted from Pion's MCP
122122
startup and shutdown errors. The timeout applies to connection setup,
123123
discovery, and tool calls.
124124

125-
MCP stdio servers are trusted host processes. They are **not** run inside
126-
Pion's Docker sandbox and may access resources available to the Pion process.
127-
Only configure servers and commands you trust. This first release supports MCP
128-
tools over stdio; MCP resources, prompts, and Streamable HTTP are not yet
129-
exposed.
125+
MCP stdio servers are trusted host processes. Except for Pion's own `pion
126+
mcp` sandbox server, they are **not** run inside the Docker sandbox and may
127+
access resources available to the Pion process. Only configure servers and
128+
commands you trust. This first release supports MCP tools over stdio; MCP
129+
resources, prompts, and Streamable HTTP are not yet exposed.
130130

131-
## Docker sandbox
131+
## Sandbox (mounted as MCP)
132132

133-
Pion runs its default shell and file tools with a Docker sandbox. Docker is
134-
fail-closed: if the CLI, daemon, image build, or container startup is
135-
unavailable, Pion exits before sending a request to the model. Use
136-
`--sandbox off` only when unrestricted host execution is intentional.
133+
By default Pion runs its shell and file tools **directly on the host** — no
134+
Docker, no sandbox. Sandboxing is an opt-in capability mounted through MCP:
135+
136+
```text
137+
pion # host tools, no sandbox (default)
138+
pion --sandbox mcp # mount the Docker sandbox as an MCP server
139+
```
140+
141+
With `--sandbox mcp` (or `"sandbox": {"backend": "mcp"}` in
142+
`~/.pion/config.json`), Pion starts its own `pion mcp` child process and
143+
mounts it like any other MCP server. The default tools become
144+
`sandbox__bash`, `sandbox__read`, `sandbox__write`, `sandbox__edit`, and the
145+
host-side default tools are **not** registered. Docker is fail-closed: if
146+
the daemon is unavailable, Pion exits before sending a request to the model.
147+
148+
The same `pion mcp` server can be mounted by **any MCP client** (Claude
149+
Code, Cursor, …):
150+
151+
```json
152+
{
153+
"mcpServers": {
154+
"pion-sandbox": { "command": "pion", "args": ["mcp"] }
155+
}
156+
}
157+
```
137158

138159
The sandbox keeps Pion itself, model credentials, configuration, and sessions
139-
on the host. It creates one disposable, non-root container per Pion process and
140-
bind-mounts only the current project at the same absolute path. Project changes
141-
are therefore visible immediately on the host. Git metadata is read-only by
142-
default, `.env` files are denied to file tools and masked in the container, and
143-
host environment variables and the Docker socket are not injected.
160+
on the host. It creates one disposable, non-root container per server process
161+
and bind-mounts only the current project at the same absolute path. Project
162+
changes are therefore visible immediately on the host. Git metadata is
163+
read-only by default, `.env` files are denied to file tools and masked in the
164+
container, and host environment variables and the Docker socket are not
165+
injected.
144166

145-
Useful options:
167+
Useful options (forwarded to the sandbox server):
146168

147169
```text
148-
--sandbox docker|off
170+
--sandbox off|mcp
149171
--sandbox-image IMAGE
150172
--sandbox-network bridge|none
151173
--sandbox-git-write
@@ -165,7 +187,7 @@ Sandbox defaults can be stored in the version 1 configuration:
165187
{
166188
"version": 1,
167189
"sandbox": {
168-
"backend": "docker",
190+
"backend": "off",
169191
"image": null,
170192
"network": "bridge",
171193
"memory_mb": 4096,
@@ -179,6 +201,10 @@ Sandbox defaults can be stored in the version 1 configuration:
179201
}
180202
```
181203

204+
Legacy `"backend": "docker"` values are migrated to `"mcp"` automatically —
205+
the integrated in-process Docker path no longer exists; the same hardened
206+
container engine now lives inside the `pion mcp` server.
207+
182208
A custom image must already be available to Docker and provide `sleep` plus the
183209
tools needed by the agent. The built-in image contains Python 3.12, uv, Bash,
184210
Git, ripgrep, curl, certificates, and basic compilation tools.

README.zh-CN.md

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,25 +108,46 @@ Pion 内置了基于 stdio 的 [Model Context Protocol](https://modelcontextprot
108108
启动和关闭错误中会隐藏已配置的环境变量值。超时时间同时用于连接、工具发现和工具
109109
调用。
110110

111-
stdio MCP 服务是受信任的宿主进程,**不会**在 Pion 的 Docker 沙盒中运行,能够访问
112-
Pion 进程可访问的宿主资源。请只配置你信任的服务和命令。首版仅支持通过 stdio
113-
使用 MCP tools,暂不提供 resources、prompts 和 Streamable HTTP。
111+
stdio MCP 服务是受信任的宿主进程(pion 自带的 `pion mcp` 沙盒服务除外),
112+
**不会**在 Pion 的 Docker 沙盒中运行,能够访问 Pion 进程可访问的宿主资源。请只
113+
配置你信任的服务和命令。首版仅支持通过 stdio 使用 MCP tools,暂不提供
114+
resources、prompts 和 Streamable HTTP。
114115

115-
## Docker 沙盒
116+
## 沙盒(以 MCP 方式挂载)
116117

117-
Pion 默认使用 Docker 沙盒运行 shell 和文件工具。Docker 采用失败关闭策略:
118-
如果 Docker CLI、daemon、镜像构建或容器启动不可用,Pion 会在向模型发送请求前退出。
119-
只有明确需要不受限制的宿主执行时,才应使用 `--sandbox off`
118+
默认情况下 Pion 的 shell 和文件工具**直接在宿主机运行**——不启动 Docker、不启用
119+
沙盒。沙盒是一项按需挂载的 MCP 能力:
120120

121-
Pion 进程本身、模型凭据、配置和会话保留在宿主机上。每个 Pion 进程会创建一个
121+
```text
122+
pion # 宿主工具,无沙盒(默认)
123+
pion --sandbox mcp # 以 MCP 服务方式挂载 Docker 沙盒
124+
```
125+
126+
使用 `--sandbox mcp`(或在 `~/.pion/config.json` 中设置 `"sandbox": {"backend":
127+
"mcp"}`)后,Pion 会启动自带的 `pion mcp` 子进程并像挂载其他 MCP 服务一样挂载它。
128+
默认工具变为 `sandbox__bash``sandbox__read``sandbox__write``sandbox__edit`
129+
宿主机默认工具**不再注册**。Docker 采用失败关闭策略:daemon 不可用时,Pion 会在向
130+
模型发送请求前退出。
131+
132+
同一个 `pion mcp` 服务也可以被**任意 MCP client**(Claude Code、Cursor 等)挂载:
133+
134+
```json
135+
{
136+
"mcpServers": {
137+
"pion-sandbox": { "command": "pion", "args": ["mcp"] }
138+
}
139+
}
140+
```
141+
142+
Pion 进程本身、模型凭据、配置和会话保留在宿主机上。每个沙盒服务进程会创建一个
122143
一次性的非 root 容器,并仅将当前项目以相同的绝对路径绑定挂载到容器中。因此,
123144
项目修改会实时反映到宿主机。Git 元数据默认只读;文件工具无法访问 `.env` 文件,
124145
容器内对应路径也会被遮蔽;宿主环境变量和 Docker socket 不会注入容器。
125146

126-
常用选项:
147+
常用选项(会转发给沙盒服务)
127148

128149
```text
129-
--sandbox docker|off
150+
--sandbox off|mcp
130151
--sandbox-image IMAGE
131152
--sandbox-network bridge|none
132153
--sandbox-git-write
@@ -144,7 +165,7 @@ Pion 进程本身、模型凭据、配置和会话保留在宿主机上。每个
144165
{
145166
"version": 1,
146167
"sandbox": {
147-
"backend": "docker",
168+
"backend": "off",
148169
"image": null,
149170
"network": "bridge",
150171
"memory_mb": 4096,
@@ -158,6 +179,9 @@ Pion 进程本身、模型凭据、配置和会话保留在宿主机上。每个
158179
}
159180
```
160181

182+
旧的 `"backend": "docker"` 配置会自动迁移为 `"mcp"`——进程内集成的 Docker 路径
183+
已移除,同一套加固容器引擎现在运行在 `pion mcp` 服务内部。
184+
161185
自定义镜像必须已经存在于 Docker 本地,并提供 `sleep` 以及 Agent 所需的工具。
162186
内置镜像包含 Python 3.12、uv、Bash、Git、ripgrep、curl、CA 证书和基础编译工具。
163187

0 commit comments

Comments
 (0)