SpringBoot搭建MCPServer
MCP Server
- MCP 服务器是模型上下文协议 (MCP) 架构中的基础组件,可为客户提供工具、资源和功能。它实现协议的服务器端,负责:
- 服务器端协议作实现
- 工具曝光和发现
- 使用基于 URI 的访问进行资源管理
- 及时的模板配置和处理
- 与客户的能力协商
- 结构化日志记录和通知
- 并发客户端连接管理
- 同步和异步 API 支持
- Transport 实现:
- 基于 Stdio 的传输,用于基于进程的通信
- 基于 Servlet 的 SSE 服务器传输
- 用于反应式 HTTP 流的 WebFlux SSE 服务器传输
- 用于基于 servlet 的 HTTP 流的 WebMVC SSE 服务器传输
- 服务器端协议作实现
导入pom依赖
- 完整的 MCP 服务器功能支持基于 Spring WebFlux 的 SSE(服务器发送事件)服务器传输和可选的 STDIO 传输。
- 启动器激活 McpWebFluxServerAutoConfiguration 和 McpServerAutoConfiguration 自动配置以提供:
- 使用 Spring WebFlux 的反应式传输 WebFluxSseServerTransportProvider
- 自动配置的反应式 SSE 终端节点
- 可选的 STDIO 传输(通过设置
spring.ai.mcp.server.stdio=true启用 ) - 包括
spring-boot-starter-webflux和mcp-spring-webflux依赖项
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.ai.bom.version>1.0.0-SNAPSHOT</spring.ai.bom.version>
</properties>
<!--版本管理-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring.ai.bom.version}</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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<!--添加spring的里程碑和快照仓库,下载Alibaba相关包-->
<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>
<repository>
<id>aliyunmaven</id>
<name>aliyun</name>
<url>https://maven.aliyun.com/repository/public</url>
</repository>
</repositories>
配置文件介绍
- 在
application.yml文件中可配置以下MCP服务器属性 - 所有属性统一前缀为
spring.ai.mcp.server
| Property | Description | Default |
|---|---|---|
enabled |
启用/禁用 MCP 服务器 | true |
stdio |
启用/禁用 stdio 传输 | false |
name |
用于标识的服务器名称 | mcp-server |
version |
服务器版本 | 1.0.0 |
type |
服务器类型 (SYNC/ASYNC) |
SYNC |
resource-change-notification |
启用资源更改通知 | true |
prompt-change-notification |
启用提示更改通知 | true |
tool-change-notification |
启用工具更改通知 | true |
tool-response-mime-type |
(可选)每个工具名称的响应 MIME 类型。例如 spring.ai.mcp.server.tool-response-mime-type.generateImage=image/png ,将 image/png mime 类型与 generateImage() 工具名称相关联 | |
sse-message-endpoint |
客户端用于发送消息的 Web 传输的自定义 SSE 消息终端节点路径 | /mcp/message |
sse-endpoint |
用于 Web 传输的自定义 SSE 终端节点路径 | /sse |
base-url |
可选 URL 前缀。例如,base-url=/api/v1 表示客户端应访问 /api/v1 + sse-endpoint 的 sse 终端节点,消息终端节点为 /api/v1 + sse-message-endpoint |
配置文件示例
server:
port: 8801
spring:
ai:
mcp:
server:
name: my-weather-server
version: 1.0.0
sse-endpoint: /sse
查询天气MCP Server
查询天气工具编写
@Service
@Slf4j
public class OpenMeteoWeatherService {
private final WebClient weatherClient;
private final WebClient airQualityClient;
public OpenMeteoWeatherService(WebClient.Builder webClientBuilder) {
this.weatherClient = webClientBuilder.baseUrl("https://api.open-meteo.com/v1").build();
this.airQualityClient = webClientBuilder.baseUrl("https://air-quality-api.open-meteo.com/v1").build();
}
@Tool(description = "根据经纬度获取天气预报")
public String getWeatherForecastByLocation(
@ToolParam(description = "纬度,例如:39.9042") String latitude,
@ToolParam(description = "经度,例如:116.4074") String longitude) {
log.info("latitude:{}, longitude = {}", latitude, longitude);
try {
latitude = Optional.ofNullable(latitude).orElse("39.9042");
longitude = Optional.ofNullable(longitude).orElse("116.4074");
String finalLatitude = latitude;
String finalLongitude = longitude;
String response = weatherClient.get()
.uri(uriBuilder -> uriBuilder
.path("/forecast")
.queryParam("latitude", finalLatitude)
.queryParam("longitude", finalLongitude)
.queryParam("current", "temperature_2m,wind_speed_10m")
.queryParam("timezone", "auto")
.build())
.retrieve()
.bodyToMono(String.class)
.block();
// 解析响应并返回格式化的天气信息
// 这里简化处理,实际应用中应该解析JSON
return "当前位置(纬度:" + latitude + ",经度:" + longitude + ")的天气信息:\n" + response;
} catch (Exception e) {
return "获取天气信息失败:" + e.getMessage();
}
}
@Tool(description = "根据经纬度获取空气质量信息")
public String getAirQuality(
@ToolParam(description = "纬度,例如:39.9042") String latitude,
@ToolParam(description = "经度,例如:116.4074") String longitude) {
try {
String response = airQualityClient.get()
.uri(uriBuilder -> uriBuilder
.path("/air-quality")
.queryParam("latitude", latitude)
.queryParam("longitude", longitude)
.queryParam("hourly", "pm10,pm2_5")
.queryParam("timezone", "auto")
.build())
.retrieve()
.bodyToMono(String.class)
.block();
// 解析响应并返回格式化的天气信息
// 这里简化处理,实际应用中应该解析JSON
return "当前位置(纬度:" + latitude + ",经度:" + longitude + ")空气质量信息:\n" + response;
} catch (Exception e) {
return "获取空气质量信息失败:" + e.getMessage();
}
}
}
注册工具
@Configuration
public class McpServerConfig {
@Bean
public ToolCallbackProvider weatherTools(OpenMeteoWeatherService openMeteoWeatherService) {
return MethodToolCallbackProvider.builder().toolObjects(openMeteoWeatherService).build();
}
// @Bean
// public WebClient.Builder webClientBuilder() {
// return WebClient.builder();
// }
}
浙公网安备 33010602011771号