in spring-ai-alibaba-mcp/spring-ai-alibaba-mcp-nacos-dynamic-server/src/main/java/com/alibaba/cloud/ai/mcp/dynamic/server/watcher/DynamicNacosToolsWatcher.java [291:375]
private void updateHighVersionServiceTools(String mcpName) {
try {
String url = NacosHelper.getServerUrl(nacosMcpProperties.getServerAddr());
String mcpServerDetail = webClient.get()
.uri(url + "/nacos/v3/admin/ai/mcp?mcpName=" + mcpName)
.header("userName", nacosMcpProperties.getUsername())
.header("password", nacosMcpProperties.getPassword())
.retrieve()
.bodyToMono(String.class)
.block();
logger.info("Nacos mcp server info (name {}): {}", mcpName, mcpServerDetail);
Map<String, Object> serverInfoMap = JacksonUtils.toObj(mcpServerDetail, Map.class);
if (serverInfoMap != null && serverInfoMap.containsKey("data")) {
Map<String, Object> data = (Map<String, Object>) serverInfoMap.get("data");
if (data != null && data.containsKey("toolSpec")) {
Object toolSpec = data.get("toolSpec");
Object remoteServerConfig = data.get("remoteServerConfig");
Object localeServerConfig = data.get("localeServerConfig");
String protocol = (String) data.get("protocol");
if (toolSpec != null) {
Map<String, Object> toolSpecMap = JacksonUtils.toObj(JacksonUtils.toJson(toolSpec), Map.class);
List<Map<String, Object>> tools = (List<Map<String, Object>>) toolSpecMap.get("tools");
Map<String, Object> toolsMeta = (Map<String, Object>) toolSpecMap.get("toolsMeta");
// Update tools cache
Set<String> currentTools = new HashSet<>();
for (Map<String, Object> tool : tools) {
String toolName = (String) tool.get("name");
currentTools.add(toolName);
// Check if tool is enabled
Object metaInfo = toolsMeta.getOrDefault(toolName, new Object());
boolean enabled = false;
if (metaInfo instanceof Map) {
Object enabledObj = ((Map<?, ?>) metaInfo).get("enabled");
if (enabledObj instanceof Boolean) {
enabled = (Boolean) enabledObj;
}
else if (enabledObj instanceof String) {
enabled = Boolean.parseBoolean((String) enabledObj);
}
}
if (!enabled) {
logger.info("Tool {} is disabled by metaInfo, skipping.", toolName);
continue;
}
// Create and add tool definition
ToolDefinition toolDefinition = DynamicNacosToolDefinitionV3.builder()
.name(toolName)
.description((String) tool.get("description"))
.inputSchema(tool.get("inputSchema"))
.protocol(protocol)
.remoteServerConfig(remoteServerConfig)
.localServerConfig(localeServerConfig)
.toolsMeta(metaInfo)
.build();
dynamicMcpToolsProvider.addTool(toolDefinition);
}
// Get previous tools for this service
Set<String> previousTools = serviceToolsCache.getOrDefault(mcpName, new HashSet<>());
// Remove obsolete tools
Set<String> toolsToRemove = new HashSet<>(previousTools);
toolsToRemove.removeAll(currentTools);
for (String toolName : toolsToRemove) {
logger.info("Removing obsolete tool: {} for service: {}", toolName, mcpName);
dynamicMcpToolsProvider.removeTool(toolName);
}
// Update cache
serviceToolsCache.put(mcpName, currentTools);
}
}
}
}
catch (Exception e) {
logger.error("Failed to update tools for high version service: {}", mcpName, e);
}
}