尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Spring AI 干货笔记之 Streamable-HTTP MCP 服务器:把 endpoint 改到 TaoToken 的完整配置

Spring AI 干货笔记之 Streamable-HTTP MCP 服务器:把 endpoint 改到 TaoToken 的完整配置 1. 为什么要把 Streamable-HTTP MCP 服务器接到 TaoTokenSpring AI 从 1.0 版本开始正式支持 MCPModel Context Protocol而 Streamable-HTTP 是 2025-03-26 规范里新增的传输方式用来替代早期的 SSE。它允许 MCP 服务器作为独立进程运行客户端通过 HTTP POST 和 GET 处理多个连接服务器还可以选择性地用 SSE 流式推送多条消息。简单说它把「一问一答」升级成了「长连接 双向通知」工具、资源、提示的动态变更都能实时推给客户端。但真正落地时很多人卡在同一个地方MCP 服务器本身跑起来了可模型调用通道还是散的。工具回调走一套配置对话模型走另一套配置Key 分散在多个文件里换一个环境就要改一堆 endpoint。尤其是团队协作时Java 侧要统一管理模型调用通道这件事比写 MCP 工具本身还费劲。我试过把 MCP 服务器的 endpoint 和模型调用的 endpoint 统一指向 TaoToken 的 API 通道效果比预想中顺。TaoToken 提供统一的 Key 和 API 入口MCP 服务器负责暴露工具能力模型侧负责消费这些工具两边共用一套鉴权和地址配置量直接砍半。这篇笔记就围绕这个思路展开先讲清楚 Streamable-HTTP MCP 服务器在 Spring AI 里怎么配再把 endpoint 改到 TaoToken最后用一次真实的启动日志和请求返回验证握手是否成功。适合谁看如果你正在用 Spring AI 做 Java 侧的 AI 应用需要把 MCP 工具服务器和模型调用通道统一管理或者你已经被 SSE 的断连问题折腾过想换到 Streamable-HTTP这篇可以直接跟着做。下面所有配置片段都是可复制的依赖版本以 Spring AI 1.0.0 为准。2. TaoToken 前置准备与 Streamable-HTTP MCP 服务器依赖选型在动手改 endpoint 之前先把两件事理清楚TaoToken 这边要拿到什么Spring AI 这边要引哪个 starter。TaoToken 侧你需要一个 API Key。登录后进入控制台在 API Keys 页面创建一个新 Key复制出来备用。这个 Key 后面会同时用在 MCP 服务器的模型调用和客户端连接上。地址方面API 入口是https://taotoken.net/api注意这个地址不带任何查询参数直接作为 base URL 使用。如果你还没注册可以先从官网入口进去了解整体能力再决定用哪种套餐。Spring AI 侧Streamable-HTTP MCP 服务器有两个 starter 可选区别在于底层 Web 栈starter底层适用场景传输特性spring-ai-starter-mcp-server-webmvcSpring MVC传统阻塞式应用团队熟悉 Servlet 栈完整 MCP 能力Streamable 传输spring-ai-starter-mcp-server-webfluxWebFlux响应式应用需要高并发长连接非阻塞、持久连接管理两个 starter 都支持工具、资源、提示、补全、日志记录、进度、ping、根目录变更等能力。选哪个取决于你现有项目的 Web 栈不要为了用 WebFlux 而强行改架构。我这边用的是 WebMVC 版本因为现有项目就是 Spring MVC改造成本最低。依赖引入很简单在pom.xml里加dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server-webmvc/artifactId /dependency如果你用 WebFlux把 artifactId 换成spring-ai-starter-mcp-server-webflux即可。版本跟随 Spring AI BOM 管理不需要单独指定。这里有个容易忽略的点Streamable-HTTP 服务器必须显式设置spring.ai.mcp.server.protocolSTREAMABLE否则默认还是走 SSE。这个属性是整篇配置的核心开关漏了它后面所有 endpoint 配置都不生效。另外MCP 服务器的能力默认全部开启。如果你只想暴露工具不想暴露资源和提示可以用spring.ai.mcp.server.capabilities.tooltrue|false这类属性单独控制。禁用某个能力会阻止服务器向客户端注册和公开对应功能这在生产环境做权限收敛时很有用。3. 可复制的 application.yml 与 MCP 客户端 Bean 配置这一节是整篇的核心配置片段可以直接复制到你的项目里改。先看application.yml我把 MCP 服务器和 TaoToken 通道的配置放在一起方便对照。spring: ai: mcp: server: protocol: STREAMABLE name: streamable-mcp-server version: 1.0.0 type: SYNC instructions: This streamable server provides real-time notifications resource-change-notification: true tool-change-notification: true prompt-change-notification: true streamable-http: mcp-endpoint: /api/mcp keep-alive-interval: 30s openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o-mini几个关键点逐个说明。protocol: STREAMABLE是必须的它告诉 Spring AI 用 Streamable-HTTP 传输而不是 SSE。mcp-endpoint: /api/mcp是 MCP 服务器对外暴露的路径客户端会往这个地址发 POST 和 GET。keep-alive-interval: 30s开启保活服务器会定期向连接发送 ping 验证健康状态注意这个机制目前只对「监听来自服务器的消息SSE」连接生效。模型侧我用了spring.ai.openai前缀因为 TaoToken 的 API 兼容 OpenAI 协议。base-url指向https://taotoken.net/apiapi-key从环境变量读取不要硬编码在文件里。model按你实际需要的模型填这里用gpt-4o-mini只是示例。接下来是 MCP 客户端的 Bean 配置。如果你需要 Java 侧主动连接这个 Streamable-HTTP 服务器可以这样写Configuration public class McpClientConfig { Bean public McpSyncClient mcpSyncClient() { var client McpClient.sync( HttpClientSseClientTransport.builder(https://taotoken.net/api) .sseEndpoint(/api/mcp) .build()) .requestTimeout(Duration.ofSeconds(30)) .build(); client.initialize(); return client; } }注意这里的HttpClientSseClientTransport用于 Streamable-HTTP 的 SSE 流式部分sseEndpoint要和服务器端的mcp-endpoint保持一致。requestTimeout设 30 秒避免长连接被过早掐断。client.initialize()在 Bean 初始化时完成握手如果这一步抛异常说明 endpoint 或协议配置有问题。如果你用的是 WebFlux 版本客户端换成WebFluxSseClientTransport其余参数逻辑一致。三件套要记牢Base URL 是https://taotoken.net/apiKey 是你在控制台创建的那个Model ID 按需填。这三个值在 MCP 服务器和客户端两侧必须一致否则握手会失败。工具注册部分Spring AI 会自动检测并注册来自ToolCallbackbean、ToolCallback列表、ToolCallbackProviderbean 的所有工具回调。工具按名称去重每个名称首次出现的项会被使用。你可以通过把tool-callback-converter设为false来禁用自动检测。下面是一个带 MCP 工具的 Spring Boot 应用示例Service public class WeatherService { Tool(description Get weather information by city name) public String getWeather(String cityName) { return Sunny in cityName; } } SpringBootApplication public class McpServerApplication { public static void main(String[] args) { SpringApplication.run(McpServerApplication.class, args); } Bean public ToolCallbackProvider weatherTools(WeatherService weatherService) { return MethodToolCallbackProvider.builder() .toolObjects(weatherService) .build(); } }Tool注解标记的方法会被自动转换为 MCP 工具MethodToolCallbackProvider负责把服务对象里的工具方法收集起来。启动后这个getWeather工具就会通过/api/mcp暴露给客户端。4. 启动日志与请求返回验证 MCP 服务器握手配置写完启动应用看日志。正常握手时控制台会输出类似下面的内容2025-06-10T10:23:41.51208:00 INFO 18234 --- [main] o.s.a.m.s.McpServerAutoConfiguration : Registered MCP tool: getWeather 2025-06-10T10:23:41.53008:00 INFO 18234 --- [main] o.s.a.m.s.StreamableHttpServerTransport : Streamable-HTTP MCP server started at /api/mcp 2025-06-10T10:23:41.54508:00 INFO 18234 --- [main] o.s.a.m.s.McpSyncServer : MCP server initialized, protocol version: 2025-03-26 2025-06-10T10:23:41.56008:00 INFO 18234 --- [main] c.e.m.McpServerApplication : Started McpServerApplication in 3.421 seconds看到Streamable-HTTP MCP server started at /api/mcp和MCP server initialized这两行说明服务器侧握手成功。如果只看到工具注册但没看到 server started多半是protocol没设成STREAMABLE。接下来用 curl 发一个初始化请求验证curl -X POST https://taotoken.net/api/api/mcp \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { jsonrpc: 2.0, id: 1, method: initialize, params: { protocolVersion: 2025-03-26, capabilities: {}, clientInfo: {name: curl-test, version: 1.0} } }正常返回应该包含result字段里面有protocolVersion、serverInfo和capabilities。如果返回401检查Authorization头里的 Key 是否正确如果返回404检查路径是不是多了一层或漏了一层。再发一个工具调用请求curl -X POST https://taotoken.net/api/api/mcp \ -H Content-Type: application/json \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -d { jsonrpc: 2.0, id: 2, method: tools/call, params: { name: getWeather, arguments: {cityName: Beijing} } }返回里应该能看到Sunny in Beijing这样的结果。到这一步MCP 服务器和 TaoToken 通道的握手就验证完了。整个过程的关键是协议设对、endpoint 对齐、Key 有效三者缺一不可。5. 本篇常见错误排查401、local proxy failed 与 reading choices配置过程中最容易撞上三类报错我按实际遇到的顺序整理一下。第一类是401 Unauthorized。这个最直接就是 Key 不对或没传。检查application.yml里的api-key是否读到了环境变量或者 curl 命令里的Authorization头是否拼写正确。注意 Bearer 后面有个空格漏了也会 401。还有一种情况是 Key 创建后没复制完整建议重新生成一个再试。第二类是local proxy failed或连接被拒绝。这个通常出现在客户端侧说明sseEndpoint和服务器实际暴露的路径不一致。比如服务器配的是/api/mcp客户端写成了/mcp就会连不上。另外检查base-url有没有多写或漏写/apiTaoToken 的 API 入口是https://taotoken.net/apiMCP 路径拼在后面变成/api/api/mcp是正常的不要觉得重复就删掉一层。第三类是reading choices相关的解析错误。这个一般出现在模型调用侧说明返回的 JSON 结构不符合预期。常见原因是model字段填了一个 TaoToken 不支持的模型 ID或者base-url指向了错误的路径。确认base-url是https://taotoken.net/apimodel用控制台里列出的可用模型。如果还是报错把请求体打印出来对照 OpenAI 兼容格式检查一遍。还有一类是 OAuth 相关的报错如果你在 MCP 客户端里配了 OAuth 认证但服务器没开对应能力会提示认证失败。Streamable-HTTP 服务器默认不需要 OAuth除非你显式配置了安全模块。遇到这类报错先检查spring.ai.mcp.server下有没有多余的 security 配置。排查顺序建议先看启动日志有没有 server started再用 curl 测 initialize最后测 tools/call。每一步的报错对应不同层不要跳步。6. 统一通道后的接入建议与后续动作把 MCP 服务器 endpoint 改到 TaoToken 之后最直观的变化是配置收敛了。以前 MCP 工具一套 Key、模型调用一套 Key现在共用一套换环境只改一个base-url和api-key就行。对于 Java 侧需要统一管理模型调用通道的团队来说这个改动省掉的不只是配置量还有排查问题时来回切换文件的成本。如果你还没拿到 Key先去控制台创建一个地址是 API Keys 页面。创建完把 Key 存到环境变量里不要写进代码仓库。接入文档里有完整的参数说明和示例遇到路径或协议问题可以先翻一遍。验证模型是否正常响应可以用模型对话页面发一条测试消息确认通道通了再回到 MCP 配置。如果你打算长期做编码类或 Agent 类应用Coding Plan 那边有更完整的通道管理方案适合把 MCP 工具和模型调用放在同一个计划里统一调度。最后提醒一个实操细节Streamable-HTTP 的保活机制目前只对 SSE 连接生效普通 POST 请求不会触发 ping。如果你的场景需要长时间保持连接确保客户端走的是 SSE 流式通道并且keep-alive-interval设一个合理的值30 秒是个比较稳的起点。改完配置后重启应用按第 4 节的 curl 命令走一遍确认 initialize 和 tools/call 都返回正常就算接好了。
返回列表