Skip to main content
Glama
yumumg

mcp-python-sandbox

by yumumg
README.md
# mcp-python-sandbox

轻量级 MCP Python 代码沙箱执行器 —— 让任意 MCP 客户端拥有本地代码解释器能力。

基于 [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) 标准协议实现,适用于低功耗、不支持 AVX 指令集的 x86 服务器(如 Intel Celeron / Atom / Pentium Silver 系列),有效规避主流托管代码解释器方案的高内存开销与 AVX 指令集依赖。

> [!WARNING]
> 本项目由 AI 辅助完成,开发目的仅为个人使用,可能存在非预期的 bug。
> 目前项目无法确认处于稳定,请谨慎使用最新代码,避免因意外问题导致损失!
> 建议配合 Docker 容器隔离部署(见下方安全模型章节)。

## ✨ 特性

- **协议通用** — 标准 MCP stdio 服务器,兼容 LibreChat、Claude Desktop、Cursor、Cline 等任意 MCP 客户端
- **异步沙箱执行** — 基于 `asyncio.create_subprocess_exec` 拉起独立子进程执行代码,主进程永不阻塞
- **临时目录隔离** — 每次请求独享 `tempfile.TemporaryDirectory()` 工作目录,执行完自动销毁,杜绝多人并发文件冲突
- **超时强杀** — `asyncio.wait_for` 时间锁,死循环代码超时立即强杀,保护宿主机 CPU
- **安全加固** — 子进程内封禁 `os.system` / `subprocess` / `eval` / `exec` 等危险调用,写文件限制在工作目录内
- **图像内联透传** — 自动劫持 `plt.show()`,matplotlib 图表以 Base64 编码通过 MCP 原生 `image` Content Block 返回,客户端直接渲染,不占用大模型上下文 Token
- **旧平台兼容** — 针对无 AVX 指令集处理器提供源码编译方案与 Docker 多阶段构建

## 📦 项目结构

```
mcp-python-sandbox/
├── pyproject.toml              # 项目元数据与依赖声明
├── Dockerfile                  # 多阶段构建(源码编译 + 精简运行时)
├── docker-compose.yml          # 镜像构建与手动测试
├── librechat.yaml              # LibreChat 对接配置示例(可选)
└── src/mcp_python_sandbox/
    ├── __init__.py
    ├── __main__.py             # python -m mcp_python_sandbox 入口
    ├── server.py               # MCP 服务主入口(FastMCP, stdio 传输)
    ├── executor.py             # 异步子进程执行引擎
    ├── preamble.py             # matplotlib plt.show() 劫持注入脚本
    └── restrictions.py         # 安全沙箱限制注入脚本
```

## 🚀 快速开始

### 方式一:Docker 部署(推荐)

源码编译全部在镜像构建阶段完成,宿主机零污染:

```bash
# 构建镜像(首次含 numpy/pandas/scipy/sklearn 源码编译,低功耗处理器上可能耗时 30-60 分钟)
docker compose build

# 手动测试 MCP 通信(可选)
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}' | docker run -i --rm mcp-python-sandbox:latest
```

### 方式二:宿主机虚拟环境部署

#### 1. 构建预装依赖的虚拟环境(Fat Venv)

预先安装常用科学计算库,避免模型每次请求时执行 `pip install` 浪费时间与 Token:

```bash
python3 -m venv /opt/mcp-python-sandbox/venv
source /opt/mcp-python-sandbox/venv/bin/activate

# ⚠️ 对指令集敏感的库:在无 AVX 处理器上必须源码编译
# (预编译轮子可能包含 AVX 指令,运行时会触发 Illegal instruction 崩溃)
# 注意:--no-binary 只锁定目标库,不要用 :all:(会连 meson/ninja/cython
# 等构建工具也强制源码构建,导致失败且不带来任何兼容性收益)
export MAKEFLAGS="-j$(nproc)"
pip install --no-binary numpy,pandas,scipy,scikit-learn \
    numpy pandas scipy scikit-learn

# 🟢 无兼容性问题的库:直接安装
pip install matplotlib seaborn Pillow \
    requests beautifulsoup4 lxml urllib3 yfinance \
    openpyxl xlrd PyPDF2 python-docx \
    python-dateutil networkx sympy
```

#### 2. 安装本项目

```bash
pip install /path/to/mcp-python-sandbox
```

## 🔌 客户端接入

本项目为标准 MCP stdio 服务器,任何支持 MCP 的客户端均可接入。

### LibreChat(`librechat.yaml`)

```yaml
mcpServers:
  python-sandbox:
    command: "docker"
    args:
      - "run"
      - "-i"
      - "--rm"
      - "--memory=512m"
      - "--cpus=2"
      - "--security-opt=no-new-privileges:true"
      - "--read-only"
      - "--tmpfs=/tmp"
      - "--tmpfs=/home/sandbox"
      - "mcp-python-sandbox:latest"
    timeout: 90000
```

### Claude Desktop(`claude_desktop_config.json`)

```json
{
  "mcpServers": {
    "python-sandbox": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "--memory=512m", "--cpus=2",
               "mcp-python-sandbox:latest"]
    }
  }
}
```

### 宿主机虚拟环境方式(任意客户端)

```yaml
command: "/opt/mcp-python-sandbox/venv/bin/python"
args: ["-m", "mcp_python_sandbox"]
```

> 💡 Cursor / Cline / VS Code 等客户端的 MCP 配置结构与上述示例基本一致,仅配置文件位置不同。

## 🔧 工具接口

服务暴露单个 MCP 工具:

### `execute_python`

| 参数 | 类型 | 说明 |
|------|------|------|
| `code` | `string` | 要执行的 Python 代码 |

**返回**:多模态 Content Block 列表

```json
{
  "content": [
    { "type": "text", "text": "执行输出(已剔除 Base64 巨串)" },
    { "type": "image", "data": "<base64>", "mimeType": "image/png" }
  ]
}
```

- 代码中调用 `plt.show()` 的图表会自动以内联图片返回
- 默认超时 60 秒,超时后子进程被强杀
- 每次执行拥有独立临时工作目录,结束后自动销毁

> 图像内联渲染依赖客户端对 MCP `image` 类型的支持(LibreChat、Claude Desktop、Cursor 等主流客户端均已支持);不支持的客户端仍可正常执行代码,仅不显示图表。

## 🛡️ 安全模型

多层纵深防御:

| 层级 | 机制 |
|------|------|
| 容器层(Docker) | `--read-only` + `no-new-privileges` + 非 root 用户 |
| 资源层 | `--memory=512m --cpus=2` 硬限制 + 60s 超时强杀 |
| 代码层 | 注入沙箱脚本封禁 `os.system` / `subprocess` / `eval` / `exec` / `ctypes` 等 |
| 文件系统层 | tmpfs 临时目录隔离,写操作限制在工作目录内,执行后销毁 |

> ⚠️ 注意:代码层的 Python 沙箱可被高级技巧绕过,**请不要作为唯一防线**。生产环境建议使用 Docker 部署进行容器层隔离。

## 🖼️ 图像透传原理

```
AI 生成代码
    │
    ▼ MCP 服务端注入前置脚本(劫持 plt.show → Base64 输出到 stdout)
子进程执行
    │
    ▼ stdout 含 [IMAGE_DATA_BEGIN]<base64>[IMAGE_DATA_END] 标记
MCP 服务端正则提取
    │
    ├─▶ 文本部分(已剔除 Base64)→ type: "text"   → 大模型上下文保持干净
    └─▶ Base64 图像数据          → type: "image"  → 客户端原生渲染
```

## 📋 环境要求

- Python >= 3.10
- MCP SDK >= 1.0.0
- 任意支持 MCP 的客户端(LibreChat / Claude Desktop / Cursor / Cline 等)
- Docker(可选,推荐)

## 📄 License

本项目采用 [MIT License](LICENSE)。