别只会配 MCP!从 JSON-RPC 到 Streamable HTTP,带你用 Sprin...

166 阅读17分钟

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 的核心三要素

要素英文说明
工具ToolsAI 可调用的函数(如查文章、查数据库)
资源ResourcesAI 可读取的数据(如文件、配置)
提示词PromptsAI 可使用的提示模板

本项目只实现了 Tools,所以配置中 capabilities.tool=true,其余为 false。

MCP 的架构角色

graph LR
    Client[&#34;MCP Client<br/>(AI 应用端)<br/>Claude / Cursor / Trae&#34;] <-- &#34;MCP 协议<br/>JSON-RPC 2.0&#34; --> Server[&#34;MCP Server<br/>(工具服务端)<br/>本项目 jar&#34;]
  • 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 + HTTPstdio
通信方式网络(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 请求这个地址完成连接。

字段速查表

字段适用协议含义
commandstdio启动命令
argsstdio命令参数
envstdio环境变量(可选)
urlHTTP/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[&#34;用户提问&#34;]
    L[&#34;LLM 大模型&#34;]
    C[&#34;MCP Client 连接器&#34;]
    S1[&#34;stdio 模式&#34;]
    S2[&#34;HTTP/SSE 模式&#34;]
    M1[&#34;McpToolConfig 工具注册&#34;]
    M2[&#34;ToolCallbackProvider&#34;]
    M3[&#34;MyMCPService @Tool 方法&#34;]

    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[&#34;用户提问:帮我查 IT空门:门主 的文章&#34;] --> B[&#34;AI 客户端&#34;]
    B -->|&#34;tools/list&#34;| C[&#34;MCP Server&#34;]
    C -->|&#34;返回工具列表&#34;| B
    B -->|&#34;决定调用 getAllArticle&#34;| D[&#34;tools/call&#34;]
    D --> E[&#34;MyMCPService.getAllArticle&#34;]
    E -->|&#34;返回文章列表&#34;| F[&#34;AI 整合回答&#34;]
    F --> G[&#34;最终回答输出&#34;]

第二部分:实战开发


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 注解属性

属性类型说明
nameString工具名称(MCP 协议中的 tools/list 返回的 name)
descriptionString工具描述(最关键,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 的最佳实践

  1. description 要写给 AI 看:用自然语言说明工具做什么、什么时候用、参数含义。
  2. 参数名要有语义:author 比 a 好,AI 能更好理解。
  3. 返回值要可序列化: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.namemcp_it_kmServer 标识,客户端连接后可见
spring.ai.mcp.server.version1.0.0协议版本
spring.ai.mcp.server.protocolSTREAMABLE2.0 的流式 HTTP 协议
spring.ai.mcp.server.typeASYNC异步模式
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 包的环境要求

项要求
JDK17 及以上(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 包的环境

  1. JDK 17 必须已安装并在系统 PATH 中,否则 java 命令找不到。
  2. 验证方式:
    java -version
    # 应输出 openjdk version "17.x.x" 或更高
    
  3. jar 包路径必须是绝对路径,避免相对路径在不同工作目录下失效。
  4. AI 客户端(如 Claude Desktop、Cursor、Trae)会把这段配置放在其 MCP 配置文件中:
    • Claude Desktop:claude_desktop_config.json
    • Cursor:.cursor/mcp.json
    • Trae:.trae/mcp.json

工作原理

AI 客户端读取 JSON 配置
   │
   ├─ 执行: java -jar xxx.jar   (启动子进程)
   │
   ├─ 通过 stdin 写入: {"method":"tools/list"}
   │
   └─ 从 stdout 读取: {"result":[...工具列表]}

实现的图片: 微信图片_20260818142634_60_107.png 微信图片_20260818142646_61_107.png 微信图片_20260818142659_62_107.png


第四部分:版本演进


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-serverstdio❌本地子进程
spring-ai-starter-mcp-server-webmvcSSE + 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.0Spring AI 2.0
传输协议SSE + HTTPStreamable HTTP
协议配置项spring.ai.mcp.server.type=syncspring.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
客户端 urlhttp://localhost:8095/ssehttp://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

为什么升级?

  1. 更简单:一个端点替代两个,配置和调试都更轻松。
  2. 更高效:Streamable HTTP 支持流式,减少连接开销。
  3. 更标准:对齐 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/messagehttp://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部署、微服务架构、线上问题排查
  • ✅ 偶尔聊聊「如何保住头发」这类程序员终极话题 😂

不搞水文,不贩卖焦虑,只写能跑通、能落地、能帮你少加班的实战内容。

关注我,咱们一起少踩坑,多写优雅代码。


📖 更多干货推荐


🤝 项目合作 / 技术咨询

平时工作之余,也会接一些技术项目和咨询,主要方向:

⚔️ 企业级开发

  • Java / Spring Boot 项目开发与重构
  • 微服务架构设计与落地
  • 系统性能调优、线上问题排查

🤖 AI 应用落地(这是我最近的主力方向)

  • Spring AI Alibaba / RAG / Agent 应用开发
  • 企业私有知识库搭建
  • AI能力接入现有业务系统
  • 大模型本地化部署与调优

🛠️ 技术顾问 / 疑难Bug排查

  • 项目架构评审与方案设计
  • 线上疑难问题定位解决
  • 技术选型与团队培训

如果你正遇到以下情况,欢迎找我聊聊:

  • ✅ 想做AI项目,但技术方案拿不准
  • ✅ 项目卡在某个Bug上很久,团队搞不定
  • ✅ 想把AI接入现有业务,不知道从哪下手
  • ✅ 需要靠谱的开发外包或长期技术顾问

📮 联系渠道(按回复速度排序):

  1. 最快:私信空门技术栈

一个人踩坑,是事故;一群人踩坑,就是《避坑宝典》。

—— IT 空门,与诸君共修技术大道 😎