add 增加 ruoyi-common-mcp 模块 支持作为server提供mcp接口提供数据 与 接入多个client做数据采集
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
<module>ruoyi-common-encrypt</module>
|
||||
<module>ruoyi-common-push</module>
|
||||
<module>ruoyi-common-mqtt</module>
|
||||
<module>ruoyi-common-mcp</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -159,6 +159,13 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mcp模块 -->
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-mcp</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>ruoyi-common-mcp</artifactId>
|
||||
|
||||
<description>
|
||||
ruoyi-common-mcp mcp模块
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>ruoyi-common-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-starter-mcp-client</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package org.dromara.common.mcp.config;
|
||||
|
||||
import io.modelcontextprotocol.client.McpSyncClient;
|
||||
import org.dromara.common.mcp.core.McpClientTemplate;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MCP 公共模块自动配置。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@AutoConfiguration
|
||||
public class McpAutoConfiguration {
|
||||
|
||||
/**
|
||||
* MCP Client 通用操作模板。
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnBean(McpSyncClient.class)
|
||||
@ConditionalOnMissingBean
|
||||
public McpClientTemplate mcpClientTemplate(List<McpSyncClient> mcpSyncClients) {
|
||||
return new McpClientTemplate(mcpSyncClients);
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
package org.dromara.common.mcp.core;
|
||||
|
||||
import io.modelcontextprotocol.client.McpSyncClient;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* MCP Client 通用操作模板。
|
||||
* <p>
|
||||
* Spring AI 已经负责 MCP Client 的创建、初始化与连接管理,本模板只做项目内常用调用封装,
|
||||
* 避免业务模块直接遍历 `McpSyncClient` 或重复处理返回结构。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class McpClientTemplate {
|
||||
|
||||
private final List<McpSyncClient> mcpSyncClients;
|
||||
|
||||
/**
|
||||
* 查询所有已连接 MCP Server 的工具列表。
|
||||
*
|
||||
* @return Server 名称与工具名称列表
|
||||
*/
|
||||
public Map<String, List<String>> listTools() {
|
||||
Map<String, List<String>> result = new LinkedHashMap<>();
|
||||
for (McpSyncClient client : mcpSyncClients) {
|
||||
List<String> tools = client.listTools().tools().stream()
|
||||
.map(McpSchema.Tool::name)
|
||||
.toList();
|
||||
result.put(getServerName(client), tools);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用所有 MCP Server 上的同名工具。
|
||||
*
|
||||
* @param toolName 工具名称
|
||||
* @param arguments 工具参数
|
||||
* @return 各 Server 的工具调用结果
|
||||
*/
|
||||
public Map<String, McpToolCallResult> callTool(String toolName, Map<String, Object> arguments) {
|
||||
Map<String, McpToolCallResult> result = new LinkedHashMap<>();
|
||||
for (McpSyncClient client : mcpSyncClients) {
|
||||
McpSchema.CallToolResult callResult = client.callTool(new McpSchema.CallToolRequest(toolName, arguments));
|
||||
result.put(getServerName(client), McpToolCallResult.of(getServerName(client), callResult));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用指定 MCP Server 上的工具。
|
||||
*
|
||||
* @param serverName Server 名称
|
||||
* @param toolName 工具名称
|
||||
* @param arguments 工具参数
|
||||
* @return 工具调用结果
|
||||
*/
|
||||
public Optional<McpToolCallResult> callTool(String serverName, String toolName, Map<String, Object> arguments) {
|
||||
return findClient(serverName)
|
||||
.map(client -> McpToolCallResult.of(serverName, client.callTool(new McpSchema.CallToolRequest(toolName, arguments))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取所有 MCP Server 上的同名资源。
|
||||
*
|
||||
* @param uri 资源地址
|
||||
* @return 各 Server 的资源内容
|
||||
*/
|
||||
public Map<String, McpResourceReadResult> readResource(String uri) {
|
||||
Map<String, McpResourceReadResult> result = new LinkedHashMap<>();
|
||||
for (McpSyncClient client : mcpSyncClients) {
|
||||
McpSchema.ReadResourceResult readResult = client.readResource(new McpSchema.ReadResourceRequest(uri));
|
||||
result.put(getServerName(client), McpResourceReadResult.of(getServerName(client), readResult));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取指定 MCP Server 上的资源。
|
||||
*
|
||||
* @param serverName Server 名称
|
||||
* @param uri 资源地址
|
||||
* @return 资源内容
|
||||
*/
|
||||
public Optional<McpResourceReadResult> readResource(String serverName, String uri) {
|
||||
return findClient(serverName)
|
||||
.map(client -> McpResourceReadResult.of(serverName, client.readResource(new McpSchema.ReadResourceRequest(uri))));
|
||||
}
|
||||
|
||||
/**
|
||||
* 按 Server 名称查找 MCP Client。
|
||||
*
|
||||
* @param serverName Server 名称
|
||||
* @return MCP Client
|
||||
*/
|
||||
public Optional<McpSyncClient> findClient(String serverName) {
|
||||
return mcpSyncClients.stream()
|
||||
.filter(client -> serverName.equals(getServerName(client)))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询已连接的 MCP Client。
|
||||
*
|
||||
* @return MCP Client 列表
|
||||
*/
|
||||
public List<McpSyncClient> getClients() {
|
||||
return mcpSyncClients;
|
||||
}
|
||||
|
||||
private String getServerName(McpSyncClient client) {
|
||||
McpSchema.Implementation serverInfo = client.getServerInfo();
|
||||
if (serverInfo == null || serverInfo.name() == null) {
|
||||
return "unknown";
|
||||
}
|
||||
return serverInfo.name();
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package org.dromara.common.mcp.core;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MCP 资源读取结果。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public record McpResourceReadResult(
|
||||
String serverName,
|
||||
List<McpSchema.ResourceContents> contents
|
||||
) {
|
||||
|
||||
public static McpResourceReadResult of(String serverName, McpSchema.ReadResourceResult result) {
|
||||
return new McpResourceReadResult(serverName, result.contents());
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.dromara.common.mcp.core;
|
||||
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* MCP 工具调用结果。
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
public record McpToolCallResult(
|
||||
String serverName,
|
||||
boolean error,
|
||||
List<McpSchema.Content> content,
|
||||
Object structuredContent
|
||||
) {
|
||||
|
||||
public static McpToolCallResult of(String serverName, McpSchema.CallToolResult result) {
|
||||
return new McpToolCallResult(
|
||||
serverName,
|
||||
Boolean.TRUE.equals(result.isError()),
|
||||
result.content(),
|
||||
result.structuredContent()
|
||||
);
|
||||
}
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.dromara.common.mcp.config.McpAutoConfiguration
|
||||
Reference in New Issue
Block a user