代码沙盒服务

一个自托管的MCP服务器,允许LLM在隔离的Docker容器中执行Python代码,迭代错误并检索生成的文件(如图表、PDF、数据文件等)。

  • by gaiar
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 gaiar/mcp-code-sandbox

使用说明

mcp代码沙箱

自托管MCP服务器,允许LLM在隔离的Docker容器中执行Python,迭代错误,并检索生成的工件(图表、PDF、数据文件)。

专为与Claude Code、n8n和任何兼容MCP的客户端一起使用而构建。

运作原理

MCP Client (Claude Code, n8n, ...)
    │  stdio / streamable HTTP
    ▼
FastMCP Server (5 tools)
    │
    ▼
SessionManager (docker-py)
    │
    ▼
Sandbox Container (per session)
    --network none
    --cap-drop ALL
    --read-only rootfs
    /mnt/data/ (writable volume)

每个会话都会获得一个专用的Docker容器,其中预装了pandas、numpy、matplotlib、seaborn、scipy、openpyxl、reportlab和pyarrow。容器是完全隔离的——没有网络,没有功能,只读根文件系统。文件持续存在 /mnt/data/ 同一会话内的通话。

MCP工具

工具 说明
sandbox_run_python 执行Python代码并返回stdout、stderr、退出代码和新工件
sandbox_upload_file 将数据文件(CSV、Excel、JSON等)上传到会话中
sandbox_read_artifact 将生成的文件以base64格式读回
sandbox_list_artifacts 列出会话中的所有文件 /mnt/data/ 目录
sandbox_close_session 销毁会话容器并释放资源

所有工具都返回结构化响应,无一例外。错误包括机器可读代码(file_exists, session_busy, code_too_large等等),因此LLM可以以编程方式对其进行操作。

快速开始

先决条件

  • Python 3.12+
  • Docker守护进程正在运行
  • conda(建议使用Miniforge)

设置

# Clone
git clone https://github.com/gaiar/mcp-code-sandbox.git
cd mcp-code-sandbox

# Create conda environment
conda create -n mcp-code-sandbox python=3.12 -y
conda activate mcp-code-sandbox
pip install -e ".[dev]"

# Build the sandbox Docker image
docker build -t llm-sandbox:latest docker/

跑

# Start the MCP server (stdio transport)
mcp-code-sandbox

# Or run as a module
python -m mcp_code_sandbox

Claude代码集成

添加到您的Claude Code MCP配置中(~/.claude/claude_code_config.json):

{
  "mcpServers": {
    "code-sandbox": {
      "command": "mcp-code-sandbox"
    }
  }
}

工作流示例

上传CSV、运行分析、生成图表并检索它——所有这些都在一个会话中完成:

User: "Analyze sales.csv and create a revenue chart"

LLM calls: sandbox_upload_file(filename="sales.csv", content_base64="...")
  → {"session_id": "sess_a1b2c3d4e5f6", "path": "/mnt/data/sales.csv"}

LLM calls: sandbox_run_python(session_id="sess_a1b2c3d4e5f6", code="
    import pandas as pd
    import matplotlib.pyplot as plt
    df = pd.read_csv('/mnt/data/sales.csv')
    print(df.describe())
    df.groupby('month')['revenue'].sum().plot(kind='bar')
    plt.savefig('/mnt/data/chart.png')
")
  → {"exit_code": 0, "stdout": "...", "artifacts": [{"filename": "chart.png", ...}]}

LLM calls: sandbox_read_artifact(session_id="sess_a1b2c3d4e5f6", path="/mnt/data/chart.png")
  → {"content_base64": "iVBORw0KGgo...", "mime_type": "image/png"}

LLM calls: sandbox_close_session(session_id="sess_a1b2c3d4e5f6")
  → {"status": "closed"}

如果代码失败,LLM将读取错误、修复代码并重试——所有这些都在同一会话中进行。文件在通话中持续存在。

配置

所有设置均通过环境变量进行 SANDBOX_ 前缀:

变量 默认值 描述
SANDBOX_IMAGE llm-sandbox:latest 沙盒容器的Docker镜像
SANDBOX_MEMORY_LIMIT 512m 容器内存限制
SANDBOX_CPU_LIMIT 1.0 容器CPU内核
SANDBOX_EXEC_TIMEOUT_S 60 代码执行超时(秒)
SANDBOX_SESSION_TTL_M 30 会话空闲超时(分钟)
SANDBOX_MAX_SESSIONS 10 最大并发会话数
SANDBOX_MAX_UPLOAD_BYTES 52428800 最大文件上传大小(50 MB)
SANDBOX_MAX_OUTPUT_BYTES 102400 每次执行的最大stdout/stderr(100 KB)
SANDBOX_MAX_CODE_BYTES 102400 最大代码长度(100 KB)
SANDBOX_HTTP_HOST 127.0.0.1 HTTP工件服务器绑定地址
SANDBOX_HTTP_PORT 8080 HTTP工件服务器端口
SANDBOX_LOG_LEVEL INFO 日志级别(调试、信息、警告、错误)
SANDBOX_LOG_FILE logs/sandbox.log 日志文件路径
SANDBOX_LOG_FORMAT console 日志格式(console 或 json)

集装箱安全

每个沙盒容器都运行:

  • 无网络 — --network none 阻止所有出站连接
  • 没有能力 — --cap-drop ALL 删除所有Linux功能
  • 无特权升级 — --security-opt no-new-privileges
  • 只读root — --read-only 使用tmpfs /tmp (64 MB)且可写 /mnt/data/ 体积
  • 非root用户 --运行为 sandbox (uid 1000)
  • 资源限制 --可配置内存(512 MB)和CPU(1.0核)
  • 执行超时 --60秒后死亡(可配置)
  • 自动清理 --空闲会话在30分钟后过期;启动时删除孤立容器

沙盒包

Docker镜像包括:

包装 使用
pandas 数据操作和分析
numpy 数值计算
matplotlib 图表和绘图
seaborn 统计可视化
scipy 统计检验和科学计算
openpyxl Excel文件读/写
reportlab PDF生成
pyarrow 支持拼花和箭头格式

HTTP工件服务器

可选的HTTP服务器与MCP服务器一起运行,用于直接工件下载:

GET http://localhost:8080/files/{session_id}/{filename}

文物在 RunResult 包括a download_url HTTP服务器处于活动状态时的字段。

发展

# Activate environment
conda activate mcp-code-sandbox

# Run all tests (88 total)
pytest tests/ -v

# Unit tests only (no Docker needed)
pytest tests/unit/ -v

# Integration tests (requires Docker)
pytest tests/integration/ -m integration -v

# Code quality
ruff check src/ tests/
ruff format --check src/ tests/
mypy src/

# Run smoke test
python test_real_life.py

# Run large-scale EDA test (50K rows)
python test_eda_large.py

建筑

src/mcp_code_sandbox/
├── server.py          # FastMCP server + 5 tool definitions
├── session.py         # SessionManager: container lifecycle, exec, artifacts
├── models.py          # Pydantic response models (RunResult, ErrorResponse, etc.)
├── config.py          # SandboxConfig with env var parsing
├── validation.py      # Input validation (session IDs, filenames, sizes)
├── logging.py         # structlog file-only setup with contextvars
├── cleanup.py         # TTL cleanup thread + orphan removal
├── http_server.py     # Starlette/uvicorn artifact download server
└── __main__.py        # python -m entry point

tests/
├── unit/              # 55 tests (no Docker required)
└── integration/       # 33 tests (requires Docker daemon)

docker/
└── Dockerfile         # Sandbox image with scientific Python packages

许可证

麻省理工学院