From 84dbc2cfbfc0221008efecee3dab66625663fec0 Mon Sep 17 00:00:00 2001
From: evo <446796145@qq.com>
Date: Sun, 8 Mar 2026 22:41:24 +0800
Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=81=A2=E5=A4=8Dmcp=E6=A8=A1?=
=?UTF-8?q?=E5=9D=97=20=E5=8A=A8=E6=80=81agent?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 1 +
pom.xml | 7 -
ruoyi-admin/pom.xml | 5 -
.../ruoyi/config/MapperConflictResolver.java | 48 +++
ruoyi-modules/pom.xml | 1 -
.../ruoyi-chat/docs/frontend-guide.md | 244 +++++++++++++
ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md | 336 ++++++++++++++++++
ruoyi-modules/ruoyi-chat/pom.xml | 5 -
.../org/ruoyi/agent/ChartGenerationAgent.java | 2 +-
.../main/java/org/ruoyi/agent/McpAgent.java | 2 +-
.../main/java/org/ruoyi/agent/SqlAgent.java | 3 +-
.../ruoyi/agent/StreamingCreativeWriter.java | 18 -
.../java/org/ruoyi/agent/WebSearchAgent.java | 2 +-
.../agent/manager/TableSchemaManager.java | 11 +-
.../ruoyi/agent/tool/ExecuteSqlQueryTool.java | 27 +-
.../ruoyi/agent/tool/QueryAllTablesTool.java | 86 +++--
.../agent/tool/QueryTableSchemaTool.java | 28 +-
.../config/mcp}/SystemToolInitializer.java | 8 +-
.../controller/mcp}/McpMarketController.java | 15 +-
.../controller/mcp}/McpToolController.java | 12 +-
.../org/ruoyi/domain/bo/mcp}/McpMarketBo.java | 4 +-
.../org/ruoyi/domain/bo/mcp}/McpToolBo.java | 4 +-
.../domain/dto/mcp}/McpMarketListResult.java | 4 +-
.../dto/mcp}/McpMarketRefreshResult.java | 2 +-
.../dto/mcp}/McpMarketToolListResult.java | 4 +-
.../domain/dto/mcp}/McpToolListResult.java | 4 +-
.../domain/dto/mcp}/McpToolTestResult.java | 2 +-
.../ruoyi/domain/entity/mcp}/McpMarket.java | 2 +-
.../domain/entity/mcp}/McpMarketTool.java | 2 +-
.../org/ruoyi/domain/entity/mcp}/McpTool.java | 2 +-
.../org/ruoyi/domain/vo/mcp}/McpMarketVo.java | 4 +-
.../org/ruoyi/domain/vo/mcp}/McpToolVo.java | 8 +-
.../java/org/ruoyi}/enums/McpToolStatus.java | 2 +-
.../ruoyi/mapper/mcp}/McpMarketMapper.java | 6 +-
.../mapper/mcp}/McpMarketToolMapper.java | 4 +-
.../org/ruoyi/mapper/mcp}/McpToolMapper.java | 6 +-
.../service/core/BuiltinToolDefinition.java | 0
.../mcp/service/core/BuiltinToolProvider.java | 0
.../mcp/service/core/BuiltinToolRegistry.java | 174 +++++++++
.../LangChain4jMcpToolProviderService.java | 37 +-
.../mcp/service/core/ToolProviderFactory.java | 49 +++
.../org/ruoyi/mcp/tools/EditFileTool.java | 0
.../ruoyi/mcp/tools/ListDirectoryTool.java | 0
.../org/ruoyi/mcp/tools/ReadFileTool.java | 0
.../impl/AbstractStreamingChatService.java | 202 +++++------
.../impl/provider/QianWenChatServiceImpl.java | 75 ----
.../ruoyi/service/mcp}/IMcpMarketService.java | 12 +-
.../ruoyi/service/mcp}/IMcpToolService.java | 10 +-
.../mcp}/impl/McpMarketServiceImpl.java | 28 +-
.../service/mcp}/impl/McpToolServiceImpl.java | 18 +-
ruoyi-modules/ruoyi-mcp/pom.xml | 77 ----
.../org/ruoyi/mcp/config/McpProperties.java | 40 ---
.../mcp/service/core/BuiltinToolRegistry.java | 129 -------
.../mcp/service/core/ToolProviderFactory.java | 171 ---------
54 files changed, 1150 insertions(+), 793 deletions(-)
create mode 100644 ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java
create mode 100644 ruoyi-modules/ruoyi-chat/docs/frontend-guide.md
create mode 100644 ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md
delete mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/config => ruoyi-chat/src/main/java/org/ruoyi/config/mcp}/SystemToolInitializer.java (95%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller => ruoyi-chat/src/main/java/org/ruoyi/controller/mcp}/McpMarketController.java (92%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller => ruoyi-chat/src/main/java/org/ruoyi/controller/mcp}/McpToolController.java (93%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo => ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp}/McpMarketBo.java (93%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo => ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp}/McpToolBo.java (94%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto => ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp}/McpMarketListResult.java (90%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto => ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp}/McpMarketRefreshResult.java (94%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto => ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp}/McpMarketToolListResult.java (92%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto => ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp}/McpToolListResult.java (90%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto => ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp}/McpToolTestResult.java (96%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity => ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp}/McpMarket.java (96%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity => ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp}/McpMarketTool.java (96%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity => ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp}/McpTool.java (96%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo => ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp}/McpMarketVo.java (94%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo => ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp}/McpToolVo.java (88%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp => ruoyi-chat/src/main/java/org/ruoyi}/enums/McpToolStatus.java (96%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper => ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp}/McpMarketMapper.java (68%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper => ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp}/McpMarketToolMapper.java (76%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper => ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp}/McpToolMapper.java (68%)
rename ruoyi-modules/{ruoyi-mcp => ruoyi-chat}/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolDefinition.java (100%)
rename ruoyi-modules/{ruoyi-mcp => ruoyi-chat}/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolProvider.java (100%)
create mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolRegistry.java
rename ruoyi-modules/{ruoyi-mcp => ruoyi-chat}/src/main/java/org/ruoyi/mcp/service/core/LangChain4jMcpToolProviderService.java (90%)
create mode 100644 ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/ToolProviderFactory.java
rename ruoyi-modules/{ruoyi-mcp => ruoyi-chat}/src/main/java/org/ruoyi/mcp/tools/EditFileTool.java (100%)
rename ruoyi-modules/{ruoyi-mcp => ruoyi-chat}/src/main/java/org/ruoyi/mcp/tools/ListDirectoryTool.java (100%)
rename ruoyi-modules/{ruoyi-mcp => ruoyi-chat}/src/main/java/org/ruoyi/mcp/tools/ReadFileTool.java (100%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/service => ruoyi-chat/src/main/java/org/ruoyi/service/mcp}/IMcpMarketService.java (89%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/service => ruoyi-chat/src/main/java/org/ruoyi/service/mcp}/IMcpToolService.java (88%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/service => ruoyi-chat/src/main/java/org/ruoyi/service/mcp}/impl/McpMarketServiceImpl.java (94%)
rename ruoyi-modules/{ruoyi-mcp/src/main/java/org/ruoyi/mcp/service => ruoyi-chat/src/main/java/org/ruoyi/service/mcp}/impl/McpToolServiceImpl.java (95%)
delete mode 100644 ruoyi-modules/ruoyi-mcp/pom.xml
delete mode 100644 ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/config/McpProperties.java
delete mode 100644 ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolRegistry.java
delete mode 100644 ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/service/core/ToolProviderFactory.java
diff --git a/.gitignore b/.gitignore
index 03567532..d9cc6d06 100644
--- a/.gitignore
+++ b/.gitignore
@@ -47,3 +47,4 @@ nbdist/
!*/build/*.xml
.flattened-pom.xml
+/.claude/settings.local.json
diff --git a/pom.xml b/pom.xml
index dbd40c94..36bf6d39 100644
--- a/pom.xml
+++ b/pom.xml
@@ -397,13 +397,6 @@
${revision}
-
-
- org.ruoyi
- ruoyi-mcp
- ${revision}
-
-
com.github.binarywang
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 153e82da..49750f04 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -110,11 +110,6 @@
ruoyi-aiflow
-
-
- org.ruoyi
- ruoyi-mcp
-
de.codecentric
diff --git a/ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java b/ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java
new file mode 100644
index 00000000..467c96db
--- /dev/null
+++ b/ruoyi-admin/src/main/java/org/ruoyi/config/MapperConflictResolver.java
@@ -0,0 +1,48 @@
+package org.ruoyi.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * BeanDefinitionRegistry后置处理器
+ * 解决 MapStruct Plus 生成的 mapper 冲突问题
+ *
+ * @author ruoyi team
+ */
+@Configuration
+public class MapperConflictResolver implements BeanDefinitionRegistryPostProcessor {
+
+ private static final Logger log = LoggerFactory.getLogger(MapperConflictResolver.class);
+
+ @Override
+ public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
+ String[] beanNames = registry.getBeanDefinitionNames();
+
+ // 查找冲突的 mapper bean
+ for (String beanName : beanNames) {
+ if (beanName.equals("chatMessageBoToChatMessageMapperImpl")) {
+ BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
+ String beanClassName = beanDefinition.getBeanClassName();
+
+ log.info("Found mapper bean: {} -> {}", beanName, beanClassName);
+
+ // 如果是 org.ruoyi.domain.bo.chat 包下的(冲突的),移除它
+ if (beanClassName != null && beanClassName.startsWith("org.ruoyi.domain.bo.chat")) {
+ log.warn("Removing conflicting bean definition: {} ({})", beanName, beanClassName);
+ registry.removeBeanDefinition(beanName);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+ // 不需要实现
+ }
+}
diff --git a/ruoyi-modules/pom.xml b/ruoyi-modules/pom.xml
index 73fe7257..5db99df1 100644
--- a/ruoyi-modules/pom.xml
+++ b/ruoyi-modules/pom.xml
@@ -15,7 +15,6 @@
ruoyi-demo
ruoyi-generator
ruoyi-job
- ruoyi-mcp
ruoyi-system
ruoyi-wechat
ruoyi-workflow
diff --git a/ruoyi-modules/ruoyi-chat/docs/frontend-guide.md b/ruoyi-modules/ruoyi-chat/docs/frontend-guide.md
new file mode 100644
index 00000000..05cb5b9f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/docs/frontend-guide.md
@@ -0,0 +1,244 @@
+# MCP工具管理前端开发指南
+
+## 前置条件
+
+- Node.js >= 16.0
+- Vue 3
+- Element Plus
+- ECharts (用于图表展示)
+- Axios (用于HTTP请求)
+
+## 安装依赖
+
+```bash
+npm install element-plus echarts axios
+```
+
+## 项目结构
+
+```
+ruoyi-ui/
+├── src/
+│ ├── api/
+│ │ └── mcp/
+│ │ └── tool.js # API接口
+│ ├── views/
+│ │ └── mcp/
+│ │ ├── tool/
+│ │ │ └── index.vue # 工具管理页面
+│ │ ├── market/
+│ │ │ └── index.vue # 市场管理页面
+│ │ └── log/
+│ │ └── index.vue # 调用日志页面
+│ └── utils/
+│ └── request.js # Axios封装
+```
+
+## 菜单配置
+
+在系统菜单管理中添加以下菜单:
+
+### 1. MCP工具管理
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | MCP工具管理 |
+| 菜单类型 | 目录 |
+| 显示顺序 | 1 |
+| 路由地址 | mcp |
+| 组件路径 | |
+
+#### 子菜单:工具列表
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | 工具列表 |
+| 菜单类型 | 菜单 |
+| 显示顺序 | 1 |
+| 路由地址 | tool |
+| 组件路径 | mcp/tool/index |
+| 权限标识 | mcp:tool:list |
+
+#### 子菜单:市场管理
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | 市场管理 |
+| 菜单类型 | 菜单 |
+| 显示顺序 | 2 |
+| 路由地址 | market |
+| 组件路径 | mcp/market/index |
+| 权限标识 | mcp:market:list |
+
+#### 子菜单:调用日志
+
+| 字段 | 值 |
+|------|-----|
+| 菜单名称 | 调用日志 |
+| 菜单类型 | 菜单 |
+| 显示顺序 | 3 |
+| 路由地址 | log |
+| 组件路径 | mcp/log/index |
+| 权限标识 | mcp:tool:query |
+
+## 权限配置
+
+| 权限标识 | 权限名称 | 说明 |
+|----------|----------|------|
+| mcp:tool:list | 工具列表 | 查看工具列表 |
+| mcp:tool:query | 工具查询 | 查看工具详情 |
+| mcp:tool:add | 工具新增 | 新增工具 |
+| mcp:tool:edit | 工具修改 | 修改工具 |
+| mcp:tool:remove | 工具删除 | 删除工具 |
+| mcp:tool:export | 工具导出 | 导出工具数据 |
+| mcp:market:list | 市场列表 | 查看市场列表 |
+| mcp:market:query | 市场查询 | 查看市场详情 |
+| mcp:market:add | 市场新增 | 新增市场 |
+| mcp:market:edit | 市场修改 | 修改市场 |
+| mcp:market:remove | 市场删除 | 删除市场 |
+
+## 路由配置
+
+在路由配置文件中添加:
+
+```javascript
+{
+ path: '/mcp',
+ component: Layout,
+ redirect: '/mcp/tool',
+ name: 'Mcp',
+ meta: { title: 'MCP工具管理', icon: 'tools' },
+ children: [
+ {
+ path: 'tool',
+ name: 'McpTool',
+ component: () => import('@/views/mcp/tool/index'),
+ meta: { title: '工具列表', icon: 'tool' }
+ },
+ {
+ path: 'market',
+ name: 'McpMarket',
+ component: () => import('@/views/mcp/market/index'),
+ meta: { title: '市场管理', icon: 'shop' }
+ },
+ {
+ path: 'log',
+ name: 'McpLog',
+ component: () => import('@/views/mcp/log/index'),
+ meta: { title: '调用日志', icon: 'document' }
+ }
+ ]
+}
+```
+
+## API请求配置
+
+确保Axios请求拦截器正确配置:
+
+```javascript
+// src/utils/request.js
+import axios from 'axios'
+import { ElMessage } from 'element-plus'
+
+const service = axios.create({
+ baseURL: process.env.VUE_APP_BASE_API,
+ timeout: 30000
+})
+
+// 请求拦截器
+service.interceptors.request.use(
+ config => {
+ // 添加token
+ const token = localStorage.getItem('Admin-Token')
+ if (token) {
+ config.headers['Authorization'] = 'Bearer ' + token
+ }
+ return config
+ },
+ error => {
+ return Promise.reject(error)
+ }
+)
+
+// 响应拦截器
+service.interceptors.response.use(
+ response => {
+ const res = response.data
+ if (res.code !== 200) {
+ ElMessage.error(res.msg || '请求失败')
+ return Promise.reject(new Error(res.msg || '请求失败'))
+ }
+ return res
+ },
+ error => {
+ ElMessage.error(error.message)
+ return Promise.reject(error)
+ }
+)
+
+export default service
+```
+
+## 开发步骤
+
+1. **复制代码文件**
+ - 将 `tool.js` 复制到 `src/api/mcp/` 目录
+ - 将 `*.vue` 文件复制到对应的视图目录
+
+2. **安装依赖**
+ ```bash
+ npm install element-plus echarts
+ ```
+
+3. **配置路由**
+ - 在路由配置中添加MCP相关路由
+
+4. **配置菜单**
+ - 在系统管理中添加菜单
+
+5. **配置权限**
+ - 在系统管理中添加权限标识
+
+6. **测试功能**
+ - 启动开发服务器
+ - 测试各项功能
+
+## 注意事项
+
+1. **工具类型说明**
+ - BUILTIN: 内置工具(系统自带,不可编辑)
+ - LOCAL: 本地STDIO工具(通过命令行启动)
+ - REMOTE: 远程HTTP工具(通过网络连接)
+
+2. **配置JSON格式**
+ - LOCAL类型: `{"command": "npx", "args": ["-y", "@example/tool"], "env": {}}`
+ - REMOTE类型: `{"baseUrl": "http://localhost:8080/mcp"}`
+
+3. **错误处理**
+ - 工具连接测试可能超时,请合理设置超时时间
+ - 删除工具前请确认没有正在运行的Agent使用该工具
+
+4. **性能优化**
+ - 调用日志数据量大时,建议使用分页加载
+ - 图表数据建议缓存处理,避免频繁请求
+
+## 常见问题
+
+### 1. 跨域问题
+在 `vue.config.js` 中配置代理:
+```javascript
+devServer: {
+ proxy: {
+ '/api': {
+ target: 'http://localhost:8080',
+ changeOrigin: true
+ }
+ }
+}
+```
+
+### 2. 图表不显示
+确保ECharts容器有固定高度,并在数据加载后初始化图表。
+
+### 3. 权限不生效
+检查菜单权限配置和后端接口权限注解是否一致。
diff --git a/ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md b/ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md
new file mode 100644
index 00000000..9d8460b7
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/docs/mcp-api-spec.md
@@ -0,0 +1,336 @@
+# MCP工具管理模块 - API接口文档
+
+## 概述
+
+本文档描述了MCP工具管理模块的REST API接口,供前端开发人员参考。
+
+## 基础信息
+
+- **Base URL**: `/api/mcp`
+- **认证方式**: Bearer Token (SaToken)
+- **响应格式**: JSON
+
+---
+
+## 1. MCP工具管理
+
+### 1.1 查询工具列表(分页)
+
+**接口**: `GET /tool/list`
+
+**权限**: `mcp:tool:list`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| name | String | 否 | 工具名称(模糊查询) |
+| description | String | 否 | 工具描述(模糊查询) |
+| type | String | 否 | 工具类型:LOCAL/REMOTE/BUILTIN |
+| status | String | 否 | 状态:0-启用, 1-禁用 |
+| pageNum | Integer | 是 | 页码,默认1 |
+| pageSize | Integer | 是 | 每页数量,默认10 |
+
+**响应示例**:
+```json
+{
+ "rows": [
+ {
+ "id": 1,
+ "name": "ReadFileTool",
+ "description": "读取文件内容工具",
+ "type": "BUILTIN",
+ "status": "0",
+ "configJson": null,
+ "createTime": "2026-03-08 10:00:00",
+ "updateTime": "2026-03-08 10:00:00"
+ }
+ ],
+ "total": 1
+}
+```
+
+### 1.2 查询工具列表(不分页)
+
+**接口**: `GET /tool/all`
+
+**权限**: `mcp:tool:list`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| keyword | String | 否 | 关键词 |
+| type | String | 否 | 工具类型 |
+| status | String | 否 | 状态 |
+
+**响应示例**:
+```json
+{
+ "tools": [
+ {
+ "id": 1,
+ "name": "ReadFileTool",
+ "description": "读取文件内容工具",
+ "type": "BUILTIN",
+ "status": "0"
+ }
+ ],
+ "total": 1
+}
+```
+
+### 1.3 获取工具详情
+
+**接口**: `GET /tool/{id}`
+
+**权限**: `mcp:tool:query`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| id | Long | 是 | 工具ID |
+
+### 1.4 新增工具
+
+**接口**: `POST /tool`
+
+**权限**: `mcp:tool:add`
+
+**请求体**:
+```json
+{
+ "name": "MyMcpTool",
+ "description": "我的MCP工具",
+ "type": "REMOTE",
+ "status": "0",
+ "configJson": "{\"baseUrl\": \"http://localhost:8080/mcp\"}"
+}
+```
+
+### 1.5 修改工具
+
+**接口**: `PUT /tool`
+
+**权限**: `mcp:tool:edit`
+
+**请求体**: 同新增工具
+
+### 1.6 删除工具
+
+**接口**: `DELETE /tool/{ids}`
+
+**权限**: `mcp:tool:remove`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| ids | String | 是 | 工具ID,多个用逗号分隔 |
+
+### 1.7 更新工具状态
+
+**接口**: `PUT /tool/{id}/status`
+
+**权限**: `mcp:tool:edit`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| id | Long | 是 | 工具ID |
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| status | String | 是 | 状态:0-启用, 1-禁用 |
+
+### 1.8 测试工具连接
+
+**接口**: `POST /tool/{id}/test`
+
+**权限**: `mcp:tool:query`
+
+**响应示例**:
+```json
+{
+ "success": true,
+ "message": "连接测试成功",
+ "toolCount": 5,
+ "tools": ["tool1", "tool2", "tool3", "tool4", "tool5"]
+}
+```
+
+---
+
+## 2. MCP市场管理
+
+### 2.1 查询市场列表
+
+**接口**: `GET /market/list`
+
+**权限**: `mcp:market:list`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| name | String | 否 | 市场名称 |
+| description | String | 否 | 市场描述 |
+| status | String | 否 | 状态 |
+| pageNum | Integer | 是 | 页码 |
+| pageSize | Integer | 是 | 每页数量 |
+
+### 2.2 获取市场工具列表
+
+**接口**: `GET /market/{marketId}/tools`
+
+**权限**: `mcp:market:query`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| marketId | Long | 是 | 市场ID |
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| page | Integer | 否 | 页码,默认1 |
+| size | Integer | 否 | 每页数量,默认10 |
+
+### 2.3 刷新市场工具
+
+**接口**: `POST /market/{marketId}/refresh`
+
+**权限**: `mcp:market:edit`
+
+**响应示例**:
+```json
+{
+ "success": true,
+ "message": "刷新成功",
+ "addedCount": 3,
+ "updatedCount": 5
+}
+```
+
+### 2.4 加载工具到本地
+
+**接口**: `POST /market/tool/{toolId}/load`
+
+**权限**: `mcp:market:edit`
+
+**路径参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| toolId | Long | 是 | 市场工具ID |
+
+### 2.5 批量加载工具
+
+**接口**: `POST /market/tools/batchLoad`
+
+**权限**: `mcp:market:edit`
+
+**请求体**:
+```json
+{
+ "toolIds": [1, 2, 3]
+}
+```
+
+---
+
+## 3. 工具调用日志
+
+### 3.1 查询调用日志
+
+**接口**: `GET /tool/callLog`
+
+**权限**: `mcp:tool:query`
+
+**请求参数**:
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| toolId | Long | 否 | 工具ID |
+| sessionId | Long | 否 | 会话ID |
+| startDate | Date | 否 | 开始日期 |
+| endDate | Date | 否 | 结束日期 |
+| pageNum | Integer | 是 | 页码 |
+| pageSize | Integer | 是 | 每页数量 |
+
+### 3.2 获取工具统计
+
+**接口**: `GET /tool/{toolId}/metrics`
+
+**权限**: `mcp:tool:query`
+
+**响应示例**:
+```json
+{
+ "toolId": 1,
+ "toolName": "ReadFileTool",
+ "today": {
+ "callCount": 100,
+ "successCount": 95,
+ "failureCount": 5,
+ "avgDurationMs": 150,
+ "successRate": 95.0
+ },
+ "week": {
+ "callCount": 500,
+ "successCount": 475,
+ "failureCount": 25,
+ "avgDurationMs": 160,
+ "successRate": 95.0
+ }
+}
+```
+
+---
+
+## 4. 状态码说明
+
+| 状态码 | 说明 |
+|--------|------|
+| 200 | 请求成功 |
+| 401 | 未认证 |
+| 403 | 无权限 |
+| 404 | 资源不存在 |
+| 500 | 服务器错误 |
+
+---
+
+## 5. 前端页面需求
+
+### 5.1 MCP工具管理页面 (`/mcp/tool`)
+
+**功能**:
+- 工具列表展示(分页)
+- 工具搜索和筛选
+- 新增/编辑/删除工具
+- 工具状态切换
+- 工具连接测试
+
+**表格列**:
+- 工具名称
+- 工具描述
+- 工具类型(标签显示)
+- 状态(开关)
+- 创建时间
+- 操作(编辑、删除、测试)
+
+### 5.2 MCP市场管理页面 (`/mcp/market`)
+
+**功能**:
+- 市场列表展示
+- 市场工具浏览
+- 刷新市场工具
+- 加载工具到本地
+
+### 5.3 工具调用日志页面 (`/mcp/log`)
+
+**功能**:
+- 调用日志列表
+- 按工具/日期筛选
+- 成功率统计
+- 响应时间统计
+
+**图表**:
+- 每日调用次数趋势图
+- 工具调用成功率饼图
+- 平均响应时间柱状图
diff --git a/ruoyi-modules/ruoyi-chat/pom.xml b/ruoyi-modules/ruoyi-chat/pom.xml
index e88a1d87..f0a95fe5 100644
--- a/ruoyi-modules/ruoyi-chat/pom.xml
+++ b/ruoyi-modules/ruoyi-chat/pom.xml
@@ -19,11 +19,6 @@
ruoyi-common-chat
-
- org.ruoyi
- ruoyi-mcp
-
-
org.ruoyi
ruoyi-common-sensitive
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java
index 2de1fcea..ab61ee62 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/ChartGenerationAgent.java
@@ -6,7 +6,7 @@ import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
-public interface ChartGenerationAgent {
+public interface ChartGenerationAgent extends Agent {
@SystemMessage("""
You are a chart generation specialist. Your only task is to generate Apache ECharts
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java
index fda33dce..7bef6b4a 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/McpAgent.java
@@ -5,7 +5,7 @@ import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
-public interface McpAgent {
+public interface McpAgent extends Agent {
/**
* 系统提示词:通用工具调用智能体
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java
index 99e1ff05..77b8e1ab 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/SqlAgent.java
@@ -2,7 +2,6 @@ package org.ruoyi.agent;
import dev.langchain4j.agentic.Agent;
import dev.langchain4j.service.SystemMessage;
-import dev.langchain4j.service.TokenStream;
import dev.langchain4j.service.UserMessage;
import dev.langchain4j.service.V;
@@ -12,7 +11,7 @@ import dev.langchain4j.service.V;
* and returning relevant data and analysis results.
*
*/
-public interface SqlAgent {
+public interface SqlAgent extends Agent {
@SystemMessage("""
This agent is designed for MySQL 5.7
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java
deleted file mode 100644
index 9486b853..00000000
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/StreamingCreativeWriter.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.agent;
-
-import dev.langchain4j.agentic.Agent;
-import dev.langchain4j.service.TokenStream;
-import dev.langchain4j.service.UserMessage;
-import dev.langchain4j.service.V;
-
-public interface StreamingCreativeWriter {
- @UserMessage("""
- You are a creative writer.
- Generate a draft of a story no more than
- 3 sentences long around the given topic.
- Return only the story and nothing else.
- The topic is {{topic}}.
- """)
- @Agent("Generates a story based on the given topic")
- TokenStream generateStory(@V("topic") String topic);
-}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java
index 33f8737e..970e3a2b 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/WebSearchAgent.java
@@ -10,7 +10,7 @@ import dev.langchain4j.service.V;
* A web search assistant that answers natural language questions by searching the internet
* and returning relevant information from web pages.
*/
-public interface WebSearchAgent {
+public interface WebSearchAgent extends Agent {
@SystemMessage("""
You are a web search assistant. Answer questions by searching and retrieving web content.
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java
index a02eb78d..7366acc8 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/manager/TableSchemaManager.java
@@ -40,7 +40,7 @@ import lombok.extern.slf4j.Slf4j;
@Component
@DS("agent")
public class TableSchemaManager {
-
+
@Autowired(required = false)
private DataSource agentDataSource;
@@ -77,7 +77,7 @@ public class TableSchemaManager {
loadAllowedTableSchemas();
initialized = true;
log.info("Schema cache initialized with {} tables", schemaCache.size());
-
+
} catch (Exception e) {
log.error("Failed to initialize schema cache", e);
}
@@ -87,7 +87,7 @@ public class TableSchemaManager {
/**
* 加载所有允许的表的结构信息
*/
- private void loadAllowedTableSchemas() throws SQLException {
+ private void loadAllowedTableSchemas() {
List allowedTables = getAllowedTableNames();
for (String tableName : allowedTables) {
try {
@@ -191,10 +191,7 @@ public class TableSchemaManager {
}
List allowedTables = getAllowedTableNames();
- return allowedTables.stream()
- .map(schemaCache::get)
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
+ return allowedTables.stream().map(schemaCache::get).filter(Objects::nonNull).collect(Collectors.toList());
}
/**
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java
index 2cc33a67..7fb56ad6 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/ExecuteSqlQueryTool.java
@@ -11,13 +11,14 @@ import java.util.Map;
import javax.sql.DataSource;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.ruoyi.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.mcp.service.core.BuiltinToolProvider;
/**
* 执行 SQL 查询的 Tool
@@ -25,10 +26,12 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
@Component
-public class ExecuteSqlQueryTool {
+public class ExecuteSqlQueryTool implements BuiltinToolProvider {
- @Autowired(required = false)
- private DataSource dataSource;
+ // 使用延迟初始化,避免在构造函数中调用 SpringUtils.getBean()
+ private DataSource getDataSource() {
+ return SpringUtils.getBean(DataSource.class);
+ }
/**
* 执行 SELECT SQL 查询
@@ -52,6 +55,7 @@ public class ExecuteSqlQueryTool {
}
try {
+ DataSource dataSource = getDataSource();
if (dataSource == null) {
return "Error: Database datasource not configured";
}
@@ -177,4 +181,19 @@ public class ExecuteSqlQueryTool {
}
return str;
}
+
+ @Override
+ public String getToolName() {
+ return "execute_sql_query";
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "执行SQL查询";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Execute a SELECT SQL query and return the results. Example: SELECT * FROM sys_user";
+ }
}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java
index d9ed0666..9fd6637c 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryAllTablesTool.java
@@ -4,11 +4,12 @@ import java.util.List;
import org.ruoyi.agent.domain.TableStructure;
import org.ruoyi.agent.manager.TableSchemaManager;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.ruoyi.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.mcp.service.core.BuiltinToolProvider;
/**
* 查询数据库所有表的 Tool
@@ -16,11 +17,13 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
@Component
-public class QueryAllTablesTool {
+public class QueryAllTablesTool implements BuiltinToolProvider {
+
+ // 使用延迟初始化,避免在构造函数中调用 SpringUtils.getBean()
+ private TableSchemaManager getTableSchemaManager() {
+ return SpringUtils.getBean(TableSchemaManager.class);
+ }
-
- @Autowired
- private TableSchemaManager tableSchemaManager; // 注入管理器
/**
* 查询数据库中所有表
* 返回数据库中存在的所有表的列表
@@ -30,36 +33,49 @@ public class QueryAllTablesTool {
@Tool("Query all tables in the database and return table names and basic information")
public String queryAllTables() {
try {
- // 1. 从管理器获取所有允许的表结构信息(内部已包含初始化/缓存逻辑)
- List tableSchemas = tableSchemaManager.getAllowedTableSchemas();
-
- if (tableSchemas == null || tableSchemas.isEmpty()) {
- return "No tables found in database or cache is empty.";
- }
-
- // 2. 格式化结果
- StringBuilder result = new StringBuilder();
- result.append("Found ").append(tableSchemas.size()).append(" tables in cache:\n");
-
- for (TableStructure schema : tableSchemas) {
- String tableName = schema.getTableName();
- String tableType = schema.getTableType() != null ? schema.getTableType() : "TABLE";
- String tableComment = schema.getTableComment();
-
- result.append(String.format("- %s (%s) - %s\n",
- tableName,
- tableType,
- tableComment != null ? tableComment : "No comment"));
- }
-
- log.info("Successfully retrieved {} tables from schema cache", tableSchemas.size());
- return result.toString();
-
- } catch (Exception e) {
- log.error("Error retrieving tables from cache", e);
- return "Error: " + e.getMessage();
+ // 1. 从管理器获取所有允许的表结构信息(内部已包含初始化/缓存逻辑)
+ List tableSchemas = getTableSchemaManager().getAllowedTableSchemas();
+
+ if (tableSchemas == null || tableSchemas.isEmpty()) {
+ return "No tables found in database or cache is empty.";
}
-
-
+
+ // 2. 格式化结果
+ StringBuilder result = new StringBuilder();
+ result.append("Found ").append(tableSchemas.size()).append(" tables in cache:\n");
+
+ for (TableStructure schema : tableSchemas) {
+ String tableName = schema.getTableName();
+ String tableType = schema.getTableType() != null ? schema.getTableType() : "TABLE";
+ String tableComment = schema.getTableComment();
+
+ result.append(String.format("- %s (%s) - %s\n",
+ tableName,
+ tableType,
+ tableComment != null ? tableComment : "No comment"));
+ }
+
+ log.info("Successfully retrieved {} tables from schema cache", tableSchemas.size());
+ return result.toString();
+
+ } catch (Exception e) {
+ log.error("Error retrieving tables from cache", e);
+ return "Error: " + e.getMessage();
+ }
+ }
+
+ @Override
+ public String getToolName() {
+ return "query_all_tables";
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "查询所有表";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Query all tables in the database and return table names and basic information";
}
}
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java
index 33d06b27..73a62670 100644
--- a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/agent/tool/QueryTableSchemaTool.java
@@ -6,20 +6,23 @@ import java.sql.ResultSet;
import javax.sql.DataSource;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.ruoyi.common.core.utils.SpringUtils;
import org.springframework.stereotype.Component;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import dev.langchain4j.agent.tool.Tool;
import lombok.extern.slf4j.Slf4j;
+import org.ruoyi.mcp.service.core.BuiltinToolProvider;
@Component
@Slf4j
-public class QueryTableSchemaTool {
+public class QueryTableSchemaTool implements BuiltinToolProvider {
- @Autowired(required = false)
- private DataSource dataSource;
+ // 使用延迟初始化,避免在构造函数中调用 SpringUtils.getBean()
+ private DataSource getDataSource() {
+ return SpringUtils.getBean(DataSource.class);
+ }
@Tool("Query the CREATE TABLE statement (DDL) for a specific table by table name")
public String queryTableSchema(String tableName) {
@@ -35,7 +38,7 @@ public class QueryTableSchemaTool {
String sql = "SHOW CREATE TABLE `" + tableName + "`";
- try (Connection connection = dataSource.getConnection();
+ try (Connection connection = getDataSource().getConnection();
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
@@ -54,4 +57,19 @@ public class QueryTableSchemaTool {
DynamicDataSourceContextHolder.clear();
}
}
+
+ @Override
+ public String getToolName() {
+ return "query_table_schema";
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "查询表结构";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Query the CREATE TABLE statement (DDL) for a specific table by table name";
+ }
}
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/config/SystemToolInitializer.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/config/mcp/SystemToolInitializer.java
similarity index 95%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/config/SystemToolInitializer.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/config/mcp/SystemToolInitializer.java
index 30647c65..8426db52 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/config/SystemToolInitializer.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/config/mcp/SystemToolInitializer.java
@@ -1,11 +1,11 @@
-package org.ruoyi.mcp.config;
+package org.ruoyi.config.mcp;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.mcp.domain.entity.McpTool;
-import org.ruoyi.mcp.enums.McpToolStatus;
-import org.ruoyi.mcp.mapper.McpToolMapper;
+import org.ruoyi.domain.entity.mcp.McpTool;
+import org.ruoyi.enums.McpToolStatus;
+import org.ruoyi.mapper.mcp.McpToolMapper;
import org.ruoyi.mcp.service.core.BuiltinToolDefinition;
import org.ruoyi.mcp.service.core.BuiltinToolRegistry;
import org.springframework.boot.ApplicationArguments;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller/McpMarketController.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpMarketController.java
similarity index 92%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller/McpMarketController.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpMarketController.java
index 52a0eacc..3f840425 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller/McpMarketController.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpMarketController.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.controller;
+package org.ruoyi.controller.mcp;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
@@ -11,11 +11,12 @@ import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
-import org.ruoyi.mcp.domain.bo.McpMarketBo;
-import org.ruoyi.mcp.domain.dto.McpMarketListResult;
-import org.ruoyi.mcp.domain.dto.McpMarketToolListResult;
-import org.ruoyi.mcp.domain.vo.McpMarketVo;
-import org.ruoyi.mcp.service.IMcpMarketService;
+import org.ruoyi.domain.bo.mcp.McpMarketBo;
+import org.ruoyi.domain.dto.mcp.McpMarketListResult;
+import org.ruoyi.domain.dto.mcp.McpMarketRefreshResult;
+import org.ruoyi.domain.dto.mcp.McpMarketToolListResult;
+import org.ruoyi.domain.vo.mcp.McpMarketVo;
+import org.ruoyi.service.mcp.IMcpMarketService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -143,7 +144,7 @@ public class McpMarketController extends BaseController {
@SaCheckPermission("mcp:market:edit")
@Log(title = "MCP市场管理", businessType = BusinessType.UPDATE)
@PostMapping("/{marketId}/refresh")
- public R refreshMarketTools(@PathVariable Long marketId) {
+ public R refreshMarketTools(@PathVariable Long marketId) {
return R.ok(mcpMarketService.refreshMarketTools(marketId));
}
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller/McpToolController.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpToolController.java
similarity index 93%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller/McpToolController.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpToolController.java
index eae82f72..96d51298 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/controller/McpToolController.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/controller/mcp/McpToolController.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.controller;
+package org.ruoyi.controller.mcp;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
@@ -11,11 +11,11 @@ import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
-import org.ruoyi.mcp.domain.bo.McpToolBo;
-import org.ruoyi.mcp.domain.dto.McpToolListResult;
-import org.ruoyi.mcp.domain.dto.McpToolTestResult;
-import org.ruoyi.mcp.domain.vo.McpToolVo;
-import org.ruoyi.mcp.service.IMcpToolService;
+import org.ruoyi.domain.bo.mcp.McpToolBo;
+import org.ruoyi.domain.dto.mcp.McpToolListResult;
+import org.ruoyi.domain.dto.mcp.McpToolTestResult;
+import org.ruoyi.domain.vo.mcp.McpToolVo;
+import org.ruoyi.service.mcp.IMcpToolService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo/McpMarketBo.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp/McpMarketBo.java
similarity index 93%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo/McpMarketBo.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp/McpMarketBo.java
index 00493b8d..e0306c0d 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo/McpMarketBo.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp/McpMarketBo.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.bo;
+package org.ruoyi.domain.bo.mcp;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
@@ -6,7 +6,7 @@ import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
-import org.ruoyi.mcp.domain.entity.McpMarket;
+import org.ruoyi.domain.entity.mcp.McpMarket;
/**
* MCP 市场业务对象
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo/McpToolBo.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp/McpToolBo.java
similarity index 94%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo/McpToolBo.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp/McpToolBo.java
index 7bb2005a..74d699e6 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/bo/McpToolBo.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/mcp/McpToolBo.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.bo;
+package org.ruoyi.domain.bo.mcp;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
@@ -6,7 +6,7 @@ import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
-import org.ruoyi.mcp.domain.entity.McpTool;
+import org.ruoyi.domain.entity.mcp.McpTool;
import java.io.Serial;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketListResult.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketListResult.java
similarity index 90%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketListResult.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketListResult.java
index 69f0a5d9..eba96d0a 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketListResult.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketListResult.java
@@ -1,10 +1,10 @@
-package org.ruoyi.mcp.domain.dto;
+package org.ruoyi.domain.dto.mcp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import org.ruoyi.mcp.domain.entity.McpMarket;
+import org.ruoyi.domain.entity.mcp.McpMarket;
import java.util.List;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketRefreshResult.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketRefreshResult.java
similarity index 94%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketRefreshResult.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketRefreshResult.java
index d52e91c7..e9c1002d 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketRefreshResult.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketRefreshResult.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.dto;
+package org.ruoyi.domain.dto.mcp;
import lombok.AllArgsConstructor;
import lombok.Builder;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketToolListResult.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketToolListResult.java
similarity index 92%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketToolListResult.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketToolListResult.java
index 8f2e6a81..a66cfd9a 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpMarketToolListResult.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpMarketToolListResult.java
@@ -1,10 +1,10 @@
-package org.ruoyi.mcp.domain.dto;
+package org.ruoyi.domain.dto.mcp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import org.ruoyi.mcp.domain.entity.McpMarketTool;
+import org.ruoyi.domain.entity.mcp.McpMarketTool;
import java.util.List;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpToolListResult.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpToolListResult.java
similarity index 90%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpToolListResult.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpToolListResult.java
index e330abc2..385edcae 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpToolListResult.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpToolListResult.java
@@ -1,10 +1,10 @@
-package org.ruoyi.mcp.domain.dto;
+package org.ruoyi.domain.dto.mcp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import org.ruoyi.mcp.domain.entity.McpTool;
+import org.ruoyi.domain.entity.mcp.McpTool;
import java.util.List;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpToolTestResult.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpToolTestResult.java
similarity index 96%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpToolTestResult.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpToolTestResult.java
index eeb6f3dd..71b873da 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/dto/McpToolTestResult.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/dto/mcp/McpToolTestResult.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.dto;
+package org.ruoyi.domain.dto.mcp;
import lombok.AllArgsConstructor;
import lombok.Builder;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpMarket.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpMarket.java
similarity index 96%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpMarket.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpMarket.java
index 8d2cf21e..1f805fe2 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpMarket.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpMarket.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.entity;
+package org.ruoyi.domain.entity.mcp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpMarketTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpMarketTool.java
similarity index 96%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpMarketTool.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpMarketTool.java
index 69b942ab..ac7e9c02 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpMarketTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpMarketTool.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.entity;
+package org.ruoyi.domain.entity.mcp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpTool.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpTool.java
similarity index 96%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpTool.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpTool.java
index 0a5b3088..8ce47880 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/entity/McpTool.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/mcp/McpTool.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.domain.entity;
+package org.ruoyi.domain.entity.mcp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo/McpMarketVo.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp/McpMarketVo.java
similarity index 94%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo/McpMarketVo.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp/McpMarketVo.java
index 243604cf..0abbea71 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo/McpMarketVo.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp/McpMarketVo.java
@@ -1,10 +1,10 @@
-package org.ruoyi.mcp.domain.vo;
+package org.ruoyi.domain.vo.mcp;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
-import org.ruoyi.mcp.domain.entity.McpMarket;
+import org.ruoyi.domain.entity.mcp.McpMarket;
import java.io.Serial;
import java.io.Serializable;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo/McpToolVo.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp/McpToolVo.java
similarity index 88%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo/McpToolVo.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp/McpToolVo.java
index 88cd2494..a5fbd748 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/domain/vo/McpToolVo.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/mcp/McpToolVo.java
@@ -1,12 +1,11 @@
-package org.ruoyi.mcp.domain.vo;
+package org.ruoyi.domain.vo.mcp;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
-import org.ruoyi.mcp.domain.entity.McpTool;
+import org.ruoyi.domain.entity.mcp.McpTool;
-import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
@@ -20,9 +19,6 @@ import java.util.Date;
@AutoMapper(target = McpTool.class)
public class McpToolVo implements Serializable {
- @Serial
- private static final long serialVersionUID = 1L;
-
/**
* 工具ID
*/
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/enums/McpToolStatus.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/enums/McpToolStatus.java
similarity index 96%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/enums/McpToolStatus.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/enums/McpToolStatus.java
index caf8c49b..7facd02a 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/enums/McpToolStatus.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/enums/McpToolStatus.java
@@ -1,4 +1,4 @@
-package org.ruoyi.mcp.enums;
+package org.ruoyi.enums;
import lombok.Getter;
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpMarketMapper.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpMarketMapper.java
similarity index 68%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpMarketMapper.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpMarketMapper.java
index 7d9ed31d..6864f2c4 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpMarketMapper.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpMarketMapper.java
@@ -1,9 +1,9 @@
-package org.ruoyi.mcp.mapper;
+package org.ruoyi.mapper.mcp;
import org.apache.ibatis.annotations.Mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import org.ruoyi.mcp.domain.entity.McpMarket;
-import org.ruoyi.mcp.domain.vo.McpMarketVo;
+import org.ruoyi.domain.entity.mcp.McpMarket;
+import org.ruoyi.domain.vo.mcp.McpMarketVo;
/**
* MCP 市场信息 Mapper
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpMarketToolMapper.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpMarketToolMapper.java
similarity index 76%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpMarketToolMapper.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpMarketToolMapper.java
index 2211906d..4580f33c 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpMarketToolMapper.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpMarketToolMapper.java
@@ -1,8 +1,8 @@
-package org.ruoyi.mcp.mapper;
+package org.ruoyi.mapper.mcp;
import org.apache.ibatis.annotations.Mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import org.ruoyi.mcp.domain.entity.McpMarketTool;
+import org.ruoyi.domain.entity.mcp.McpMarketTool;
/**
* MCP 市场工具关联 Mapper
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpToolMapper.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpToolMapper.java
similarity index 68%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpToolMapper.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpToolMapper.java
index 5e46f399..a3ce4d33 100644
--- a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/mapper/McpToolMapper.java
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mapper/mcp/McpToolMapper.java
@@ -1,9 +1,9 @@
-package org.ruoyi.mcp.mapper;
+package org.ruoyi.mapper.mcp;
import org.apache.ibatis.annotations.Mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
-import org.ruoyi.mcp.domain.entity.McpTool;
-import org.ruoyi.mcp.domain.vo.McpToolVo;
+import org.ruoyi.domain.entity.mcp.McpTool;
+import org.ruoyi.domain.vo.mcp.McpToolVo;
/**
* MCP 工具信息 Mapper
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolDefinition.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolDefinition.java
similarity index 100%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolDefinition.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolDefinition.java
diff --git a/ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolProvider.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolProvider.java
similarity index 100%
rename from ruoyi-modules/ruoyi-mcp/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolProvider.java
rename to ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolProvider.java
diff --git a/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolRegistry.java b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolRegistry.java
new file mode 100644
index 00000000..48e1034f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/mcp/service/core/BuiltinToolRegistry.java
@@ -0,0 +1,174 @@
+package org.ruoyi.mcp.service.core;
+
+import jakarta.annotation.PostConstruct;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 内置工具注册表
+ * 自动发现并注册所有实现 {@link BuiltinToolProvider} 接口的工具
+ *
+ * 工具注册流程:
+ *
+ * - Spring 自动注入所有 {@link BuiltinToolProvider} 实现
+ * - {@link #init()} 方法在 Bean 初始化后自动调用
+ * - 将所有工具注册到内部 Map
+ *
+ *
+ * 添加新工具只需:
+ *
+ * - 创建一个类实现 {@link BuiltinToolProvider} 接口
+ * - 添加 {@code @Component} 注解
+ * - 工具会自动被发现和注册
+ *
+ *
+ * @author ruoyi team
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class BuiltinToolRegistry {
+
+ /**
+ * 工具类型常量
+ */
+ public static final String TYPE_BUILTIN = "BUILTIN";
+
+ /**
+ * Spring 自动注入所有实现 BuiltinToolProvider 接口的 Bean
+ * 注意:这些是 Spring 代理,不能直接用于 LangChain4j
+ * 我们需要提取 Class 信息以便创建新实例
+ */
+ private final List toolProviders;
+
+ /**
+ * 内置工具类映射表 (工具名称 -> 工具类)
+ * 存储 Class 对象而不是实例,以便创建不带 Spring 代理的新实例
+ */
+ private final Map> registeredToolClasses = new ConcurrentHashMap<>();
+
+ /**
+ * 内置工具显示名称映射表 (工具名称 -> 显示名称)
+ */
+ private final Map displayNames = new ConcurrentHashMap<>();
+
+ /**
+ * 初始化方法,在 Bean 创建后自动调用
+ * 提取工具类信息而不是存储 Spring 代理实例
+ */
+ @PostConstruct
+ public void init() {
+ log.info("开始注册内置工具,发现 {} 个工具提供者", toolProviders.size());
+
+ // 1. 注册通过 Spring 自动发现工具
+ for (BuiltinToolProvider provider : toolProviders) {
+ String toolName = provider.getToolName();
+
+ if (registeredToolClasses.containsKey(toolName)) {
+ log.warn("工具名称重复: {},将覆盖原有注册", toolName);
+ }
+
+ // 使用 ClassUtils.getUserClass 获取原始类,避免 Spring CGLIB 代理类
+ Class> targetClass = ClassUtils.getUserClass(provider);
+ registeredToolClasses.put(toolName, targetClass);
+ displayNames.put(toolName, provider.getDisplayName());
+ log.info("注册内置工具: {} ({}) - 原始类: {}", toolName, provider.getDisplayName(), targetClass.getName());
+ }
+
+ log.info("内置工具注册完成,共 {} 个工具", registeredToolClasses.size());
+ }
+
+ /**
+ * 获取工具提供者(返回 Spring 代理,仅用于元数据查询)
+ *
+ * @param toolName 工具名称
+ * @return 工具提供者,如果不存在则返回 null
+ */
+ public BuiltinToolProvider getToolProvider(String toolName) {
+ // 这个方法返回 Spring 代理,仅用于获取元数据
+ for (BuiltinToolProvider provider : toolProviders) {
+ if (provider.getToolName().equals(toolName)) {
+ return provider;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 检查工具是否已注册
+ *
+ * @param toolName 工具名称
+ * @return 是否已注册
+ */
+ public boolean hasTool(String toolName) {
+ return registeredToolClasses.containsKey(toolName);
+ }
+
+ /**
+ * 获取所有内置工具定义
+ *
+ * @return 内置工具定义集合
+ */
+ public Collection getAllBuiltinTools() {
+ return displayNames.entrySet().stream()
+ .map(entry -> new BuiltinToolDefinition(
+ entry.getKey(),
+ entry.getValue(),
+ "" // Description can be added later if needed
+ ))
+ .toList();
+ }
+
+ /**
+ * 获取所有内置工具对象
+ * 这些对象包含 @Tool 注解的方法,可直接用于 AgenticServices
+ * 注意:每次调用都创建新实例,以避免 Spring CGLIB 代理问题
+ *
+ * @return 内置工具对象列表
+ */
+ public List