小智服务器:设备的各种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系统的工作流程包括初始化阶段和运行阶段,初始化阶段负责建立连接和获取工具列表,运行阶段则负责调用工具和处理响应。这种设计使得系统具有良好的扩展性和灵活性,可以根据需要添加新的工具和功能。

相关推荐
啦啦啦_99992 小时前
Redis实例-2
java
alice--小文子2 小时前
cursor-mcp工具使用
java·服务器·前端
进阶小白猿2 小时前
Java技术八股学习Day33
java·开发语言·学习
程序员敲代码吗3 小时前
如何通过命令行启动COMSOL的参数化、批处理和集群扫描
java·c#·bash
MX_93593 小时前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
市场部需要一个软件开发岗位3 小时前
JAVA开发常见安全问题:纵向越权
java·数据库·安全
历程里程碑3 小时前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
weixin_395448913 小时前
mult_yolov5_post_copy.c_cursor_0205
c语言·python·yolo
执风挽^3 小时前
Python基础编程题2
开发语言·python·算法·visual studio code
程序员泠零澪回家种桔子3 小时前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构