Spring AI 集成 MCP 服务踩坑实录:SSE 与 Streamable HTTP 协议的兼容性深度剖析

摘要: 在使用 Spring AI 集成 Model Context Protocol (MCP) 服务时,开发者常遇到 404 Not Found 错误。本文通过分析 MCP 协议从 2024 版本(SSE)到 2025 版本(Streamable HTTP)的演进,结合 LangChain4j 的源码差异,详细解释了为何直接升级传输层会导致报错,并给出了适用于 Spring AI 框架的最佳实践方案。


1. 引言:背景与问题

随着 AI 应用的复杂化,MCP(Model Context Protocol)成为了连接 LLM 和外部工具的标准。在 Java 生态中,我们通常使用 LangChain4j 或 Spring AI 来构建客户端。

最近在尝试对接一个 MCP 服务端时,我遇到了一个典型的报错:

java 复制代码
java.lang.RuntimeException: Unexpected status code: 404
    at dev.langchain4j.mcp.client.transport.http.StreamableHttpMcpTransport.lambda$execute$0(StreamableHttpMcpTransport.java:209)

明明旧的代码能跑通,为什么换成新的 StreamableHttpMcpTransport 就报 404?这背后其实是 MCP 协议版本迭代带来的"代沟"。

2. 协议演进:从 SSE 到 Streamable HTTP

为了理解这个问题,我查阅了 MCP 官方文档的历史版本,对比了 2024-11-05 (旧版)和 2025-03-26(新版)的核心差异。

2.1 传输机制的根本变革
特性 2024-11-05 (旧版) 2025-03-26 (新版)
核心协议 HTTP + SSE (Server-Sent Events) Streamable HTTP
通信模式 双工模式:GET 建立 SSE 长连接 + POST 发送指令 单一端点:统一通过 POST 交互,可选 GET 流式响应
端点数量 通常需要两个端点(如 /sse 和 /post) 仅需一个 MCP Endpoint (如 /mcp)
Spring AI 支持 ✅ 原生支持 ❌ 暂不支持(截至 2026 年初)

深度解析:

  • 旧版 (SSE) :客户端发送 GET /sse 建立一个"听筒",服务端通过这个连接推送消息;客户端发送 POST 到另一个地址(如 /message)来发送指令。
  • 新版 (Streamable) :废弃了 SSE。客户端直接向 POST /mcp 发送所有请求。如果需要流式响应,服务端会返回 Content-Type: text/event-stream。
2.2 为什么会出现 404?

当你在代码中使用:

java 复制代码
McpTransport transport = StreamableHttpMcpTransport.builder()
        .url("http://127.0.0.1:3000/sse") // 错误!
        .build();

你的意图是使用 新版客户端 去连接 旧版服务端。

  • 新版客户端 会向 http://127.0.0.1:3000/sse 发送一个 POST 请求。
  • 旧版服务端 的 /sse 路径只接受 GET 请求(用来建立长连接),根本不认识 POST。
  • 结果:服务端懵了,返回 404 Not Found。

3. Spring AI 与 LangChain4j 的现状分析

3.1 Spring AI 的兼容性

截至目前,Spring AI 框架主要基于旧版的 LangChain4j 实现 ,其底层逻辑完全遵循 2024-11-05 (SSE) 规范。

这意味着,如果你在 Spring Boot 项目中配置 MCP:

yaml 复制代码
spring:
  ai:
    mcp:
      clients:
        my-client:
          transport: http
          http:
            sse-url: http://127.0.0.1:3000/sse # 必须指向 SSE 端点

你必须确保后端服务支持旧版的 SSE 协议。强行在配置中填入 Streamable 的参数是无效的,因为框架底层并没有实现新版的握手逻辑。

3.2 LangChain4j 的过渡期

LangChain4j 1.0 版本为了兼容未来,引入了 StreamableHttpMcpTransport。但这并不意味着它能自动适配所有服务端。这是一个"非此即彼"的选择:

  • 服务端是旧版 →\rightarrow→ 客户端必须用 HttpMcpTransport (SSE模式)。
  • 服务端是新版 →\rightarrow→ 客户端必须用 StreamableHttpMcpTransport。

4. 解决方案与最佳实践

针对目前的开发环境,我建议采取以下策略:

4.1 方案一:拥抱现状(推荐)

既然 Spring AI 和大部分现有工具链都还在使用旧版协议,我们就不要强行"升级"传输层。

保持旧代码:

java 复制代码
McpTransport transport = new HttpMcpTransport.Builder()
        .sseUrl("http://127.0.0.1:3000/sse") // 指向服务端的 SSE 入口
        .build();

服务端要求: 确保你的 MCP 服务端(如 Python 的 FastMCP)开启了 transport="sse" 或兼容模式。

4.2 方案二:纯 Java 项目升级指南

如果你不使用 Spring AI,而是纯 LangChain4j 项目,并且你确定服务端已经升级到了 2025-03-26 协议:

  1. 服务端 :必须监听单一的 POST 端点(通常是 /mcp),不再区分 SSE。

  2. 客户端 :修改 URL 为 /mcp。

    java 复制代码
    McpTransport transport = StreamableHttpMcpTransport.builder()
            .url("http://127.0.0.1:3000/mcp") // 注意路径变了
            .build();

5. 总结

MCP 协议的演进是为了简化流式传输,但在过渡期给开发者带来了不小的困扰。

核心结论:

  1. 不要混用:新版客户端不能连旧版服务端,反之亦然。
  2. Spring AI 用户 :请继续使用 .sseUrl() 配置,目前的 Spring AI 版本尚未适配 Streamable HTTP。
  3. 404 报错的本质:是 HTTP Method 不匹配(客户端发 POST,服务端只听 GET)。

希望这篇文章能帮你少走弯路!如果你也在研究 MCP,欢迎在评论区交流。

相关推荐
eBest数字化转型方案7 分钟前
快消渠道 AI 落地路线:拍照、数据、决策三阶段的工程逻辑
大数据·人工智能
七牛云行业应用8 分钟前
DeepSeek Harness 插件 dsh-zen-remote 教程:手机访问、桌面配对与通知配置
人工智能·ai·智能手机·ai编程
张星河zen9 分钟前
英伟达Groq 3 LPX全面量产,AI工厂进入Token拼价时代,重构智能体AI底座
人工智能·大模型·英伟达·groq·推理芯片
ZEB11069 分钟前
AI 转型服务商怎么选?五类机构的能力与适用边界
人工智能
数聚天成DeepSData10 分钟前
夜间灯光可以代表经济活动吗?先处理年际一致性
人工智能·深度学习·机器学习·数据集·deepsdata
青春不朽51215 分钟前
Python 里 a is b 有时 True 有时 False?小整数缓存和常量折叠的底层真相
python·spring·缓存
AllData公司负责人17 分钟前
AllData搭建AI中台,集成开源项目LabelStudio/CubeStudio,建设数据标注平台/机器学习平台
数据库·人工智能·机器学习·labelstudio·cubestudio
百胜软件@百胜软件19 分钟前
百胜软件黄飞:让AI真正走进零售,把不确定性变成“胜券在握”
大数据·人工智能·零售
高洁0120 分钟前
数字孪生、具身智能、世界模型三者交叉
人工智能·python·深度学习·机器学习
广州智造24 分钟前
Radioss二次开发需要准备什么?
人工智能·算法·机器学习·cad·cae