|
|
@@ -2,6 +2,7 @@ package edu.nju.software.aipaasagent.mcp.client;
|
|
|
|
|
|
import edu.nju.software.aipaasagent.mcp.config.CustomMcpProperties;
|
|
|
import edu.nju.software.aipaasagent.mcp.config.DefaultMcpJsonMapper;
|
|
|
+import io.modelcontextprotocol.client.McpAsyncClient;
|
|
|
import io.modelcontextprotocol.client.McpClient;
|
|
|
import io.modelcontextprotocol.client.McpSyncClient;
|
|
|
import io.modelcontextprotocol.client.transport.WebClientStreamableHttpTransport;
|
|
|
@@ -28,12 +29,11 @@ public class McpClientService {
|
|
|
|
|
|
private final CustomMcpProperties properties;
|
|
|
private final Builder webClientBuilder;
|
|
|
- private final McpJsonMapper mcpJsonMapper;
|
|
|
|
|
|
//private final ObjectMapper objectMapper;
|
|
|
// 1. 使用 CopyOnWriteArrayList 保证读写并发安全
|
|
|
- private final List<McpSyncClient> mcpSyncClients = new CopyOnWriteArrayList<>();
|
|
|
- // private final Map<String, McpToolMetadata> toolRegistry = new ConcurrentHashMap<>();
|
|
|
+ private final List<McpAsyncClient> mcpAsyncClients = new CopyOnWriteArrayList<>();
|
|
|
+
|
|
|
|
|
|
@Resource
|
|
|
DefaultMcpJsonMapper defaultMcpJsonMapper;
|
|
|
@@ -42,7 +42,6 @@ public class McpClientService {
|
|
|
Builder webClientBuilder) {
|
|
|
this.properties = properties;
|
|
|
this.webClientBuilder = webClientBuilder;
|
|
|
- this.mcpJsonMapper = defaultMcpJsonMapper;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -63,7 +62,7 @@ public class McpClientService {
|
|
|
|
|
|
// 使用更灵活的方式处理 SSE 流
|
|
|
String sessionId = webClient.get()
|
|
|
- .uri("/mcp")
|
|
|
+ .uri("/mcp/airouting")
|
|
|
.retrieve()
|
|
|
.bodyToFlux(String.class)
|
|
|
.doOnNext(line -> {
|
|
|
@@ -107,7 +106,7 @@ public class McpClientService {
|
|
|
// log.info("🛠️ 正在执行 MCP 节点重构...");
|
|
|
|
|
|
// 3. 资源释放:关闭旧客户端,防止内存泄漏
|
|
|
- mcpSyncClients.forEach(client -> {
|
|
|
+ mcpAsyncClients.forEach(client -> {
|
|
|
try {
|
|
|
if (client instanceof AutoCloseable) { // 兼容不同SDK实现
|
|
|
((AutoCloseable) client).close();
|
|
|
@@ -117,7 +116,7 @@ public class McpClientService {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
- mcpSyncClients.clear();
|
|
|
+ mcpAsyncClients.clear();
|
|
|
// toolRegistry.clear();
|
|
|
|
|
|
String sessionId = "";
|
|
|
@@ -149,10 +148,10 @@ public class McpClientService {
|
|
|
// MCP 协议使用日期格式版本号,常见:2024-11-05, 2025-03-26 等
|
|
|
List<String> supportedProtocolVersions = List.of("2025-11-25", "2025-03-26", "2024-11-05");
|
|
|
|
|
|
- var transport = WebClientStreamableHttpTransport.builder(dedicatedBuilder).openConnectionOnStartup(openConnectionOnStartup).endpoint("/mcp").jsonMapper(defaultMcpJsonMapper).resumableStreams(true)
|
|
|
+ var transport = WebClientStreamableHttpTransport.builder(dedicatedBuilder).openConnectionOnStartup(openConnectionOnStartup).endpoint("/mcp/airouting").jsonMapper(defaultMcpJsonMapper).resumableStreams(true)
|
|
|
.supportedProtocolVersions(supportedProtocolVersions).build();
|
|
|
// 6. 建立连接
|
|
|
- McpSyncClient client = McpClient.sync(transport).build();
|
|
|
+ McpAsyncClient client = McpClient.async(transport).build();
|
|
|
log.info("🛠️执行成功 {}", client.getClientInfo());
|
|
|
|
|
|
// 等待服务端完全准备好
|
|
|
@@ -164,14 +163,14 @@ public class McpClientService {
|
|
|
|
|
|
// 获取工具列表
|
|
|
log.info("📡 节点 [{}] 请求工具列表...", name);
|
|
|
- McpSchema.ListToolsResult toolResponse = client.listTools();
|
|
|
+ McpSchema.ListToolsResult toolResponse = client.listTools().block();
|
|
|
|
|
|
log.info("🔍 节点 [{}] 工具列表响应:{} 个工具", name,
|
|
|
toolResponse != null && toolResponse.tools() != null ? toolResponse.tools().size() : "null");
|
|
|
|
|
|
if (toolResponse != null && toolResponse.tools() != null) {
|
|
|
List<McpSchema.Tool> tools = toolResponse.tools();
|
|
|
- mcpSyncClients.add(client);
|
|
|
+ mcpAsyncClients.add(client);
|
|
|
if (tools.isEmpty()) {
|
|
|
log.warn("⚠️ 节点 [{}] 挂载成功,但工具列表为空。可能原因:1) 服务端未注册工具;2) 认证权限不足;3) 工具注册延迟", name);
|
|
|
} else {
|
|
|
@@ -180,7 +179,7 @@ public class McpClientService {
|
|
|
}
|
|
|
} else {
|
|
|
log.warn("⚠️ 节点 [{}] 挂载成功,但工具列表返回为 null", name);
|
|
|
- mcpSyncClients.add(client);
|
|
|
+ mcpAsyncClients.add(client);
|
|
|
}
|
|
|
} catch (WebClientResponseException e) {
|
|
|
log.error("❌ 节点 [{}] 挂载失败:HTTP {} - 服务端返回错误,请检查服务端状态",
|