Spring AI 實現(xiàn) STDIO和SSE MCP Server的過程詳解
Spring AI 實現(xiàn) STDIO和SSE MCP Server
Java MCP 三層架構(gòu)中,傳輸?shù)姆绞接蠸TDIO和SSE兩種,如下圖所示。
STDIO方式是基于進程間通信,MCP Client和MCP Server運行在同一主機,主要用于本地集成、命令行工具等場景。
SSE方式是基于HTTP協(xié)議,MCP Client遠程調(diào)用MCP Server提供的SSE服務(wù)。實現(xiàn)客戶端和服務(wù)端遠程通信。
SSE Server
spring-ai-starter-mcp-server-webflux
基于WebFlux SSE 實現(xiàn)SSE Server。
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webflux</artifactId> </dependency>
MCP 服務(wù)端功能支持基于 Spring WebFlux 的 SSE(服務(wù)器發(fā)送事件)服務(wù)器傳輸和可選的 STDIO 傳輸。
1.新建Spring Boot項目
使用https://start.spring.io/新建項目,引入以下依賴。
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mcp.example</groupId> <artifactId>mcp-webflux-server-example</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mcp-webflux-server-example</name> <description>mcp-webflux-server-example</description> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webflux</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <name>Central Portal Snapshots</name> <id>central-portal-snapshots</id> <url>https://central.sonatype.com/repository/maven-snapshots/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> </repositories> </project>
2.application.yaml配置
spring: ai: mcp: server: name: webflux-mcp-server version: 1.0.0 type: ASYNC # Recommended for reactive applications sse-message-endpoint: /mcp/messages
定義MCP名稱和版本號以及同步或異步配置。
3.定義工具類
@Service public class DateTimeService { @Tool(description = "Get the current date and time in the user's timezone") String getCurrentDateTime() { return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString(); } @Tool(description = "Set a user alarm for the given time, provided in ISO-8601 format") String setAlarm(String time) { LocalDateTime alarmTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME); return "Alarm set for " + alarmTime; } }
定義二個工具:
1.獲取當前日期和時間
2.設(shè)置提醒功能
4.暴露工具
@Configuration public class McpWebFluxServiceExampleConfig { @Bean public ToolCallbackProvider dateTimeTools(DateTimeService dateTimeService) { return MethodToolCallbackProvider.builder().toolObjects(dateTimeService).build(); } }
5.啟動MCP Server項目
啟動項目發(fā)現(xiàn)注冊的兩個工具成功,可以端可以發(fā)現(xiàn)兩個工具。到此MCP Server服務(wù)完成,SSE的端點路徑:http://localhost:9090
,接下來是客戶端連接使用服務(wù)端提供的工具。
6.MCP Client連接MCP Server
1.新建Spring Boot項目,然后引入starter
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-client</artifactId> </dependency>
完整pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mcp.example</groupId> <artifactId>mcp-client-example</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mcp-client-example</name> <description>mcp-client-example</description> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai-spring-boot-starter</artifactId> <version>1.0.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <name>Central Portal Snapshots</name> <id>central-portal-snapshots</id> <url>https://central.sonatype.com/repository/maven-snapshots/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> </repositories> </project>
2.配置
spring: ai: openai: api-key: 你自己密鑰 base-url: https://api.siliconflow.cn chat: options: model: Qwen/Qwen2.5-72B-Instruct mcp: client: sse: connections: server1: url: http://localhost:9090 toolcallback: enabled: true server: port: 9091
配置文件內(nèi)容,大模型配置方便測試工具使用,mcp服務(wù)端設(shè)置就是mcp server提供的sse端點。
toolcalback.enable=true 自動注入Spring AI ToolCallbackProvider。
3.測試
package com.mcp.example.mcpclientexample; import io.modelcontextprotocol.client.McpAsyncClient; import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.mcp.SyncMcpToolCallbackProvider; import org.springframework.ai.tool.ToolCallback; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.Arrays; import java.util.List; @SpringBootApplication public class McpClientExampleApplication implements CommandLineRunner { @Resource private ToolCallbackProvider tools; @Resource ChatClient.Builder chatClientBuilder; public static void main(String[] args) { SpringApplication.run(McpClientExampleApplication.class, args); } @Override public void run(String... args) throws Exception { var chatClient = chatClientBuilder .defaultTools(tools) .build(); String content = chatClient.prompt("10分鐘后,設(shè)置一個鬧鈴。").call().content(); System.out.println(content); String content1 = chatClient.prompt("明天星期幾?").call().content(); System.out.println(content1); } }
運行客戶端項目:
結(jié)果表明定義的工具大模型根據(jù)用戶的提問,選擇了合適的工具進行回答。
STDIO Server
標準 MCP 服務(wù)器,通過 STDIO 服務(wù)器傳輸支持完整的 MCP 服務(wù)器功能。
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server</artifactId> </dependency>
1.創(chuàng)建Server項目
新建Spring Boot項目引入以下依賴
<?xml version="1.0" encoding="UTF-8"?> <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.mcp.example</groupId> <artifactId>mcp-stdio-server-example</artifactId> <version>0.0.1-SNAPSHOT</version> <name>mcp-stdio-server-example</name> <description>mcp-stdio-server-example</description> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <name>Central Portal Snapshots</name> <id>central-portal-snapshots</id> <url>https://central.sonatype.com/repository/maven-snapshots/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> </repositories> </project>
配置文件application.yaml
spring: ai: mcp: server: name: stdio-mcp-server version: 1.0.0 stdio: true main: banner-mode: off web-application-type: none logging: pattern: console: server: port: 9090
main:
banner-mode: off
web-application-type: none 這個配置非常關(guān)鍵,否則client與server通信會提示json解析有問題。這個必須關(guān)掉。
2.新建工具
與sse server一樣,新建DateTimeTool并注冊。
3.打包項目
STDIO方式server和client之間是進程間通信,所以需要把server打包成jar,以便client命令啟動執(zhí)行,或者三方客戶端命令啟動執(zhí)行。將server jar放到一個指定目錄,如下所示:
target/mcp-stdio-server-example.jar
4.創(chuàng)建client項目
直接使用上面sse server使用的 Clinet,修改對應(yīng)配置文件application.yaml
和新建mcp-server配置json。mcp-servers-config.json
。
{ "mcpServers": { "stdio-mcp-server": { "command": "java", "args": [ "-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none", "-jar", "mcp server正確的路徑 ../mcp-stdio-server-example-0.0.1-SNAPSHOT.jar" ], "env": {} } } }
application.yaml
spring: ai: openai: api-key: sk-qwkegvacbfpsctyhfgakxlwfnklinwjunjyfmonnxddmcixr base-url: https://api.siliconflow.cn chat: options: model: Qwen/Qwen2.5-72B-Instruct mcp: client: # sse: # connections: # server1: # url: http://localhost:9090 stdio: root-change-notification: false servers-configuration: classpath:/mcp-servers-config.json toolcallback: enabled: true server: port: 9091
5.啟動客戶端
到此這篇關(guān)于Spring AI 實現(xiàn) STDIO和SSE MCP Server的過程詳解的文章就介紹到這了,更多相關(guān)Spring AI STDIO和SSE MCP Server內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java編程中實現(xiàn)Condition控制線程通信
這篇文章主要介紹了Java編程中實現(xiàn)Condition控制線程通信,簡單介紹了Java中控制線程通信的方法,以及對condition的解析和實例,具有一定參考價值,需要的朋友可以了解下。2017-11-11SpringBoot 改造成https訪問的實現(xiàn)
這篇文章主要介紹了SpringBoot 改造成https訪問的實現(xiàn),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10