MCP 集成与工具桥接
MCP 集成与工具桥接
学习目标
理解 Nanobot 如何连接多个 MCP 服务器,将 MCP 工具桥接到 Agent 的工具注册表。
前置知识
- MCP 协议与生态集成 — Model Context Protocol 基础
- 多服务器 MCP — 多 MCP 服务器连接与管理
下文假设你已理解上述概念,直接聚焦 Nanobot 的具体实现。
项目实践
连接模型
Nanobot 支持两种 MCP 传输层:
- stdio:通过子进程运行 MCP 服务器(如
npx命令) - sse/streamableHttp:通过 HTTP 连接到远程 MCP 服务器
{ "tools": { "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"], "toolTimeout": 30 }, "web-search": { "url": "http://localhost:3000/sse", "enabledTools": ["search"] } } }}工具命名空间隔离
MCP 工具通过命名前缀桥接到 Agent 工具注册表:
- 内置 MCP 工具:直接使用工具原名
- 多服务器场景:
mcp_<server>_<tool>格式
_tool_cache_marker_indices() 方法在工具列表中识别 MCP 工具的边界(以 mcp_ 开头的工具),在 Anthropic 提示词缓存中标记这些工具的边界位置。
连接生命周期
MCP 连接在 AgentLoop 启动时建立,在关闭时清理:
async def run(self): await self._connect_mcp() # ... agent loop ...
async def close_mcp(self): for name, stack in self._mcp_stacks.items(): await stack.aclose()每个 MCP 服务器有独立的 AsyncExitStack,确保连接资源正确释放。
工具超时
每个 MCP 服务器可配置 tool_timeout(默认 30 秒),超时后工具调用被取消。
设计取舍
为什么使用 AsyncExitStack 管理 MCP 连接
原因:MCP 连接可能涉及多个异步资源(子进程、HTTP 连接),AsyncExitStack 提供了统一的上下文管理协议,确保在异常情况下所有资源都被正确清理。