将 Spring Boot 微服务快速转换为支持 Streamable HTTP 传输协议的 MCP Server。集成后微服务自动暴露 /mcp 路由,按照 MCP 规范 2025-11-25 处理所有 MCP 通信。
spring-boot-mcp-starter
├── mcp-core # 核心能力层(无 Spring 依赖,可独立复用)
│ ├── annotation # @McpScan / @McpTool / @McpResource / @McpPrompt
│ ├── descriptor # MCP 描述符模型
│ ├── protocol # JSON-RPC 2.0 类型 + McpProcessResult
│ └── server # McpServerEngine / McpSession / McpSessionManager
├── mcp-spring-common # Spring 公共层(扫描器、配置属性、参数解析)
├── spring-boot-webmvc-mcp-starter # WebMVC 适配层(Servlet 环境)
├── spring-boot-webflux-mcp-starter # WebFlux 适配层(Reactive 环境)
├── spring-boot-webmvc-mcp-sample # WebMVC 示例应用(端口 8082)
└── spring-boot-webflux-mcp-sample # WebFlux 示例应用(端口 8083)
| 模块 | 职责 |
|---|---|
mcp-core |
Streamable 协议处理、注解定义、MCP 描述生成、JSON-RPC 路由、会话管理 |
mcp-spring-common |
Spring 感知扫描器、McpProperties、Swagger/SpringDoc 参数解析 |
spring-boot-webmvc-mcp-starter |
Servlet 环境适配、McpServerController(SseEmitter)、自动装配 |
spring-boot-webflux-mcp-starter |
Reactor 环境适配、McpServerController(Flux<ServerSentEvent>)、自动装配 |
WebMVC 项目(Servlet):
<dependency>
<groupId>io.github.spring-boot-mcp</groupId>
<artifactId>spring-boot-webmvc-mcp-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>WebFlux 项目(Reactive):
<dependency>
<groupId>io.github.spring-boot-mcp</groupId>
<artifactId>spring-boot-webflux-mcp-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>plugin:
mcp:
enable: true
stateless: false # 是否支持无状态,默认false不支持无状态,true支持无状态@Component
@McpScan
public class CalculatorTools {
@McpTool(description = "Add two integers and return their sum")
public int add(int a, int b) {
return a + b;
}
@McpTool(name = "multiply", description = "Multiply two numbers")
public double multiply(double x, double y) {
return x * y;
}
@McpResource(uri = "config://{key}", name = "Configuration",
description = "Read an application configuration value by key")
public String getConfig(String key) {
return configData.getOrDefault(key, "<not found>");
}
@McpPrompt(name = "math-tutor", description = "Generate a tutoring prompt")
public String mathTutorPrompt(String topic) {
return "You are a patient math tutor. Explain " + topic + " step by step.";
}
}启动后 /mcp 端点自动就绪,无需额外配置。
plugin:
mcp:
enable: true # 是否启用 MCP Server,默认 false
stateless: false # 是否跳过 Session 校验,默认 false(见下方说明)
server-name: my-service # initialize 握手时返回的服务名,默认 spring-boot-mcp-server
server-version: 1.0.0 # initialize 握手时返回的服务版本,默认 1.0.0
sse-timeout-seconds: 300 # GET /mcp SSE 流的超时时间(秒),0 表示不超时,默认 300| 值 | 行为 |
|---|---|
false(默认) |
规范模式:客户端必须先调用 initialize 获得 MCP-Session-Id,后续所有请求必须携带该 Header;缺失或无效时返回 HTTP 400 |
true |
无状态模式:跳过所有 Session 校验,客户端可直接调用任意 MCP 方法,无需先握手 |
标记一个 Spring Bean 类为 MCP 声明类,Starter 启动时会扫描其中所有带方法级注解的方法。
@Component
@McpScan
public class MyMcpService { ... }将方法注册为 MCP Tool,自动生成 JSON Schema 输入描述。
@McpTool(name = "add", description = "Add two integers")
public int add(int a, int b) {
return a + b;
}| 属性 | 说明 | 默认值 |
|---|---|---|
name |
Tool 名称 | 方法名 |
description |
Tool 描述 | "" |
将方法注册为 MCP Resource,URI 支持路径变量({varName} 语法)。
@McpResource(uri = "config://{key}", name = "Configuration",
description = "Read config by key", mimeType = "text/plain")
public String getConfig(String key) { ... }| 属性 | 说明 | 默认值 |
|---|---|---|
uri |
资源 URI 模板(必填) | — |
name |
资源名称 | 方法名 |
description |
资源描述 | "" |
mimeType |
内容类型 | text/plain |
将方法注册为 MCP Prompt,方法应返回 String 类型的提示词文本。
@McpPrompt(name = "code-review", description = "Generate a code review prompt")
public String codeReviewPrompt(String language, String code) {
return "Review the following " + language + " code:\n" + code;
}| 属性 | 说明 | 默认值 |
|---|---|---|
name |
Prompt 名称 | 方法名 |
description |
Prompt 描述 | "" |
启用后自动注册单一 MCP 端点 POST/GET/DELETE /mcp:
| 方法 | 路径 | 说明 |
|---|---|---|
POST |
/mcp |
客户端发送 JSON-RPC 请求/通知/响应 |
GET |
/mcp |
客户端打开 SSE 流,接收服务端主动推送 |
DELETE |
/mcp |
客户端显式终止 Session |
| 输入类型 | HTTP 状态 | 响应体 |
|---|---|---|
JSON-RPC 请求(有 id) |
200 OK |
application/json,JSON-RPC 响应 |
JSON-RPC 通知(无 id) |
202 Accepted |
空 |
| Session 无效/缺失 | 400 Bad Request |
错误描述(stateless=false 时) |
客户端 服务端
│── POST /mcp initialize ──────▶│ 创建 Session
│◀─ 200 OK MCP-Session-Id: xxx ─│
│
│── POST /mcp tools/list ───────▶│ 校验 Session
│ MCP-Session-Id: xxx │
│◀─ 200 OK { tools: [...] } ─────│
│
│── DELETE /mcp ──────────────────▶│ 销毁 Session
│ MCP-Session-Id: xxx │
│◀─ 200 OK ────────────────────────│
支持 MCP 规范 2025-11-25 定义的全部核心方法:
| 方法 | 说明 |
|---|---|
initialize |
握手,返回服务端能力声明与 Session ID |
initialized(通知) |
客户端确认初始化完成 |
tools/list |
列出所有已注册的 Tool |
tools/call |
调用指定 Tool,返回执行结果 |
resources/list |
列出所有已注册的 Resource |
resources/read |
读取指定 URI 的 Resource 内容 |
prompts/list |
列出所有已注册的 Prompt |
prompts/get |
获取渲染后的 Prompt 内容 |
ping |
心跳检测 |
方法参数的名称和描述按以下优先级自动解析:
@Parameter(description = "...")— SpringDoc / OpenAPI 3.x@ApiParam(value = "...")— Swagger 2.x / Springfox@Schema(description = "...")— OpenAPI 3.x Schema 注解- 反射(兜底) — 需编译时开启
-parameters标志以保留参数名
两种注解库均为可选依赖,运行时动态检测,有则使用,无则兜底。
示例(SpringDoc):
@McpTool(description = "Search products")
public List<Product> search(
@Parameter(description = "Keyword to search") String keyword,
@Parameter(description = "Max results to return") int limit) {
...
}实现 McpScanner.ParamDescriptorResolver 并注册为 Spring Bean,替换默认解析逻辑:
@Bean
public McpScanner.ParamDescriptorResolver myParamResolver() {
return method -> {
// 自定义逻辑:读取注解、文档注释等
return List.of(...);
};
}注册一个 McpServerEngine Bean 可完全替换默认引擎(例如集成自定义鉴权、限流等):
@Bean
public McpServerEngine mcpServerEngine(...) {
return new McpServerEngine(tools, resources, prompts, stateless);
}两个 Starter 均在 McpServerController 上暴露了 pushToSession(sessionId, jsonRpc) 方法,
可通过注入 Controller 向已建立 SSE 连接的客户端主动推送 JSON-RPC 消息:
@Autowired
private McpServerController mcpController;
// 向客户端推送进度通知
mcpController.pushToSession(sessionId,
"{\"jsonrpc\":\"2.0\",\"method\":\"notifications/progress\",\"params\":{...}}");