StreamableHTTP 的 /mcp 握手通了,客户端 tools/call 还是调不动?TaoToken 只管模型通道这一段
1. 先别急着改代码这个坑八成不在 MCP 服务里如果你用 Spring AI 的mcp-server-webmvcstarter 把CalculatorTool、SystemInfoResource、CodeReviewPrompt暴露到/mcpcurl走initialize能拿到Mcp-Session-Idtools/list也能列出calculate但一挂进 Codex 当客户端tools/call就是发不出去——先别怀疑Tool注解写错了也别急着翻MethodToolCallbackProvider的源码。我踩过的坑是MCP 端点地址和模型通道地址填混了。这两个地址长得像作用却完全不同。MCP 地址是http://localhost:8080/mcp它负责把你的CalculatorTool暴露给客户端模型通道地址是https://taotoken.net/api它负责让客户端里的模型能正常对话、决定要不要调工具。很多人把模型通道的 Base URL 顺手填成了http://localhost:8080/mcp结果客户端把tools/call当成聊天请求发给了本地 MCP 服务握手通了才怪。这篇就按排障视角走一遍先确认 MCP 服务本身没问题再把客户端里两个地址拆开最后用一次真实的tools/call验证请求确实走到了CalculatorTool。适合正在用 Java StreamableHTTP 搭 MCP 服务、并且已经卡在客户端调用这一步的人。2. 前置MCP 服务归 MCP模型通道归 TaoToken先把职责划清楚后面排查才不会乱。MCP 服务这一侧你只需要保证http://localhost:8080/mcp能正常响应 JSON-RPC。它不认识什么模型、什么 Key只认initialize、tools/list、tools/call这些方法。Spring AI 的 starter 已经把 transport 层、JSON-RPC 解析、会话管理全自动做完了你写的CalculatorTool只要被Tool标注就会被注册成 MCP tool。模型通道这一侧是客户端里真正“动脑子”的部分。Codex 这类客户端需要一个大模型来决定“用户这句话要不要调calculate”这个模型请求得走一个独立的 Base URL。这里用 TaoToken 作为模型通道Base URL 写https://taotoken.net/apiKey 到https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end注册后创建。注意MCP 地址和模型通道地址是两条独立的链路。MCP 地址指向你本地的8080模型通道地址指向taotoken.net。两者填反握手能通tools/call必挂。如果你还没建 Key进控制台创建即可https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite。创建完在 API Keys 页面复制https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite。接入细节可以对照文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite。3. 可复制配置把两个地址彻底拆开3.1 先确认 MCP 服务端配置没跑偏application.yml里这段是 StreamableHTTP 的开关enabled: true才会走/mcp单端点模式否则 starter 会退回旧的 SSE transportspring: ai: mcp: server: type: SYNC streamable-http: enabled: true endpoint: /mcp启动后先用curl把三步走完确认服务端自身是好的。第一步initialize重点看响应头里的Mcp-Session-Idcurl -i -X POST http://localhost:8080/mcp \ -H Content-Type: application/json \ -d {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2025-03-26,capabilities:{},clientInfo:{name:test,version:1.0}}}第二步tools/list把上一步拿到的 session id 填进去应该能看到calculatecurl -X POST http://localhost:8080/mcp \ -H Content-Type: application/json \ -H Mcp-Session-Id: 上一步响应头里的值 \ -d {jsonrpc:2.0,id:2,method:tools/list}第三步直接tools/call这一步能返回42说明 MCP 服务端完全没问题curl -X POST http://localhost:8080/mcp \ -H Content-Type: application/json \ -H Mcp-Session-Id: 同一个 session id \ -d {jsonrpc:2.0,id:3,method:tools/call,params:{name:calculate,arguments:{operation:multiply,a:6,b:7}}}3.2 客户端里两个地址分开填这是整篇最关键的一步。在 Codex 这类客户端的配置里MCP server 的地址填本地{ mcpServers: { calculator: { url: http://localhost:8080/mcp } } }模型通道单独配置Base URL 指向 TaoTokenKey 用你刚创建的那串{ model: { baseUrl: https://taotoken.net/api, apiKey: sk-你的TaoToken密钥, model: claude-sonnet-4-5 } }两处分开之后客户端的行为就对了它先通过http://localhost:8080/mcp完成initialize和tools/list知道有个calculate工具当用户说“6 乘 7 等于几”时模型请求走https://taotoken.net/api模型返回一个tools/call意图客户端再把tools/call发回http://localhost:8080/mcp。请求这才真的走得到CalculatorTool。3.3 用环境变量兜底避免手滑如果你不想在配置文件里写死 Key用环境变量更稳export TAOTOKEN_API_KEYsk-你的TaoToken密钥 export TAOTOKEN_BASE_URLhttps://taotoken.net/api export MCP_SERVER_URLhttp://localhost:8080/mcp然后在客户端配置里引用这些变量。这样即使换机器也不会把localhost和taotoken.net填反。4. 验证请求确认 tools/call 真的到了 CalculatorTool配置改完重启客户端做一次端到端验证。最直接的办法是在CalculatorTool的calculate方法里加一行日志Tool(description 四则运算计算器支持 add/subtract/multiply/divide) public double calculate(String operation, double a, double b) { System.out.println([MCP] tools/call 到达 CalculatorTool: operation a b); return switch (operation) { case add - a b; case subtract - a - b; case multiply - a * b; case divide - a / b; default - throw new IllegalArgumentException(不支持的运算: operation); }; }然后在客户端里输入“帮我算一下 6 乘 7”。预期结果有两层第一层客户端控制台或日志里能看到模型通道请求成功说明https://taotoken.net/api这条链路是通的。第二层你的 Spring Boot 应用控制台打印出[MCP] tools/call 到达 CalculatorTool: multiply 6.0 7.0说明tools/call确实发到了http://localhost:8080/mcp并且被路由到了CalculatorTool。如果第一层通、第二层没打印那基本就是 MCP 地址填错了或者客户端把tools/call发到了模型通道地址。反过来如果第二层打印了但客户端没显示结果那问题在响应回传跟地址无关。想单独验证模型通道是否正常可以到模型对话页面发一条普通消息https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite。如果那边能正常回复说明 Key 和 Base URL 没问题问题就锁定在 MCP 地址这一侧。5. 本篇常见错排查5.1 把 MCP 地址填成了模型通道地址最常见的错。客户端里 MCP server 的url写成了https://taotoken.net/api结果initialize请求发给了模型通道返回的是一段模型回复而不是Mcp-Session-Id。表现就是“握手看起来通了但tools/call发不出去”。改回http://localhost:8080/mcp即可。5.2 把模型通道地址填成了 MCP 地址反过来也常见。Base URL 写成http://localhost:8080/mcp客户端把聊天请求发给本地 MCP 服务MCP 服务只认 JSON-RPC收到普通聊天请求直接报错。表现是模型完全不回复或者回复一段 JSON-RPC 错误。Base URL 必须是https://taotoken.net/api。5.3 session id 没带上tools/call必须带Mcp-Session-Id请求头这个值来自initialize的响应头。有些客户端会自动管理有些需要手动配置。如果你用curl测试时忘了带服务端会返回会话不存在的错误。检查客户端是否在initialize之后正确保存并复用了 session id。5.4 endpoint 路径写错application.yml里endpoint: /mcp客户端地址就必须是http://localhost:8080/mcp。如果写成http://localhost:8080/mcp/多了斜杠或者http://localhost:8080少了路径都可能 404。Spring MVC 对路径匹配比较严格建议完全按配置来。5.5 端口被占用或服务没起来8080是常见端口容易被其他服务占用。启动时看日志有没有Tomcat started on port 8080。如果端口冲突改server.port并同步改客户端里的 MCP 地址。这个错的表现是initialize直接连接失败跟地址填混的表现不一样容易区分。5.6 模型通道 Key 无效如果模型通道返回 401客户端可能根本走不到tools/call这一步。先确认 Key 是在https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite创建的并且没有多余空格。Key 无效时模型不会返回工具调用意图自然也就没有tools/call。6. 地址分开之后链路才真的通回到最初那个现象initialize通了tools/call调不动。根因不是 Spring AI 的 starter 有问题也不是CalculatorTool注册失败而是客户端里两个地址混在了一起。MCP 地址负责工具暴露模型通道地址负责模型推理两者必须分开。你现在可以这样收尾MCP 地址保持http://localhost:8080/mcp模型通道 Base URL 写https://taotoken.net/apiKey 到https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end注册后创建。如果你后面要长期跑编码类 Agent可以考虑 Coding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite。接入过程中遇到报错先翻文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite大部分地址和鉴权问题那里都有对照。最后留一个实用习惯每次改完客户端配置先在CalculatorTool里看那行日志有没有打印。日志打印了说明tools/call真的到了没打印就回去检查两个地址是不是又填混了。这比盯着客户端界面猜要快得多。

相关新闻

明星粉丝商城系统架构设计与技术选型指南

明星粉丝商城系统架构设计与技术选型指南

1. 明星粉丝周边商城系统架构设计1.1 技术选型对比分析在构建明星粉丝周边商城系统时,后端框架的选择至关重要。Flask和Django各有优势,需要根据项目规模和发展预期做出决策。Flask作为微框架的代表,其轻量级特性体现在:核心功能仅…

2026/9/24 7:16:44 阅读更多 →
Ory Hydra OAuth2LoginRequest 模型详解:登录请求的数据结构与 SDK 使用指南

Ory Hydra OAuth2LoginRequest 模型详解:登录请求的数据结构与 SDK 使用指南

Ory Hydra OAuth2LoginRequest 模型详解:登录请求的数据结构与 SDK 使用指南 【免费下载链接】hydra Internet-scale OpenID Certified™ OpenID Connect and OAuth2.1 provider that integrates with your user management through headless APIs. Solve OIDC/OAut…

2026/9/24 12:24:06 阅读更多 →
Node.js+小程序构建农商信息平台的技术实践

Node.js+小程序构建农商信息平台的技术实践

1. 项目概述:农商信息交流平台的定位与价值这个基于Node.js和小程序的农商信息交流平台,本质上是一个连接农产品生产者与消费者的数字化桥梁。我在农业信息化领域做过多个类似项目,发现传统农产品交易存在严重的信息不对称问题——农户不知道…

2026/9/23 20:18:09 阅读更多 →

最新新闻

Moto CodeBuild 模拟实战:在测试中 Mock AWS CodeBuild 项目与构建 API

Moto CodeBuild 模拟实战:在测试中 Mock AWS CodeBuild 项目与构建 API

Mock测试 【免费下载链接】moto A library that allows you to easily mock out tests based on AWS infrastructure. 项目地址: https://gitcode.com/gh_mirrors/mo/moto 点击查看 免费下载 本篇技术指南围绕 moto 仓库中 CodeBuild 服务文档 展开,系统…

2026/9/25 3:31:50 阅读更多 →
并行加法器 vs 先行进位加法器:进位延迟、关键路径与工程实现

并行加法器 vs 先行进位加法器:进位延迟、关键路径与工程实现

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

2026/9/25 3:31:50 阅读更多 →
grammars-v4 中 R 语言 ANTLR 语法解析指南:掌握 RFilter 换行符预处理机制

grammars-v4 中 R 语言 ANTLR 语法解析指南:掌握 RFilter 换行符预处理机制

编程语言编译器开发工具 【免费下载链接】grammars-v4 Grammars written for ANTLR v4; expectation that the grammars are free of actions. 项目地址: https://gitcode.com/gh_mirrors/gr/grammars-v4 点击查看 免费下载 导读 在 grammars-v4 仓库的 r 目录下&…

2026/9/25 3:31:50 阅读更多 →
VoltAgent 接入 Deep Infra:使用 `deepinfra/<model>` 模型路由打通低成本高性能推理

VoltAgent 接入 Deep Infra:使用 `deepinfra/<model>` 模型路由打通低成本高性能推理

人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆 【免费下载链接】voltagent AI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework 项目地址: https://gitcode.com/gh_mirrors/vo/voltagent 点击查看 免费下载 De…

2026/9/25 3:31:50 阅读更多 →
用 ANTLR v4 解析 Scala 3:grammars-v4 中 Scala3 语法的设计、覆盖率与已知限制

用 ANTLR v4 解析 Scala 3:grammars-v4 中 Scala3 语法的设计、覆盖率与已知限制

编程语言编译器开发工具 【免费下载链接】grammars-v4 Grammars written for ANTLR v4; expectation that the grammars are free of actions. 项目地址: https://gitcode.com/gh_mirrors/gr/grammars-v4 点击查看 免费下载 本文面向需要为 Scala 3 构建词法/语法分…

2026/9/25 3:31:50 阅读更多 →
Java工业物联网IOT驱动包:统一Modbus-TCP、Bacnet与OPC-UA协议接入

Java工业物联网IOT驱动包:统一Modbus-TCP、Bacnet与OPC-UA协议接入

简介:这份基于Java的物联网IOT通用驱动包设计源码,面向中高级Java开发者与系统集成商,解决Modbus-TCP、Bacnet、OPC-UA等多协议设备接入问题,封装为SDK形式,可直接嵌入业务系统。压缩包共76个文件,约1.73MB…

2026/9/25 3:30:49 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/24 9:10:42 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →