MCP Server 设计
Agent Sandbox MCP Server 将沙箱能力暴露为 MCP (Model Context Protocol) Tools,让 AI Agent(Cursor、Claude Desktop、VS Code 等)可以直接操作云端沙箱。
已实现面(与 src/agent/ 保持同步):
- 7 个 P0 工具(
agent/tools.ts) - STDIO 传输(
agent/mcp.ts)—abx mcp start - Streamable HTTP 传输(
agent/mcp_http.ts)— HTTP 应用 - CLI:
abx mcp install / start / status / deploy
1. Tools 定义
全部 7 个工具定义于 TOOL_SCHEMAS(agent/tools.ts)。省略 sandbox_id 时作用于默认沙箱(见第 2 章)。
create_sandbox
{
"name": "create_sandbox",
"description": "创建一个云端沙箱,并将其设为当前会话的默认沙箱。省略 template 时使用 MCP server 配置的模板(abx mcp start 默认为 code-interpreter-v1)。",
"inputSchema": {
"type": "object",
"properties": {
"template": {
"type": "string",
"description": "沙箱模板名称,省略时使用 server 配置的模板"
},
"timeout": {
"type": "integer",
"description": "沙箱超时时间(秒),默认 300",
"default": 300
},
"envs": {
"type": "object",
"description": "环境变量键值对",
"additionalProperties": { "type": "string" }
}
}
},
"returns": {
"sandbox_id": "string — 沙箱 ID",
"status": "string — 沙箱状态",
"url": "string — 沙箱访问 URL"
}
}
run_code
{
"name": "run_code",
"description": "在沙箱中执行代码(通过 Code Interpreter)。支持 Python、JavaScript 等语言。省略 sandbox_id 时使用默认沙箱。",
"inputSchema": {
"type": "object",
"properties": {
"code": { "type": "string", "description": "要执行的代码" },
"language": {
"type": "string",
"description": "编程语言,默认 python",
"enum": ["python", "javascript", "shell", "typescript", "r"],
"default": "python"
},
"sandbox_id": {
"type": "string",
"description": "沙箱 ID,省略时使用默认沙箱"
},
"timeout": {
"type": "integer",
"description": "执行超时(秒),默认 30",
"default": 30
}
},
"required": ["code"]
},
"returns": {
"stdout": "string",
"stderr": "string",
"exit_code": "integer",
"output_files": "array — [{name, path, size}] 生成的文件列表"
}
}
run_command
{
"name": "run_command",
"description": "在沙箱中执行 Shell 命令。省略 sandbox_id 时使用默认沙箱。",
"inputSchema": {
"type": "object",
"properties": {
"command": { "type": "string", "description": "Shell 命令" },
"sandbox_id": { "type": "string", "description": "沙箱 ID" },
"cwd": {
"type": "string",
"description": "工作目录,省略时使用镜像工作目录",
"default": "/app"
},
"timeout": {
"type": "integer",
"description": "执行超时(秒),默认 60",
"default": 60
}
},
"required": ["command"]
},
"returns": {
"stdout": "string",
"stderr": "string",
"exit_code": "integer"
}
}
read_file
{
"name": "read_file",
"description": "读取沙箱中的文件内容。省略 sandbox_id 时使用默认沙箱。",
"inputSchema": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件绝对路径" },
"sandbox_id": { "type": "string", "description": "沙箱 ID" },
"encoding": {
"type": "string",
"description": "文件编码,默认 utf-8",
"default": "utf-8"
}
},
"required": ["path"]
},
"returns": { "content": "string" }
}
write_file
{
"name": "write_file",
"description": "在沙箱中创建或覆写文件。省略 sandbox_id 时使用默认沙箱。",
"inputSchema": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件绝对路径" },
"content": { "type": "string", "description": "文件内容" },
"sandbox_id": { "type": "string", "description": "沙箱 ID" }
},
"required": ["path", "content"]
},
"returns": { "success": "boolean", "bytes_written": "integer" }
}
list_files
{
"name": "list_files",
"description": "列出沙箱中指定目录的文件和子目录。省略 sandbox_id 时使用默认沙箱。",
"inputSchema": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "目录路径,省略时列出 /",
"default": "/app"
},
"sandbox_id": { "type": "string", "description": "沙箱 ID" }
}
},
"returns": {
"files": "array — [{name, path, type, size}]"
}
}
kill_sandbox
{
"name": "kill_sandbox",
"description": "销毁指定沙箱。省略 sandbox_id 时销毁默认沙箱。",
"inputSchema": {
"type": "object",
"properties": {
"sandbox_id": {
"type": "string",
"description": "要销毁的沙箱 ID,省略时销毁默认沙箱"
}
}
},
"returns": { "success": "boolean" }
}
2. 会话绑定设计
默认沙箱概念
MCP Server 引入「默认沙箱」概念,简化 Agent 操作:
graph TD
A["Agent 首次调用工具(无 sandbox_id)"] --> B[MCP Server 自动创建默认沙箱]
B --> C["后续无 sandbox_id 的调用复用默认沙箱"]
行为规则(由 agent/mcp.ts 中的 SandboxManager 实现):
create_sandbox创建沙箱,并把它设为默认沙箱。随后省略sandbox_id的调用使用这只沙箱;更早创建的沙箱仍存活,直到被kill_sandbox或会话结束- 还没有默认沙箱时,第一次省略
sandbox_id的工具调用懒创建一只。并发的懒创建只会创建一只 - 默认模板:经
abx mcp start启动时为code-interpreter-v1(CLI 默认值);编程式构造SandboxMCPServer/ HTTPSessionStore且未显式指定模板时为base。create_sandbox省略template时用的就是这个模板 - 省略
sandbox_id的kill_sandbox销毁默认沙箱;当前没有默认沙箱时返回错误。会话结束时销毁该会话里的全部沙箱 — STDIO EOF / server 关闭,或 HTTPDELETE /mcp/ 空闲会话 TTL 到期 - 显式传入
sandbox_id时寻址那只沙箱,不改变默认沙箱。每次使用前按创建时的 timeout 调用Sandbox.setTimeout延长存活时间
sequenceDiagram
participant Agent
participant MCP as MCP Server
participant SB1 as sb-001
participant SB2 as sb-002
Note over Agent,MCP: 会话开始
Agent->>MCP: run_code("print(1)")
MCP->>SB1: 自动创建默认沙箱 sb-001
Agent->>MCP: run_code("print(2)")
MCP->>SB1: 复用 sb-001
Agent->>MCP: create_sandbox(template=...)
MCP->>SB2: 创建 sb-002,并把它设为默认沙箱
Agent->>MCP: write_file / run_code(不带 sandbox_id)
MCP->>SB2: 使用 sb-002
Agent->>MCP: run_code("...", sandbox_id=sb-001)
MCP->>SB1: 显式 id 仍指向 sb-001
Note over Agent,MCP: 会话结束
MCP->>SB1: 销毁 sb-001 与 sb-002
3. 传输方式
STDIO — 本地 IDE 集成
graph LR
IDE["IDE / Agent<br/>Cursor, Claude, VS Code"] <-->|"STDIO stdin/stdout<br/>换行分隔 JSON-RPC 2.0"| MCP["MCP Server<br/>abx mcp start"]
MCP --> SM[SandboxManager]
SM --> FC[阿里云 FC]
- 实现:
agent/mcp.ts— 自包含的最小 JSON-RPC 2.0 换行分隔 STDIO 处理器,无需外部mcpSDK 依赖 - 协议版本:
2024-11-05—— STDIO server 唯一支持的版本。initialize在请求该版本时回显,请求缺失或不支持时也回退到该版本,保持原有行为不变 - 支持方法:
initialize、notifications/initialized、tools/list、tools/call、ping - 适用场景:本地开发、单用户,IDE 直接拉起进程
- 启动方式:
abx mcp start [--template 名称] [--api-key KEY] [--api-url URL] [--domain DOMAIN](通常由 IDE 调用)。手动运行时配置写到 stderr,stdout 保持 JSON-RPC;abx mcp stop结束记录的 pid。--http --background把 Streamable HTTP 放到后台
Streamable HTTP — 远程部署
graph LR
A["Client A - Cursor"] <-->|"Streamable HTTP<br/>POST /mcp"| MCP["MCP Server<br/>FC 函数 / uvicorn"]
B["Client B - Claude"] <-->|"Streamable HTTP<br/>POST /mcp"| MCP
MCP --> SM["SessionStore<br/>按 Mcp-Session-Id 分派"]
SM --> FC[阿里云 FC]
- 实现:
agent/mcp_http.ts—createMcpApp()返回的 HTTP 应用(FC 产物使用的 Python ASGI 对应实现以模块级asgi_app入口提供) - 协议:MCP Streamable HTTP(规范 2025-06-18)
- 端点:
POST /mcp— JSON-RPC 请求;initialize创建会话并返回Mcp-Session-Id,后续请求必须携带该头DELETE /mcp— 会话终止并清理沙箱(需要Mcp-Session-Id)GET /mcp— 返回 405;SSE 服务端通知尚未实现GET /health— 健康检查,返回{"status": "ok", "protocol": "2025-06-18"}- 会话:进程内
SessionStore;空闲 TTL 默认 3600 秒、并发会话上限默认 100;容量满时返回 503 与 JSON-RPC 错误-32000 - 版本协商:
initialize在请求版本受支持时原样回显;本传输仅支持2025-06-18,与GET /health一致。请求缺失或不支持的版本时协商到2025-06-18—— 按 MCP 规范,服务器回复自己支持的版本,无法接受的客户端可自行断开。STDIO 传输独立保持2024-11-05 - 适用场景:远程服务、团队共享、多客户端;用
abx mcp deploy产物部署到阿里云 FC,或本地以 uvicorn 运行 - 可选依赖:
abx mcp start --http无需任何可选依赖;FC 产物 / uvicorn 的 Python ASGI 运行时需要 Starlette + uvicorn(pip install 'agent-sandbox[mcp]')
认证
- 客户端 → MCP:
Authorization: Bearer <token>,常量时间比较校验;经ABX_MCP_AUTH_TOKEN配置。本机回环未配置时认证关闭;配置为空时 fail-closed(所有请求返回 401)。FC 产物调用require_auth_token,token 为空则进程拒绝启动 - MCP → 沙箱:
ABX_SANDBOX_API_KEY环境变量
环境变量
| 变量 | 用途 |
|---|---|
ABX_SANDBOX_API_KEY |
沙箱后端 API Key |
ABX_SANDBOX_BASE_URL |
平台 API URL |
ABX_SANDBOX_DOMAIN |
沙箱 Domain 覆盖 |
ABX_DEFAULT_TEMPLATE |
默认沙箱模板 |
ABX_MCP_AUTH_TOKEN |
客户端认证 Bearer token(HTTP 传输) |
4. Server 架构图
graph TD
subgraph MCP["MCP Server"]
TL["传输层\nSTDIO (mcp.ts) / Streamable HTTP (mcp_http.ts)"]
TR["工具注册表\n7 个 P0 工具 (agent/tools.ts)"]
SM["SandboxManager / SessionStore"]
RR["JSON-RPC 路由\ninitialize / tools/list / tools/call / ping"]
SC["沙箱客户端\nsrc/api (Sandbox)"]
end
TL --> RR
TR --> RR
SM --> RR
RR --> SC
SC --> FC["阿里云 FC 沙箱运行时"]
5. 安装方式与 CLI
一键安装
# 安装到 Cursor
abx mcp install --target cursor
# 安装到 Claude Desktop
abx mcp install --target claude
# 安装到 VS Code (Copilot)
abx mcp install --target vscode
install 将 agent-sandbox 条目合并进目标 IDE 的配置文件:Cursor ~/.cursor/mcp.json、Claude Desktop claude_desktop_config.json(mcpServers)、VS Code 工作区 .vscode/mcp.json(servers,type: stdio)。命令是正在运行的 abx 可执行文件的绝对路径,找不到时使用 node <abx.js 的绝对路径>。Cursor 与 Claude 在 API key 可用时写入 env;VS Code 工作区文件不写入 API key。不是严格 JSON 的配置文件不会被覆盖。
安装过程
$ abx mcp install --target cursor
MCP Server config written to ~/.cursor/mcp.json
Registered tools:
• create_sandbox — Create a cloud sandbox
• run_code — Execute code
• run_command — Execute a command
• read_file — Read a file
• write_file — Write a file
• list_files — List files
• kill_sandbox — Destroy a sandbox
Please restart Cursor to apply changes.
status
abx mcp status # 表格输出
abx --json mcp status # JSON 输出
报告 server 名称、传输方式(stdio)、工具数量与名称、API key 是否已配置、以及各支持 IDE 中的安装状态。
6. 配置示例
Claude Desktop
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"agent-sandbox": {
"command": "abx",
"args": ["mcp", "start"],
"env": {
"ABX_SANDBOX_API_KEY": "your-api-key"
}
}
}
}
Cursor
// ~/.cursor/mcp.json
{
"mcpServers": {
"agent-sandbox": {
"command": "abx",
"args": ["mcp", "start"],
"env": {
"ABX_SANDBOX_API_KEY": "your-api-key"
}
}
}
}
VS Code
// .vscode/mcp.json
{
"servers": {
"agent-sandbox": {
"type": "stdio",
"command": "/path/to/abx",
"args": ["mcp", "start"]
}
}
}
远程(Streamable HTTP)
部署 HTTP 应用(第 7 章)后,客户端指向该端点;配置了 token 时附加 Bearer 头:
{
"mcpServers": {
"agent-sandbox-remote": {
"url": "https://<FC_HTTP_TRIGGER_URL>/mcp",
"headers": {
"Authorization": "Bearer <BEARER_TOKEN>"
}
}
}
}
7. FC 部署
状态:
abx mcp deploy生成部署产物;自动调用 FC 部署 API 尚未实现。生成后会打印手动部署步骤。
架构
MCP Server 可部署到阿里云函数计算 (FC) 作为 Streamable HTTP 端点,利用 FC 原生的 MCP 会话亲和路由。
graph TB
CLI["abx mcp deploy → 产物目录"]
FC["FC 函数: agent-sandbox-mcp(手动创建)"]
Sandbox["Envd 沙箱(另一个 FC 实例)"]
CLI --> FC
FC --> Sandbox
subgraph FC_Function ["FC 函数"]
ASGI["app.py → agent_sandbox.agent.mcp_http:asgi_app"]
Trigger["HTTP 触发器: POST/GET/DELETE /mcp"]
Session["会话亲和: Mcp-Session-Id"]
Env["环境变量: ABX_SANDBOX_API_KEY / ABX_MCP_AUTH_TOKEN / ABX_DEFAULT_TEMPLATE"]
end
CLI 命令
abx mcp deploy \
--name agent-sandbox-mcp \
--region cn-hangzhou \
--template base \
--memory 512 --timeout 600 \
--generate-token \
--api-key $ABX_SANDBOX_API_KEY \
--output-dir ./mcp-artifact
选项:--name(默认 agent-sandbox-mcp)、--region(命令 --region > ALIBABA_CLOUD_REGION_ID > abx config set region > cn-hangzhou)、--template(默认 base)、--memory(默认 512)、--timeout(默认 600)、Bearer token 来源 --auth-token-file / --generate-token / 环境变量 ABX_MCP_AUTH_TOKEN、--enable-session-affinity/--no-session-affinity(默认启用)、--sandbox-api-key(ABX_SANDBOX_API_KEY)、--custom-domain、--output-dir。
产物内容
| 文件 | 内容 |
|---|---|
requirements.txt |
agent-sandbox[mcp]、uvicorn>=0.29 |
app.py |
ASGI 入口,从 FC 函数环境变量读取 ABX_MCP_AUTH_TOKEN、ABX_SANDBOX_API_KEY、ABX_SANDBOX_BASE_URL、ABX_SANDBOX_DOMAIN、ABX_DEFAULT_TEMPLATE |
config.yaml |
YAML 部署清单(非 FC API 载荷):function_name、region、runtime(python3.10)、handler(app.app)、memory、timeout、environment_variables、http_trigger(POST/GET/DELETE 方法 + enable_session_affinity)、可选 custom_domain |
abx mcp deploy 还会打印手动部署步骤(打包产物、经 FC 控制台或 SDK 创建函数、创建 HTTP 触发器、如支持则启用 Mcp-Session-Id 亲和)以及 Bearer token 打码的 IDE 配置模板。
关键设计要点
- 协议:Streamable HTTP(MCP 规范 2025-06-18);
initialize协商2025-06-18,与GET /health一致(STDIO 独立保持2024-11-05) - 会话亲和:委托 FC 平台层通过
Mcp-Session-Id头实现 — 无需应用层粘性路由 - 认证:双层 — 客户端→MCP 使用
Authorization: Bearer <token>;MCP→沙箱使用 FC 环境变量中的ABX_SANDBOX_API_KEY - 生命周期:沙箱按 MCP 会话懒创建;
DELETE /mcp触发清理;空闲会话 TTL 作为安全网 - 冷启动:FC 冷启动 (~1–3s) 可能与 MCP initialize 超时冲突;生产环境建议使用预留实例
- 密钥:
config.yaml含 API key 与 Bearer token — 切勿提交到版本控制
详见 CLI 设计 — mcp deploy 获取完整参数参考,MCP 集成指南 获取端到端用法。
相关 SDK 文档
Python SDK 自带 python -m agent_sandbox.agent.mcp 入口与 create_mcp_app ASGI 工厂,见 SDK 的 MCP Server 设计 与 MCP 集成指南。本页描述 abx mcp 命令与 Node.js 实现。