跳转到内容

MCP 集成与工具桥接

MCP 集成与工具桥接

学习目标

理解 Nanobot 如何连接多个 MCP 服务器,将 MCP 工具桥接到 Agent 的工具注册表。

前置知识

下文假设你已理解上述概念,直接聚焦 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 提供了统一的上下文管理协议,确保在异常情况下所有资源都被正确清理。

参考来源