MCP 的简单运用:从协议原理到 Spring AI 实战
本文以一个真实可运行的
mcp_demo项目为蓝本,带你从 0 到 1 理解 MCP(Model Context Protocol)是什么、怎么通信、怎么用 Spring AI 实现一个 MCP Server,并对比 Spring AI 1.0 与 2.0 的配置差异。
1. MCP 是什么
MCP(Model Context Protocol,模型上下文协议) 是由 Anthropic 在 2024 年底开源发布的一套开放标准协议,目标是让 AI 应用(如 Claude Desktop、Cursor、Trae 等)以统一的标准方式连接到外部数据源、工具和服务。
一个通俗的比喻
把 MCP 理解成 AI 世界的 USB 接口:
- 在 USB 出现之前,鼠标、键盘、U 盘各有各的接口,每接一个设备就要装一个驱动。
- USB 统一了接口标准,任何设备只要遵循 USB 协议,插上就能用。
- MCP 之于 AI 也是如此:任何工具/服务只要实现 MCP 协议,AI 客户端就能直接调用,无需为每个工具单独写适配代码。
MCP 的核心三要素
| 要素 | 英文 | 说明 |
|---|---|---|
| 工具 | Tools | AI 可调用的函数(如查文章、查数据库) |
| 资源 | Resources | AI 可读取的数据(如文件、配置) |
| 提示词 | Prompts | AI 可使用的提示模板 |
本项目只实现了 Tools,所以配置中 capabilities.tool=true,其余为 false。
MCP 的架构角色
graph LR
Client["MCP Client<br/>(AI 应用端)<br/>Claude / Cursor / Trae"] <-- "MCP 协议<br/>JSON-RPC 2.0" --> Server["MCP Server<br/>(工具服务端)<br/>本项目 jar"]
- MCP Host / Client:发起请求的一方,例如 Claude Desktop、Cursor、Trae。
- MCP Server:提供服务的一方,例如本项目打包出来的
mcp_demo-0.0.1-SNAPSHOT.jar。
2. MCP 的两种传输协议
MCP 底层使用 JSON-RPC 2.0 进行消息通信,但在「消息怎么传输」这一层,MCP 定义了两种传输方式:
第一种:SSE + HTTP 协议(网络传输)
用于 远程/网络 场景,MCP Server 部署成 Web 服务,通过网络访问。
- SSE(Server-Sent Events):服务端单向推送消息给客户端。
- HTTP POST:客户端向服务端发送请求。
- 适合:MCP Server 部署在远程服务器、容器、云上。
Spring AI 1.0 时代主要使用这种模式(spring-ai-starter-mcp-server-webmvc)。
⚠️ 注意:用户原始需求中写的 "sydio" 是 stdio(标准输入输出)的笔误,下文第二点即 stdio 协议。
第二种:stdio 协议(标准输入输出)
用于 本地进程 场景,AI 客户端直接启动 MCP Server 进程,通过标准输入/输出通信。
- stdin(标准输入):客户端把 JSON-RPC 请求写到 Server 进程的输入流。
- stdout(标准输出):Server 把响应写到输出流,客户端读取。
- 适合:MCP Server 是一个本地命令行程序(如
java -jar xxx.jar)。
Spring AI 中使用 spring-ai-starter-mcp-server(不含 webmvc 后缀)即对应 stdio 模式。
两种协议对比
| 对比项 | SSE + HTTP | stdio |
|---|---|---|
| 通信方式 | 网络(HTTP + SSE) | 进程标准输入输出 |
| 部署形态 | Web 服务(远程) | 本地可执行程序 |
| 客户端配置 | 配 url | 配 command + args |
| 典型场景 | 远程部署、容器化 | 本地开发、Claude Desktop |
| Spring AI 依赖 | ...-server-webmvc | ...-server |
💡 Spring AI 2.0 引入了更先进的 Streamable HTTP 协议(可流式 HTTP),是 SSE+HTTP 的升级版,下文第 12 节详述。
3. MCP 的 JSON 连接格式
AI 客户端(如 Claude Desktop、Cursor、Trae)通过一个 JSON 配置文件 来描述如何连接 MCP Server。
通用结构
{
"mcpServers": {
"服务名称": {
"连接方式": "..."
}
}
}
stdio 方式的 JSON 格式
{
"mcpServers": {
"mcp-demo": {
"command": "java",
"args": [
"-jar",
"D:\\project\\learn\\learn\\mcp_demo\\target\\mcp_demo-0.0.1-SNAPSHOT.jar"
]
}
}
}
command:启动 MCP Server 的可执行命令(这里是java)。args:传给命令的参数数组(这里是-jar+ jar 包绝对路径)。- AI 客户端会以子进程方式拉起这个命令,通过 stdin/stdout 通信。
HTTP/SSE 方式的 JSON 格式
{
"mcpServers": {
"mcp_it_km": {
"url": "http://localhost:8095/mcp"
}
}
}
url:MCP Server 暴露的 HTTP 端点地址。- AI 客户端通过 HTTP 请求这个地址完成连接。
字段速查表
| 字段 | 适用协议 | 含义 |
|---|---|---|
command | stdio | 启动命令 |
args | stdio | 命令参数 |
env | stdio | 环境变量(可选) |
url | HTTP/SSE | 服务端点地址 |
4. MCP 通信原理与架构图解
4.1 通信流程时序图
MCP 通信分为四个阶段:初始化握手 → 工具发现 → 工具调用 → AI 整合回答。
sequenceDiagram
participant C as AI 客户端
participant S as MCP Server
rect rgb(230, 245, 255)
Note over C,S: 阶段一:初始化握手
C->>S: initialize(协议版本、能力)
S-->>C: 返回 Server 能力
C->>S: initialized 确认
end
rect rgb(230, 255, 240)
Note over C,S: 阶段二:工具发现
C->>S: tools/list
S-->>C: 返回 @Tool 方法列表
end
rect rgb(255, 245, 230)
Note over C,S: 阶段三:工具调用
C->>S: tools/call(name, arguments)
S->>S: 执行 @Tool 方法
S-->>C: 返回结果 JSON
end
rect rgb(245, 230, 255)
Note over C,S: 阶段四:AI 整合回答
C->>C: 结合工具结果 + 用户问题
C->>C: 生成最终回答
end
四个阶段说明:
| 阶段 | 请求方法 | 说明 |
|---|---|---|
| 初始化握手 | initialize → initialized | 协商协议版本、交换能力信息 |
| 工具发现 | tools/list | 客户端获取 Server 提供的所有工具定义 |
| 工具调用 | tools/call | 客户端调用指定工具,Server 执行并返回结果 |
| AI 整合 | — | AI 结合工具结果与用户问题,生成最终回答 |
4.2 整体架构结构图
下图展示了 MCP 通信的完整架构,包含两种传输方式(stdio 和 HTTP/SSE)以及服务端内部组件。
graph TB
U["用户提问"]
L["LLM 大模型"]
C["MCP Client 连接器"]
S1["stdio 模式"]
S2["HTTP/SSE 模式"]
M1["McpToolConfig 工具注册"]
M2["ToolCallbackProvider"]
M3["MyMCPService @Tool 方法"]
U --> L
L --> C
C --> S1
C --> S2
S1 --> M1
S2 --> M1
M1 --> M2
M2 --> M3
架构组件说明:
| 组件 | 职责 |
|---|---|
| AI 客户端 | 发起用户提问,调用 MCP 工具 |
| MCP Client 连接器 | 负责协议编解码、消息收发 |
| McpToolConfig | 注册工具提供者到 Spring 容器 |
| ToolCallbackProvider | 收集 @Tool 方法,暴露给 MCP 协议层 |
| MyMCPService | 实际的业务逻辑实现 |
4.3 MCP 通信体系思维导图
mindmap
root((MCP 通信体系))
传输协议
stdio 本地进程
command + args
stdin/stdout
适合本地开发
SSE + HTTP 网络
url 端点
HTTP POST + SSE
适合远程部署
Streamable HTTP 2.0
单端点流式
Spring AI 2.0 推荐
通信消息 JSON-RPC 2.0
initialize 初始化
tools/list 工具发现
tools/call 工具调用
核心三要素
Tools 工具 ✅ 已实现
Resources 资源 ❌ 未实现
Prompts 提示词 ❌ 未实现
Spring AI 实现
starter-mcp-server-webmvc
@Tool 注解定义工具
ToolCallbackProvider 注册
application.properties 配置
4.4 一次完整调用的数据流
graph TD
A["用户提问:帮我查 IT空门:门主 的文章"] --> B["AI 客户端"]
B -->|"tools/list"| C["MCP Server"]
C -->|"返回工具列表"| B
B -->|"决定调用 getAllArticle"| D["tools/call"]
D --> E["MyMCPService.getAllArticle"]
E -->|"返回文章列表"| F["AI 整合回答"]
F --> G["最终回答输出"]
第二部分:实战开发
5. 用 Spring AI 实现 MCP Server
本项目实现了一个「查询 IT空门:门主 文章」的 MCP Server,整体只需 4 个文件。
5.1 项目结构
src/main/java/com/mcp_demo/test/
├── McpDemoApplication.java # 启动类
└── mcp/
├── MyArticle.java # 文章实体
├── MyMCPService.java # 工具实现(@Tool)
└── McpToolConfig.java # 工具注册(ToolCallbackProvider)
5.2 启动类
package com.mcp_demo.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class McpDemoApplication {
public static void main(String[] args) {
SpringApplication.run(McpDemoApplication.class, args);
}
}
5.3 文章实体 MyArticle
package com.mcp_demo.test.mcp;
public class MyArticle {
private String author; // 作者
private String title; // 标题
private String content; // 内容
private String link; // 链接
public MyArticle() {}
public MyArticle(String author, String title, String content, String link) {
this.author = author;
this.title = title;
this.content = content;
this.link = link;
}
// Getter / Setter 省略...
}
5.4 工具实现 MyMCPService(核心)
package com.mcp_demo.test.mcp;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class MyMCPService {
private static final Logger logger = LoggerFactory.getLogger(MyMCPService.class);
@Tool(description = "这是一个文章获取工具,通过作者名称可以获取文章", name = "getAllArticle")
public List<MyArticle> getAllArticle(String author) {
logger.info("MCP调用 getAllArticle 方法,参数 author: {}", author);
return myArticleData();
}
@Tool(description = "这是一个文章获取工具,通过作者名称和文章标题可以获取文章", name = "getArticleByTitle")
public MyArticle getArticleByTitle(String author, String title) {
logger.info("MCP调用 getArticleByTitle 方法,参数 author: {}, title: {}", author, title);
return myArticleData().stream()
.filter(article -> article.getAuthor().equals(author)
&& article.getTitle().equals(title))
.findFirst()
.orElse(null);
}
public List<MyArticle> myArticleData() {
List<MyArticle> articleList = new ArrayList<>();
articleList.add(new MyArticle(
"IT空门:门主",
"告别手动复制接口文档!Apifox MCP + AI 自动测试让开发效率起飞",
"告别手动复制接口文档!Apifox MCP + AI 自动测试让开发效率起飞",
"https://mp.weixin.qq.com/s/QC1f1q7nob1S7NPvrW4Evg"));
// ... 其余文章数据
return articleList;
}
}
5.5 工具注册 McpToolConfig
package com.mcp_demo.test.mcp;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class McpToolConfig {
@Bean
public ToolCallbackProvider articleToolCallbackProvider(MyMCPService articleService) {
return MethodToolCallbackProvider.builder()
.toolObjects(articleService)
.build();
}
}
5.6 Maven 依赖(pom.xml 关键部分)
<properties>
<java.version>17</java.version>
<spring-ai.version>2.0.0</spring-ai.version>
</properties>
<dependencies>
<!-- SSE WebMVC 模式:自动配置 SSE 端点,内含 spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</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>
💡 注意:Bean 方法名命名为
articleToolCallbackProvider而非myMCPService,是为了避免与@Service注解产生的同名 Bean 冲突(详见第 6.4 节避坑说明)。
6. ToolCallbackProvider 详解
6.1 作用
ToolCallbackProvider 是 Spring AI 提供的工具回调提供者接口,职责是:
把你用
@Tool注解标记的普通 Java 方法,收集、包装、注册成 MCP 协议能识别的工具,暴露给 AI 客户端调用。
6.2 在通信链路中的位置
MyMCPService (@Tool 方法)
│
│ 被 ToolCallbackProvider 收集
▼
ToolCallbackProvider (Bean)
│
│ Spring AI 自动装配到 MCP Server
▼
MCP Server 暴露 tools/list、tools/call 端点
│
▼
AI 客户端通过 JSON-RPC 调用工具
6.3 实现方式
本项目使用 MethodToolCallbackProvider(基于方法的提供者):
@Bean
public ToolCallbackProvider articleToolCallbackProvider(MyMCPService articleService) {
return MethodToolCallbackProvider.builder()
.toolObjects(articleService) // 传入含 @Tool 方法的服务对象
.build();
}
toolObjects(...):可传入多个服务对象,会扫描其中所有@Tool方法。- 构建出的
ToolCallbackProvider被 Spring AI 自动装配,转换成 MCP 协议的工具描述。
6.4 命名约定
按项目工程规范,Bean 方法名应遵循 [功能]ToolCallbackProvider 的命名:
articleToolCallbackProvider—— 文章工具weatherToolCallbackProvider—— 天气工具
⚠️ 避坑:Bean 名冲突
之前曾踩坑:@Bean 方法名与 @Service 的 Bean 名相同(都叫 myMCPService),导致启动报错:
Bean 'myMCPService' could not be registered.
Bean already exists...
解决方案:把 @Bean 方法改名为 articleToolCallbackProvider,而不是开启 spring.main.allow-bean-definition-overriding=true(该配置会引入 Bean 覆盖隐患)。
7. @Tool 注解详解
7.1 作用
@Tool 是 Spring AI 的核心注解,标记在方法上,表示这个方法是一个可被 AI 调用的工具。
7.2 注解属性
| 属性 | 类型 | 说明 |
|---|---|---|
name | String | 工具名称(MCP 协议中的 tools/list 返回的 name) |
description | String | 工具描述(最关键,AI 根据它决定何时调用) |
7.3 示例解读
@Tool(
description = "这是一个文章获取工具,通过作者名称可以获取文章",
name = "getAllArticle"
)
public List<MyArticle> getAllArticle(String author) { ... }
name = "getAllArticle":AI 客户端在tools/call时传的name就是它。description:AI 大模型靠这段文字判断该不该用这个工具,写得越清晰,AI 调用越准确。- 方法参数
author:会自动转换成 JSON Schema,AI 根据参数名和类型生成参数。
7.4 工具发现的过程
1. AI 客户端发起 tools/list 请求
2. Spring AI 通过 ToolCallbackProvider 收集所有 @Tool 方法
3. 把方法名、描述、参数签名转成 JSON Schema 返回:
{
"name": "getAllArticle",
"description": "这是一个文章获取工具...",
"inputSchema": {
"type": "object",
"properties": { "author": { "type": "string" } },
"required": ["author"]
}
}
4. AI 大模型结合用户问题,决定是否调用、传什么参数
7.5 编写 @Tool 的最佳实践
- description 要写给 AI 看:用自然语言说明工具做什么、什么时候用、参数含义。
- 参数名要有语义:
author比a好,AI 能更好理解。 - 返回值要可序列化:POJO、List、Map 都可以,Spring AI 会自动转 JSON。
8. application.properties 配置详解
本项目对应 Spring AI 2.0 版本的配置(application.properties):
# ==============================
# 基础配置
# ==============================
spring.application.name=mcp_demo
server.port=8095
# ==============================
# MCP Server
# ==============================
# MCP Server 名称
spring.ai.mcp.server.name=mcp_it_km
# MCP Server 版本
spring.ai.mcp.server.version=1.0.0
# ⭐ 使用 Streamable HTTP(2.0 新协议)
spring.ai.mcp.server.protocol=STREAMABLE
# 同步 / 异步
spring.ai.mcp.server.type=ASYNC
# 给 AI Client 的说明
spring.ai.mcp.server.instructions=这个是查询IT空门:门主发布文章作品的一个服务
# ==============================
# MCP 能力(必须与实现一致)
# ==============================
spring.ai.mcp.server.capabilities.tool=true # 已实现 @Tool
spring.ai.mcp.server.capabilities.resource=false # 未实现 ResourceProvider
spring.ai.mcp.server.capabilities.prompt=false # 未实现 PromptProvider
spring.ai.mcp.server.capabilities.completion=false # 未实现
# ==============================
# Streamable HTTP
# ==============================
spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp
# ==============================
# 日志
# ==============================
logging.level.org.springframework.ai.mcp=DEBUG
logging.level.io.modelcontextprotocol=DEBUG
配置项说明
| 配置项 | 值 | 说明 |
|---|---|---|
spring.ai.mcp.server.name | mcp_it_km | Server 标识,客户端连接后可见 |
spring.ai.mcp.server.version | 1.0.0 | 协议版本 |
spring.ai.mcp.server.protocol | STREAMABLE | 2.0 的流式 HTTP 协议 |
spring.ai.mcp.server.type | ASYNC | 异步模式 |
spring.ai.mcp.server.instructions | 查询文章服务 | 告诉 AI 这个 Server 干什么 |
capabilities.* | tool=true | 只开启工具能力 |
streamable-http.mcp-endpoint | /mcp | 暴露的 HTTP 端点路径 |
⚠️ 关键约束
capabilities必须与实际实现一致:没实现ResourceProvider就不能开resource=true,否则会误导客户端。- ASYNC 模式需要显式配置端点:在 1.0 中需要配
sse-endpoint和message-endpoint(2.0 的 STREAMABLE 模式则用mcp-endpoint)。
第三部分:部署与运行
9. 打包与运行 jar
9.1 Maven 打包
项目已配置 spring-boot-maven-plugin,执行:
mvn clean package -DskipTests
打包成功后,jar 包位于:
D:\project\learn\learn\mcp_demo\target\mcp_demo-0.0.1-SNAPSHOT.jar
本项目
target/目录下已经存在mcp_demo-0.0.1-SNAPSHOT.jar,可直接使用。
9.2 运行 jar 包的环境要求
| 项 | 要求 |
|---|---|
| JDK | 17 及以上(pom.xml 中 java.version=17) |
| 操作系统 | Windows / macOS / Linux 均可 |
| 内存 | 建议 512MB+ |
9.3 本地运行验证
java -jar D:\project\learn\learn\mcp_demo\target\mcp_demo-0.0.1-SNAPSHOT.jar
启动后看到 Started McpDemoApplication 即表示 MCP Server 已就绪,监听 8095 端口。
9.4 Docker 部署(可选)
项目提供了 Dockerfile 和 docker-compose.yml:
cd docker
docker-compose up -d --build
多阶段构建:第一阶段用 maven:3.9-eclipse-temurin-17 编译,第二阶段用 eclipse-temurin:17-jre 运行,镜像更小。
10. MCP JSON 配置(stdio 方式)
当 MCP Server 打成 jar 后,若使用 stdio 协议(本地子进程方式),AI 客户端的 JSON 配置如下:
{
"mcpServers": {
"mcp-demo": {
"command": "java",
"args": [
"-jar",
"D:\\project\\learn\\learn\\mcp_demo\\target\\mcp_demo-0.0.1-SNAPSHOT.jar"
]
}
}
}
配置说明
mcp-demo:自定义的服务名称(AI 客户端内部标识)。command: "java":使用系统java命令启动。args:-jar+ jar 包绝对路径(Windows 路径用\\转义反斜杠,或用/)。
⚠️ 运行 jar 包的环境
- JDK 17 必须已安装并在系统
PATH中,否则java命令找不到。 - 验证方式:
java -version # 应输出 openjdk version "17.x.x" 或更高 - jar 包路径必须是绝对路径,避免相对路径在不同工作目录下失效。
- AI 客户端(如 Claude Desktop、Cursor、Trae)会把这段配置放在其 MCP 配置文件中:
- Claude Desktop:
claude_desktop_config.json - Cursor:
.cursor/mcp.json - Trae:
.trae/mcp.json
- Claude Desktop:
工作原理
AI 客户端读取 JSON 配置
│
├─ 执行: java -jar xxx.jar (启动子进程)
│
├─ 通过 stdin 写入: {"method":"tools/list"}
│
└─ 从 stdout 读取: {"result":[...工具列表]}
实现的图片:

第四部分:版本演进
11. Spring AI 1.0 部署与访问
问题背景
在 Spring AI 1.0 时代,默认的依赖是:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
这个依赖是 stdio 模式,MCP Server 只能以子进程方式被调用,没有暴露 HTTP 端点。
部署后需要请求地址怎么办?
如果 MCP Server 部署到服务器上(远程访问),就需要把它变成 Web 服务,需要换成 WebMVC 依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
1.0 的 application 配置(参见 application-1.0.properties)
# 传输模式: SYNC(同步 HTTP+SSE,基于 WebMVC)/ ASYNC(异步,基于 WebFlux)
spring.ai.mcp.server.type=sync
# ASYNC 模式必需配置 SSE 端点
spring.ai.mcp.server.sse-endpoint=/sse
spring.ai.mcp.server.message-endpoint=/mcp/message
1.0 的访问方式
换成 webmvc 依赖后,MCP Server 会暴露:
- SSE 端点:
http://localhost:8095/sse(服务端推送消息) - 消息端点:
http://localhost:8095/mcp/message(客户端 POST 请求)
1.0 的客户端 JSON 配置
{
"mcpServers": {
"mcp_it_km": {
"url": "http://localhost:8095/sse"
}
}
}
依赖对比
| 依赖 | 通信方式 | 是否暴露 HTTP | 适用场景 |
|---|---|---|---|
spring-ai-starter-mcp-server | stdio | ❌ | 本地子进程 |
spring-ai-starter-mcp-server-webmvc | SSE + HTTP | ✅ | 远程网络访问 |
结论:1.0 想要远程访问,必须从
server换成server-webmvc。
12. Spring AI 2.0 新特性
2.0 的依赖选择
在 Spring AI 2.0 中,继续使用(推荐使用):
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
注意:本项目 pom.xml 用的就是 2.0.0 版本 +
webmvc依赖,但协议换成了 Streamable HTTP。
2.0 的核心变化:Streamable HTTP
Spring AI 2.0 引入了 Streamable HTTP 传输协议,它是 SSE+HTTP 的升级版:
- 单一端点:不再需要分开的
/sse和/mcp/message,统一用一个/mcp端点。 - 流式支持:支持流式响应,更高效。
- 配置更简洁:只需一个
mcp-endpoint。
2.0 的配置
# ⭐ 使用 Streamable HTTP
spring.ai.mcp.server.protocol=STREAMABLE
# Streamable HTTP 端点
spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp
2.0 的访问方式
MCP Server 只暴露一个端点:
- 统一端点:
http://localhost:8095/mcp
2.0 的客户端 JSON 配置
{
"mcpServers": {
"mcp_it_km": {
"url": "http://localhost:8095/mcp"
}
}
}
不再需要
/sse路径,直接访问/mcp即可。
13. 1.0 vs 2.0 配置对比
配置对比总表
| 维度 | Spring AI 1.0 | Spring AI 2.0 |
|---|---|---|
| 传输协议 | SSE + HTTP | Streamable HTTP |
| 协议配置项 | spring.ai.mcp.server.type=sync | spring.ai.mcp.server.type=async + spring.ai.mcp.server.protocol=STREAMABLE |
| SSE 端点 | spring.ai.mcp.server.sse-endpoint=/sse | ❌ 已废弃 |
| 消息端点 | spring.ai.mcp.server.message-endpoint=/mcp/message | ❌ 已废弃 |
| 统一端点 | ❌ 无 | ✅ spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp |
| 客户端 url | http://localhost:8095/sse | http://localhost:8095/mcp |
❌ 2.0 放弃(废弃)的配置
# 以下配置在 2.0 中已废弃,不再需要:
# 1.0 的 SSE 双端点(被统一 mcp-endpoint 替代)
spring.ai.mcp.server.sse-endpoint=/sse # ❌ 废弃
spring.ai.mcp.server.message-endpoint=/mcp/message # ❌ 废弃
⚠️ 注意:
spring.ai.mcp.server.type并未废弃。在 1.0 中值为sync,在 2.0 中改为async(配合protocol=STREAMABLE使用),仍然需要保留。
✅ 2.0 新增的配置
# 1. 协议类型(新增)
spring.ai.mcp.server.protocol=STREAMABLE
# 2. Streamable HTTP 统一端点(新增,替代 sse-endpoint + message-endpoint)
spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp
🔄 2.0 调整的配置
# type 值从 sync 改为 async(配置项本身保留,值变了)
spring.ai.mcp.server.type=async # 1.0 是 sync,2.0 改为 async
保留不变的配置
以下配置在 1.0 和 2.0 中保持一致:
spring.application.name=mcp_demo
server.port=8095
spring.ai.mcp.server.name=mcp_it_km
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.instructions=这个是查询IT空门:门主发布文章作品的一个服务
spring.ai.mcp.server.capabilities.tool=true
spring.ai.mcp.server.capabilities.resource=false
spring.ai.mcp.server.capabilities.prompt=false
spring.ai.mcp.server.capabilities.completion=false
logging.level.org.springframework.ai.mcp=DEBUG
logging.level.io.modelcontextprotocol=DEBUG
配置演进示意图
Spring AI 1.0(SSE + HTTP)
├── sse-endpoint=/sse ──┐
│ ├──→ 两个端点,客户端连 /sse
└── message-endpoint=/mcp/message ─┘
▼ 升级
Spring AI 2.0(Streamable HTTP)
├── protocol=STREAMABLE ──→ 声明协议
└── streamable-http.mcp-endpoint=/mcp ──→ 一个端点搞定,客户端连 /mcp
为什么升级?
- 更简单:一个端点替代两个,配置和调试都更轻松。
- 更高效:Streamable HTTP 支持流式,减少连接开销。
- 更标准:对齐 MCP 官方最新的 Streamable HTTP 规范。
14. 2.0 默认端点 /mcp
默认端点
在 Spring AI 2.0 中,spring.ai.mcp.server.streamable-http.mcp-endpoint 的默认值就是 /mcp。
也就是说,即使你不显式配置这一行:
# 这行可以省略,因为默认就是 /mcp
spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp
MCP Server 依然会在 http://localhost:8095/mcp 暴露服务。
客户端 JSON 配置
因此,Spring AI 2.0 部署后,AI 客户端的连接配置非常简洁:
{
"mcpServers": {
"mcp_it_km": {
"url": "http://localhost:8095/mcp"
}
}
}
完整访问流程
1. 打包:mvn clean package -DskipTests
2. 启动:java -jar target/mcp_demo-0.0.1-SNAPSHOT.jar
3. 验证:浏览器访问 http://localhost:8095/mcp (返回 MCP 响应)
4. 客户端配置:url 指向 http://localhost:8095/mcp
5. AI 客户端即可调用 getAllArticle、getArticleByTitle 工具
端点路径对比
| 版本 | 端点路径 | 客户端 url |
|---|---|---|
| 1.0 (SSE) | /sse + /mcp/message | http://localhost:8095/sse |
| 2.0 (Streamable) | /mcp(默认) | http://localhost:8095/mcp |
💡 2.0 的
/mcp默认值让配置更简洁,大多数场景无需额外配置端点路径。
👇 三连支持,动力源泉
如果这篇文章帮你省下了踩坑的时间,欢迎:
🔹 点赞 —— 让更多人看到这篇干货 🔹 在看 —— 你的认可是我持续输出的动力 🔹 转发 —— 分享给身边正在做AI Agent的朋友
你的每一个小动作,对我都很重要 ❤️
🙏 关于作者
你好,我是 空门技术栈,一个常年和Bug战斗、持续填坑的Java开发者。
专注分享:
- ✅ Java / Spring Boot / Spring AI Alibaba 企业级实战
- ✅ RAG知识库、AI Agent、多智能体协作落地经验
- ✅ Docker部署、微服务架构、线上问题排查
- ✅ 偶尔聊聊「如何保住头发」这类程序员终极话题 😂
不搞水文,不贩卖焦虑,只写能跑通、能落地、能帮你少加班的实战内容。
关注我,咱们一起少踩坑,多写优雅代码。
📖 更多干货推荐
- 告别手动复制接口文档!Apifox MCP + AI 自动测试让开发效率起飞
- MySQL MCP Server 从零安装到使用实战,AI 直接查询数据库
- Spring Event 用了三年,同事一句话把我问懵了
- Spring AI Alibaba 多智能体(Multi-agent)实战:6 大协作模式 + 完整代码
- Spring AI Alibaba 智能体作为工具实战:别再让主 Agent 当"人肉路由器"了
- 一文搞懂 Spring AI Alibaba Workflow:10 个实战案例带你彻底掌握 AI 工作流编排
- RAG 知识库为什么越更新越乱?一文讲透生产级文档更新方案
- Transformers VS vLLM:大模型部署到底该选谁?从本地运行到生产上线完整解析
- LangChain Agent终于讲透了:短期记忆、Redis持久化、Middleware企业级实战,一篇带你从入门到生产
- LangChain 流式输出终于讲透了:6 种 stream_mode 一篇全搞懂
- Spring AI 流式对话踩坑:SSE 已关闭,为什么大模型还在继续生成?
- LangChain 结构化输出终于讲透了:ProviderStrategy、ToolStrategy、动态 Schema 一篇全会
- Spring WebFlux 真的比 MVC 快?我用 5 万长连接测出了真相
🤝 项目合作 / 技术咨询
平时工作之余,也会接一些技术项目和咨询,主要方向:
⚔️ 企业级开发
- Java / Spring Boot 项目开发与重构
- 微服务架构设计与落地
- 系统性能调优、线上问题排查
🤖 AI 应用落地(这是我最近的主力方向)
- Spring AI Alibaba / RAG / Agent 应用开发
- 企业私有知识库搭建
- AI能力接入现有业务系统
- 大模型本地化部署与调优
🛠️ 技术顾问 / 疑难Bug排查
- 项目架构评审与方案设计
- 线上疑难问题定位解决
- 技术选型与团队培训
如果你正遇到以下情况,欢迎找我聊聊:
- ✅ 想做AI项目,但技术方案拿不准
- ✅ 项目卡在某个Bug上很久,团队搞不定
- ✅ 想把AI接入现有业务,不知道从哪下手
- ✅ 需要靠谱的开发外包或长期技术顾问
📮 联系渠道(按回复速度排序):
- 最快:私信空门技术栈
一个人踩坑,是事故;一群人踩坑,就是《避坑宝典》。
—— IT 空门,与诸君共修技术大道 😎