Token导航 LogoToken导航TokenDH.com
Rl Sandbox MCP logo
AI代理stdio官方级别未说明来源级核验

Rl Sandbox MCP

MCP Server

一个安全的隔离环境,AI代理可以在LibreOffice中执行电子表格任务,并通过MCP协议进行交互,支持自动性能评估。

工具数

17

提示词数

0

GitHub Stars

0

资源数

0
PythonClaudeAI代理Claude DesktopClaudeCursor

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

arnavgarg233

提供方

arnavgarg233

最后核验

2026/5/17 20:19

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

pip install streamlit openai

详细介绍

基于MCP的沙盒任务环境

一个安全、隔离的RL环境,AI代理可以在LibreOffice中执行电子表格任务,并自动评估性能。代理通过 模型上下文协议(MCP) API,支持基于GUI(计算机使用)和编程(odfpy)交互模式。

视频演示: 织机-MCP沙盒演示

演示和评分验证

演示仪表板(scripts/demo_ui.py)运行这两个代理,并在每次MCP工具调用时实时显示电子表格更新。

pip install streamlit openai
docker compose up -d
streamlit run scripts/demo_ui.py

脚本代理(scripts/demo_agent.py)

一个按顺序调用MCP工具的确定性Python代理: list_filesget_sheet_inforead_range → 计算插值储量→ write_cell + write_rangetask/complete。每次得分100%。

LLM代理(scripts/llm_agent.py)

一个GPT-4o代理,可以自主发现并使用MCP工具来解决相同的任务。GPT-4o接收所有17个可用工具的列表,并决定调用哪个工具。

我们如何知道评分是有效的——GPT-4o的迭代故事:

当GPT-4o被赋予完全自主权时,它试图通过以下方式编写原始odfpy代码 execute_python 和一贯的失败-odfpy的API是不明显的,模型不断产生有缺陷的细胞操作代码(错误的属性名称,错误的类型转换)。评分员抓住了每一个错误:GPT-4o的首次尝试得分 67%(214/315个细胞),评分报告显示了哪些细胞是错误的,以及为什么。

在观察到这些故障后,我们指导GPT-4o使用 execute_python 与熊猫(pd.read_excel / df.to_excel 使用odf引擎),它对此非常熟悉。这使比分达到 100%(315/315个细胞).

这表明了两件事:

  1. 分级系统有效 --它捕获不正确的输出并报告精确的单元格级别不匹配
  2. 沙箱很灵活 --代理可以直接使用MCP工具,运行任意Python,或结合这两种方法

最终LLM代理流程:

  1. list_filesget_sheet_inforead_range (通过MCP发现和读取数据)
  2. write_cell (通过MCP设置标题)
  3. execute_python 使用pandas脚本(计算插值+写入结果)
  4. TASK_COMPLETE → 平地机运行→ PASS

架构概述

┌─────────────────────────────────────────────────────────┐
│                    Host Machine                         │
│                                                         │
│  ┌──────────────┐    ┌──────────────────────────────┐   │
│  │   sandbox_    │    │     Docker Container         │   │
│  │   manager.py  │───▶│  ┌────────────────────────┐  │   │
│  │              │    │  │     MCP Server (:8080)  │  │   │
│  │  • build     │    │  │                        │  │   │
│  │  • run       │    │  │  17 Tools Exposed:     │  │   │
│  │  • grade     │    │  │  • 9 Programmatic      │  │   │
│  │  • destroy   │    │  │  • 8 Computer Use      │  │   │
│  └──────────────┘    │  └────────┬───────────────┘  │   │
│                      │           │                   │   │
│  ┌──────────────┐    │  ┌────────▼───────────────┐  │   │
│  │  shared/     │◀──▶│  │  /workspace            │  │   │
│  │  (volume     │    │  │  • cash_flows.ods      │  │   │
│  │   mount)     │    │  │  • (agent output)      │  │   │
│  └──────────────┘    │  └────────────────────────┘  │   │
│                      │                               │   │
│  ┌──────────────┐    │  ┌────────────────────────┐  │   │
│  │  grader.py   │    │  │  LibreOffice Calc      │  │   │
│  │  • compare   │    │  │  Xvfb (virtual display)│  │   │
│  │  • score     │    │  │  Python + pandas/odfpy │  │   │
│  └──────────────┘    │  └────────────────────────┘  │   │
│                      │                               │   │
│                      │  🔒 Network-restricted:        │   │
│                      │  │  iptables blocks outbound   │   │
│                      │  │  DNS disabled, caps dropped  │   │
│                      │  🔒 2GB RAM / 2 CPU / 256 PIDs│   │
│                      └──────────────────────────────┘   │
└─────────────────────────────────────────────────────────┘

沙盒生命周期:

  1. 从镜像构建容器(Ubuntu 22.04+LibreOffice+Python)
  2. 将特定任务的起始文件复制到共享工作区
  3. 代理通过MCP连接并处理任务
  4. 代理发出“完成”信号时提取输出文件
  5. 运行分级脚本,将输出与oracle进行比较
  6. 销毁容器(下次尝试时彻底销毁)

先决条件

  • Docker 桌面版 (macOS/Windows)或Docker引擎(Linux)
  • Python 3.10+ (用于在本地运行沙盒管理器、分级和测试)
pip install -e ".[dev]"

这将安装所有运行时依赖项(odfpy, openpyxl, pydantic, starlette, uvicorn, mcp)以及开发依赖关系(pytest, httpx).由于测试套件导入,因此需要MCP SDK mcp_server.py,使用 mcp.server.Servermcp.server.sse.SseServerTransport.

快速开始

1.生成示例任务文件

python3 tasks/banking_reserve/generate_task_files.py

这将创建:

  • tasks/banking_reserve/starting_files/cash_flows.ods --带有稀疏速率点的100行电子表格
  • tasks/banking_reserve/oracle/expected_reserves.ods --正确答案加上插值储备

2.构建Docker镜像

python3 scripts/sandbox_manager.py build

3.端到端运行任务

python3 scripts/sandbox_manager.py run --task banking_reserve

这将:

  • 将起始文件复制到 shared/
  • 启动具有网络限制(iptables+DNS阻止)的容器
  • 等待代理完成(或300秒后超时)
  • 提取输出文件
  • 运行评分脚本
  • 打印分数
  • 销毁容器

4.或者使用docker compose手动运行

docker compose up -d          # start the container
curl http://localhost:8080/health   # verify it's running
curl http://localhost:8080/tools    # see all 17 MCP tools
docker compose down           # stop and remove

MCP协议实现

服务器建立在官方 MCP Python SDK (mcp>=1.0.0).核心MCP实现使用 mcp.server.Server 用于工具/资源注册和 mcp.server.sse.SseServerTransport 用于符合标准的SSE传输——与Claude Desktop、Cursor和其他MCP客户端本机使用的JSON-RPC协议相同。

工具通过注册 @mcp_sdk_server.list_tools()@mcp_sdk_server.call_tool() 装饰师和资源通过 @mcp_sdk_server.list_resources()。两种传输方式共享相同的内容 TOOL_HANDLERS 调度表,因此无论客户端如何连接,行为都是相同的。

传输1:MCP SDK(SSE)——符合标准

任何MCP客户端都可以直接连接:

端点方法描述
/mcp/sseGETSSE连接端点(MCP JSON-RPC协议)
/mcp/messagesPOST消息端点(MCP JSON-RPC协议)

传输2:REST/HTTP-轻量级JSON API

对于脚本, curl,以及简单的代理集成:

端点方法描述
/healthGET健康检查
/toolsGET列出所有可用的MCP工具
/tools/callPOST执行MCP工具
/resourcesGET将工作区文件列为MCP资源
/task/startPOST开始超时任务会话
/task/statusGET检查当前任务状态
/task/completePOST将任务标记为已完成

两种传输共享相同的工具处理程序和工作区状态。

MCP工具(共17个)

模式2:程序化(odfpy/openpyxl)——9个工具

工具说明
read_cell从电子表格中的特定单元格读取值
write_cell将值写入电子表格中的特定单元格
read_range读取矩形范围的单元格
write_range从单元格开始写一个值块
set_formula在特定单元格中设置公式(例如。 =SUM(A1:A10))
list_sheets列出电子表格文件中的所有工作表
get_sheet_info获取工作表的元数据(行/列计数、标题)
list_files列出工作区目录中的所有文件
execute_python在沙盒中执行任意Python代码

模式1:计算机使用(GUI)——8个工具

工具说明
take_screenshot将当前屏幕状态捕获为base64编码的PNG(1280x720)
click点击特定屏幕坐标
double_click双击特定屏幕坐标
type_text使用键盘输入键入文本
key_press按下一个键或组合(例如。 Return, ctrl+s)
mouse_move将鼠标光标移动到特定坐标
drag单击并从一个位置拖动到另一个位置
get_cursor_position获取当前鼠标光标位置

示例:调用MCP工具

# Read a cell
curl -X POST http://localhost:8080/tools/call \
  -H "Content-Type: application/json" \
  -d '{"tool_name":"read_cell","arguments":{"file_path":"cash_flows.ods","sheet_name":"Sheet1","cell_reference":"A1"}}'

# Response:
# {"success":true,"result":{"cell_reference":"A1","value":"Period","value_type":"string"},"error":null}

# Take a screenshot (Mode 1)
curl -X POST http://localhost:8080/tools/call \
  -H "Content-Type: application/json" \
  -d '{"tool_name":"take_screenshot","arguments":{}}'

# Response:
# {"success":true,"result":{"image_base64":"iVBOR...","width":1280,"height":720,"timestamp":1773001940.1},"error":null}

任务结构

每个任务都是一个目录 tasks/ 包含:

tasks//
├── task.json              # Problem statement, instructions, grading config
├── generate_task_files.py # Script to generate starting + oracle files
├── grade.py               # Task-specific grading script
├── starting_files/        # Files the agent receives
│   └── cash_flows.ods
└── oracle/                # Expected correct output
    └── expected_reserves.ods

评分

评分员将代理输出与oracle电子表格进行比较:

  • 具有可配置容差的逐单元格数字比较(默认值:0.01)
  • 非数字单元格的字符串匹配
  • 处理丢失的纸张和空单元格
  • 返回0.0到1.0的分数,并包含详细的不匹配报告

预期演示输出

构建

$ python3 scripts/sandbox_manager.py build
[BUILD] Building sandbox Docker image...
  → docker compose build
 Image mcp-sandbox Built
[BUILD] Done.

全生命周期自动检查

$ python3 scripts/sandbox_manager.py run --task banking_reserve --demo
============================================================
TASK: Banking Reserve Calculation
============================================================
  Copied .../starting_files/cash_flows.ods → .../shared/cash_flows.ods
[START] MCP server is up: {'status': 'ok', 'workspace': '/workspace'}

[DEMO] Running automated MCP tool checks...
  [PASS] Health endpoint responds
  [PASS] Tools endpoint returns 17 tools
  [PASS] Mode 2: read_cell tool available
  [PASS] Mode 2: write_cell tool available
  [PASS] Mode 2: set_formula tool available
  [PASS] Mode 1: take_screenshot tool available
  [PASS] Mode 1: click tool available
  [PASS] Mode 1: type_text tool available
  [PASS] Workspace has files: ['cash_flows.ods']
  [PASS] read_cell A1 = 'Period'
  [PASS] read_range returns 3 rows
  [PASS] Sheet has 101 rows (expected 101)
  [PASS] write_cell D1 header
  [PASS] take_screenshot (1280px wide, 159808 chars)
  [PASS] click(400, 300)
  [PASS] task/start
  [PASS] task/status shows running
[DEMO] Results: 17/17 checks passed

GRADING RESULT: PASS
Score: 100.00%
Matched: 404/404 cells

[CLEAN] Removing sandbox container...

演示代理通过MCP解决任务

$ docker compose up -d && sleep 5 && python3 scripts/demo_agent.py
=== Demo Agent: Banking Reserve Calculation ===
[1] Starting task session...
[2] Listing workspace files...
    Found: cash_flows.ods
[3] Reading sheet info...
    101 rows, 3 cols, Headers: ['Period', 'Cash_Flow_Amount', 'Rate_Point']
[5] Analyzing data...
    100 periods, 11 known rate points
[8] Writing 100 reserve values...
[10] Signaling task completion...
=== Agent finished! ===

# Grade the agent's output:
GRADING RESULT: PASS
Score: 100.00%
Matched: 404/404 cells

错误处理

MCP服务器对所有故障情况返回结构化错误响应:

{"success": false, "result": null, "error": "File not found: /workspace/nonexistent.ods"}
{"success": false, "result": null, "error": "Sheet 'BadSheet' not found"}
{"success": false, "result": null, "error": "Invalid cell reference: ZZZ"}
{"success": false, "result": null, "error": "Task has timed out"}
{"success": false, "result": null, "error": "Unknown tool: fake_tool"}
{"success": false, "result": null, "error": "Code execution timed out after 30 seconds"}

所有工具调用在执行前都会通过Pydantic模型进行验证。格式错误的请求返回HTTP 400。未知工具返回HTTP 404。超时任务返回HTTP 408。内部错误(文件路径错误、工作表名称错误、单元格引用错误)返回HTTP 500并显示描述性错误消息。

沙盒安全

容器通过多层进行网络限制和权限限制。它控制了对两个已挂载目录的访问(shared/ 用于工作区文件和 mcp_server/ 对于服务器代码)——这允许文件交换,同时保持主机文件系统的其余部分不可访问。

实现工作原理
防火墙(iptables)entrypoint.sh 设置 OUTPUT 在删除特权之前,将链规则作为根规则阻止所有出站连接;仅回复入站请求(ESTABLISHED/RELATED)是允许的。MCP服务器可以响应API调用,但沙箱中的任何进程都不能启动与互联网的连接。
DNS阻止--dns 0.0.0.0docker-compose.ymlsandbox_manager.py深度防御:即使绕过iptables,主机名解析也会失败。
能力下降cap_drop: ALL +选择性 cap_add: NET_ADMIN, SETUID, SETGID删除所有Linux功能。三个附加的背部被使用 仅在容器启动期间: NET_ADMIN 对于iptables规则, SETUID/SETGID 为了 su 从根到根 sandbox 用户。一旦入口点完成其特权设置并执行 sandbox,这些功能不再可由无特权用户执行。
特权升级预防security_opt: no-new-privileges:true防止任何进程通过以下方式获得新权限 execve() (例如suid二进制文件)。一旦入口点下降到 sandbox,没有回到根的路。
非根执行入口点从iptables的根开始,然后 exec su sandbox 对于所有服务MCP服务器、LibreOffice和Xvfb都以无特权模式运行 sandbox 用户。
资源限制mem_limit: 2g, cpus: 2.0, pids_limit: 256防止资源枯竭和分叉炸弹。
仅本地主机端口127.0.0.1:8080:8080MCP服务器只能从主机访问,不能从网络访问
期限可配置超时,到期后自动拒绝工具mcp_server.py (_check_timeout())
干净的石板每次任务尝试后,容器都会被销毁sandbox_manager.py (clean_container())
代码执行超时execute_python 30秒后死亡mcp_server.py (subprocess.run(timeout=30))

为什么不 --network none?

真正的网络禁用(network_mode: none)这将是最强大的隔离,但它也会阻止MCP服务器通过HTTP访问——主机需要一个TCP路径 localhost:8080 以便代理调用工具。另一种选择是基于文件的IPC(代理将请求写入共享卷,服务器轮询并写入响应),它以网络攻击面换取架构复杂性。这里使用的iptables+DNS+能力下降方法是一种务实的中间立场:容器可以 接收 连接,但不能 发起 any,这是对沙盒任务运行器很重要的威胁模型。

项目结构

rl-sandbox-mcp/
├── README.md
├── pyproject.toml
├── docker-compose.yml
├── sandbox/
│   ├── Dockerfile
│   ├── requirements.txt
│   └── entrypoint.sh
├── mcp_server/
│   ├── models.py               # Pydantic models (strongly typed)
│   ├── spreadsheet_engine.py   # ODS + XLSX read/write engines
│   ├── mcp_server.py           # HTTP MCP server (17 tools)
│   ├── computer_use.py         # GUI interaction tools
│   └── grader.py               # Automated grading engine
├── tasks/
│   ├── banking_reserve/        # Medium: interpolation + finance
│   │   ├── task.json
│   │   ├── generate_task_files.py
│   │   ├── grade.py
│   │   ├── starting_files/
│   │   └── oracle/
│   └── sales_revenue/          # Easy: arithmetic (Qty × Price)
│       ├── task.json
│       ├── generate_task_files.py
│       ├── grade.py
│       ├── starting_files/
│       └── oracle/
├── scripts/
│   ├── sandbox_manager.py      # Full lifecycle automation
│   ├── demo_agent.py           # Scripted agent that solves a task via MCP
│   ├── llm_agent.py            # GPT-4o agent (autonomous MCP tool use)
│   ├── demo_ui.py              # Streamlit visual dashboard for demos
│   └── run_demo.sh             # Shell script for end-to-end demo
├── tests/
│   └── test_suite.py           # Unit + integration tests
└── shared/                     # Volume mount (agent workspace)

目录标签

目录标签

PythonClaudeAI代理沙盒环境本地部署电子表格处理自动化评估MCP协议

支持客户端

Claude DesktopClaudeCursor

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

session

工具数量(toolCount,工具数)

17

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiosession部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP