小智服务器:设备的各种MCP消息、初始化响应、工具列表和工具调用响应

核心功能概述

handle_mcp_message 函数位于 core/providers/tools/device_mcp/mcp_handler.py,是设备端MCP(Model Control Protocol)通信的核心处理函数,负责处理来自设备的各种MCP消息,包括初始化响应、工具列表和工具调用响应等。

函数签名与参数

复制代码
async def handle_mcp_message(conn, mcp_client: MCPClient, payload: dict)
  • conn: 连接对象,用于与设备通信

  • mcp_client: MCPClient实例,用于管理MCP状态和工具

  • payload: MCP消息的负载内容,必须为字典格式

详细执行流程

1. 消息验证与日志记录

复制代码
if not isinstance(payload, dict):
    logger.bind(tag=TAG).error("MCP消息缺少payload字段或格式错误")
    return
  • 验证payload是否为字典格式

  • 记录MCP消息的前100个字符用于调试

2. 处理响应消息(包含result字段)

2.1 工具调用响应处理
复制代码
if msg_id in mcp_client.call_results:
    logger.bind(tag=TAG).debug(
        f"收到工具调用响应,ID: {msg_id}, 结果: {result}"
    )
    await mcp_client.resolve_call_result(msg_id, result)
    return
  • 检查消息ID是否在待处理的工具调用结果中

  • 如果存在,将结果传递给等待的future对象

  • 立即返回,结束处理

2.2 MCP初始化响应处理(ID=1)
复制代码
if msg_id == 1:  # mcpInitializeID
    logger.bind(tag=TAG).debug("收到MCP初始化响应")
    # 记录服务器信息
    server_info = result.get("serverInfo")
    if isinstance(server_info, dict):
        name = server_info.get("name")
        version = server_info.get("version")
        # 记录日志
    
    await asyncio.sleep(1)
    logger.bind(tag=TAG).debug("初始化完成,开始请求MCP工具列表")
    await send_mcp_tools_list_request(conn)
    return
  • 记录设备端MCP服务器的名称和版本信息

  • 等待1秒后,发送工具列表请求

2.3 工具列表响应处理(ID=2)
复制代码
elif msg_id == 2:  # mcpToolsListID
    logger.bind(tag=TAG).debug("收到MCP工具列表响应")
    if isinstance(result, dict) and "tools" in result:
        tools_data = result["tools"]
        # 遍历工具列表,添加到MCP客户端
        for i, tool in enumerate(tools_data):
            # 解析工具信息
            name = tool.get("name", "")
            description = tool.get("description", "")
            # 处理输入schema

            input_schema = {"type": "object", "properties": {}, "required": [ ]}

            # 添加工具到MCP客户端
            await mcp_client.add_tool(new_tool)
        
        # 替换工具描述中的原始名称为清理后的名称
        # ...
        
        # 处理分页
        next_cursor = result.get("nextCursor", "")
        if next_cursor:
            await send_mcp_tools_list_continue_request(conn, next_cursor)
        else:
            # 所有工具已获取,标记MCP客户端就绪
            await mcp_client.set_ready(True)
            # 刷新工具缓存
            if hasattr(conn, "func_handler") and conn.func_handler:
                conn.func_handler.tool_manager.refresh_tools()
                conn.func_handler.current_support_functions()
    return
  • 解析设备返回的工具列表

  • 逐个处理工具,提取名称、描述和输入schema

  • 将工具添加到MCP客户端的工具字典中

  • 替换工具描述中的原始名称为清理后的名称

  • 处理分页:如果有nextCursor,请求更多工具;否则标记MCP客户端就绪

  • 刷新工具缓存,确保MCP工具被包含在函数列表中

3. 处理请求消息(包含method字段)

复制代码
elif "method" in payload:
    method = payload["method"]
    logger.bind(tag=TAG).info(f"收到MCP客户端请求: {method}")
  • 记录收到的MCP客户端请求方法

  • 目前仅记录日志,未进行具体处理

4. 处理错误消息(包含error字段)

复制代码
elif "error" in payload:
    error_data = payload["error"]
    error_msg = error_data.get("message", "未知错误")
    logger.bind(tag=TAG).error(f"收到MCP错误响应: {error_msg}")
    
    msg_id = int(payload.get("id", 0))
    if msg_id in mcp_client.call_results:
        await mcp_client.reject_call_result(
            msg_id, Exception(f"MCP错误: {error_msg}")
        )
  • 记录错误信息

  • 如果有对应的工具调用结果,拒绝该调用并返回错误信息

关键数据结构与交互

MCPClient类

MCPClient类用于管理MCP状态和工具,主要功能包括:

  • 工具管理:添加、查询和缓存工具

  • 状态管理:标记MCP客户端是否就绪

  • 工具调用结果管理:存储和处理工具调用的future对象

工具调用流程

  1. 调用call_mcp_tool函数,发送工具调用请求

  2. 函数创建future对象,注册到mcp_client.call_results

  3. 等待设备返回响应

  4. handle_mcp_message函数处理响应,调用resolve_call_resultreject_call_result

  5. future对象被设置结果或拒绝,call_mcp_tool函数返回结果

整个MCP系统的工作流程

复制代码
┌─────────────────────────────────────────────────────────┐
│                     初始化阶段                           │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│           发送初始化消息(send_mcp_initialize_message)  │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│       设备返回初始化响应                               │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│  处理初始化响应(handle_mcp_message, msg_id=1)         │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│   发送工具列表请求(send_mcp_tools_list_request)       │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│       设备返回工具列表响应                              │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│   处理工具列表响应(handle_mcp_message, msg_id=2)       │
│  ┌───────────────────────────────────────────────────┐  │
│  │  有nextCursor                                     │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │     请求更多工具(send_mcp_tools_list_continue_request) │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │  无nextCursor                                     │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │   标记MCP客户端就绪(mcp_client.set_ready(True))   │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │   刷新工具缓存(func_handler.tool_manager.refresh_tools) │
│  └───────────────────────────────────────────────────┘  │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                     运行阶段                             │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│           调用MCP工具(call_mcp_tool)                   │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│       设备返回工具调用响应                              │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│   处理工具调用响应(handle_mcp_message, 有result)       │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│           返回工具调用结果                              │
└─────────────────────────────────────────────────────────┘

代码优化建议

  1. 添加请求消息处理逻辑:目前代码中仅记录了MCP客户端请求,未进行具体处理。建议根据实际需求添加相应的处理逻辑。

  2. 优化错误处理:在处理工具调用响应时,可以添加更详细的错误信息,帮助调试和问题定位。

  3. 改进工具描述替换逻辑:目前的工具描述替换逻辑较为简单,仅替换了原始名称为清理后的名称。可以考虑使用更高效的替换方法,如正则表达式。

  4. 添加超时处理:在等待工具调用响应时,可以添加超时处理,避免长时间等待。

  5. 优化日志记录:可以根据日志级别调整日志内容的详细程度,避免不必要的日志输出。

总结

handle_mcp_message 函数是设备端MCP通信的核心处理函数,负责处理来自设备的各种MCP消息,包括初始化响应、工具列表和工具调用响应等。它通过与 MCPClient 类和其他辅助函数的配合,实现了完整的MCP通信流程,为设备提供了强大的工具调用能力。

整个MCP系统的工作流程包括初始化阶段和运行阶段,初始化阶段负责建立连接和获取工具列表,运行阶段则负责调用工具和处理响应。这种设计使得系统具有良好的扩展性和灵活性,可以根据需要添加新的工具和功能。

相关推荐
AGC79211 小时前
PCB沉银工艺科普Q&A:定义、区别与应用指南
网络·pcb工艺
喵手1 小时前
Python爬虫零基础入门【第四章:解析与清洗·第3节】文本清洗:去空格、去噪、金额/日期/单位标准化!
爬虫·python·python爬虫实战·文本清洗·python爬虫工程化实战·python爬虫零基础入门·去空格去噪
夜勤月1 小时前
拒绝线程死锁与调度延迟:深度实战 C++ 内存模型与无锁队列,构建高并发系统级中枢
java·c++·spring
Qiuner2 小时前
软件工程计算机网络WindowService2008 DNS DHCP网络策略和访问策略IIS 相关配置 期末考试实操题操作题windows运维
运维·网络·windows·计算机网络
喵手2 小时前
Python爬虫零基础入门【第四章:解析与清洗·第1节】BeautifulSoup 入门:从 HTML 提取结构化字段!
爬虫·python·beautifulsoup·爬虫实战·python爬虫工程化实战·零基础python爬虫教学·beautifulsoup入门
安科瑞刘鸿鹏172 小时前
电量和碳量如何建立关系?企业能碳管理的关键一步
运维·网络·物联网·安全
智子喻2 小时前
2026企业微信社群运营工具专业度排名:AI驱动下的私域增长工具实测
大数据·网络·新媒体运营·企业微信·用户运营
小李独爱秋2 小时前
计算机网络经典问题透视:试述资源预留协议RSVP的工作原理?
运维·服务器·网络·网络协议·计算机网络·rsvp
应用市场2 小时前
CNN池化层深度解析:从原理到PyTorch实现
人工智能·pytorch·python