MCP执行器代理
代理多个 模型上下文协议 (MCP)服务器。它提供:
- 渐进式发现 用于列出服务器和工具的API,而不会让LLM客户端不堪重负。
- 独立代码执行 因此,一个代码片段可以通过一个小SDK调用下游的MCP工具。
该实现以Claude Desktop为目标,但适用于任何支持MCP的客户端。
架构概述
broker.server注册MCP工具(servers_list,server_tools_list,tool_info,exec_*)并连接全球单线。broker.discovery解析broker.config.json,对下游服务器发出列表/模式请求,并缓存结果。broker.targets维持MCPClient每个配置的服务器的子流程,通过stdio使用JSON-RPC。broker.ipc.ExecBroker启动一个worker来运行用户代码,用挂钟/每次调用限制来保护它,并强制执行允许列表。worker/python_runner.py在每次执行工作区内执行上传的脚本,并在以下位置公开SDKworker/sdk/mcp_sdk.py.broker.workspace配置下的每个执行目录的配置workspace_root.
安全控制和限制
- 执行配额:
Policy强制执行wall_clock_ms,per_call_ms,max_calls,以及max_output_kb在允许跑步之前。 - 工具允许列表:
exec_run要求调用者声明允许的服务器/工具;ExecBroker拒绝允许列表之外的任何内容。 - 结果截断: 大型下游工具响应被修剪并作为工件持久化,因此客户端只能看到小的预览。
- 工作区隔离: 每次运行都在自己的目录中执行,并自动清理,除非
persist被要求。
⚠️ 仅测试原型。 此存储库有意轻量级 未硬化用于生产Worker代码以与代理进程相同的操作系统权限运行——除了挂钟和每次调用超时外,没有内存、网络或文件系统包含。对于任何实际部署,您必须将执行封装在更强大的沙盒(容器、seccomp、AppArmor、Firecracker、gVisor等)中,或评估提供隔离保证的替代执行技术。
公开发布前的已知差距:
- 路径遍历:
exec_id逐字接受;呼叫者可以提供../分段以逃离工作区根。在发布之前对ID进行消毒(例如,只接受UUID)。 - 进程沙盒: 请参阅上面的警告——在处理不受信任的代码之前添加操作系统级沙盒。
- 秘密处理: 下游API密钥应在运行时从环境中加载;将实际值排除在源代码控制之外。
- 资源使用情况: 没有内存或磁盘配额强制,在长时间运行期间,worker stdout/stderr可能会变大。
入门指南
先决条件
- Python 3.11+
- 访问至少一个下游MCP服务器(例如,
finance-mcp)以及它所需要的API密钥。
安装
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt配置
- 复制
broker.config.json到私人地点(或集合MCP_EXEC_CONFIG). - 替换占位符路径(
/path/to/...)以及为您的系统提供正确值的环境变量引用。 - 将真正的API密钥存储在shell环境中,然后使用
${VARIABLE}占位符如下所示。
{
"workspace_root": "/tmp/mcp-exec-broker",
"defaults": {
"wall_clock_ms": 45000,
"per_call_ms": 15000,
"max_calls": 8,
"max_output_kb": 256,
"persist": false
},
"targets": [
{
"name": "finance-mcp",
"command": "/path/to/finance-mcp/.venv/bin/python",
"args": ["-m", "finance_mcp.server"],
"cwd": "/path/to/finance-mcp",
"env": {
"PYTHONPATH": "/path/to/finance-mcp/src",
"FINNHUB_API_KEY": "${FINNHUB_API_KEY}",
"MARKETAUX_KEY": "${MARKETAUX_KEY}",
"NEWSAPI_KEY": "${NEWSAPI_KEY}",
"CACHE_TTL_SECONDS": "0",
"NEWS_LANG": "en"
},
"tags": [
"finance",
"read"
],
"tools_allow": [
"news",
"compare_assets",
"crypto_price",
"crypto_top_movers",
"crypto_ohlc",
"stock_quote",
"stock_candles"
]
}
]
}不要承诺你的真实 broker.config.json. 添加到 .gitignore 以及来自环境变量或秘密管理器的源秘密。
运行经纪人
export PYTHONPATH=/path/to/mcp-exec-broker/src
export MCP_EXEC_CONFIG=/path/to/private/broker.config.json
python -m broker.server通过添加以下内容与Claude Desktop集成:
{
"mcpServers": {
"mcp-exec-broker": {
"command": "/path/to/mcp-exec-broker/.venv/bin/python",
"args": ["-m", "broker.server"],
"cwd": "/path/to/mcp-exec-broker",
"env": {
"PYTHONPATH": "/path/to/mcp-exec-broker/src",
"MCP_EXEC_CONFIG": "/path/to/private/broker.config.json"
}
}
}
}执行生命周期
exec_open→ Broker分配新的工作空间并返回exec_id.- 客户端上传代码和输入,然后调用
exec_run随着limits以及允许列表。 - 工人跑步
user_code.py,使用mcp_sdk.call_tool以到达下游MCP服务器。 - 经纪人收集
result.json,stdout/stderr以及任何大型工件。 exec_close拆除工作区,除非persist设置。
使用 exec_get_artifact 获取保存在下的任何截断的有效载荷 artifacts/.
测试
这 tests/test_exec_run.py 集成脚本练习 exec_run.准备一个有效的配置(具有可访问的下游服务器)并运行:
export PYTHONPATH=/path/to/mcp-exec-broker/src
export MCP_EXEC_CONFIG=/path/to/private/broker.config.json
python -m anyio run tests.test_exec_run如果没有实时的下游服务器,测试将失败;如果分发预构建的包,请考虑将其标记为可选。
操作检查表
- 创建一个
.gitignore入口为broker.config.json本地工作区和虚拟环境。 - 定期轮换API密钥,并在下游提供商支持时更喜欢短时间令牌。
- 在专用系统用户下运行代理,以限制执行代码的爆炸半径。
- 监视stderr日志:
ExecBroker当下游调用失败或超过配额时,发出回溯。
贡献
一旦上述安全强化项目得到解决,就欢迎拉取请求。请在下面添加新功能的覆盖范围 tests/.
许可证
该项目在MIT许可证下分发;查看捆绑 LICENSE 文件以获取详细信息。
