三、使用Spring AI实现基于stdio协议的MCP Server
三、使用Spring AI实现基于stdio协议的MCP Server
==================================================================================
==================================================================================
参考资料:
==================================================================================
同第一篇《一、MCP和Spring AI MCP》参考资料
==================================================================================
SSE传输协议:SSE(Server-Sent Events)传输层是基于HTTP的单向通信机制,专门用于服务器向客户端推送数据。MCP Client远程调用MCP Server提供的SSE服务。实现客户端和服务端远程通信。
优点:
支持分布式部署;可跨网络访问;支持多客户端连接;轻量级,使用标准HTTP协议。
缺点:
需要额外的网络配置;相比stdio实现略微复杂;需要考虑网络安全性
STDIO传输协议:STDIO方式是基于进程间通信,MCP Client和MCP Server运行在同一主机,主要用于本地集成、命令行工具等场景。
优点:
简单可靠,无需网络配置;适合本地部署场景;进程隔离,安全性好。
缺点:
仅支持单机部署;不支持跨网络访问;每个客户端需要独立启动服务器进程。
基于stdio的MCP服务端通过标准输入输出流与客户端通信,适用于作为子进程被客户端启动和管理的场景,非常适合嵌入式应用。
1、创建SpringBoot工程


1.1、application.yml
spring:
ai:
mcp:
server:
name: springai_mcp_stdio_server # MCP服务器名称
version: 1.0.0 # 服务器版本号
1.2、pom.xml
MCP Server有三个常用依赖:
spring-ai-starter-mcp-server:支持STDIO(标准流)传输的核心服务器
spring-ai-starter-mcp-server-webmvc:基于Spring MVC的SSE传输实现
spring-ai-starter-mcp-server-webflux:基于Spring WebFlux的SSE传输实现
这里我们选择基于Spring WebFlux的SSE传输实现实现方式。
<?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.5.8</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.youzhuo</groupId>
<artifactId>springai_mcp_stdio_server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springai_mcp_stdio_server</name>
<description>springai_mcp_stdio_server</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.1.0</spring-ai.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<!-- <artifactId>spring-ai-starter-mcp-server</artifactId>-->
<artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、配置log日志
在resources目录下,新建一个log日志配置文件logback-spring.xml,目的是记录MCP Server端的接口是否被调用。
<configuration>
<!-- 定义日志文件存储的路径,可以使用Spring的属性占位符 -->
<property name="LOGS_PATH" value="${user.dir}/logs"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS_PATH}/springai_mcp_stdio_server.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOGS_PATH}/springai_mcp_stdio_server.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
3、新建计算器工具服务类
创建一个MathTools类,模拟计算器服务,通过@Tool注解把方法标注为MCP服务接口。
@Service
public class MathTools {
private static final Logger log = LoggerFactory.getLogger(MathTools.class);
@Tool(description = "将两个数相加")
public double add(double x, double y) {
log.info("CalculatorTools的add被调用了: x={}, y={}", x, y);
return x + y;
}
@Tool(description = "将两个数相减")
public double subtract(double x, double y) {
log.info("CalculatorTools的subtract被调用了: x={}, y={}", x, y);
return x - y;
}
@Tool(description = "将两个数相乘")
public double multiply(double x, double y) {
log.info("CalculatorTools的multiply被调用了: x={}, y={}", x, y);
return x * y;
}
@Tool(description = "将两个数相除")
public double divide(double x, double y) {
if (y == 0) {
throw new IllegalArgumentException("除数不能为零");
}
log.info("CalculatorTools的divide被调用了: x={}, y={}", x, y);
return x / y;
}
@Tool(description = "计算平方根")
public double sqrt(double x) {
if (x < 0) {
throw new IllegalArgumentException("不能对负数开平方根");
}
log.info("CalculatorTools的sqrt被调用了: x={}", x);
return Math.sqrt(x);
}
}
4、注册为MCP工具
将 MathTools封装为工具回调提供者(ToolCallbackProvider),便于被MCP Client端发现和调用。
@SpringBootApplication
public class SpringaiMcpStdioServerApplication {
private static final Logger log = LoggerFactory.getLogger(SpringaiMcpStdioServerApplication.class);
public static void main(String[] args) {
SpringApplication.run(SpringaiMcpStdioServerApplication.class, args);
log.info("=============================================");
log.info("SpringaiMcpStdioServerApplication服务启动成功");
log.info("=============================================");
}
@Bean
public ToolCallbackProvider calculatorTools(MathTools mathTools) {
return MethodToolCallbackProvider.builder()
.toolObjects(mathTools).build();
}
}
通过Spring AI创建的MCP Stdio Server完成了。
stdio方式是server和client通过进程通信,所以需要把server打包成jar,以便client命令启动执行。
通过maven工具打包即可,打包后路径为:{项目工程目录}\target\springai_mcp_stdio_server-0.0.1-SNAPSHOT.jar。
5、测试Mcp Stdio服务是否发布成功
启动项目,测试服务是否启动成功
启动项目,验证服务是否启动成功。

在日志文件中可以看出工具注册成功,服务也启动成功

6、使用bat启动jar,方便MCP Client调用
在{项目工程目录}下新建run_mcp_stdio_server.bat
java -Dspring.ai.mcp.server.stdio=true -Dspring.main.web-application-type=none -Dspring.main.banner-mode=off -Dfile.encoding=UTF-8 -jar target/springai_mcp_stdio_server-0.0.1-SNAPSHOT.jar
pause
启动bat文件,验证服务是否启动成功。
至此,我们通过spring ai框架开发完成了2个MCP Server服务,一个通过sse协议发布,另一个通过stdio协议发布,接下来,开发一个MCP Client端,调用这两个MCP Server服务。
本文来自博客园,作者:老羅,转载请注明原文链接:https://www.cnblogs.com/laoluo2025/p/19276622

浙公网安备 33010602011771号