diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index da406558..e952157f 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -15,9 +15,9 @@ spring:
master:
type: ${spring.datasource.type}
driverClassName: com.mysql.cj.jdbc.Driver
- url: jdbc:mysql://127.0.0.1:3306/ruoyi_ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
+ url: jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
username: root
- password: 1234
+ password: root
hikari:
# 最大连接池数量
diff --git a/ruoyi-extend/ruoyi-mcp-server/pom.xml b/ruoyi-extend/ruoyi-mcp-server/pom.xml
index 6dfb5d17..a35f0140 100644
--- a/ruoyi-extend/ruoyi-mcp-server/pom.xml
+++ b/ruoyi-extend/ruoyi-mcp-server/pom.xml
@@ -47,39 +47,6 @@
test
-
-
- cn.hutool
- hutool-all
- 5.8.25
-
-
-
-
- com.squareup.okhttp3
- okhttp
- 4.12.0
-
-
-
-
- net.sourceforge.plantuml
- plantuml
- 1.2024.3
-
-
-
-
- org.springframework.ai
- spring-ai-tika-document-reader
-
-
-
-
- org.projectlombok
- lombok
- true
-
diff --git a/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/config/ToolsProperties.java b/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/config/ToolsProperties.java
deleted file mode 100644
index 18cf16ff..00000000
--- a/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/config/ToolsProperties.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.ruoyi.mcpserve.config;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-/**
- * 工具配置属性类
- *
- * @author OpenX
- */
-@Data
-@Component
-@ConfigurationProperties(prefix = "tools")
-public class ToolsProperties {
-
- /**
- * Pexels图片搜索配置
- */
- private Pexels pexels = new Pexels();
-
- /**
- * Tavily搜索配置
- */
- private Tavily tavily = new Tavily();
-
- /**
- * 文件操作配置
- */
- private FileConfig file = new FileConfig();
-
- @Data
- public static class Pexels {
- /**
- * Pexels API密钥
- */
- private String apiKey;
-
- /**
- * API地址
- */
- private String apiUrl = "https://api.pexels.com/v1/search";
- }
-
- @Data
- public static class Tavily {
- /**
- * Tavily API密钥
- */
- private String apiKey;
-
- /**
- * API地址
- */
- private String baseUrl = "https://api.tavily.com/search";
- }
-
- @Data
- public static class FileConfig {
- /**
- * 文件保存目录
- */
- private String saveDir = "./tmp";
- }
-}
diff --git a/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/service/ToolService.java b/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/service/ToolService.java
index 3bf07a65..a12b1d20 100644
--- a/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/service/ToolService.java
+++ b/ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcpserve/service/ToolService.java
@@ -1,57 +1,21 @@
package org.ruoyi.mcpserve.service;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.HttpUtil;
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import net.sourceforge.plantuml.FileFormat;
-import net.sourceforge.plantuml.FileFormatOption;
-import net.sourceforge.plantuml.SourceStringReader;
-import okhttp3.*;
-import org.ruoyi.mcpserve.config.ToolsProperties;
-import org.springframework.ai.document.Document;
-import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
-import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
+import java.util.UUID;
+
/**
- * MCP工具服务类
- * 整合了文件操作、图片搜索、PlantUML生成、网页搜索、终端命令、文档解析等功能
- *
- * @author ageer,OpenX
+ * @author ageer
*/
@Service
public class ToolService {
- private final ToolsProperties toolsProperties;
- private final OkHttpClient httpClient;
- private final ObjectMapper objectMapper;
-
- public ToolService(ToolsProperties toolsProperties) {
- this.toolsProperties = toolsProperties;
- this.httpClient = new OkHttpClient.Builder()
- .connectTimeout(30, TimeUnit.SECONDS)
- .readTimeout(30, TimeUnit.SECONDS)
- .build();
- this.objectMapper = new ObjectMapper();
- }
-
- // ==================== 基础工具 ====================
-
@Tool(description = "获取一个指定前缀的随机数")
public String add(@ToolParam(description = "字符前缀") String prefix) {
// 定义日期格式
@@ -67,268 +31,4 @@ public class ToolService {
public LocalDateTime getCurrentTime() {
return LocalDateTime.now();
}
-
- // ==================== 文件操作工具 ====================
-
- @Tool(description = "Read content from a file")
- public String readFile(@ToolParam(description = "Name of the file to read") String fileName) {
- String fileDir = toolsProperties.getFile().getSaveDir() + "/file";
- String filePath = fileDir + "/" + fileName;
- try {
- return FileUtil.readUtf8String(filePath);
- } catch (Exception e) {
- return "Error reading file: " + e.getMessage();
- }
- }
-
- @Tool(description = "Write content to a file")
- public String writeFile(
- @ToolParam(description = "Name of the file to write") String fileName,
- @ToolParam(description = "Content to write to the file") String content) {
- String fileDir = toolsProperties.getFile().getSaveDir() + "/file";
- String filePath = fileDir + "/" + fileName;
- try {
- FileUtil.mkdir(fileDir);
- FileUtil.writeUtf8String(content, filePath);
- return "File written successfully to: " + filePath;
- } catch (Exception e) {
- return "Error writing to file: " + e.getMessage();
- }
- }
-
- // ==================== 图片搜索工具 ====================
-
- @Tool(description = "Search for images from Pexels")
- public String searchImage(@ToolParam(description = "Image search keywords") String query) {
- try {
- String apiKey = toolsProperties.getPexels().getApiKey();
- String apiUrl = toolsProperties.getPexels().getApiUrl();
-
- Map headers = new HashMap<>();
- headers.put("Authorization", apiKey);
-
- Map params = new HashMap<>();
- params.put("query", query);
-
- String response = HttpUtil.createGet(apiUrl)
- .addHeaders(headers)
- .form(params)
- .execute()
- .body();
-
- List images = JSONUtil.parseObj(response)
- .getJSONArray("photos")
- .stream()
- .map(photoObj -> (JSONObject) photoObj)
- .map(photoObj -> photoObj.getJSONObject("src"))
- .map(photo -> photo.getStr("medium"))
- .filter(StrUtil::isNotBlank)
- .collect(Collectors.toList());
-
- return String.join(",", images);
- } catch (Exception e) {
- return "Error search image: " + e.getMessage();
- }
- }
-
- // ==================== PlantUML工具 ====================
-
- @Tool(description = "Generate a PlantUML diagram and return SVG code")
- public String generatePlantUmlSvg(
- @ToolParam(description = "UML diagram source code") String umlCode) {
- try {
- if (umlCode == null || umlCode.trim().isEmpty()) {
- return "Error: UML代码不能为空";
- }
-
- System.setProperty("PLANTUML_LIMIT_SIZE", "32768");
- System.setProperty("java.awt.headless", "true");
-
- String normalizedUmlCode = normalizeUmlCode(umlCode);
-
- SourceStringReader reader = new SourceStringReader(normalizedUmlCode);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- reader.generateImage(outputStream, new FileFormatOption(FileFormat.SVG));
-
- byte[] svgBytes = outputStream.toByteArray();
- if (svgBytes.length == 0) {
- return "Error: 生成的SVG内容为空,请检查UML语法是否正确";
- }
-
- return new String(svgBytes, StandardCharsets.UTF_8);
- } catch (Exception e) {
- return "Error generating PlantUML: " + e.getMessage();
- }
- }
-
- private String normalizeUmlCode(String umlCode) {
- umlCode = umlCode.trim();
- if (umlCode.contains("@startuml")) {
- int startIndex = umlCode.indexOf("@startuml");
- int endIndex = umlCode.lastIndexOf("@enduml");
- if (endIndex > startIndex) {
- String startPart = umlCode.substring(startIndex);
- int firstNewLine = startPart.indexOf('\n');
- String content = firstNewLine > 0 ? startPart.substring(firstNewLine + 1) : "";
- if (content.contains("@enduml")) {
- content = content.substring(0, content.lastIndexOf("@enduml")).trim();
- }
- umlCode = content;
- }
- }
-
- StringBuilder normalizedCode = new StringBuilder();
- normalizedCode.append("@startuml\n");
- normalizedCode.append("!pragma layout smetana\n");
- normalizedCode.append("skinparam charset UTF-8\n");
- normalizedCode.append("skinparam defaultFontName SimHei\n");
- normalizedCode.append("skinparam defaultFontSize 12\n");
- normalizedCode.append("skinparam dpi 150\n");
- normalizedCode.append("\n");
- normalizedCode.append(umlCode);
- if (!umlCode.endsWith("\n")) {
- normalizedCode.append("\n");
- }
- normalizedCode.append("@enduml");
- return normalizedCode.toString();
- }
-
- // ==================== 网页搜索工具 ====================
-
- @Tool(description = "Search for information from web search engines")
- public String webSearch(
- @ToolParam(description = "Search query text") String query,
- @ToolParam(description = "Max results count") int maxResults) {
- List