diff --git a/modules/cms-ai/src/main/java/com/jeesite/modules/cms/ai/config/CmsAiChatConfig.java b/modules/ai/ai-cms/src/main/java/com/jeesite/modules/ai/cms/config/AiCmsChatConfig.java
similarity index 55%
rename from modules/cms-ai/src/main/java/com/jeesite/modules/cms/ai/config/CmsAiChatConfig.java
rename to modules/ai/ai-cms/src/main/java/com/jeesite/modules/ai/cms/config/AiCmsChatConfig.java
index 250ac5a4..d3e2330e 100644
--- a/modules/cms-ai/src/main/java/com/jeesite/modules/cms/ai/config/CmsAiChatConfig.java
+++ b/modules/ai/ai-cms/src/main/java/com/jeesite/modules/ai/cms/config/AiCmsChatConfig.java
@@ -2,16 +2,18 @@
* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
* No deletion without permission, or be held responsible to law.
*/
-package com.jeesite.modules.cms.ai.config;
+package com.jeesite.modules.ai.cms.config;
import com.jeesite.common.datasource.DataSourceHolder;
import com.jeesite.common.lang.StringUtils;
-import com.jeesite.modules.cms.ai.properties.CmsAiProperties;
-import com.jeesite.modules.cms.ai.service.CacheChatMemoryRepository;
-import com.jeesite.modules.cms.ai.tools.CmsAiTools;
+import com.jeesite.modules.ai.cms.properties.AiCmsProperties;
+import com.jeesite.modules.ai.cms.service.CacheChatMemoryRepository;
+import com.jeesite.modules.ai.tools.TestAiTools;
+import com.jeesite.modules.ai.tools.UserAITools;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.MessageWindowChatMemory;
+import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
@@ -24,24 +26,41 @@ import org.springframework.jdbc.core.JdbcTemplate;
* @author ThinkGem
*/
@Configuration
-@EnableConfigurationProperties(CmsAiProperties.class)
-public class CmsAiChatConfig {
+@EnableConfigurationProperties(AiCmsProperties.class)
+public class AiCmsChatConfig {
/**
- * 聊天对话客户端
+ * 聊天对话客户端(使用本地 Tools)
* @author ThinkGem
*/
- @Bean
- public ChatClient chatClient(ChatClient.Builder builder, CmsAiProperties properties) {
+ @Bean("chatClient")
+ @ConditionalOnProperty(name = "spring.ai.mcp.client.enabled", havingValue = "false", matchIfMissing = true)
+ public ChatClient chatClient(ChatClient.Builder builder, AiCmsProperties properties,
+ TestAiTools testAiTools, UserAITools userAITools) {
if (StringUtils.isNotBlank(properties.getDefaultSystem())) {
builder.defaultSystem(properties.getDefaultSystem());
}
- if (properties.getToolCalls()) {
- builder.defaultTools(new CmsAiTools());
+ if (properties.getTools().getEnabled()) {
+ builder.defaultTools(testAiTools, userAITools);
}
return builder.build();
}
+ /**
+ * 聊天对话客户端(使用 MCP Tools)
+ * @author ThinkGem
+ */
+ @Bean("chatClient")
+ @ConditionalOnProperty(name = "spring.ai.mcp.client.enabled", havingValue = "true", matchIfMissing = false)
+ public ChatClient chatClientMcp(ChatClient.Builder builder, AiCmsProperties properties,
+ SyncMcpToolCallbackProvider syncMcpToolCallbackProvider) {
+ if (StringUtils.isNotBlank(properties.getDefaultSystem())) {
+ builder.defaultSystem(properties.getDefaultSystem());
+ }
+ builder.defaultToolCallbacks(syncMcpToolCallbackProvider.getToolCallbacks());
+ return builder.build();
+ }
+
/**
* 聊天对话数据存储
* @author ThinkGem
diff --git a/modules/cms-ai/src/main/resources/config/jeesite-cms-ai.yml b/modules/ai/ai-cms/src/main/resources/config/jeesite-ai-cms.yml
similarity index 83%
rename from modules/cms-ai/src/main/resources/config/jeesite-cms-ai.yml
rename to modules/ai/ai-cms/src/main/resources/config/jeesite-ai-cms.yml
index 99b83e29..fb73643d 100644
--- a/modules/cms-ai/src/main/resources/config/jeesite-cms-ai.yml
+++ b/modules/ai/ai-cms/src/main/resources/config/jeesite-ai-cms.yml
@@ -7,10 +7,16 @@ spring:
model:
chat: openai
embedding: ${spring.ai.model.chat}
- image: ${spring.ai.model.chat}
- audio: ${spring.ai.model.chat}
+ embedding.text: ${spring.ai.model.chat}
+ embedding.multimodal: ${spring.ai.model.chat}
+ audio.transcription: none
+ audio.speech: none
+ moderation: none
+ image: none
- # 在线大模型【请在 pom.xml 中打开 openai 的注释,并注释上其它模型】
+# ========= 聊天对话 相关配置 =========
+
+ # 云端模型【请在 pom.xml 中打开 openai 的注释,并注释上其它模型】
openai:
# 聊天对话模型使用阿里百炼
@@ -88,7 +94,7 @@ spring:
# 聊天对话模型
chat:
options:
- model: qwen2.5
+ model: qwen3:8b
#model: deepseek-r1:7b
max-tokens: 1024
temperature: 0.6
@@ -98,11 +104,11 @@ spring:
embedding:
# 维度 dimensions 设置为 384
#model: all-minilm:33m
- # 维度 dimensions 设置为 768
- #model: nomic-embed-text
# 维度 dimensions 设置为 1024
model: bge-m3
+# ========= 向量数据库 相关配置 =========
+
# 向量数据库配置
vectorstore:
@@ -153,8 +159,31 @@ spring:
index-type: HNSW
metric-type: COSINE
- # 是否启用工具调用【例子详见 CmsAiTools.java 】
- tool-calls: false
+# ========= 本地工具调用 相关配置 =========
+
+ # 是否启用 Tool calling 工具调用【例子详见 TestAiTools.java、UserAiTools.java 】
+ tools:
+ enabled: false
+
+# ========= MPC 远程工具调用 相关配置 =========
+
+ # https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html
+ mcp:
+ client:
+ enabled: false
+ name: jeesite-mcp-client
+ version: 1.0.0
+ request-timeout: 30s
+ type: SYNC
+ sse:
+ connections:
+ jeesite:
+ url: http://127.0.0.1:8981
+ sse-endpoint: /api/v1/sse
+ toolcallback:
+ enabled: true
+
+# ========= 默认提示词、默认回答模版 =========
# 默认系统提示词
default-system: |
@@ -166,7 +195,6 @@ spring:
{query}
请根据知识库和提供的历史信息作答。如果知识库中没有答案,请自我发挥。
以下是知识库信息:{question_answer_context}
-
# ========= Postgresql 向量数据库数据源 =========
@@ -192,6 +220,8 @@ spring:
# username: elastic
# password: elastic
+# ========= 其他配置选项 =========
+
# 对话消息存缓存,可自定义存数据库
j2cache:
caffeine:
@@ -199,7 +229,3 @@ j2cache:
# 对话消息的超期时间,默认 30天,根据需要可以设置更久。
cmsChatCache: 100000, 30d
cmsChatMsgCache: 100000, 30d
-
-#logging:
-# level:
-# org.springframework: debug
diff --git a/modules/ai/ai-tools/src/main/java/com/jeesite/modules/ai/tools/TestAiTools.java b/modules/ai/ai-tools/src/main/java/com/jeesite/modules/ai/tools/TestAiTools.java
index f7e13c18..f2576a87 100644
--- a/modules/ai/ai-tools/src/main/java/com/jeesite/modules/ai/tools/TestAiTools.java
+++ b/modules/ai/ai-tools/src/main/java/com/jeesite/modules/ai/tools/TestAiTools.java
@@ -23,7 +23,7 @@ public class TestAiTools {
/**
* 获取服务器时间
*/
- @Tool(name="获取服务器时间", description = "获取当前的日期和时间,格式为 yyyy-MM-dd HH:mm:ss。")
+ @Tool(name="当前服务器时间", description = "当前服务器日期时间,格式为 yyyy-MM-dd HH:mm:ss。")
public String getCurrentDateTime() {
String dateTime = "当前日期时间:" + DateUtils.getDateTime();
logger.info("当前日期时间 ============== {}", dateTime);
diff --git a/modules/pom.xml b/modules/pom.xml
index ea2de2cc..e9f7d1a8 100644
--- a/modules/pom.xml
+++ b/modules/pom.xml
@@ -13,10 +13,10 @@
2013-Now
- core
+ ai
app
cms
- cms-ai
+ core
static
test
diff --git a/root/pom.xml b/root/pom.xml
index e71439de..4009a868 100644
--- a/root/pom.xml
+++ b/root/pom.xml
@@ -14,6 +14,7 @@
../parent
+ ../parent/ai
../common
../modules
../web
diff --git a/web-ai/web-ai-mcp/README.md b/web-ai/web-ai-mcp/README.md
new file mode 100644
index 00000000..168fc29a
--- /dev/null
+++ b/web-ai/web-ai-mcp/README.md
@@ -0,0 +1,13 @@
+## 介绍
+
+jeesite-web-ai-mcp 是一个 JeeSite 模型上下文协议(Model Context Protocol,MCP)服务端
+
+可提供外部 AI 大模型调用,语义化调用 JeeSite 服务数据,如:查询张三用户信息
+
+## 文档
+
+部署文档:http://jeesite.com/docs/install-deploy/
+
+常见问题:http://jeesite.com/docs/faq/
+
+更多文档:http://jeesite.com/docs
diff --git a/web-ai/web-ai-mcp/bin/docker-build.bat b/web-ai/web-ai-mcp/bin/docker-build.bat
new file mode 100644
index 00000000..a70a6f87
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/docker-build.bat
@@ -0,0 +1,19 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] WeḅDocker
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+call mvn clean package docker:remove docker:build -Dmaven.test.skip=true -U
+
+cd bin
+pause
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/docker-build.sh b/web-ai/web-ai-mcp/bin/docker-build.sh
new file mode 100644
index 00000000..ab475930
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/docker-build.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 打包Web工程,编译Docker镜像。"
+echo ""
+
+cd ..
+mvn clean package docker:remove docker:build -Dmaven.test.skip=true -U
+
+cd bin
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/docker/Dockerfile b/web-ai/web-ai-mcp/bin/docker/Dockerfile
new file mode 100644
index 00000000..ec998b79
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/docker/Dockerfile
@@ -0,0 +1,22 @@
+FROM docker.m.daocloud.io/openjdk:17
+LABEL maintainer="ThinkGem@163.com"
+ENV TZ "Asia/Shanghai"
+ENV LANG C.UTF-8
+VOLUME /tmp
+VOLUME /data
+
+WORKDIR /app
+
+#RUN mkdir WEB-INF
+#ADD jeesite.lic ./WEB-INF
+ADD ./maven/web.war ./app.war
+
+#ENV JAVA_OPTS "$JAVA_OPTS -Xms256m -Xmx1024m"
+ENV JAVA_OPTS "$JAVA_OPTS -Dspring.profiles.active=prod"
+
+ENTRYPOINT if [ -f "app.war" ]; then jar -xvf app.war && rm app.war; \
+ fi && cd WEB-INF && sh startup.sh && cd WEB-INF && sh startup.sh
+
+EXPOSE 8980
+
+#docker run -p 8980:8980 thinkgem/jeesite-web:5.10
diff --git a/web-ai/web-ai-mcp/bin/init-data.bat b/web-ai/web-ai-mcp/bin/init-data.bat
new file mode 100644
index 00000000..42886268
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/init-data.bat
@@ -0,0 +1,34 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] ʼݿ⡣
+echo.
+echo [Ϣ] Ҫ״ΰװ JeeSite װ Module ݱʼģѰװԶԡ
+echo.
+echo [Ϣ] ٷĬṩijʼݿDZȽϰȫģûаɾҵݱݵĽű
+echo.
+echo [Ϣ] ð汾ųǷΪȫȱݿٲ
+echo.
+pause
+
+%~d0
+cd %~dp0
+
+cd ..
+
+call mvn clean compile -Dmaven.test.skip=true -U
+echo.
+echo [Ϣ] ɣ濪ʼʼݿ⡣
+echo.
+pause
+
+set "MAVEN_OPTS=%MAVEN_OPTS% -Xms512m -Xmx1024m"
+call mvn test -Dmaven.test.skip=false -Dtest=com.jeesite.test.InitData
+
+cd bin
+pause
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/init-data.sh b/web-ai/web-ai-mcp/bin/init-data.sh
new file mode 100644
index 00000000..71018685
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/init-data.sh
@@ -0,0 +1,35 @@
+#!/usr/bin/env bash
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 初始化数据库。"
+echo ""
+echo "[信息] 本操作主要用于首次安装 JeeSite 或后安装 Module 的数据表初始化,若模块已安装会自动忽略。"
+echo ""
+echo "[信息] 官方默认提供的初始化数据库工具是比较安全的,她没有包含删除您的业务数据表及数据的脚本。"
+echo ""
+echo "[信息] 如果你是升级到该版本,不排除你是否升级完整,为安全起见,建议先备份数据库后再操作。"
+echo ""
+echo "请按回车键继续 ... "
+read text
+
+cd ..
+
+mvn clean compile -Dmaven.test.skip=true -U
+echo ""
+echo "[信息] 依赖下载完成,下面开始初始化数据库。"
+echo ""
+echo "请按回车键继续 ... "
+read text
+
+MAVEN_OPTS="$MAVEN_OPTS -Xms512m -Xmx1024m"
+mvn test -Dmaven.test.skip=false -Dtest=com.jeesite.test.InitData
+
+cd bin
+echo "请按回车键完成 ... "
+read text
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/package.bat b/web-ai/web-ai-mcp/bin/package.bat
new file mode 100644
index 00000000..7613a836
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/package.bat
@@ -0,0 +1,22 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] Weḅwar/jarļ
+echo.
+
+%~d0
+cd %~dp0
+
+call mvn -v
+echo.
+
+cd ..
+call mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+
+cd bin
+pause
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/package.sh b/web-ai/web-ai-mcp/bin/package.sh
new file mode 100644
index 00000000..b066d9f3
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/package.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# */
+echo ""
+echo "[信息] 打包Web工程,生成war/jar包文件。"
+echo ""
+
+mvn -v
+echo ""
+
+cd ..
+mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+
+cd bin
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/run-tomcat.bat b/web-ai/web-ai-mcp/bin/run-tomcat.bat
new file mode 100644
index 00000000..1d090eea
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/run-tomcat.bat
@@ -0,0 +1,20 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] ʹ Spring Boot Tomcat Web ̡
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+title %cd%
+set "MAVEN_OPTS=%MAVEN_OPTS% -Xms512m -Xmx1024m"
+call mvn clean spring-boot:run -Dmaven.test.skip=true
+
+pause
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/run-tomcat.sh b/web-ai/web-ai-mcp/bin/run-tomcat.sh
new file mode 100644
index 00000000..982b7958
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/run-tomcat.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 使用 Spring Boot Tomcat 运行 Web 工程。"
+echo ""
+
+cd ..
+MAVEN_OPTS="$MAVEN_OPTS -Xms512m -Xmx1024m"
+mvn clean spring-boot:run -Dmaven.test.skip=true
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/run-web.bat b/web-ai/web-ai-mcp/bin/run-web.bat
new file mode 100644
index 00000000..ea09d7a8
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/run-web.bat
@@ -0,0 +1,31 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] WeḅWeb̡
+echo.
+
+%~d0
+cd %~dp0
+
+rem Weḅʼ
+cd ..
+call mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+cd target
+rem Weḅ
+
+
+rem web.war pom.xml finalNamepackaging һ
+mkdir app
+copy web.war app
+cd app
+jar -xvf web.war
+del web.war
+cd WEB-INF
+call startup.bat
+
+pause
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/bin/run-web.sh b/web-ai/web-ai-mcp/bin/run-web.sh
new file mode 100644
index 00000000..442a08b1
--- /dev/null
+++ b/web-ai/web-ai-mcp/bin/run-web.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# *
+# */
+echo ""
+echo "[信息] 打包Web工程,并运行Web工程。"
+echo ""
+
+# 打包Web工程(开始)
+cd ..
+mvn clean package spring-boot:repackage -Dmaven.test.skip=true -U
+cd target
+# 打包Web工程(结束)
+
+
+# web.war 与 pom.xml 中 finalName、packaging 一致
+mkdir app
+cp web.war ./app
+cd app
+jar -xvf web.war
+rm web.war
+cd WEB-INF
+sh ./startup.sh
diff --git a/web-ai/web-ai-mcp/pom.xml b/web-ai/web-ai-mcp/pom.xml
new file mode 100644
index 00000000..e1e097d2
--- /dev/null
+++ b/web-ai/web-ai-mcp/pom.xml
@@ -0,0 +1,138 @@
+
+
+ 4.0.0
+
+
+ com.jeesite
+ jeesite-parent-ai
+ 5.14.0.springboot3-SNAPSHOT
+ ../../parent/ai/pom.xml
+
+
+ jeesite-web-ai-mcp
+ war
+
+ Web AI MCP 服务
+
+ JeeSite Web
+ http://jeesite.com
+ 2013-Now
+
+
+
+ web
+ com.jeesite.modules.AiMcpApplication
+
+
+ 8980:8980
+
+
+
+
+
+
+
+ com.jeesite
+ jeesite-module-core
+ ${project.parent.version}
+
+
+
+
+ com.jeesite
+ jeesite-module-ai-tools
+ ${project.parent.version}
+
+
+
+
+ org.springframework.ai
+ spring-ai-starter-mcp-server-webmvc
+
+
+
+
+
+
+
+ ${finalName}
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ ${finalName}
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-eclipse-plugin
+
+ ${finalName}
+
+
+
+
+
+
+
+
+ thinkgem
+ WangZhen
+ thinkgem at 163.com
+ Project lead
+ +8
+
+
+
+
+ JeeSite
+ http://jeesite.com
+
+
+
+
+ aliyun-repos
+ https://maven.aliyun.com/repository/public
+ true
+ false
+
+
+ jeesite-repos
+ https://maven.jeesite.net/repository/maven-public
+
+
+
+
+ aliyun-repos
+ https://maven.aliyun.com/repository/public
+ true
+ false
+
+
+ jeesite-repos
+ https://maven.jeesite.net/repository/maven-public
+
+
+
+
diff --git a/web-ai/web-ai-mcp/src/main/java/com/jeesite/modules/AiMcpApplication.java b/web-ai/web-ai-mcp/src/main/java/com/jeesite/modules/AiMcpApplication.java
new file mode 100644
index 00000000..7c9bb1f4
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/java/com/jeesite/modules/AiMcpApplication.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ */
+package com.jeesite.modules;
+
+import com.jeesite.common.config.Global;
+import com.jeesite.common.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
+
+/**
+ * Application
+ * @author ThinkGem
+ */
+@SpringBootApplication
+public class AiMcpApplication extends SpringBootServletInitializer {
+
+ private static final Logger logger = LoggerFactory.getLogger(AiMcpApplication.class);
+
+ public static void main(String[] args) {
+ SpringApplication.run(AiMcpApplication.class, args);
+ logger.info(
+ "\n\n==============================================================\n"
+ + "\n 启动完成,MCP 地址:http://127.0.0.1:{}/api/v1/sse\n"
+ + "\n==============================================================\n",
+ Global.getProperty("server.port") + FileUtils.path(
+ Global.getProperty("server.servlet.context-path")));
+ }
+
+ @Override
+ protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
+ this.setRegisterErrorPageFilter(false); // 错误页面有容器来处理,而不是SpringBoot
+ return builder.sources(AiMcpApplication.class);
+ }
+
+}
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/src/main/java/com/jeesite/modules/ai/mcp/config/McpServerConfig.java b/web-ai/web-ai-mcp/src/main/java/com/jeesite/modules/ai/mcp/config/McpServerConfig.java
new file mode 100644
index 00000000..abbbf212
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/java/com/jeesite/modules/ai/mcp/config/McpServerConfig.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law.
+ */
+package com.jeesite.modules.ai.mcp.config;
+
+import com.jeesite.modules.ai.tools.TestAiTools;
+import com.jeesite.modules.ai.tools.UserAITools;
+import org.springframework.ai.tool.ToolCallbackProvider;
+import org.springframework.ai.tool.method.MethodToolCallbackProvider;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+/**
+ * AI MCP 服务配置
+ * @author ThinkGem
+ */
+@Lazy(false)
+@Configuration
+public class McpServerConfig {
+
+ @Bean
+ public ToolCallbackProvider mcpServerTools(TestAiTools testAiTools, UserAITools userAITools) {
+ return MethodToolCallbackProvider.builder().toolObjects(testAiTools, userAITools).build();
+ }
+
+}
diff --git a/web-ai/web-ai-mcp/src/main/resources/config/application-prod.yml b/web-ai/web-ai-mcp/src/main/resources/config/application-prod.yml
new file mode 100644
index 00000000..925c74fe
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/config/application-prod.yml
@@ -0,0 +1,53 @@
+
+# 使用环境配置,只需 JVM 参数里加:-Dspring.profiles.active=prod
+
+#======================================#
+#========== Server settings ===========#
+#======================================#
+
+server:
+
+ port: 8980
+ servlet:
+ context-path: /js
+
+#======================================#
+#========= Database settings ==========#
+#======================================#
+
+# 数据库连接
+jdbc:
+
+ # Mysql 数据库配置
+ type: mysql
+ driver: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://192.168.56.1:3306/jeesite?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai
+ username: jeesite
+ password: jeesite
+ testSql: SELECT 1
+
+ # 数据库连接池配置
+ pool:
+
+ # 初始化连接数
+ init: 1
+ # 最小连接数
+ minIdle: 3
+ # 最大连接数
+ maxActive: 20
+
+#======================================#
+#========== Spring settings ===========#
+#======================================#
+
+# 日志配置
+logging:
+ config: classpath:config/logback-spring-prod.xml
+
+# MyBatis 相关
+mybatis:
+
+ # Mapper文件刷新线程
+ mapper:
+ refresh:
+ enabled: false
diff --git a/web-ai/web-ai-mcp/src/main/resources/config/application.yml b/web-ai/web-ai-mcp/src/main/resources/config/application.yml
new file mode 100644
index 00000000..d056f338
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/config/application.yml
@@ -0,0 +1,171 @@
+
+#======================================#
+#========== Project settings ==========#
+#======================================#
+
+# 产品或项目名称、软件开发公司名称
+productName: JeeSite MCP Server
+companyName: ThinkGem
+
+# 产品版本、版权年份
+productVersion: V5.14
+copyrightYear: 2025
+
+# 是否演示模式
+demoMode: false
+
+# 专为分离端提供接口服务
+apiMode: false
+
+#======================================#
+#========== Server settings ===========#
+#======================================#
+
+server:
+
+ port: 8981
+# servlet:
+# context-path: /js
+# register-default-servlet: false
+# tomcat:
+# uri-encoding: UTF-8
+# max-http-form-post-size: 20MB
+#
+# # 当 Nginx 为 https,tomcat 为 http 时,设置该选项为 true
+# schemeHttps: false
+
+#======================================#
+#========= Database settings ==========#
+#======================================#
+
+# 数据库连接
+jdbc:
+
+ # Mysql 数据库配置
+ type: mysql
+ driver: com.mysql.cj.jdbc.Driver
+ url: jdbc:mysql://127.0.0.1:3306/jeesite_v5?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=CONVERT_TO_NULL&serverTimezone=Asia/Shanghai
+ username: root
+ password: 123456
+ testSql: SELECT 1
+
+ # 数据库连接池配置
+ pool:
+
+ # 初始化连接数
+ init: 1
+ # 最小连接数
+ minIdle: 3
+ # 最大连接数
+ maxActive: 20
+
+#======================================#
+#========== Framework settings ========#
+#======================================#
+
+spring:
+
+ # 应用程序名称
+ application:
+ name: jeesite-web-ai-mcp
+
+ # 环境名称(注意:不可设置为 test 它是单元测试专用的名称)
+ profiles:
+ active: default
+
+ # 打印横幅
+ main:
+ banner-mode: "off"
+ lazy-initialization: false
+
+# # MVC 映射匹配策略
+# mvc:
+# pathmatch:
+# matching-strategy: ANT_PATH_MATCHER
+
+ # JTA XA 事务(spring boot 3)
+ jta:
+ enabled: false
+
+ # 缓存配置
+ cache:
+ # 缓存及会话共享(专业版)
+ isClusterMode: false
+
+# ========= MPC Server 相关配置 =========
+
+ # https://docs.spring.io/spring-ai/reference/api/mcp/mcp-server-boot-starter-docs.html
+ ai:
+ mcp:
+ server:
+ enabled: true
+ name: jeesite-mcp-server
+ version: 1.0.0
+ type: SYNC
+ sse-endpoint: /api/v1/sse
+ sse-message-endpoint: /api/v1/mcp
+ capabilities:
+ tool: true
+ resource: true
+ prompt: true
+ completion: true
+
+# 日志配置
+logging:
+ config: classpath:config/logback-spring.xml
+
+# MyBatis 相关
+mybatis:
+
+ # Mapper文件刷新线程
+ mapper:
+ refresh:
+ enabled: false
+
+# 管理基础路径
+adminPath: /a
+
+# 前端基础路径
+frontPath: /f
+
+# 基础配置(参数、模块、字典)
+config:
+ enabled: true
+
+# 用户权限相关(用户、角色、菜单)
+user:
+ enabled: true
+
+# 国际化管理
+lang:
+ enabled: false
+
+# 任务调度
+job:
+ enabled: false
+
+# 代码生成
+gen:
+ enabled: false
+
+# 系统监控(默认开启,可关闭)访问地址如下:
+# 服务监控:http://127.0.0.1:8980/js/a/state/server/index
+state:
+ enabled: true
+
+# 核心功能 Controller 开关
+web:
+ core:
+ enabled: true
+
+# 文件上传
+file:
+ enabled: false
+
+# 消息提醒中心
+msg:
+ enabled: false
+
+#======================================#
+#========== Project settings ==========#
+#======================================#
diff --git a/web-ai/web-ai-mcp/src/main/resources/config/logback-spring-prod.xml b/web-ai/web-ai-mcp/src/main/resources/config/logback-spring-prod.xml
new file mode 100644
index 00000000..3606e74f
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/config/logback-spring-prod.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %d{MM-dd HH:mm:ss.SSS} %clr(%-5p) %clr([%-39logger{39}]){cyan} - %m%n%wEx
+
+
+
+
+
+ ${log.path}/debug.log
+
+ ${log.path}/debug.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+
+
+
+
+ ${log.path}/error.log
+
+ ${log.path}/error.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+ ERROR
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/src/main/resources/config/logback-spring.xml b/web-ai/web-ai-mcp/src/main/resources/config/logback-spring.xml
new file mode 100644
index 00000000..4156d4b3
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/config/logback-spring.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ %d{MM-dd HH:mm:ss.SSS} %clr(%-5p) %clr([%-39logger{39}]){cyan} - %m%n%wEx
+
+
+
+
+
+ ${log.path}/debug.log
+
+ ${log.path}/debug.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+
+
+
+
+ ${log.path}/error.log
+
+ ${log.path}/error.%d{yyyy-MM-dd}.%i.log.zip
+ 50MB
+ 30
+
+
+ %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p ${PID:- } [%15.15t] [%-39logger{39}] [%X{TRACE_ID}] - %m%n%wEx
+
+
+ ERROR
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/web-ai/web-ai-mcp/src/main/resources/static/favicon.png b/web-ai/web-ai-mcp/src/main/resources/static/favicon.png
new file mode 100644
index 00000000..72734e51
Binary files /dev/null and b/web-ai/web-ai-mcp/src/main/resources/static/favicon.png differ
diff --git a/web-ai/web-ai-mcp/src/main/resources/views/include/csslibs.html b/web-ai/web-ai-mcp/src/main/resources/views/include/csslibs.html
new file mode 100644
index 00000000..7dc9d5db
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/views/include/csslibs.html
@@ -0,0 +1,23 @@
+<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law. */ %>
+
+
+
+
+<% if (@ListUtils.inString('zTree', libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString('tabPage', libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString('dataGrid', libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString('layout', libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString('fileupload', libs!)){ %>
+
+<% } %>
+
+
diff --git a/web-ai/web-ai-mcp/src/main/resources/views/include/head.html b/web-ai/web-ai-mcp/src/main/resources/views/include/head.html
new file mode 100644
index 00000000..8497d414
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/views/include/head.html
@@ -0,0 +1,11 @@
+<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law. */%>
+
+
+
+
+${(isNotBlank(title!) ? title! + ' - ' : '') + @Global.getConfig('productName')}
+
+
+
+
diff --git a/web-ai/web-ai-mcp/src/main/resources/views/include/jslibs.html b/web-ai/web-ai-mcp/src/main/resources/views/include/jslibs.html
new file mode 100644
index 00000000..55b010ab
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/views/include/jslibs.html
@@ -0,0 +1,48 @@
+<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law. */ %>
+
+
+
+
+
+<% if (@ListUtils.inString('zTree', libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString(['tabPage', 'dataGrid', 'fileupload'], libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString('tabPage', libs!)){ %>
+
+
+
+<% } %>
+<% if (@ListUtils.inString('dataGrid', libs!)){ %>
+
+
+
+<% } %>
+<% if (@ListUtils.inString('validate', libs!)){ %>
+
+
+
+<% } %>
+<% if (@ListUtils.inString('layout', libs!)){ %>
+
+
+
+<% } %>
+<% if (@ListUtils.inString('inputmask', libs!)){ %>
+
+<% } %>
+<% if (@ListUtils.inString('fileupload', libs!)){ %>
+
+
+
+<% } %>
+<% if (@ListUtils.inString('ueditor', libs!)){ %>
+
+
+
+<% } %>
+
+
diff --git a/web-ai/web-ai-mcp/src/main/resources/views/layouts/default.html b/web-ai/web-ai-mcp/src/main/resources/views/layouts/default.html
new file mode 100644
index 00000000..dfc14e55
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/resources/views/layouts/default.html
@@ -0,0 +1,12 @@
+<%/* Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+ * No deletion without permission, or be held responsible to law. */ %>
+<% print('<'+'!DOC'+'TYPE html'+'>'); %>
+<% print('<'+'html'+'><'+'head'+'>'); %>
+<% include('/include/head.html', {title: text(title!)}){} %>
+<% include('/include/csslibs.html', {libs: libs!}){} %>
+
+<% if (!@ListUtils.inString('layout', libs!)){ %>
+${layoutContent}
+<% }else{ %>${layoutContent}<% } %>
+
+<% include('/include/jslibs.html', {libs: libs!}){} %>
diff --git a/web-ai/web-ai-mcp/src/main/webapp/WEB-INF/startup.bat b/web-ai/web-ai-mcp/src/main/webapp/WEB-INF/startup.bat
new file mode 100644
index 00000000..1d09a113
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/webapp/WEB-INF/startup.bat
@@ -0,0 +1,51 @@
+@echo off
+rem /**
+rem * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+rem * No deletion without permission, or be held responsible to law.
+rem *
+rem * Author: ThinkGem@163.com
+rem */
+echo.
+echo [Ϣ] Web̡
+echo.
+rem pause
+rem echo.
+
+%~d0
+cd %~dp0
+
+title %cd%
+
+rem JDKĿ¼
+rem set "JAVA_HOME=%cd%\jdk1.8.0_x64"
+
+rem ·
+set "CLASS_PATH=%cd%/../"
+
+rem ŻJVM
+set "JAVA_OPTS=%JAVA_OPTS% -Xms512m -Xmx1024m"
+
+rem ʽһⲿԶļ飩
+rem set "JAVA_OPTS=%JAVA_OPTS% -Dspring.config.location=%cd%\app.yml"
+
+rem ʽûƣزͬļ
+rem set "JAVA_OPTS=%JAVA_OPTS% -Dspring.profiles.active=prod"
+
+if "%JAVA_HOME%" == "" goto noJavaHome
+if not "%JAVA_HOME%" == "" goto gotJavaHome
+goto end
+
+:noJavaHome
+set RUN_JAVA=java
+goto runJava
+
+:gotJavaHome
+set "RUN_JAVA=%JAVA_HOME%\bin\java"
+goto runJava
+
+:runJava
+call "%RUN_JAVA%" -cp %CLASS_PATH% %JAVA_OPTS% org.springframework.boot.loader.launch.WarLauncher %*
+goto end
+
+:end
+pause
diff --git a/web-ai/web-ai-mcp/src/main/webapp/WEB-INF/startup.sh b/web-ai/web-ai-mcp/src/main/webapp/WEB-INF/startup.sh
new file mode 100644
index 00000000..7520c5cd
--- /dev/null
+++ b/web-ai/web-ai-mcp/src/main/webapp/WEB-INF/startup.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+# /**
+# * Copyright (c) 2013-Now http://jeesite.com All rights reserved.
+# * No deletion without permission, or be held responsible to law.
+# *
+# * Author: ThinkGem@163.com
+# */
+echo ""
+echo "[信息] 运行Web工程。"
+echo ""
+
+cd "$(cd "$(dirname "$0")"; pwd)"
+
+# 设置JDK目录
+# JAVA_HOME="$PWD/jdk1.8.0_x64"
+
+# 设置类加载路径
+CLASS_PATH="$PWD/../"
+
+# 优化JVM参数
+# JAVA_OPTS="$JAVA_OPTS -Xms512m -Xmx1024m"
+
+# 方式一、配置外部自定义的属性文件(建议)
+# JAVA_OPTS="$JAVA_OPTS -Dspring.config.location=$PWD/app.yml"
+
+# 方式二、配置环境名称,加载不同的属性文件
+# JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prod"
+
+if [ -z "$JAVA_HOME" ]; then
+ RUN_JAVA=java
+else
+ RUN_JAVA="$JAVA_HOME"/bin/java
+fi
+
+exec "$RUN_JAVA" -cp $CLASS_PATH $JAVA_OPTS org.springframework.boot.loader.launch.WarLauncher $@
\ No newline at end of file
diff --git a/web/pom.xml b/web/pom.xml
index 18a0ce08..302e0928 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -69,7 +69,7 @@