新闻详情

新闻详情

首页 / 资讯中心 / 详情

Java Spring AI 搭建 MCP 服务初体验:从踩坑到实现的小确幸(TaoToken 统一 Key 接入版)

发布时间:2026/9/26 3:24:10来源:尧图网络
Java Spring AI 搭建 MCP 服务初体验:从踩坑到实现的小确幸(TaoToken 统一 Key 接入版)
1. 为什么 Java 开发者搭 MCP 服务总在第一步卡住MCP 服务这件事Java 开发者上手时最容易卡住的不是协议本身而是模型通道。Spring AI 的 MCP Server Starter 已经把 SSE 端点、工具注册、Tool注解扫描这些活干得差不多了真正让人反复重启项目的是鉴权配置base-url填哪个、api-key从哪来、模型名写gpt-4o还是gpt-4o-mini、为什么客户端连上了却调不出工具。我一开始也是照着文档把spring-ai-mcp-server-webmvc-spring-boot-starter加进pom.xml写了个带Tool的方法mvn spring-boot:run起来看到/sse端点通了结果客户端一发请求就 401。排查半天发现是模型侧的 Key 没配Spring AI 默认会去读OPENAI_API_KEY环境变量本地没设就直接抛鉴权异常。后来换成 TaoToken 的统一 Key 通道把base-url和api-key一次性写进application.yml服务端和客户端共用同一套凭证这类问题才彻底消失。这篇就按我实际跑通的顺序来先讲清楚 MCP 服务在 Spring AI 里是什么形态再把 TaoToken 的 Key 和通道配好然后给出可复制的application.yml骨架、MCP 服务端启动配置最后用一次端到端调用验证通道连通。适合已经会 Spring Boot、想快速把第一个 MCP 服务跑起来的 Java 开发者。2. TaoToken 前置统一 Key 与 API 通道准备MCP 服务本身不产生模型能力它只是把本地方法暴露成工具真正干活的是背后的大模型。所以第一步不是写代码而是把模型通道准备好。TaoToken 在这里的角色是统一入口一个 Key 覆盖多种模型base-url固定省得你在 OpenAI、Claude、国产模型之间来回换配置。操作路径很直接。打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后在控制台生成 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 。生成后先复制保存页面刷新就不再完整显示。API 通道的基础地址是 https://taotoken.net/api 注意这个地址不带任何查询参数直接作为base-url使用。Spring AI 的 OpenAI 兼容客户端会在这个地址后面拼/v1/chat/completions之类的路径所以你在配置里只写根地址就行不要自己加/v1。注意Key 只放在本地application.yml或环境变量里不要提交到 Git。团队协作时用环境变量注入配置文件里写${TAOTOKEN_API_KEY}占位。如果你只是想先确认模型能不能通可以先用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 发一条消息确认 Key 有效再进代码环节。这一步能省掉后面「到底是 Key 错还是代码错」的扯皮。3. 可复制配置application.yml 与 MCP 服务端骨架先给依赖。Spring AI 的 MCP Server 目前用 WebMVC 版本最省事SSE 传输开箱即用dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-mcp-server-webmvc-spring-boot-starter/artifactId version1.0.0-M6/version /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId version1.0.0-M6/version /dependency版本号按你项目里 Spring AI 的 BOM 对齐M6 是我实测能跑通 MCP Server 的版本。接下来是application.yml这是整篇最该直接抄的部分server: port: 8080 spring: application: name: gzh-mcp-server 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: gzh-mcp-server version: 1.0.0 sse-endpoint: /sse sse-message-endpoint: /mcp/message几个关键点解释一下。base-url写 TaoToken 的 API 根地址Spring AI 会自动补全路径api-key用环境变量注入本地跑之前在终端export TAOTOKEN_API_KEY你的Keymodel先填gpt-4o-mini验证通道跑通后再换更强的模型。sse-endpoint和sse-message-endpoint是 MCP 客户端要连的两个地址默认值就是这两个写出来是为了后面客户端配置对得上。然后是服务端主类和工具类。工具类用Tool注解暴露方法Spring AI 会自动扫描并注册到 MCP 服务SpringBootApplication public class McpServerApplication { public static void main(String[] args) { SpringApplication.run(McpServerApplication.class, args); } } Component public class GzhTools { Tool(description 根据城市名查询当前天气返回温度和天气状况) public String getWeather(ToolParam(description 城市名称例如 杭州) String city) { // 这里替换成真实调用示例先返回固定结构 return city 当前 22 摄氏度多云; } Tool(description 把一段中文翻译成英文) public String translate(ToolParam(description 待翻译的中文文本) String text) { return translated: text; } }Tool的description很重要模型靠它决定什么时候调用这个工具。写得太模糊模型就不会触发写清楚输入输出命中率明显提升。ToolParam同理参数说明会进到模型的上下文里。4. 启动与端到端验证一次调用确认通道连通配置齐了就可以启动。终端里先设 Key再跑export TAOTOKEN_API_KEYsk-你的实际Key mvn spring-boot:run看到日志里出现Registered tools: [getWeather, translate]和SSE endpoint: /sse就说明服务端起来了。这时候别急着写客户端先用 curl 确认 SSE 端点活着curl -N http://localhost:8080/sse正常会返回一行event: endpoint加一个data: /mcp/message?sessionIdxxx。这个sessionId是本次连接的会话标识客户端后续发消息要带上它。-N是关掉缓冲不然你看不到流式输出。接下来配客户端。如果你用支持 MCP 的编辑器插件配置就是一段 JSON{ mcpServers: { gzh-mcp-server: { url: http://localhost:8080/sse } } }配好之后客户端会连上 SSE 端点拉取工具列表。成功的话你能在工具面板里看到getWeather和translate两个方法参数说明也一并解析出来。这时候在对话里问「杭州天气怎么样」模型会触发getWeather服务端日志打印调用记录客户端返回「杭州 当前 22 摄氏度多云」。这一条链路走通就说明 TaoToken 的模型通道、Spring AI 的 MCP 服务端、客户端三者全部连通。如果你想在代码里做一次自动化验证可以写个简单的测试直接调 MCP 客户端的工具列表接口断言返回里包含你注册的工具名。这样每次改配置后跑一遍比手动点客户端快。5. 本篇常见错排查401 鉴权失败九成是api-key没读到。检查环境变量名和application.yml里的${TAOTOKEN_API_KEY}是否一致echo $TAOTOKEN_API_KEY确认有值。另一个可能是base-url多写了/v1TaoToken 的根地址就是https://taotoken.net/api不要自己加路径。SSE 连不上或一直 pending先确认端口没被占lsof -i:8080看一下。如果服务端日志显示端点注册了但 curl 没反应检查是不是被安全框架拦了Spring Security 默认会拦/sse需要在配置里放行。工具列表为空Tool注解的类必须是 Spring Bean加Component或Service。另外确认spring-ai-mcp-server-webmvc-spring-boot-starter的版本和 Spring AI BOM 一致版本错配会导致扫描不到注解。模型不触发工具调用description写得太泛或者模型选的太弱。先把model换成能力更强的型号试一次确认是描述问题还是模型问题。temperature调低一点也有帮助工具调用场景不需要发散。客户端解析出工具但调用报错看服务端日志的异常栈多半是工具方法内部抛了未捕获异常。MCP 协议会把异常包装成错误响应返回客户端只显示「调用失败」真实原因在服务端日志里。6. 后续怎么把这套通道用顺第一个 MCP 服务跑通之后你会发现真正花时间的不是写工具方法而是反复调description和参数说明让模型稳定命中。我的做法是每加一个工具先在模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 手动问几句看模型会不会主动调、调的时候参数对不对确认没问题再进代码。如果你打算长期做编码类 Agent把 MCP 服务和 Coding Plan 配合起来会更顺套餐页在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 统一 Key 在多个项目间复用不用每个服务单独配一套凭证。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 遇到路径或参数问题先翻这里比搜索引擎快。Claude Code 相关的接入配置可以参考 https://taotoken.net/ClaudeCodeAnthropic?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 思路和 Spring AI 这边一致都是把base-url指向统一通道、Key 走环境变量。把这一套配置模板固化下来下一个 MCP 服务基本就是复制粘贴加改工具方法的事。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

friend 友元:什么时候值得破坏封装 2026/9/26 4:04:36

friend 友元:什么时候值得破坏封装

友元(friend)是 C 里唯一一种「光明正大绕过 private 访问控制」的机制——它被设计出来不是让你随便用的,而是给少数「必须紧密协作」的场景留一个受控的后门。这篇把友元的三种写法、三条铁律,以及「什么时候真该用、什么时候该…

阅读更多 →
拿下开源生图第一,千问Qwen-Image-2.1把生图卷出新高度 2026/9/26 4:04:28

拿下开源生图第一,千问Qwen-Image-2.1把生图卷出新高度

视觉生成模块仅7B,生图、改图、透明素材装进了同一个模型。 AI 写代码的能力经常能让开发者「双手离开键盘」,但对于设计师而言,AI 生成的图片距离能交稿总是差了好几步。 在图像设计的工作流中,人物需要抠图、素材需要改字、各…

阅读更多 →
Java 泛型是怎么实现的?从类型擦除讲起 2026/9/26 4:04:28

Java 泛型是怎么实现的?从类型擦除讲起

Java 5 之前,集合里存的都是 Object,放进去的时候没人管你放的是什么,取出来的时候靠开发者自己保证强转的类型是对的: List list new ArrayList(); list.add("hello"); Integer i (Integer) list.get(0);这三行能正常…

阅读更多 →
只听指定的人:小米这款开源 ASR,把参考声音变成识别开关 2026/9/26 4:04:28

只听指定的人:小米这款开源 ASR,把参考声音变成识别开关

会议里三个人同时说话,普通 ASR 通常面临两个难题:要么把所有人的话糊在一起,要么先做语音分离,再一路路识别。 但如果你只关心其中一个人,其实有另一条路:给模型一段这个人的参考声音,让它直接…

阅读更多 →
Java 抽象类和接口到底有什么区别?一篇讲清楚 2026/9/26 4:04:28

Java 抽象类和接口到底有什么区别?一篇讲清楚

abstract class 和 interface 在语法上长得很像,都能声明没有方法体的方法,都不能被 new,都要靠子类去实现,都能构成多态。 abstract class Animal {abstract void makeSound(); }interface Flyable {void fly(); }两个都只给方法…

阅读更多 →
自动化测试(3) 2026/9/26 4:04:28

自动化测试(3)

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

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉