diff --git a/src/main/java/com/wok/supportbot/config/McpClientManager.java b/src/main/java/com/wok/supportbot/config/McpClientManager.java index 2e8e5cb..b97a96d 100644 --- a/src/main/java/com/wok/supportbot/config/McpClientManager.java +++ b/src/main/java/com/wok/supportbot/config/McpClientManager.java @@ -464,11 +464,23 @@ public class McpClientManager { if ("sse".equals(config.getTransportType())) { // 创建 SSE 传输层:连接远程 MCP Server - // HttpClientSseClientTransport 会自动将 /sse 作为 SSE 端点附加到 baseUri String serverUrl = config.getServerUrl().trim(); - // 如果 URL 以 /sse 结尾,去掉后缀作为 baseUri(transport 层会自动附加) - String baseUri = serverUrl.replaceAll("/sse/?$", ""); - HttpClientSseClientTransport.Builder transportBuilder = HttpClientSseClientTransport.builder(baseUri); + + // 显式拆分 origin(scheme://host:port)与 path,分别作为 baseUri 与 sseEndpoint。 + // 注意:HttpClientSseClientTransport 内部用 URI.resolve 拼接,对以 / 开头的 sseEndpoint + // 会整体替换 path,因此不能把「去掉 /sse 的完整 URL」当 baseUri(否则 /mcp-cdw/sse 会 + // 被 resolve 成 /sse,丢失路径前缀)。这里把 origin 作为 baseUri、完整 path 作为 sseEndpoint。 + java.net.URI uri = java.net.URI.create(serverUrl); + String baseUri = uri.getScheme() + "://" + uri.getAuthority(); + String ssePath = uri.getPath() == null ? "" : uri.getPath(); + // 规范化:去掉末尾 / 后,确保 path 以 /sse 结尾(兼容用户填 base 或完整 SSE URL 两种写法) + ssePath = ssePath.replaceAll("/+$", ""); + if (!ssePath.endsWith("/sse")) { + ssePath = ssePath + "/sse"; + } + + HttpClientSseClientTransport.Builder transportBuilder = + HttpClientSseClientTransport.builder(baseUri).sseEndpoint(ssePath); // 注入自定义请求头(如 Authorization / X-API-Key),适配需要鉴权的远程 MCP 服务 Map headers = config.getHeaders(); if (headers != null && !headers.isEmpty()) { @@ -481,7 +493,7 @@ public class McpClientManager { HttpClientSseClientTransport transport = transportBuilder.build(); client = buildSyncClient(transport); - log.info("正在初始化 SSE MCP 客户端: id={}, url={}, headers={}", config.getId(), baseUri, headers != null ? headers.keySet() : "无"); + log.info("正在初始化 SSE MCP 客户端: id={}, url={}, headers={}", config.getId(), baseUri + ssePath, headers != null ? headers.keySet() : "无"); } else if ("stdio".equals(config.getTransportType())) { // 创建 stdio 传输层:启动本地 MCP Server 进程