|
|
@ -464,11 +464,23 @@ public class McpClientManager { |
|
|
|
|
|
|
|
|
if ("sse".equals(config.getTransportType())) { |
|
|
if ("sse".equals(config.getTransportType())) { |
|
|
// 创建 SSE 传输层:连接远程 MCP Server |
|
|
// 创建 SSE 传输层:连接远程 MCP Server |
|
|
// HttpClientSseClientTransport 会自动将 /sse 作为 SSE 端点附加到 baseUri |
|
|
|
|
|
String serverUrl = config.getServerUrl().trim(); |
|
|
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 服务 |
|
|
// 注入自定义请求头(如 Authorization / X-API-Key),适配需要鉴权的远程 MCP 服务 |
|
|
Map<String, Object> headers = config.getHeaders(); |
|
|
Map<String, Object> headers = config.getHeaders(); |
|
|
if (headers != null && !headers.isEmpty()) { |
|
|
if (headers != null && !headers.isEmpty()) { |
|
|
@ -481,7 +493,7 @@ public class McpClientManager { |
|
|
HttpClientSseClientTransport transport = transportBuilder.build(); |
|
|
HttpClientSseClientTransport transport = transportBuilder.build(); |
|
|
|
|
|
|
|
|
client = buildSyncClient(transport); |
|
|
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())) { |
|
|
} else if ("stdio".equals(config.getTransportType())) { |
|
|
// 创建 stdio 传输层:启动本地 MCP Server 进程 |
|
|
// 创建 stdio 传输层:启动本地 MCP Server 进程 |
|
|
|