Spring AI + MCP 最详细实践:从配置开始到服务搭建(踩坑无数版)——TaoToken 统一 Key 接入实录
1. 从一次真实踩坑说起Spring AI 接 MCP 到底难在哪如果你最近在折腾 Spring AI 和 MCP大概率经历过这样的场景照着某篇教程把依赖贴进pom.xmlIDEA 一片飘红好不容易依赖拉下来了启动又报No qualifying bean of type ToolCallbackProvider再或者 MCP Server 起来了客户端却死活连不上日志里只有一句干巴巴的local proxy failed。我前后折腾了三个晚上把 Spring AI 1.0.0-M5 到 1.0.0 正式版的差异、MCP Server 的 SSE 端点、工具回调注册这几块全踩了一遍才把本地 MCP 服务和 Spring AI 的联调跑通。这篇就按“能直接抄”的思路来写。核心检索词先摆出来Spring AI 集成 MCP 的完整配置与服务搭建它解决的是“让 Java 后端把自己的方法暴露成 MCP 工具再让任意 MCP 客户端调用”这件事适合已经会写 Spring Boot、但被版本和依赖卡住的开发者。我会给出可复制的pom.xml、application.yml、ToolCallbackProvider配置以及通过 TaoToken 统一 Key 完成模型调用验证的步骤。全程不绕弯报错对照着改就行。先说清楚 MCP 在这里的角色。MCPModel Context Protocol本质是一套“工具描述 调用”的协议Spring AI 把它做成了 Server 端 starter你只要在方法上打Tool注解框架就自动生成工具描述通过 SSE 暴露出去。客户端比如 Cherry Studio、Cline、Claude Code连上这个 SSE 端点就能看到你注册的工具模型决定要不要调、调哪个。所以整条链路是Spring Boot 应用 → MCP ServerSSE→ MCP 客户端 → 大模型。模型这一环我用 TaoToken 的统一 Key 来打通省得每个客户端配一遍不同厂商的密钥。下面从环境准备开始一步步来。2. 前置准备与 TaoToken 统一 Key 接入环境这块别偷懒版本不对后面全是坑。Java 必须 17 以上我直接上 21Maven 3.6.3 以上我用 3.9.xSpring Boot 选 3.4.x 或更高我用 3.5.3。命令行里跑一遍确认java -version javac -version mvn -v三个输出都正常再往下。IDEA 新建工程时Server URL 一定选start.spring.io别用默认的否则后面加依赖会莫名其妙失败。Spring Boot 版本选 3.4 以上依赖可以先不勾后面手动加。接下来是 TaoToken 这一环。为什么要用它因为 MCP 客户端最终要调大模型而不同客户端Cherry Studio、Cline、Claude Code各自配 Key 很烦TaoToken 提供统一 Key 和 API 通道一个 Key 走通所有客户端。先去官网注册拿 Keyhttps://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content登录后在控制台创建 API Key路径是 console 里的 api-keys 页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite拿到 Key 后先别急着配客户端我们先把 Spring AI 的 MCP Server 搭起来。这里有个关键点MCP Server 本身不调模型它只暴露工具调模型是客户端的事。所以 TaoToken 的 Key 是配在客户端侧的但为了后面验证方便我们先把 Key 存好。API 基础地址统一用https://taotoken.net/api注意这个地址不带 UTM 参数是纯 API 端点。模型 ID 这块TaoToken 支持主流模型客户端里填对应的 Model ID 即可比如claude-sonnet-4-5、gpt-4o这类具体以控制台模型列表为准。我实测下来Cherry Studio 里配 TaoToken 的 OpenAI 兼容通道最省事Base URL 填https://taotoken.net/apiKey 填刚创建的模型选一个能用的点检测通过就能对话。如果你更习惯用 Claude Code 做长期编码TaoToken 也有对应的接入方式Base URL 同样是https://taotoken.net/apiKey 用同一个Model ID 按 Claude 系列填。这样一套 Key 在多个客户端复用不用来回切换。环境和大模型通道都通了接下来进正题建工程、导依赖。3. 可复制配置pom.xml 与 application.yml 全量片段依赖是 Spring AI MCP 最容易翻车的地方。Spring AI 的 milestone 版本在 Maven 中央仓库不一定有必须加 Spring 的 milestone 仓库。下面这份pom.xml是我实测能拉下来的直接抄properties java.version21/java.version spring-ai.version1.0.0-M5/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-core/artifactId version${spring-ai.version}/version /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server-webmvc/artifactId version1.0.0/version /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-validation/artifactId /dependency dependency groupIdcom.fasterxml.jackson.core/groupId artifactIdjackson-databind/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement repositories repository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /repository /repositories pluginRepositories pluginRepository idspring-milestones/id nameSpring Milestones/name urlhttps://repo.spring.io/milestone/url snapshots enabledfalse/enabled /snapshots /pluginRepository /pluginRepositories注意spring-ai-starter-mcp-server-webmvc的版本我写的是1.0.0不是${spring-ai.version}。这是因为 M5 阶段这个 starter 的版本号和 BOM 不完全对齐写死反而稳。如果你拉不到去 Spring milestone 仓库一级级点进去看实际存在的版本替换即可。配置文件我用application.yml比 properties 清晰。这里有个大坑MCP Server 的 SSE 端点配置项在不同版本里名字不一样。M5 到正式版之间sse-message-endpoint和sse-endpoint都出现过。我这份配置对应 M5server: port: 8080 spring: ai: mcp: server: name: mcp-server version: 1.0.0 sse-message-endpoint: /sse sse-endpoint: /mcp/sse如果你启动后客户端连/sse报 404就把sse-endpoint改成/sse再试。这个我踩过日志里不会明确告诉你端点错了只会连接超时。工具回调的注册用 Java 配置类这是把Tool方法暴露出去的关键import com.example.demo.service.impl.McpServiceImpl; 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 ToolCallbackProviderConfig { Bean public ToolCallbackProvider gzhRecommendTools(McpServiceImpl mcpServiceImpl) { return MethodToolCallbackProvider.builder() .toolObjects(mcpServiceImpl) .build(); } }服务实现类里用Tool注解描述每个方法描述写清楚模型靠它决定调不调import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; Service public class McpServiceImpl { Tool(description Get weather information by city name) public String getWeather(String cityName) { return cityName 天气很好; } Tool(description 用于回答关于小白和小鸡毛的相关问题) public String answerQuestionsAboutXiaoBaiAndXiaoJiMa(String question) { return 小鸡毛和小白是两个小可爱小鸡毛是白毛小鸡毛是白色; } }这三段配好工程结构就齐了一个配置类、一个服务类、一个 yml。启动类不用改Spring Boot 默认扫描即可。4. 启动验证从控制台日志到客户端调用成功启动前再确认一遍Java 21、Maven 依赖全部拉下来、yml 里端口没被占用。然后mvn spring-boot:run或 IDEA 直接跑。控制台出现类似下面的输出说明 MCP Server 起来了Tomcat started on port 8080 (http) Registered tools: [getWeather, answerQuestionsAboutXiaoBaiAndXiaoJiMa] MCP Server started with SSE endpoint: /mcp/sse如果没看到Registered tools这行八成是ToolCallbackProvider没被扫描到检查配置类包路径是否在启动类同级或子包下。服务端 OK 后用 Cherry Studio 验证。打开 Cherry Studio先在设置里配好大模型选 OpenAI 兼容通道Base URL 填https://taotoken.net/apiKey 填 TaoToken 控制台创建的 Key模型选一个可用的点检测。检测通过后回对话框随便发一句确认能正常对话。然后加 MCP 服务器设置 → MCP 服务器 → 添加 → 快速创建类型选 SSEURL 填http://localhost:8080/mcp/sse保存后记得把开关打开。如果保存报错重启一下 Spring 工程再试多半是 SSE 连接还没就绪。回到聊天框勾选刚加的 MCP 服务然后问一句“小白和小鸡毛是什么关系”。模型会判断该调answerQuestionsAboutXiaoBaiAndXiaoJiMa你就能在工具调用记录里看到它被触发返回“小鸡毛和小白是两个小可爱……”。到这一步Spring AI MCP 的本地联调就算跑通了。想更直观地看模型对话效果也可以直接用 TaoToken 的模型对话页面测https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite如果你打算长期用 MCP 做 Agent 或编码辅助建议直接上 Coding PlanKey 和通道都统一省得每个客户端单独配https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite5. 常见报错排查401、local proxy failed、reading choices 逐个拆这一节按真实报错来遇到哪个查哪个。报错一401 Unauthorized或invalid api key。这个基本出在客户端侧不是 MCP Server 的问题。检查 Cherry Studio 或 Cline 里填的 Key 是不是 TaoToken 控制台创建的、有没有多余空格。Base URL 必须是https://taotoken.net/api别写成带/v1的TaoToken 的兼容层不需要。如果 Key 没问题还报 401去控制台看下 Key 是否被禁用或额度用尽。报错二local proxy failed或connection refused。这是 MCP 客户端连不上 SSE 端点。先确认 Spring 工程在跑、端口对。然后确认客户端里填的 URL 是http://localhost:8080/mcp/sse不是/sse。如果你改了 yml 里的sse-endpoint客户端 URL 要跟着改。还有一种情况是防火墙拦了本地端口换个端口试试。报错三Error reading choices或no choices in response。这个通常是大模型返回格式不对客户端解析失败。原因多半是模型 ID 填错或者用了不兼容的通道。TaoToken 的 OpenAI 兼容通道下Model ID 要和控制台模型列表一致。我遇到过填了带版本后缀的 ID 导致返回空 choices换成标准 ID 就好了。报错四No qualifying bean of type ToolCallbackProvider。配置类没生效。检查ToolCallbackProviderConfig是否在启动类的扫描路径下Configuration有没有漏。另外MethodToolCallbackProvider.builder().toolObjects(...)里的对象必须是 Spring Bean也就是McpServiceImpl上要有Service。报错五依赖拉不下来Could not resolve dependencies。去 Spring milestone 仓库确认版本是否存在https://repo.spring.io/milestone/org/springframework/ai/一级级点进去看spring-ai-core、spring-ai-starter-mcp-server-webmvc有哪些版本把 pom 里的版本号换成实际存在的。Maven 中央仓库也可以搜但 milestone 版本大概率只在 Spring 仓库有。报错六OAuth 相关报错。如果你用的是 Claude Code 或某些需要 OAuth 的客户端报OAuth token invalid检查客户端的认证方式是否选对。TaoToken 走 API Key 通道不需要 OAuth客户端里选 API Key 模式即可。Claude Code 的接入文档在这里https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite排查顺序建议先看 Spring 控制台有没有Registered tools再看客户端能不能连上 SSE最后看模型调用返回。三段分开定位比一股脑改配置快得多。6. 把 Key 和通道固定下来后续少折腾跑通一次之后最省事的做法是把 TaoToken 的 Key 和 Base URL 固定成一套配置所有 MCP 客户端共用。Cherry Studio、Cline、Claude Code 里都填同一个 Key、同一个https://taotoken.net/api模型 ID 按各自支持的填。这样你换客户端不用重新申请 Key换模型也不用改通道。MCP Server 这边工具方法会越加越多建议按业务拆多个Service每个服务一个ToolCallbackProviderBean描述写清楚参数和用途。模型判断调不调全靠Tool(description...)这段文字写模糊了它就不调写太啰嗦又浪费 token。最后留一个我踩过的坑Spring AI 版本迭代快今天能跑的配置明天可能因为 starter 版本变动失效。遇到依赖问题第一反应是去 milestone 仓库看实际版本而不是怀疑代码。代码逻辑就那么点坑基本都在版本和端点上。把这两块摸清Spring AI MCP 的服务搭建就是个体力活。

相关新闻

Cursor 读不到 .env 文件?用 TaoToken 统一 Key 通道排查 ignore 与设置

Cursor 读不到 .env 文件?用 TaoToken 统一 Key 通道排查 ignore 与设置

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

2026/10/24 7:14:16 阅读更多 →
把 Aider 的 Base URL 改到 TaoToken:局域网 Ollama 本地化 AI Agent 部署实录

把 Aider 的 Base URL 改到 TaoToken:局域网 Ollama 本地化 AI Agent 部署实录

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

2026/10/27 11:16:32 阅读更多 →
手把手教你用CodeBuddy打造专属AI助手:从零配置到TaoToken接入实战

手把手教你用CodeBuddy打造专属AI助手:从零配置到TaoToken接入实战

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

2026/11/5 9:40:17 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/6 15:21:35 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/6 9:29:27 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/6 22:01:11 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/6 22:01:11 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/6 8:08:42 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/6 22:01:09 阅读更多 →

日新闻

周新闻

月新闻