Spring AI 番外篇01:MCP Streamable HTTP 模式

本文较长,建议点赞收藏。更多AI大模型应用开发学习视频及资料,在智泊AI

Spring AI 从 1.1.0-M1(里程碑版本) 开始正式支持 MCP 的 Streamable HTTP 模式。该版本解决了此前 1.0.x 版本仅支持 SSE 协议的局限,新增断线重连、会话恢复等核心能力,同时提供 WebFlux/WebMVC 两种编程模型的 Starter 支持。

为什么 MCP 规范要转向 Streamable HTTP 模式?

1. 解决连接不可恢复问题

  • HTTP + SSE 缺陷:SSE(服务器发送事件)连接一旦中断,客户端无法从中断点恢复,只能重新建立连接,导致上下文丢失和用户体验下降
  • Streamable HTTP 改进:支持会话状态管理,允许客户端在断线后重新连接并恢复之前的会话,保障了通信的连续性

2. 降低服务器资源压力

  • HTTP + SSE 缺陷:每个客户端都需要维持一个长期的 SSE 长连接,高并发场景下导致 TCP 连接数激增,服务器资源消耗巨大,且难以横向扩展
  • Streamable HTTP 改进:采用按需流式传输,无需为每个客户端维持长连接,连接可复用,显著降低了服务器的负载和资源占用

3. 简化架构与提升兼容性

  • HTTP + SSE 缺陷:需要维护 /sse 专用端点,增加了系统复杂性,且部分网络基础设施(如防火墙)可能干扰长期 SSE 连接
  • Streamable HTTP 改进:移除了专用端点,所有通信整合到统一端点(如 /message),架构更简洁,并且能更好地兼容现有网络基础设施

4. 支持更灵活的通信模式

  • Streamable HTTP 允许服务器在需要时将响应升级为 SSE 流,实现流式传输,同时保留标准 HTTP 通信能力,满足了"既是传统 API 又能流式推送"的混合需求

Streamable HTTP 在保留 SSE 流式传输优势的同时,解决了连接恢复、资源消耗、架构复杂和兼容性等关键问题,为企业级 AI 应用提供了更稳定、高效、易维护的通信基础,因此成为 MCP 规范的默认传输方式。

MCP Server 实战

父项目中引入spring-ai 1.1.0-M3依赖

首先在 extra01 父项目中引入 spring-ai 1.1.0-M3 版本.

xml 复制代码
<!-- extra01/pom.xml -->  
    <dependencyManagement>  
        <dependencies>  
            <dependency>  
                <groupId>org.springframework.ai</groupId>  
                <artifactId>spring-ai-bom</artifactId>  
                <version>1.1.0-M3</version>  
                <type>pom</type>  
                <scope>import</scope>  
            </dependency>  
        </dependencies>  
    </dependencyManagement>

extra-mcp-server 项目中引入依赖

xml 复制代码
<!-- extra01/extra-mcp-server/pom.xml -->  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
</dependency>  
<dependency>  
    <groupId>org.springframework.ai</groupId>  
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>  
</dependency>

编写Service类

这里只是简单模拟 通过城市名字获取温度的Service

less 复制代码
// extra01/extra-mcp-server/src/main/java/com/kaifamiao/extra01/service/WeatherService.java  
@Service  
public class WeatherService {  
    @Tool(description = "通过城市名字获取温度")  
    public String getWeatherByCity(@ToolParam(description = "城市名称") String cityName) {  
        return cityName + "今天的温度是" + (new java.util.Random().nextInt(9) + 1) * 6;  
    }  
}

注册工具

less 复制代码
// extra01/extra-mcp-server/src/main/java/com/kaifamiao/extra01/comfiguration/McpServerConfig.java  
@Configuration  
public class McpServerConfig {  
    @Bean  
    @Primary // 添加此注解指定优先使用此Bean  
    public ToolCallbackProvider toolProvider(WeatherService weatherService) {  
        // 注册工具类实例  
        return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();  
    }  
}

mcp Server yml配置

yaml 复制代码
# extra01/extra-mcp-server/src/main/resources/application.yml  
spring:  
  ai:  
    mcp:  
      server:  
        name: streamable-weather-server  
        version: 0.0.1  
        protocol: streamable  
        type: sync  
        streamable-http:  
          mcp-endpoint: /mcp  
          keep-alive-interval: 30s  
server:  
  port: 8081

在IDEA 工具中输入 protocol 的时候,发现已经可以支持 streamable 了,Spring AI 1.0.0 版本是没有这个选项的

启动服务器后,使用 Cherry Studio 客户端测试

MCP Client实现

子项目extra-mcp-client引入依赖

xml 复制代码
<!-- extra01/extra-mcp-client/pom.xml  -->  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-web</artifactId>  
</dependency>  
<dependency>  
    <groupId>com.alibaba.cloud.ai</groupId>  
    <artifactId>spring-ai-alibaba-starter-dashscope</artifactId>  
</dependency>  
<dependency>  
    <groupId>org.springframework.ai</groupId>  
    <artifactId>spring-ai-starter-mcp-client</artifactId>  
</dependency>  
  
<dependency>  
    <groupId>org.projectlombok</groupId>  
    <artifactId>lombok</artifactId>  
    <optional>true</optional>  
</dependency>  
<!--  使用测试用例进行测试 -->  
<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-test</artifactId>  
    <scope>test</scope>  
</dependency>

配置yml

yaml 复制代码
# extra01/extra-mcp-client/src/main/resources/application.yml  
spring:  
  ai:  
    dashscope:  
      api-key: ${AI_BAI_LIAN_API_KEY}   
      chat:  
        options:  
          model: qwen-plus  
          temperature: 0.7  
    mcp:  
      client:  
        streamable-http:  
          connections:  
            server1: # mcp 服务URL  
              url: http://127.0.0.1:8081/mcp

编写测试用例调用MCP

less 复制代码
// extra01/extra-mcp-client/src/test/java/com/kaifamiao/extra01/StreamableWeatherServerTest.java  
  
@SpringBootTest  
@Slf4j  
public class StreamableWeatherServerTest {  
    @Test  
    void testMcpServer(@Autowired ChatClient.Builder chatClientBuilder,  
                       @Autowired SyncMcpToolCallbackProvider syncMcpToolCallbackProvider) {  
        ChatClient chatClient = chatClientBuilder  
                .build();  
        String response = chatClient.prompt()  
                .toolCallbacks(syncMcpToolCallbackProvider)  
                .user("北京现在的天气如何").call().content();  
        log.info("response: {}", response);  
    }  
}

控制台输出:

复制代码
北京今天的温度是36℃。请注意防暑降温!

总结

之前,Spring AI 最受诟病的一点是不支持可流式传输的 HTTP(Streamable HTTP),这使得在实现自定义 MCP 服务器端时非常麻烦,开发者不得不手动实现断线自动重连等功能。不过,随着新版本的发布,这一问题得到了解决。现在,Spring AI 已经支持 Streamable HTTP,我们能够更加便捷地实现 MCP 服务,感兴趣的开发者不妨动手尝试一下。

源代码地址:github.com/kaiwill/kai...

学习资源推荐

如果你想更深入地学习大模型,以下是一些非常有价值的学习资源,这些资源将帮助你从不同角度学习大模型,提升你的实践能力。

本文较长,建议点赞收藏。更多AI大模型应用开发学习视频及资料,在智泊AI

相关推荐
蛋先生DX4 小时前
RAG 切片利器 LumberChunker 是如何智能地把文档切割成 LLM 爱吃的块
llm·aigc·ai编程
正点原子6 小时前
《ESP32-S3使用指南—IDF版 V1.6》第四十二章 录音机实验
程序员·嵌入式·产品
radient6 小时前
属于Agent的课本 - RAG
人工智能·后端·程序员
viperrrrrrrrrr77 小时前
milvus向量数据库
数据库·大模型·llm·milvus
带刺的坐椅7 小时前
LangChain4j 比 SolonAI 强在哪?弱在哪?
java·ai·langchain·solon·mcp
智泊AI1 天前
一文讲清:AI大模型的工作原理,它是怎么做到这么聪明的?
llm
京东云开发者1 天前
把算法焊死在模型上系列-后端眼中的RAG平台架构
程序员
京东云开发者1 天前
探索无限可能:生成式推荐的演进、前沿与挑战【AI业务应用方向】
程序员
SimonKing1 天前
Mybatis-Plus的竞争对手来了,试试 MyBatis-Flex
java·后端·程序员