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 @@