diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 088598e2..e536d00e 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -322,9 +322,6 @@ class ConnectionHandler: # Define intent functions functions = self.func_handler.get_functions() - mcpfuncs = self.mcp_manager.get_all_tools() # MCP工具 - functions.extend(mcpfuncs) - print("functions with mcp", functions) response_message = [] processed_chars = 0 # 跟踪已处理的字符位置 @@ -482,11 +479,17 @@ class ConnectionHandler: args_dict ), self.loop).result() # meta=None content=[TextContent(type='text', text='北京当前天气:\n温度: 21°C\n天气: 晴\n湿度: 6%\n风向: 西北 风\n风力等级: 5级', annotations=None)] isError=False - self.logger.bind(tag=TAG).info(f"tool_result:{tool_result}") - if tool_result is not None: - if tool_result.content is not None: - print(tool_result.content) - return ActionResponse(action=Action.REQLLM, result=tool_result.content[0].text, response="") + content_text = "" + if tool_result is not None and tool_result.content is not None: + for content in tool_result.content: + content_type = content.type + if content_type == "text": + content_text = content.text + elif content_type == "image": + pass + + if len(content_text) > 0: + return ActionResponse(action=Action.REQLLM, result=content_text, response="") except Exception as e: self.logger.bind(tag=TAG).error(f"MCP工具调用错误: {e}") diff --git a/main/xiaozhi-server/core/mcp/MCPClient.py b/main/xiaozhi-server/core/mcp/MCPClient.py index a8be61e1..3c32e077 100644 --- a/main/xiaozhi-server/core/mcp/MCPClient.py +++ b/main/xiaozhi-server/core/mcp/MCPClient.py @@ -1,4 +1,4 @@ -import asyncio +from datetime import timedelta from typing import Optional from contextlib import AsyncExitStack import os, shutil @@ -26,8 +26,10 @@ class MCPClient: if self.config["command"] == "npx" else self.config["command"] ) - - env={**os.environ, **self.config["env"]} + + env={**os.environ} + if self.config.get("env"): + env.update(self.config["env"]) server_params = StdioServerParameters( command=command, @@ -37,7 +39,8 @@ class MCPClient: stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params)) self.stdio, self.write = stdio_transport - self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write)) + time_out_delta = timedelta(seconds=10) + self.session = await self.exit_stack.enter_async_context(ClientSession(read_stream=self.stdio, write_stream=self.write, read_timeout_seconds=time_out_delta)) await self.session.initialize() @@ -61,7 +64,21 @@ class MCPClient: async def call_tool(self, tool_name: str, tool_args: dict): self.logger.bind(tag=TAG).info(f"MCPClient Calling tool {tool_name} with args: {tool_args}") - response = await self.session.call_tool(tool_name, tool_args) + try: + response = await self.session.call_tool(tool_name, tool_args) + except Exception as e: + self.logger.bind(tag=TAG).error(f"Error calling tool {tool_name}: {e}") + from types import SimpleNamespace + error_content = SimpleNamespace( + type='text', + text=f"Error calling tool {tool_name}: {e}" + ) + error_response = SimpleNamespace( + content=[error_content], + isError=True + ) + return error_response + self.logger.bind(tag=TAG).info(f"MCPClient Response from tool {tool_name}: {response}") return response async def cleanup(self): diff --git a/main/xiaozhi-server/core/mcp/manager.py b/main/xiaozhi-server/core/mcp/manager.py index cae3bcf2..810554e7 100644 --- a/main/xiaozhi-server/core/mcp/manager.py +++ b/main/xiaozhi-server/core/mcp/manager.py @@ -1,5 +1,5 @@ """MCP服务管理器""" -import json +import os, json from typing import Dict, Any, List from .MCPClient import MCPClient from config.logger import setup_logging @@ -16,9 +16,12 @@ class MCPManager: 初始化MCP管理器 """ self.conn = conn - self.config_path = get_project_dir() + 'data/.mcp_server_settings.json' - self.client: Dict[str, MCPClient] = {} self.logger = setup_logging() + self.config_path = get_project_dir() + 'data/.mcp_server_settings.json' + if os.path.exists(self.config_path) == False: + self.config_path = "" + self.logger.bind(tag=TAG).warning(f"请检查mcp服务配置文件:data/.mcp_server_settings.json") + self.client: Dict[str, MCPClient] = {} self.tools = [] def load_config(self) -> Dict[str, Any]: @@ -26,6 +29,9 @@ class MCPManager: Returns: Dict[str, Any]: 服务配置字典 """ + if len(self.config_path) == 0: + return {} + try: with open(self.config_path, 'r', encoding='utf-8') as f: config = json.load(f)