From 5149a8049a0c4058eb2be6c68f1de408c694ccae Mon Sep 17 00:00:00 2001 From: 3030332422 <3030332422@qq.com> Date: Wed, 29 Oct 2025 23:14:42 +0800 Subject: [PATCH] =?UTF-8?q?update=EF=BC=9A=E6=9C=8D=E5=8A=A1=E7=AB=AFMCP?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=94=AF=E6=8C=81Streamable=20HTTP=E4=BC=A0?= =?UTF-8?q?=E8=BE=93=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../providers/tools/server_mcp/mcp_client.py | 32 ++++++++++++++++--- main/xiaozhi-server/mcp_server_settings.json | 13 ++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_client.py b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_client.py index 6dd14195..c1126a64 100644 --- a/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_client.py +++ b/main/xiaozhi-server/core/providers/tools/server_mcp/mcp_client.py @@ -13,6 +13,7 @@ from typing import Optional, List, Dict, Any from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client from mcp.client.sse import sse_client +from mcp.client.streamable_http import streamablehttp_client from config.logger import setup_logging from core.utils.util import sanitize_tool_name @@ -172,10 +173,33 @@ class ServerMCPClient: if "API_ACCESS_TOKEN" in self.config: headers["Authorization"] = f"Bearer {self.config['API_ACCESS_TOKEN']}" self.logger.bind(tag=TAG).warning(f"你正在使用旧过时的配置 API_ACCESS_TOKEN ,请在.mcp_server_settings.json中将API_ACCESS_TOKEN直接设置在headers中,例如 'Authorization': 'Bearer API_ACCESS_TOKEN'") - sse_r, sse_w = await stack.enter_async_context( - sse_client(self.config["url"], headers=headers, timeout=self.config.get("timeout", 5), sse_read_timeout=self.config.get("sse_read_timeout", 60 * 5)) - ) - read_stream, write_stream = sse_r, sse_w + + # 根据transport类型选择不同的客户端,默认为SSE + transport_type = self.config.get("transport", "sse") + + if transport_type == "streamable-http" or transport_type == "http": + # 使用 Streamable HTTP 传输 + http_r, http_w, get_session_id = await stack.enter_async_context( + streamablehttp_client( + url=self.config["url"], + headers=headers, + timeout=self.config.get("timeout", 30), + sse_read_timeout=self.config.get("sse_read_timeout", 60 * 5), + terminate_on_close=self.config.get("terminate_on_close", True) + ) + ) + read_stream, write_stream = http_r, http_w + else: + # 使用传统的 SSE 传输 + sse_r, sse_w = await stack.enter_async_context( + sse_client( + url=self.config["url"], + headers=headers, + timeout=self.config.get("timeout", 5), + sse_read_timeout=self.config.get("sse_read_timeout", 60 * 5) + ) + ) + read_stream, write_stream = sse_r, sse_w else: raise ValueError("MCP客户端配置必须包含'command'或'url'") diff --git a/main/xiaozhi-server/mcp_server_settings.json b/main/xiaozhi-server/mcp_server_settings.json index 70607a2c..966741b4 100644 --- a/main/xiaozhi-server/mcp_server_settings.json +++ b/main/xiaozhi-server/mcp_server_settings.json @@ -4,7 +4,7 @@ "后面不断测试补充好用的mcp服务,欢迎大家一起补充。", "记得删除注释行,des属性仅为说明,不会被解析。", "des和link属性,仅为说明安装方式,方便大家查看原始链接,不是必须项。", - "当前支持stdio/sse两种模式。" + "当前支持三种传输模式:stdio(标准输入输出), sse(Server-Sent Events), streamable-http(流式HTTP)。" ], "mcpServers": { "Home Assistant": { @@ -41,7 +41,16 @@ "url": "http://localhost:8080/sse", "headers": { "Authorization": "Bearer YOUR TOKEN" - } + }, + "des": "使用SSE传输模式(默认)" + }, + "streamable-http-mcp-server": { + "url": "http://localhost:8000/mcp", + "transport": "streamable-http", + "headers": { + "Authorization": "Bearer YOUR TOKEN" + }, + "des": "使用Streamable HTTP传输模式,适用于生产环境的Web部署" } } }