From 6c57ce9dd2ba7e036c4529b340730e358a3b8614 Mon Sep 17 00:00:00 2001 From: 3030332422 <3030332422@qq.com> Date: Fri, 19 Dec 2025 11:49:42 +0800 Subject: [PATCH 1/3] =?UTF-8?q?update=EF=BC=9A=E5=B0=86=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=AB=AFMCP=E7=9A=84=E5=88=9D=E5=A7=8B=E5=8C=96MCP=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E4=BB=8E=E4=B8=B2=E8=A1=8C=E6=94=B9=E4=B8=BA=E5=B9=B6?= =?UTF-8?q?=E5=8F=91=E6=89=A7=E8=A1=8C=EF=BC=8C=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../providers/tools/server_mcp/mcp_manager.py | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py index 6edc44d1..1d0d9cb6 100644 --- a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py +++ b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py @@ -49,29 +49,47 @@ class ServerMCPManager: ) return {} + async def _init_server(self, name: str, srv_config: Dict[str, Any]): + """初始化单个MCP服务""" + client = None + try: + # 初始化服务端MCP客户端 + logger.bind(tag=TAG).info(f"初始化服务端MCP客户端: {name}") + client = ServerMCPClient(srv_config) + # 设置超时时间5秒 + await asyncio.wait_for(client.initialize(logging_callback=self.logging_callback), timeout=5) + self.clients[name] = client + client_tools = client.get_available_tools() + self.tools.extend(client_tools) + + except asyncio.TimeoutError: + logger.bind(tag=TAG).error( + f"Failed to initialize MCP server {name}: Timeout" + ) + if client: + await client.cleanup() + except Exception as e: + logger.bind(tag=TAG).error( + f"Failed to initialize MCP server {name}: {e}" + ) + if client: + await client.cleanup() + async def initialize_servers(self) -> None: """初始化所有MCP服务""" config = self.load_config() + tasks = [] for name, srv_config in config.items(): if not srv_config.get("command") and not srv_config.get("url"): logger.bind(tag=TAG).warning( f"Skipping server {name}: neither command nor url specified" ) continue - - try: - # 初始化服务端MCP客户端 - logger.bind(tag=TAG).info(f"初始化服务端MCP客户端: {name}") - client = ServerMCPClient(srv_config) - await client.initialize(logging_callback=self.logging_callback) - self.clients[name] = client - client_tools = client.get_available_tools() - self.tools.extend(client_tools) - - except Exception as e: - logger.bind(tag=TAG).error( - f"Failed to initialize MCP server {name}: {e}" - ) + + tasks.append(self._init_server(name, srv_config)) + + if tasks: + await asyncio.gather(*tasks, return_exceptions=True) # 输出当前支持的服务端MCP工具列表 if hasattr(self.conn, "func_handler") and self.conn.func_handler: From 85f5404b3bafcfe84a21a4135f8f5fabc368a881 Mon Sep 17 00:00:00 2001 From: 3030332422 <3030332422@qq.com> Date: Mon, 22 Dec 2025 15:56:40 +0800 Subject: [PATCH 2/3] =?UTF-8?q?update=EF=BC=9A=E6=B7=BB=E5=8A=A0=E9=94=81?= =?UTF-8?q?=E4=BF=9D=E6=8A=A4=E9=81=BF=E5=85=8DMCP=E5=B9=B6=E5=8F=91?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E6=97=B6=E7=9A=84=E7=AB=9E=E6=80=81?= =?UTF-8?q?=E6=9D=A1=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/providers/tools/server_mcp/mcp_manager.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py index 1d0d9cb6..3bca9e48 100644 --- a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py +++ b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py @@ -33,6 +33,7 @@ class ServerMCPManager: ) self.clients: Dict[str, ServerMCPClient] = {} self.tools = [] + self._init_lock = asyncio.Lock() def load_config(self) -> Dict[str, Any]: """加载MCP服务配置""" @@ -58,9 +59,12 @@ class ServerMCPManager: client = ServerMCPClient(srv_config) # 设置超时时间5秒 await asyncio.wait_for(client.initialize(logging_callback=self.logging_callback), timeout=5) - self.clients[name] = client - client_tools = client.get_available_tools() - self.tools.extend(client_tools) + + # 使用锁保护共享状态的修改 + async with self._init_lock: + self.clients[name] = client + client_tools = client.get_available_tools() + self.tools.extend(client_tools) except asyncio.TimeoutError: logger.bind(tag=TAG).error( @@ -89,7 +93,7 @@ class ServerMCPManager: tasks.append(self._init_server(name, srv_config)) if tasks: - await asyncio.gather(*tasks, return_exceptions=True) + await asyncio.gather(*tasks) # 输出当前支持的服务端MCP工具列表 if hasattr(self.conn, "func_handler") and self.conn.func_handler: From e066c1d6a144c9f23b7697e1444f62ef97a8716b Mon Sep 17 00:00:00 2001 From: 3030332422 <3030332422@qq.com> Date: Mon, 22 Dec 2025 16:38:28 +0800 Subject: [PATCH 3/3] =?UTF-8?q?update=EF=BC=9A=E8=B6=85=E6=97=B6=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=9B=B4=E6=94=B9=E4=B8=BA10=E7=A7=92=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E4=B8=94=E5=88=A0=E5=8E=BB=E6=97=A0=E7=94=A8=E7=9A=84?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/providers/tools/server_mcp/mcp_manager.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py index 3bca9e48..b1fc0aa3 100644 --- a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py +++ b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_manager.py @@ -3,12 +3,8 @@ import asyncio import os import json -from datetime import timedelta from typing import Dict, Any, List -from mcp import Implementation -from mcp.client.session import SamplingFnT, ElicitationFnT, ListRootsFnT, LoggingFnT, MessageHandlerFnT -from mcp.shared.session import ProgressFnT from mcp.types import LoggingMessageNotificationParams from config.config_loader import get_project_dir @@ -57,8 +53,8 @@ class ServerMCPManager: # 初始化服务端MCP客户端 logger.bind(tag=TAG).info(f"初始化服务端MCP客户端: {name}") client = ServerMCPClient(srv_config) - # 设置超时时间5秒 - await asyncio.wait_for(client.initialize(logging_callback=self.logging_callback), timeout=5) + # 设置超时时间10秒 + await asyncio.wait_for(client.initialize(logging_callback=self.logging_callback), timeout=10) # 使用锁保护共享状态的修改 async with self._init_lock: