【MCP教程系列】SpringBoot 用 Spring AI 搭建 SSE 模式 MCP 服务并改到 TaoToken
1. 为什么要在 SpringBoot 里搭 SSE 模式的 MCP 服务MCP 全称 Model Context Protocol你可以把它理解成一套“让模型调用外部工具”的通用插座标准。模型本身只会聊天但通过 MCP它能去查数据库、调接口、跑脚本。而 SSE 模式就是这套插座里“服务端主动往客户端推消息”的那一种传输方式。传统 HTTP 请求是“你问一句我答一句”模型调用工具时如果工具执行要好几秒中间状态你完全看不到。SSE 不一样它是一条长连接服务端可以持续把“工具开始执行”“中间日志”“最终结果”一段段推回来。对于需要流式展示工具调用过程的场景比如文章润色、批量生成标题SSE 的体验明显更顺。这篇要解决的问题很具体用 SpringBoot Spring AI 搭一个 SSE 模式的 MCP 服务然后把它的模型调用通道统一改到 TaoToken 上。适合谁看如果你手上有本地工具想暴露给模型又不想每个工具都单独配一套 Key 和地址那这套路径就是给你准备的。我试过把工具逻辑和模型通道拆开配置结果发现最省心的做法是MCP 服务只负责“暴露工具”模型调用统一走一个兼容 OpenAI 协议的入口。TaoToken 正好提供这个入口Base URL 是https://taotoken.net/api模型 ID 和 Key 在控制台拿。这样你的 SpringBoot 项目里只需要维护一份模型配置工具代码不用动。整个闭环分四步建项目引依赖、写工具方法、配 SSE 端点、启动验证。下面一步步来每段都有可复制的代码和配置。2. 前置准备Spring AI 依赖与 TaoToken 接入参数怎么配先把环境对齐。JDK 17 是底线Spring AI 1.0.0-M6 对 JDK 版本有要求低于 17 会在编译期报Unsupported class file major version。Maven 用 3.8.6 以上避免依赖解析时出现仓库元数据拉取失败。2.1 pom.xml 依赖片段核心是两个 starter一个负责 MCP 服务端的 WebMVC 暴露一个负责 OpenAI 兼容的模型调用。注意版本号要和 Spring AI 的 BOM 对齐否则会出现NoSuchMethodError。properties java.version17/java.version spring-ai.version1.0.0-M6/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-mcp-server-webmvc-spring-boot-starter/artifactId version${spring-ai.version}/version /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version${spring-ai.version}/version /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement2.2 application.yml 里的 TaoToken 参数这里的关键是把 OpenAI 的 base-url 指向 TaoToken 的 API 地址而不是默认的官方地址。模型 ID 填你在控制台看到的那个Key 用sk-开头的那串。server: port: 8080 spring: ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o-mini temperature: 0.7 mcp: server: name: springboot-sse-mcp version: 1.0.0 sse-endpoint: /sse sse-message-endpoint: /mcp/message注意api-key不要硬编码进 yml 提交到仓库。用环境变量TAOTOKEN_API_KEY注入本地跑的时候在 IDE 的 Run Configuration 里加或者用export TAOTOKEN_API_KEYsk-xxx。Key 的获取路径是控制台里的 API Keys 页面模型 ID 在模型对话页面能看到当前可用的列表。如果你打算长期跑编码类 AgentCoding Plan 那条通道的额度策略更适合高频调用普通验证用按量计费就够。2.3 三件套对照表配置项值说明Base URLhttps://taotoken.net/api兼容 OpenAI 协议末尾不加/v1API Keysk-开头控制台 API Keys 页获取Model ID如gpt-4o-mini模型对话页查看可用列表这三样在 Spring AI 里分别对应base-url、api-key、chat.options.model。配错任何一个启动时不一定报错但第一次调用工具就会抛异常。3. 可复制配置ToolServer 工具类与 SSE 端点注册工具类是 MCP 服务的核心。Spring AI 用Tool注解把一个普通 Java 方法标记成模型可调用的工具方法参数和返回值会被自动转成 JSON Schema 描述给模型。3.1 ToolServer.java 完整代码这里定义两个工具批量生成标题和文章润色。两个方法都通过注入的ChatClient调模型而ChatClient底层走的就是上面配的 TaoToken 通道。package com.example.mcp; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; Service public class ToolServer { private final ChatClient chatClient; public ToolServer(ChatClient.Builder builder) { this.chatClient builder.build(); } Tool(description 根据主题批量生成 5 个文章标题返回 JSON 数组) public String generateTitles(String topic) { String prompt 请围绕主题「 topic 」生成 5 个吸引人的中文标题 以 JSON 数组格式返回每个元素是一个字符串。; return chatClient.prompt() .user(prompt) .call() .content(); } Tool(description 对给定文章进行润色保持原意提升可读性) public String polishArticle(String content) { String prompt 请对以下文章进行润色保持原意不变让表达更流畅自然\n content; return chatClient.prompt() .user(prompt) .call() .content(); } }Tool的description很重要模型靠它判断什么时候该调这个工具。描述写得太模糊模型可能该调的时候不调或者乱调。3.2 注册工具提供者Spring AI 需要一个ToolCallbackProvider把工具类里的方法注册进去。写一个配置类package com.example.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 McpConfig { Bean public ToolCallbackProvider toolCallbackProvider(ToolServer toolServer) { return MethodToolCallbackProvider.builder() .toolObjects(toolServer) .build(); } }这个 Bean 一注册MCP 服务端启动时就会扫描ToolServer里所有带Tool的方法把它们暴露成 SSE 端点可调用的工具。3.3 SSE 端点说明application.yml里配的sse-endpoint: /sse是客户端建立长连接的地址sse-message-endpoint: /mcp/message是客户端发送工具调用请求的地址。两个端点分工不同前者是服务端往客户端推后者是客户端往服务端发。启动后你可以用 curl 先探一下 SSE 端点是否活着curl -N http://localhost:8080/sse-N是关闭 curl 的缓冲让你能实时看到推送内容。正常的话会先收到一条event: endpoint的消息里面带着 message 端点的完整路径。4. 验证请求启动服务并跑通一次工具调用配置写完启动类就是标准的 SpringBoot 入口package com.example.mcp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class McpApplication { public static void main(String[] args) { SpringApplication.run(McpApplication.class, args); } }4.1 启动与日志观察运行mvn spring-boot:run控制台会打印 MCP 服务注册的工具列表。看到类似Registered tools: [generateTitles, polishArticle]就说明工具挂载成功。如果这里没打印八成是ToolCallbackProvider没被扫描到检查配置类包路径是否在启动类的同级或子包下。4.2 用 MCP 客户端测试工具调用最直接的验证方式是写一个测试类用 Spring AI 的 MCP 客户端连本地 SSE 端点package com.example.mcp; import org.junit.jupiter.api.Test; import org.springframework.ai.mcp.client.McpClient; import org.springframework.ai.mcp.client.transport.SseClientTransport; public class McpClientTest { Test void testGenerateTitles() { var transport new SseClientTransport(http://localhost:8080/sse); var client McpClient.sync(transport).build(); client.initialize(); var result client.callTool(generateTitles, {\topic\:\SpringBoot 入门\}); System.out.println(工具返回: result); } }跑通后你会看到模型返回的 JSON 数组里面是 5 个标题。这一步成功说明从 SpringBoot 到 TaoToken 的整条链路是通的。4.3 验证 SSE 流式响应工具调用本身是请求-响应但 SSE 的价值在于过程推送。你可以在ToolServer的方法里加日志观察服务端是否在工具执行期间持续往连接里写数据。更直观的做法是用浏览器访问http://localhost:8080/sse打开开发者工具的 EventStream 面板能看到event: message一条条进来。如果模型返回内容里出现choices字段解析失败通常是 base-url 末尾多写了/v1。TaoToken 的地址就是https://taotoken.net/apiSpring AI 会自己拼/v1/chat/completions你手动加反而会变成/api/v1/v1/...。5. 本篇常见错排查401、local proxy failed 与 choices 解析异常接入过程里最容易卡住的就那几个报错逐个说清楚。5.1 401 Unauthorized报错长这样org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 Unauthorized: [no body]原因就三种Key 没注入、Key 写错、Key 对应的额度用尽。先确认环境变量TAOTOKEN_API_KEY在当前 shell 里能echo出来。如果用的是 IDE检查 Run Configuration 的 Environment variables 里有没有加。Key 本身去控制台 API Keys 页重新复制一次注意别把前后空格带进去。5.2 local proxy failed / Connection refusedjava.net.ConnectException: Connection refused这个报错说明请求根本没发出去。检查base-url是不是写成了http://而不是https://或者端口被本地其他服务占了。还有一种情况是公司网络对出站请求做了限制这种需要走正常的网络配置流程不在代码层面解决。5.3 reading choices 解析失败com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field choices或者反过来报找不到choices字段。前者通常是响应体结构和 Spring AI 预期的不一致后者多半是 base-url 拼错导致返回了 HTML 错误页。确认base-url是https://taotoken.net/api模型 ID 是控制台里真实存在的那个。模型 ID 写错时有些网关会返回一个结构不同的错误体Jackson 解析时就炸了。5.4 OAuth 相关报错如果你在日志里看到OAuth字样说明请求被路由到了需要 OAuth 认证的端点。Spring AI 的 OpenAI starter 默认走 API Key 认证不会触发 OAuth。出现这个报错一般是 base-url 被改成了某个需要 OAuth 的地址。改回https://taotoken.net/api即可。5.5 工具没被调用模型回复了文字但没有触发工具。先看Tool的 description 是否足够明确再确认ToolCallbackProviderBean 是否真的注册了。可以在启动日志里搜Registered tools没有这行就是注册失败。6. 把 MCP 服务接到统一通道CTA 与后续动作服务跑通之后你手上就有了一个本地 SSE 模式的 MCP 服务工具逻辑在ToolServer里模型通道在application.yml里。后续要加新工具只需要在ToolServer里加一个带Tool的方法重启即可不用碰通道配置。如果你要把这个服务接到 Claude Code 或 Cline 这类客户端配置里需要填全三件套Base URL 用https://taotoken.net/apiKey 用控制台拿的那串Model ID 填你验证过的模型。SSE 端点则填你本地或部署后的/sse地址。几个常用的入口放这里按需取拿 Key 和看额度API Keys 页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys查接入参数和协议细节接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc快速验证模型是否可用模型对话https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentchat长期跑编码类 AgentCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan最后说个实际踩过的坑SSE 连接在本地开发时容易因为 IDE 的热重启断掉表现为客户端一直收不到event: endpoint。解决办法是关掉spring-boot-devtools的自动重启或者把 SSE 端点排除在重启监听之外。这个坑不涉及代码逻辑但排查起来很费时间提前知道能省不少事。

相关新闻

AI智能体开发的技术方案:用TaoToken统一Key打通LLM调用链路

AI智能体开发的技术方案:用TaoToken统一Key打通LLM调用链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 16:24:31 阅读更多 →
从程序员视角看AI编程的局限性:2025年的现实与反思——用TaoToken统一Key实测Cline MCP与Windsurf BYOK的边界

从程序员视角看AI编程的局限性:2025年的现实与反思——用TaoToken统一Key实测Cline MCP与Windsurf BYOK的边界

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 16:24:31 阅读更多 →
ASP.NET Core Web API 中 Excel 导入导出实战:EPPlus 与 ExcelDataReader 分工方案

ASP.NET Core Web API 中 Excel 导入导出实战:EPPlus 与 ExcelDataReader 分工方案

简介:面向ASP.NET Core WebAPI开发者的Excel处理工具包,基于EPPlus与ExcelDataReader两大开源库,解决Web应用中Excel读取、导出及避免服务器安装Office的常见需求,适用于需要构建数据导入导出接口的中高级.NET后端工程师。压缩包共…

2026/10/18 16:23:31 阅读更多 →

最新新闻

8-bit Group-64量化如何平衡显存与画质:SenseNova-U1.5-8B-MoT-8step-8bit完整指南

8-bit Group-64量化如何平衡显存与画质:SenseNova-U1.5-8B-MoT-8step-8bit完整指南

大模型媒体生成多模态本地部署模型量化模型蒸馏 【免费下载链接】SenseNova-U1.5-8B-MoT-8step-8bit 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/SenseNova-U1.5-8B-MoT-8step-8bit 点击查看 免费下载 本文带你深入拆解 SenseNova-U1.5-8B-MoT-8s…

2026/10/18 17:16:11 阅读更多 →
ESP32声学回声消除(AEC)失效的三大根因与实战排错指南

ESP32声学回声消除(AEC)失效的三大根因与实战排错指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 17:16:11 阅读更多 →
如何5分钟快速上手OneReward_repackaged:ComfyUI模型下载、目录放置与部署实战教程

如何5分钟快速上手OneReward_repackaged:ComfyUI模型下载、目录放置与部署实战教程

【免费下载链接】OneReward_repackaged 项目地址: https://ai.gitcode.com/hf_mirrors/Comfy-Org/OneReward_repackaged 点击查看 免费下载 OneReward_repackaged 是一个面向 ComfyUI 的 Flux.1 Fill Dev 图像编辑模型重打包仓库,包含 OneReward 微调后…

2026/10/18 17:16:11 阅读更多 →
从读懂到重写:C语言习题集的编译、调试与工程化训练指南

从读懂到重写:C语言习题集的编译、调试与工程化训练指南

简介:面向C语言初学者的浙大翁恺教授配套习题源码包,涵盖整数运算、时间计算、BCD解密、水仙花数、九九乘法表、素数统计、猜数字游戏、分数约分、连续和计算、字符串大小写转换、单词长度统计、矩阵局部极大值、组个最小数等典型练习,每题均…

2026/10/18 17:16:11 阅读更多 →
C语言链表实现学生成绩管理系统:课设代码与报告详解

C语言链表实现学生成绩管理系统:课设代码与报告详解

简介:数据结构是计算机存储、组织数据的方式,链表作为动态数据结构,通过节点指针将零散内存串联,插入删除无需移动元素,时间复杂度更优。工程实践中,链表常用于需要频繁增删的场景,例如学生成绩…

2026/10/18 17:16:11 阅读更多 →
Bootstrap nifty v2.9后台模板集成与优化实战

Bootstrap nifty v2.9后台模板集成与优化实战

简介:Bootstrap Nifty v2.9 是一套基于 Bootstrap 框架的后台管理模板,面向需要快速搭建企业级 Web 应用后台界面的开发者,无论初学者还是资深工程师都能借助其预置组件与响应式布局缩短开发周期。压缩包为 rar 格式,共 3602 个文…

2026/10/18 17:15:09 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →