ruoyi-extend/call-mcp-server/pom.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,83 @@ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-ai</artifactId> <version>1.0.0</version> <relativePath>../../pom.xml</relativePath> </parent> <artifactId>call-mcp-server</artifactId> <name>Archetype - call-mcp-server</name> <url>http://maven.apache.org</url> <properties> <java.version>17</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-M6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId> <version>1.0.0-M6</version> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> ruoyi-extend/call-mcp-server/src/main/java/org/ruoyi/rocket/callmcpserver/CallMcpServerApplication.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ package org.ruoyi.rocket.callmcpserver; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class CallMcpServerApplication { public static void main(String[] args) { SpringApplication.run(CallMcpServerApplication.class, args); } } ruoyi-extend/call-mcp-server/src/main/java/org/ruoyi/rocket/callmcpserver/cofing/McpClientCfg.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,22 @@ package org.ruoyi.rocket.callmcpserver.cofing; import io.modelcontextprotocol.client.McpClient; import org.springframework.ai.mcp.customizer.McpSyncClientCustomizer; import org.springframework.context.annotation.Configuration; import java.time.Duration; /** * @author ageer */ @Configuration public class McpClientCfg implements McpSyncClientCustomizer { @Override public void customize(String name, McpClient.SyncSpec spec) { // do nothing spec.requestTimeout(Duration.ofSeconds(30)); } } ruoyi-extend/call-mcp-server/src/main/java/org/ruoyi/rocket/callmcpserver/view/ChatController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,74 @@ package org.ruoyi.rocket.callmcpserver.view; import jakarta.servlet.http.HttpServletResponse; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.memory.ChatMemory; import org.springframework.ai.chat.memory.InMemoryChatMemory; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.openai.OpenAiChatOptions; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.web.bind.annotation.*; import reactor.core.publisher.Flux; /** * @author jianzhang * 2025/03/18/ä¸å8:00 */ @RestController @RequestMapping("/dashscope/chat-client") public class ChatController { private final ChatClient chatClient; private final ChatMemory chatMemory = new InMemoryChatMemory(); public ChatController(ChatClient.Builder chatClientBuilder,ToolCallbackProvider tools) { this.chatClient = chatClientBuilder .defaultTools(tools) .defaultOptions( OpenAiChatOptions.builder().model("gpt-4o-mini").build()) .build(); } @RequestMapping(value = "/generate_stream", method = RequestMethod.GET) public Flux<ChatResponse> generateStream(HttpServletResponse response, @RequestParam("id") String id, @RequestParam("prompt") String prompt) { response.setCharacterEncoding("UTF-8"); var messageChatMemoryAdvisor = new MessageChatMemoryAdvisor(chatMemory, id, 10); Flux<ChatResponse> chatResponseFlux = this.chatClient.prompt(prompt) .advisors(messageChatMemoryAdvisor) .stream() .chatResponse(); Flux<String> content = this.chatClient.prompt(prompt) .advisors(messageChatMemoryAdvisor) .stream() .content(); content.subscribe( content1 -> System.out.println("chatResponse"+content1) ); return chatResponseFlux; } @GetMapping("/advisor/chat/{id}/{prompt}") public Flux<String> advisorChat( HttpServletResponse response, @PathVariable String id, @PathVariable String prompt) { response.setCharacterEncoding("UTF-8"); var messageChatMemoryAdvisor = new MessageChatMemoryAdvisor(chatMemory, id, 10); return this.chatClient.prompt(prompt) .advisors(messageChatMemoryAdvisor).stream().content(); } } ruoyi-extend/call-mcp-server/src/main/java/org/ruoyi/rocket/callmcpserver/view/IndexController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ package org.ruoyi.rocket.callmcpserver.view; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; /** * @author jianzhang * 2025/03/18/ä¸å8:00 */ @Controller public class IndexController { @GetMapping("/") public String chat(Model model) { //model.addAttribute("name", "User"); // è¿åè§å¾åç§°ï¼å¯¹åº templates/index.html return "index"; } } ruoyi-extend/call-mcp-server/src/main/resources/application.yaml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,16 @@ server: port: 9999 spring: ai: openai: api-key: sk-xXe1WMPjhlVb1aiI1b4c6c8934D8463f9e4b67Ed8718B772 base-url: https://api.pandarobot.chat/ mcp: client: enabled: true name: call-mcp-server sse: connections: server1: url: http://127.0.0.1:6040 ruoyi-extend/call-mcp-server/src/main/resources/mcp-server-bak.json
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,40 @@ { "mcpServers": { "fileSystem": { "command": "D:\\software\\nodeJs\\npx.cmd", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "D:\\software\\sqlite" ] }, "sqlLite": { "command": "D:\\Program Files\\python3.12.3\\Scripts\\uvx.exe", "args": [ "mcp-server-sqlite", "--db-path", "D:\\work-space-study\\spring-ai-mcp-demo\\mcp-client\\src\\main\\resources\\test.db" ] }, "fetch": { "command": "D:\\Program Files\\python3.12.3\\Scripts\\uvx.exe", "args": [ "mcp-server-fetch" ] }, "baidu-map": { "command": "D:\\Program Files\\python3.12.3\\Scripts\\uvx.exe", "args": [ "run", "--with", "mcp[cli]", "mcp", "run", "D:\\work-space-python\\python-baidu-map\\baidu_map_mcp_server\\map.py" ], "env": { "BAIDU_MAPS_API_KEY": "{ç¾åº¦å°å¾API-KEY}" } } } } ruoyi-extend/call-mcp-server/src/main/resources/mcp-server.json
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ { "mcpServers": { "fileSystem": { "command": "D:\\software\\nodeJs\\npx.cmd", "args": [ "-y", "@modelcontextprotocol/server-filesystem", "D:\\software\\sqlite" ] }, "sqlLite": { "command": "D:\\Program Files\\python3.12.3\\Scripts\\uvx.exe", "args": [ "mcp-server-sqlite", "--db-path", "D:\\work-space-study\\spring-ai-mcp-demo\\mcp-client\\src\\main\\resources\\test.db" ] } } } ruoyi-extend/call-mcp-server/src/main/resources/templates/index.html
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,148 @@ <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>AI 对è¯å©æ</title> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="bg-gray-100 min-h-screen"> <div class="container mx-auto p-4 max-w-3xl"> <!-- æ é¢ --> <div class="text-center mb-8"> <h1 class="text-3xl font-bold text-gray-800">AI 对è¯å©æ</h1> <p class="text-gray-600 mt-2">åºäº Spring AI çæµå¼å¯¹è¯ç³»ç» By AhuCodingBeast</p> </div> <!-- èå¤©å®¹å¨ --> <div id="chat-container" class="bg-white rounded-xl shadow-lg p-4 mb-4 h-[500px] overflow-y-auto space-y-4"> <!-- åå§æ¬¢è¿æ¶æ¯ --> <div class="ai-message flex items-start gap-3"> <div class="bg-green-100 p-3 rounded-lg max-w-[85%]"> <span class="text-gray-800">æ¨å¥½ï¼ææ¯AIå©æï¼æä»ä¹å¯ä»¥å¸®æ¨ï¼</span> </div> </div> </div> <!-- è¾å ¥åºå --> <div class="flex gap-2"> <input type="text" id="message-input" class="flex-1 border border-gray-300 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500" placeholder="è¾å ¥æ¨çé®é¢..."> <button id="send-button" class="bg-blue-500 text-white px-6 py-3 rounded-xl hover:bg-blue-600 transition-colors flex items-center"> <span>åé</span> <svg id="loading-spinner" class="hidden w-4 h-4 ml-2 animate-spin" fill="none" viewBox="0 0 24 24"> <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle> <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"></path> </svg> </button> </div> </div> <script> const chatContainer = document.getElementById('chat-container'); const messageInput = document.getElementById('message-input'); const sendButton = document.getElementById('send-button'); const loadingSpinner = document.getElementById('loading-spinner'); // åéæ¶æ¯å¤ç function handleSend() { const message = messageInput.value.trim(); if (!message) return; // æ·»å ç¨æ·æ¶æ¯ addMessage(message, 'user'); messageInput.value = ''; // æå»ºAPI URL const apiUrl = new URL('http://localhost:9999/dashscope/chat-client/generate_stream'); apiUrl.searchParams.append('id', '01'); apiUrl.searchParams.append('prompt', message); // æ¾ç¤ºå è½½ç¶æ sendButton.disabled = true; loadingSpinner.classList.remove('hidden'); // å建EventSourceè¿æ¥ const eventSource = new EventSource(apiUrl); let aiMessageElement = null; eventSource.onmessage = (event) => { try { const data = JSON.parse(event.data); console.log(data); const content = data.result?.output?.text || ''; const finishReason = data.result?.metadata?.finishReason; // åå»ºæ¶æ¯å®¹å¨ï¼å¦æä¸åå¨ï¼ if (!aiMessageElement) { aiMessageElement = addMessage('', 'ai'); } // 追å å 容 if (content) { aiMessageElement.querySelector('.message-content').textContent += content; autoScroll(); } // å¤çç»æ if (finishReason === 'STOP') { eventSource.close(); sendButton.disabled = false; loadingSpinner.classList.add('hidden'); } } catch (error) { console.error('è§£æé误:', error); } }; eventSource.onerror = (error) => { console.error('è¿æ¥é误:', error); eventSource.close(); sendButton.disabled = false; loadingSpinner.classList.add('hidden'); addMessage('对è¯è¿æ¥å¼å¸¸ï¼è¯·éè¯', 'ai', true); }; } // æ·»å æ¶æ¯å°å®¹å¨ function addMessage(content, type, isError = false) { const messageDiv = document.createElement('div'); messageDiv.className = `${type}-message flex items-start gap-3`; const bubble = document.createElement('div'); bubble.className = `p-3 rounded-lg max-w-[85%] ${ type === 'user' ? 'bg-blue-500 text-white ml-auto' : `bg-green-100 ${isError ? 'text-red-500' : 'text-gray-800'}` }`; const contentSpan = document.createElement('span'); contentSpan.className = 'message-content'; contentSpan.textContent = content; bubble.appendChild(contentSpan); messageDiv.appendChild(bubble); chatContainer.appendChild(messageDiv); autoScroll(); return bubble; } // èªå¨æ»å¨å°åºé¨ function autoScroll() { chatContainer.scrollTop = chatContainer.scrollHeight; } // äºä»¶çå¬ sendButton.addEventListener('click', handleSend); messageInput.addEventListener('keypress', (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); } }); </script> </body> </html> ruoyi-extend/ruoyi-mcp-server/pom.xml
@@ -49,16 +49,16 @@ <artifactId>spring-ai-mcp</artifactId> </dependency> <dependency> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-system-api</artifactId> <exclusions> <exclusion> <groupId>org.ruoyi</groupId> <artifactId>ruoyi-common-translation</artifactId> </exclusion> </exclusions> </dependency> <!-- <dependency>--> <!-- <groupId>org.ruoyi</groupId>--> <!-- <artifactId>ruoyi-system-api</artifactId>--> <!-- <exclusions>--> <!-- <exclusion>--> <!-- <groupId>org.ruoyi</groupId>--> <!-- <artifactId>ruoyi-common-translation</artifactId>--> <!-- </exclusion>--> <!-- </exclusions>--> <!-- </dependency>--> </dependencies> </project> ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcp/service/McpCustomService.java
@@ -1,8 +1,5 @@ package org.ruoyi.mcp.service; import lombok.RequiredArgsConstructor; import org.ruoyi.system.domain.vo.SysUserVo; import org.ruoyi.system.mapper.SysUserMapper; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; @@ -10,18 +7,14 @@ * @author ageer */ @Service @RequiredArgsConstructor public class McpCustomService { private final SysUserMapper userMapper; public record User(String userName, Double userBalance) { public record User(String userName, String userBalance) { } @Tool(description = "æ ¹æ®ç¨æ·åç§°æ¥è¯¢ç¨æ·ä¿¡æ¯") public User getUserBalance(String username) { SysUserVo sysUserVo = userMapper.selectUserByUserName(username); return new User(sysUserVo.getUserName(),sysUserVo.getUserBalance()); return new User("admin","99.99"); } } ruoyi-extend/ruoyi-mcp-server/src/main/resources/application-dev.yml
ÎļþÒÑɾ³ý ruoyi-extend/ruoyi-mcp-server/src/main/resources/application-mcp.yml
ÎļþÒÑɾ³ý ruoyi-extend/ruoyi-mcp-server/src/main/resources/application.yml
@@ -1,332 +1,12 @@ # 项ç®ç¸å ³é ç½® ruoyi: # åç§° name: "ruoyi" # çæ¬ version: ${revision} # çæå¹´ä»½ copyrightYear: 2025 # å®ä¾æ¼ç¤ºå¼å ³ demoEnabled: true # è·åipå°åå¼å ³ addressEnabled: false captcha: enable: false # é¡µé¢ <åæ°è®¾ç½®> å¯å¼å¯å ³é éªè¯ç æ ¡éª # éªè¯ç ç±»å math æ°ç»è®¡ç® char å符éªè¯ type: MATH # line çº¿æ®µå¹²æ° circle ååå¹²æ° shear ææ²å¹²æ° category: CIRCLE # æ°åéªè¯ç 使° numberLength: 1 # å符éªè¯ç é¿åº¦ charLength: 4 # å¼åç¯å¢é ç½® server: # æå¡å¨çHTTP端å£ï¼é»è®¤ä¸º8080 port: 6040 servlet: # åºç¨ç访é®è·¯å¾ context-path: / # undertow é ç½® undertow: # HTTP postå 容çæå¤§å¤§å°ãå½å¼ä¸º-1æ¶ï¼é»è®¤å¼ä¸ºå¤§å°æ¯æ éç max-http-post-size: -1 # 以ä¸çé ç½®ä¼å½±åbuffer,è¿äºbufferä¼ç¨äºæå¡å¨è¿æ¥çIOæä½,æç¹ç±»ä¼¼nettyçæ± åå å管ç # æ¯åbufferç空é´å¤§å°,è¶å°ç空é´è¢«å©ç¨è¶å å buffer-size: 512 # æ¯å¦åé çç´æ¥å å direct-buffers: true threads: # 设置IOçº¿ç¨æ°, å®ä¸»è¦æ§è¡éé»å¡çä»»å¡,å®ä»¬ä¼è´è´£å¤ä¸ªè¿æ¥, é»è®¤è®¾ç½®æ¯ä¸ªCPUæ ¸å¿ä¸ä¸ªçº¿ç¨ io: 8 # é»å¡ä»»å¡çº¿ç¨æ± , 彿§è¡ç±»ä¼¼servlet请æ±é»å¡æä½, undertowä¼ä»è¿ä¸ªçº¿ç¨æ± ä¸åå¾çº¿ç¨,å®çå¼è®¾ç½®åå³äºç³»ç»çè´è½½ worker: 256 # ç¨æ·é ç½® user: password: # å¯ç æå¤§éè¯¯æ¬¡æ° maxRetryCount: 5 # å¯ç é宿¶é´ï¼é»è®¤10åéï¼ lockTime: 10 # Springé ç½® spring: application: name: ${ruoyi.name} # èµæºä¿¡æ¯ messages: # å½é åèµæºæä»¶è·¯å¾ basename: i18n/messages profiles: active: @profiles.active@ # æä»¶ä¸ä¼ servlet: multipart: # å个æä»¶å¤§å° max-file-size: 50MB # 设置æ»ä¸ä¼ çæä»¶å¤§å° max-request-size: 200MB mvc: format: date-time: yyyy-MM-dd HH:mm:ss jackson: # æ¥ææ ¼å¼å date-format: yyyy-MM-dd HH:mm:ss serialization: # æ ¼å¼åè¾åº indent_output: false # å¿½ç¥æ æ³è½¬æ¢ç对象 fail_on_empty_beans: false deserialization: # å 许对象忽ç¥jsonä¸ä¸åå¨ç屿§ fail_on_unknown_properties: false # Sa-Tokené ç½® sa-token: # tokenåç§° (忶乿¯cookieåç§°) token-name: Authorization # tokenæææ 设为7天 (å¿ å®è¿æ) åä½: ç§ timeout: 604800 # tokenä¸´æ¶æææ (æå®æ¶é´æ æä½å°±è¿æ) åä½: ç§ activity-timeout: 604800 # æ¯å¦å 许åä¸è´¦å·å¹¶åç»å½ (为trueæ¶å 许ä¸èµ·ç»å½, 为falseæ¶æ°ç»å½æ¤ææ§ç»å½) is-concurrent: true # å¨å¤äººç»å½åä¸è´¦å·æ¶ï¼æ¯å¦å ±ç¨ä¸ä¸ªtoken (为trueæ¶ææç»å½å ±ç¨ä¸ä¸ªtoken, 为falseæ¶æ¯æ¬¡ç»å½æ°å»ºä¸ä¸ªtoken) is-share: false # æ¯å¦å°è¯ä»headeré读åtoken is-read-header: true # æ¯å¦å°è¯ä»cookieé读åtoken is-read-cookie: false # tokenåç¼ token-prefix: "Bearer" # jwtç§é¥ jwt-secret-key: abcdefghijklmnopqrstuvwxyz # securityé ç½® security: # æé¤è·¯å¾ excludes: # æ¯ä»åè° - /pay/returnUrl - /pay/notifyUrl # ä¸ä¼ æä»¶ - /resource/oss/upload # éç½®å¯ç - /auth/reset/password # è天æ¥å£ - /chat # éæèµæº - /*.html - /**/*.html - /**/*.css - /**/*.js # å ¬å ±è·¯å¾ - /favicon.ico - /error # swagger ææ¡£é ç½® - /*/api-docs - /*/api-docs/** # actuator çæ§é ç½® - /actuator - /actuator/** # å¤ç§æ·é ç½® tenant: # æ¯å¦å¼å¯ enable: false # æé¤è¡¨ excludes: - sys_menu - sys_tenant - sys_tenant_package - sys_role_dept - sys_role_menu - sys_user_post - sys_user_role # MyBatisPlusé ç½® # https://baomidou.com/config/ mybatis-plus: # 䏿¯æå¤å , 妿éè¦å¯å¨æ³¨è§£é ç½® æ æåæ«å ç级 # ä¾å¦ com.**.**.mapper mapperPackage: org.ruoyi.**.mapper # 对åºç XML æä»¶ä½ç½® mapperLocations: classpath*:mapper/**/*Mapper.xml # å®ä½æ«æï¼å¤ä¸ªpackageç¨éå·æè åå·åé typeAliasesPackage: org.ruoyi.**.domain # å¯å¨æ¶æ¯å¦æ£æ¥ MyBatis XML æä»¶çåå¨ï¼é»è®¤ä¸æ£æ¥ checkConfigLocation: false configuration: # èªå¨é©¼å³°å½åè§åï¼camel caseï¼æ å° mapUnderscoreToCamelCase: true # MyBatis èªå¨æ å°çç¥ # NONEï¼ä¸å¯ç¨ PARTIALï¼åªå¯¹éåµå¥ resultMap èªå¨æ å° FULLï¼å¯¹ææ resultMap èªå¨æ å° autoMappingBehavior: FULL # MyBatis èªå¨æ å°æ¶æªç¥åææªç¥å±æ§å¤çç # NONEï¼ä¸åå¤ç WARNINGï¼æå°ç¸å ³è¦å FAILINGï¼æåºå¼å¸¸å详ç»ä¿¡æ¯ autoMappingUnknownColumnBehavior: NONE # æ´è¯¦ç»çæ¥å¿è¾åº 伿æ§è½æè org.apache.ibatis.logging.stdout.StdOutImpl # å ³éæ¥å¿è®°å½ (å¯åçº¯ä½¿ç¨ p6spy åæ) org.apache.ibatis.logging.nologging.NoLoggingImpl # é»è®¤æ¥å¿è¾åº org.apache.ibatis.logging.slf4j.Slf4jImpl logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl global-config: # æ¯å¦æå° Logo banner banner: true dbConfig: # 主é®ç±»å # AUTO èªå¢ NONE 空 INPUT ç¨æ·è¾å ¥ ASSIGN_ID éªè± ASSIGN_UUID å¯ä¸ UUID idType: ASSIGN_ID # é»è¾å·²å é¤å¼ logicDeleteValue: 2 # é»è¾æªå é¤å¼ logicNotDeleteValue: 0 # åæ®µéªè¯çç¥ä¹ insert,å¨ insert çæ¶åçåæ®µéªè¯çç¥ # IGNORED å¿½ç¥ NOT_NULL éNULL NOT_EMPTY é空 DEFAULT é»è®¤ NEVER ä¸å å ¥ SQL insertStrategy: NOT_NULL # åæ®µéªè¯çç¥ä¹ update,å¨ update çæ¶åçåæ®µéªè¯çç¥ updateStrategy: NOT_NULL # åæ®µéªè¯çç¥ä¹ select,å¨ select çæ¶åçåæ®µéªè¯çç¥æ¢ wrapper æ ¹æ®å é¨ entity çæç where æ¡ä»¶ where-strategy: NOT_NULL # æ°æ®å å¯ mybatis-encryptor: # æ¯å¦å¼å¯å å¯ enable: false # é»è®¤å å¯ç®æ³ algorithm: BASE64 # ç¼ç æ¹å¼ BASE64/HEXãé»è®¤BASE64 encode: BASE64 # å®å ¨ç§é¥ å¯¹ç§°ç®æ³çç§é¥ å¦ï¼AESï¼SM4 password: # å ¬ç§é¥ éå¯¹ç§°ç®æ³çå ¬ç§é¥ å¦ï¼SM2ï¼RSA publicKey: privateKey: # Swaggeré ç½® swagger: info: # æ é¢ title: 'æ é¢ï¼${ruoyi.name}å¤ç§æ·ç®¡çç³»ç»_æ¥å£ææ¡£' # æè¿° description: 'æè¿°ï¼ç¨äºç®¡çé墿ä¸å ¬å¸ç人åä¿¡æ¯,å ·ä½å æ¬XXX,XXX模å...' # çæ¬ version: 'çæ¬å·: ${ruoyi.version}' # ä½è ä¿¡æ¯ contact: name: ageerle email: ageerle@163.com url: https://gitee.com/ageerle/ruoyi-ai components: # é´ææ¹å¼é ç½® security-schemes: apiKey: type: APIKEY in: HEADER name: ${sa-token.token-name} springdoc: api-docs: # æ¯å¦å¼å¯æ¥å£ææ¡£ enabled: true swagger-ui: # æä¹ åè®¤è¯æ°æ® persistAuthorization: true #è¿éå®ä¹äºä¸¤ä¸ªåç»ï¼å¯å®ä¹å¤ä¸ªï¼ä¹å¯ä»¥ä¸å®ä¹ group-configs: - group: 1.æ¼ç¤ºæ¨¡å packages-to-scan: org.ruoyi.demo - group: 2.éç¨æ¨¡å packages-to-scan: org.ruoyi.web - group: 3.ç³»ç»æ¨¡å packages-to-scan: org.ruoyi.system - group: 4.代ç çææ¨¡å packages-to-scan: org.ruoyi.generator # 鲿¢XSSæ»å» xss: # è¿æ»¤å¼å ³ enabled: true # æé¤é¾æ¥ï¼å¤ä¸ªç¨éå·åéï¼ excludes: /system/notice # å¹é 龿¥ urlPatterns: /system/*,/monitor/*,/tool/* # å ¨å±çº¿ç¨æ± ç¸å ³é ç½® thread-pool: # æ¯å¦å¼å¯çº¿ç¨æ± enabled: false # éåæå¤§é¿åº¦ queueCapacity: 128 # çº¿ç¨æ± ç»´æ¤çº¿ç¨æå 许çç©ºé²æ¶é´ keepAliveSeconds: 300 --- # åå¸å¼é lock4j å ¨å±é ç½® lock4j: # è·ååå¸å¼éè¶ æ¶æ¶é´ï¼é»è®¤ä¸º 3000 æ¯«ç§ acquire-timeout: 3000 # åå¸å¼éçè¶ æ¶æ¶é´ï¼é»è®¤ä¸º 30 ç§ expire: 30000 --- # Actuator çæ§ç«¯ç¹çé 置项 management: endpoints: web: exposure: include: '*' endpoint: health: show-details: ALWAYS logfile: external-file: ./logs/sys-console.log # websocket websocket: enabled: true # è·¯å¾ path: '/resource/websocket' # è®¾ç½®è®¿é®æºå°å allowedOrigins: '*' # 微信å°ç¨åºé ç½®ä¿¡æ¯ wx: miniapp: configs: - appid: # ä½ çappid secret: # ä½ çsecret token: #微信å°ç¨åºæ¶æ¯æå¡å¨é ç½®çtoken aesKey: #微信å°ç¨åºæ¶æ¯æå¡å¨é ç½®çEncodingAESKey msgDataFormat: JSON # ä¼ä¸å¾®ä¿¡åºç¨ wechat: cp: corpId: appConfigs: - agentId: secret: '' token: '' aesKey: '' spring: name: mcp-server ai: openai: api-key: sk-xX base-url: https://api.pandarobot.chat ollama: base-url: http://localhost:11434 init: pull-model-strategy: always timeout: 60s max-retries: 1 mcp: client: enabled: true name: call-mcp-server sse: connections: server1: url: http://127.0.0.1:8080 server: name: webmvc-mcp-server version: 1.0.0 type: SYNC sse-message-endpoint: /mcp/messages