跳转到内容

MCP 协议在工具层的集成方案

MCP 协议在工具层的集成方案

学习目标

  • 理解 ChatDev 的 ToolManager 统一抽象层
  • 掌握 MCP Remote(HTTP SSE)和 MCP Local(Stdio)两种接入方式的实现差异
  • 了解工具注册、Schema 导出与缓存机制
  • 能够在 YAML 中配置 MCP 工具

前置知识

本章涉及 MCP 协议的通用原理,建议先阅读:

下文聚焦 ChatDev 的具体 ToolManager 实现。


项目实践

ToolManager 统一抽象

ChatDev 的 ToolManagerruntime/node/agent/tool/tool_manager.py 中统一管理三种工具类型:

工具类型YAML 配置实现方式
Function Tooltype: functionfunctions/function_calling/ 目录加载 Python 函数
MCP Remotetype: mcp_remote通过 HTTP SSE 连接远程 MCP Server
MCP Localtype: mcp_local通过 Stdio 启动本地 MCP Server 进程

Function Calling 工具

Function 工具是 ChatDev 的默认工具类型:

tooling:
- type: function
config:
tools:
- name: apply_text_edits # 内置工具
- name: uv_related:All # 工具组通配符
- name: deep_research:All # 自定义工具组
timeout: 30.0

内置工具列表位于 functions/function_calling/

工具功能
apply_text_edits文件内容编辑
create_folder创建目录
delete_path删除路径
read_file_segment文件片段读取
search_in_files文件搜索
save_file文件保存
execute_codePython 代码执行
web_search网页搜索(DDGS)
get_webpage_content网页内容获取

MCP Remote 接入

tooling:
- type: mcp_remote
config:
server: "http://localhost:8080/mcp"
headers:
Authorization: "Bearer ${MCP_TOKEN}"
timeout: 10.0

实现细节:

ToolManager
StreamableHttpTransport(server_url, headers)
FastMCP Client
async with client:
return await client.list_tools()

重试策略:指数退避,最多 3 次尝试:

尝试 1: 等待 0.5s
尝试 2: 等待 1.0s
尝试 3: 等待 2.0s

MCP Local 接入

tooling:
- type: mcp_local
config:
command: "uv"
args: ["run", "python", "mcp_server.py"]
cwd: "./mcp_example"
env:
API_KEY: "${API_KEY}"
inherit_env: true
startup_timeout: 10.0
wait_for_log: "Server started"

实现细节:

ToolManager
StdioTransport(command, args, cwd, env)
启动子进程 → 等待 wait_for_log 信号
FastMCP Client
list_tools()

生命周期管理

  • Stdio 客户端在工具调用时启动
  • 进程退出时自动清理缓存
  • startup_timeout 控制等待 Server 就绪的最长时间

工具缓存机制

ToolManager 使用两种缓存:

缓存类型缓存内容缓存键
FunctionManager 缓存Python 函数对象functions_dir 路径
MCP 工具缓存MCP Server 返回的工具列表launch_key(配置哈希)

MCP 缓存特别重要——避免每次工具调用都重新连接 Server 和获取工具列表。

Schema 注册

所有工具类型都通过 schema_registry 模块注册 Schema:

register_model_provider_schema(name, label=label, summary=summary)

这使得前端可以自动生成工具配置 UI。

问题与规避

问题表现规避策略
MCP Server 启动超时startup_timeout 过期后报错增大 startup_timeout 或优化 Server 启动速度
MCP 工具列表缓存过期Server 更新后客户端未感知通过 launch_key 变更强制刷新缓存
HTTP 重试风暴MCP Remote 不可用时持续重试最多 3 次 + 指数退避限制
Stdio 进程泄漏客户端断开后子进程残留进程退出时自动清理
工具组通配符解析失败name: xxx:All 中组不存在确保工具组在 functions/ 中已定义

设计取舍

FastMCP vs 原生 MCP SDK

ChatDev 选择使用 fastmcp 而非原生 mcp SDK:

维度FastMCP原生 MCP SDK
API 简洁度高(封装了传输层细节)低(需手动管理传输)
StreamableHttpTransport原生支持需额外配置
StdioTransport原生支持需手动实现
ChatDev 的选择✅ 使用❌ 仅间接依赖

三种工具类型并存的原因

  • Function:最快(本地调用),但需编写 Python 代码
  • MCP Remote:适合微服务架构(MCP Server 独立部署)
  • MCP Local:适合轻量级场景(按需启动,用完即停)

参考来源