资讯动态

Spring AI 自定义MCP Server(天气预报服务):把 endpoint 改到 TaoToken

发布时间:2026/10/13 2:15:08 来源:尧图企业网站定制
1. 为什么本地 MCP Server 跑通了模型通道却成了新瓶颈很多开发者把 Spring AI 自定义 MCP Server 写完之后第一反应是「工具能跑就行」。我一开始也这么想Tool注解加上了ToolCallbackProvider也注册了用 Cline 的 stdio 模式连上去输入经纬度天气 JSON 确实回来了。但真正把它接到一个稳定的模型调用通道上时问题才暴露出来——工具是工具模型是模型两者之间的那条「通道」如果没配好整个链路就是断的。具体场景是这样的你本地已经有一个 Spring Boot 3.2.5 JDK 17 的工程依赖spring-ai-mcp-server-webmvc-spring-boot-starter 1.0.0-M6里面写了一个WeatherService通过Tool暴露getWeatherConditionByLocation方法底层调 Open-Meteo 的免费天气 API。MCP Server 本身没问题server.port: 8098也能起来。但当你希望这个 MCP Server 背后的模型调用走统一通道而不是每个开发者各自填一堆零散的 key 时application.yml里的base-url和api-key就成了必须一次性改对的地方。这篇内容面向的就是这类开发者本地 MCP Server 已经跑通现在需要把模型调用通道统一到 TaoToken并且要能验证「改完之后天气工具真的还能被模型正确调用、返回的 JSON 结构没变」。核心检索词是 Spring AI 自定义 MCP Server 天气预报服务的接入配置关键词覆盖 Spring AI、MCP Server、天气预报服务、base-url、api-key。先说清楚 TaoToken 在这里的角色。它是一个统一的模型调用通道提供 OpenAI 兼容的接口形态官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。你不需要改 MCP Server 的工具逻辑只需要把模型侧也就是调用方比如 Cline、或者你自己的 Spring AI ChatClient的 base-url 指向它再配一个 API Key。这样团队里每个人用的都是同一条通道模型 ID 也统一排查问题时不会出现「你那边能跑我这边 401」的情况。适合谁看已经写过至少一个Tool方法、知道 MCP 的 stdio 和 SSE 两种传输模式、但被多套 key 和多套 base-url 搞烦的 Java 开发者。如果你还没写过 MCP Server建议先把WeatherService和ToolCallbackProvider那部分补上再回来看通道切换否则验证环节会缺少可观测的返回体。我试过把模型通道和工具通道混在一起配结果 Cline 那边报local proxy failed排查了半天才发现是 base-url 写成了带路径的完整地址而 SDK 自己又拼了一次/v1。所以下面第 3 节给的配置片段路径和原文保持一致你直接复制改 key 就行不要自己加后缀。2. TaoToken 前置准备Key、Base URL 与模型 ID 三件套在动application.yml之前先把三件套确认清楚Base URL、API Key、Model ID。这三样缺一个后面验证请求都会失败而且报错信息往往指向别处容易误判。Base URL 用 https://taotoken.net/api 注意这里不带任何多余路径。很多 OpenAI 兼容 SDK 会在内部再拼/v1/chat/completions如果你手动写成https://taotoken.net/api/v1就会出现双/v1典型表现是 404 或者local proxy failed。API Key 在控制台的 API Keys 页面创建地址是 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建之后复制一次后面只显示前缀所以先存到安全的地方。模型 ID 这块要看你用哪个模型。如果你只是验证 MCP 工具调用链路选一个支持 function calling / tool use 的模型即可。Cline 里配置的时候Model ID 要和通道侧一致不要写别名。比如你选的是某个 Claude 系列或者 GPT 系列就按控制台文档里给的准确 ID 填。三件套的关系可以这样理解Base URL 是「门牌号」API Key 是「门禁卡」Model ID 是「你要找的人」。门牌号错了进不去小区门禁卡错了进不去楼人找错了工具调用可能不触发。如果你用的是 Claude Code 这类偏编码场景的工具通道侧也有对应的 Coding Plan 入口https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。它的意义在于长期编码和 Agent 场景下通道的配额和稳定性更适合持续调用而不是每次临时填 key。对于 MCP Server 这种会被反复调用的工具服务建议直接走 Coding Plan省得中途 key 失效导致天气工具突然不可用。还有一个前置动作容易被忽略确认你的 MCP Server 本身能独立返回正确 JSON。也就是说先不接模型直接用 curl 或者浏览器访问 Open-Meteo确认WeatherInfo反序列化没问题。因为一旦接入模型通道后返回体异常你很难判断是模型没调工具还是工具调了但 JSON 解析失败。我踩过的坑就是current字段里weather_code是整数但我在WeatherInfo里写成了 String结果工具执行时抛异常模型侧只看到「工具调用失败」完全不知道是类型问题。所以前置准备里先把工具自身的返回体核对一遍。控制台地址再放一次方便你创建完 key 后回来核对https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。在里面可以看到调用量、错误码分布后面第 5 节排查 401 和reading choices时会用到。3. 可复制配置application.yml 里 base-url 与 api-key 的改法这一节是核心操作。你的 Spring Boot 工程里application.yml原本可能只配了 MCP Server 自己的信息像这样server: port: 8098 spring: ai: mcp: server: name: weather-server version: 0.0.1现在要加的是模型调用侧的配置。注意MCP Server 本身不直接调模型调模型的是「调用方」。所以有两种改法取决于你的架构第一种如果你的 Spring Boot 工程里同时有ChatClient在调模型比如你想让模型自动决定是否调用天气工具那就在同一个application.yml里加 OpenAI 兼容配置spring: ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: your-model-id temperature: 0.7 mcp: server: name: weather-server version: 0.0.1这里base-url就是 https://taotoken.net/api 不要加/v1。api-key建议用环境变量注入不要硬编码在 yml 里避免提交到仓库。model填你在控制台确认过的 Model ID。第二种如果你的模型调用发生在 Cline 这类外部客户端那application.yml只需要保证 MCP Server 正常暴露模型通道配置在 Cline 的 MCP 设置里。Cline 的配置是 JSON 形态路径通常在cline_mcp_settings.json片段如下{ mcpServers: { weather-server: { disabled: false, timeout: 60, command: java, args: [-jar, /path/to/weather-server-0.0.1.jar], transportType: stdio, env: { OPENAI_BASE_URL: https://taotoken.net/api, OPENAI_API_KEY: 你的TaoTokenKey, OPENAI_MODEL_ID: your-model-id } } } }注意这里的三件套是 Base URL、Key、Model ID 同时出现缺一不可。transportType用stdio表示本地 jar 启动如果你用 SSE 模式连远程就把command/args换成url字段指向http://localhost:8098/sse之类的地址。如果你用的是 Codex 这类工具它的auth.json里也要写全三件套结构类似{ base_url: https://taotoken.net/api, api_key: 你的TaoTokenKey, model: your-model-id }路径和字段名以你本地实际文件为准不要照抄字段名到别的工具里。核心原则只有一个Base URL 是 https://taotoken.net/api Key 从控制台来Model ID 和控制台一致。改完之后先别急着启动。检查一遍有没有重复的spring.ai.openai节点YAML 里重复 key 会导致后者覆盖前者表现是 base-url 没生效。另外如果你的工程里用了spring-ai-mcp-server-webmvc-spring-boot-starter它和spring-ai-openai-spring-boot-starter的版本要对齐都是1.0.0-M6版本错配会出现NoSuchMethodError看起来像通道问题其实是依赖冲突。4. 验证请求启动后调用天气工具并核对返回 JSON配置改完启动工程mvn spring-boot:run看到Tomcat started on port(s): 8098和 MCP Server 注册日志后先做一次不经过模型的直连验证。用 curl 打 SSE 端点确认工具列表能出来curl -N http://localhost:8098/sse如果返回里能看到weather-server和getWeatherConditionByLocation说明 MCP Server 本身没问题。接下来在 Cline 里发起一次真实调用输入北京天气预报: latitude: 39.9042 longitude: 116.4074预期行为是模型先决定调用getWeatherConditionByLocation工具执行后返回一段包含当前天气和未来 7 天预报的文本。返回体里应该能看到类似这样的结构{ current: { temperature_2m: 26.5, apparent_temperature: 27.1, relative_humidity_2m: 58, precipitation: 0.0, weather_code: 1, wind_speed_10m: 12.3, wind_direction_10m: 180 }, daily: { time: [2025-01-01, ...], temperature_2m_max: [28.0, ...], temperature_2m_min: [18.0, ...] } }核对三个点第一current.temperature_2m是数值不是字符串第二daily.time数组长度是 7第三weather_code能被你的getWeatherDescription正确映射成中文描述。如果这三点都对说明工具链路和模型通道都通了。再验证一次模型通道是否真的走了 TaoToken。在控制台的调用记录里应该能看到这次请求的时间戳和模型 ID。如果控制台没有记录但 Cline 又返回了结果那说明模型调用没走你配的通道可能还在用旧的 key 或本地缓存。这时候清一下 Cline 的会话重新发起。如果你想更直接地验证模型对话通道可以用模型对话入口发一条简单消息https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 。在里面问「北京天气怎么样」如果它能触发工具调用并返回天气说明通道和工具已经串起来了。这一步的意义是把「模型侧」和「工具侧」分开验证避免混在一起排查。实测下来最容易出问题的是timeout。MCP 工具调用如果超过 60 秒Cline 会断开表现是「工具无响应」。天气 API 一般很快但如果你本地网络到 Open-Meteo 慢就把timeout调到 120。另外forecast_days7返回的数据量不小如果模型侧对返回体长度有限制可能会截断导致daily数组不完整。这时候可以在工具里只返回前 3 天或者让模型总结后再输出。5. 常见报错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来。你改完配置后大概率会碰到下面几类逐个对照。401 Unauthorized。最常见的原因是 API Key 没生效。检查顺序第一application.yml或 Cline JSON 里的 key 是不是控制台创建的那个注意前后有没有空格第二如果用了环境变量${TAOTOKEN_API_KEY}确认启动时环境变量真的注入了可以在启动日志里打印一下 key 的前缀第三确认 Base URL 是 https://taotoken.net/api 如果写成了别的域名key 自然不被识别。还有一种情况是 key 被禁用或额度用完去控制台看一下状态。local proxy failed。这个报错通常出现在 Cline 里意思是本地代理层连不上目标地址。原因往往是 Base URL 带了多余路径比如https://taotoken.net/api/v1SDK 再拼一次/v1就变成/api/v1/v1/chat/completions直接 404。改回 https://taotoken.net/api 即可。另一个原因是本地网络需要走系统代理但 Cline 没读到这时候检查系统代理设置或者把timeout调大重试。reading choices 相关报错。典型信息是Error reading choices或choices is null。这说明请求发出去了但返回体结构不符合预期。常见原因是 Model ID 写错通道侧返回了错误信息而不是正常的choices数组。去控制台确认 Model ID并确认该模型支持 tool use。如果模型不支持 function calling工具调用不会触发返回体里也不会有tool_calls看起来就像「模型没调工具」。OAuth 相关报错。如果你用的是 Claude Code 或类似工具可能会看到 OAuth 流程失败。这时候不要反复重试 OAuth直接改用 API Key 方式。Claude Code 的接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 里面有 Base URL、Key、Model ID 的完整写法。ClaudeCodeAnthropic 的专用入口是 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewrite 按文档把三件套填全OAuth 报错就会消失。还有一种隐蔽的报错工具被调用了但返回体里daily是 null。这通常是WeatherInfo的字段名和 Open-Meteo 返回的 JSON 不一致。Open-Meteo 用的是下划线命名比如temperature_2m_max而 Java 字段如果写成temperature2mMax需要加JsonProperty映射。检查你的 DTO确保每个字段都有正确的映射注解。这个错误不会在模型侧报得很明显只会表现为「天气数据缺失」。最后如果所有配置都对但工具就是不被调用检查ToolCallbackProvider有没有注册成功。在启动类里加一行日志打印weatherTools的 bean 名称确认它被 Spring 扫描到了。MCP Server 的Tool方法必须是 public且参数要有ToolParam描述否则模型不知道参数含义可能直接跳过调用。6. 把通道固定下来长期编码与 Agent 场景的收尾建议通道切换完成、天气工具验证通过之后建议把配置固化下来而不是每次手动填。对于长期跑 MCP Server 的团队最省事的做法是把 Base URL、Key、Model ID 写进统一的配置中心或环境变量模板新成员拉下代码只需要填自己的 Key。Coding Plan 在这里的价值就体现出来了https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 它适合持续调用的 Agent 场景不会因为临时额度问题导致工具突然不可用。另外MCP Server 的日志建议加上请求 ID这样在控制台看到异常调用时能对应到本地哪一次工具执行。天气服务这种外部 API 依赖最好加一层缓存比如同一个经纬度 10 分钟内不重复请求减少通道和外部 API 的压力。这些细节不影响通道切换本身但能让你的 MCP Server 在真实使用中更稳。如果你还想验证其他模型在同一个 MCP Server 上的表现直接用模型对话入口切换 Model ID 即可Base URL 和 Key 不用变。这就是统一通道的好处工具不动模型随便换。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑