
1. 为什么要在 Spring AI 里统一管理 MCP 的 API Key如果你正在用 Spring AI 做 AI 应用大概率已经踩过这样一个坑每接入一个外部工具就要在配置文件里塞一个 Key。高德地图一个 Key、天气服务一个 Key、搜索服务又一个 Key项目跑起来之后application.yml里全是散落的密钥换环境、交接、排查问题都得一个个翻。MCPModel Context Protocol本身就是为了解决工具接入标准化这件事而生的。它把外部能力封装成 MCP ServerSpring AI 作为 Host通过 MCP Client 去连接这些 Server。但 MCP 只统一了怎么调用工具并没有统一Key 怎么管。高德地图 MCP Server 依然要求你在启动参数里传AMAP_MAPS_API_KEY其他 MCP Server 也各有各的鉴权方式。这篇要解决的就是这个链路问题在 Spring AI 项目里接入高德地图 MCP 服务同时把模型调用这一侧的 Key 收敛到 TaoToken 统一管理让模型 Key和工具 Key各归其位不再散落。适合已经跑通过 Spring AI 基础对话、想进一步接 MCP 工具的开发者也适合正在做多工具 Agent、被 Key 管理搞烦的同学。核心检索词先摆出来Spring AI、MCP Client、高德地图 MCP、API Key 统一管理。下面从配置骨架到一次真实的 POI 查询验证一步步走完。2. TaoToken 前置模型侧 Key 先收敛在接高德 MCP 之前先把模型调用这一侧的入口统一掉。Spring AI 默认对接各家模型时往往要改base-url、改api-key模型一换配置就乱。TaoToken 提供的是 OpenAI 兼容的接口形态Spring AI 的 OpenAI Starter 可以直接指过去模型侧只维护一个 Key。官网入口在这里https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册后在控制台生成 API Key。API 基地址是 https://taotoken.net/api 注意这个地址不带任何查询参数配置时直接填。模型侧配置大概长这样放在application.yml里spring: ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o-mini这里用环境变量${TAOTOKEN_API_KEY}而不是硬编码是为了后面多环境切换方便。你可以在 IDE 的运行配置里注入也可以走系统环境变量。这样模型侧无论换哪个模型只要 TaoToken 支持改一个model字段就行Key 不用动。需要说明的是TaoToken 在这里承担的是模型调用统一入口的角色高德地图 MCP 的 Key 依然由高德官方发放两者是分开的。这样设计的好处是模型 Key 泄露了只影响模型调用额度工具 Key 泄露了只影响地图配额风险隔离。如果你还没生成 Key进控制台创建即可https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_campaignrewrite 。生成后建议先复制保存页面刷新后不一定能再次完整查看。3. 可复制配置MCP Client 接入高德地图 MCP 服务这一节是全文的核心把依赖、MCP Server 配置、application.yml、ChatClient 装配四块拼起来。3.1 添加 MCP Client 依赖Spring AI 的 MCP Client 有多个 starter基于 WebFlux 的版本适合流式场景。在pom.xml里加dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client-webflux/artifactId /dependency版本跟随你项目里的 Spring AI BOM 即可不用单独指定。加完后 Maven 刷新一下确认依赖树里能看到spring-ai-mcp相关包。3.2 编写 mcp-servers-config.json高德地图官方 MCP Server 通过 npx 拉起Windows 下不能直接执行 npx需要套一层cmd /c。在src/main/resources下新建mcp-servers-config.json{ mcpServers: { amap-maps: { command: cmd, args: [ /c, npx, -y, amap/amap-maps-mcp-server ], env: { AMAP_MAPS_API_KEY: 你的高德 Web 服务 Key } } } }几个字段解释一下。command是启动命令Windows 用cmdmacOS/Linux 直接写npx即可。args里/c表示执行完命令后终止-y让 npx 遇到安装提示自动确认amap/amap-maps-mcp-server是高德官方发布的 MCP 包。env里塞高德 Key这个 Key 需要在 高德开放平台 创建应用、勾选Web 服务后拿到。注意高德 Key 分平台类型MCP 服务用的是 Web 服务类型别选成 Android 或 iOS否则调用会返回鉴权失败。3.3 application.yml 里的 MCP 配置把 MCP Client 指向刚才的配置文件并开启工具回调spring: ai: mcp: client: stdio: servers-configuration: classpath:/mcp-servers-config.json toolcallback: enabled: truestdio表示用标准输入输出和 MCP Server 通信适合本地拉起的进程型 Server。toolcallback.enabled打开后Spring AI 会把 MCP Server 暴露的工具自动注册成ToolCallback后面 ChatClient 直接注入就能用。3.4 装配 ChatClient在配置类里把ToolCallbackProvider注入进 ChatClientConfiguration public class ChatClientConfig { Resource private ChatMemory chatMemory; Bean public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider tools) { return ChatClient.builder(chatModel) .defaultToolCallbacks(tools) .defaultAdvisors( new SimpleLoggerAdvisor(), MessageChatMemoryAdvisor.builder(chatMemory).build() ) .build(); } }defaultToolCallbacks(tools)这一行是关键它把 MCP Server 里的所有工具挂到 ChatClient 上。SimpleLoggerAdvisor用来打印请求出入参排查 MCP 调用时非常有用能看到模型到底有没有触发工具调用。到这里配置骨架就齐了。模型侧走 TaoToken工具侧走高德 MCP两边 Key 互不干扰。4. 验证请求一次 POI 查询跑通连通性配置写完不验证等于没写。写一个流式接口用自然语言触发高德 MCP 的周边搜索工具。4.1 控制器代码RestController RequestMapping(/mcp/ai) public class McpChatClientController { Resource private ChatClient chatClient; GetMapping(value /generateStream, produces MediaType.TEXT_EVENT_STREAM_VALUE) public FluxString generateStream(RequestParam String message, RequestParam String chatId) { return chatClient.prompt() .user(message) .advisors(a - a.param(ChatMemory.CONVERSATION_ID, chatId)) .stream() .content(); } }4.2 启动观察日志重启项目控制台如果出现类似Amap Maps MCP Server running on stdio的提示说明 MCP Server 已经被成功拉起。如果没看到先检查 Node.js 是否安装、npx 是否可用。4.3 发起一次真实查询浏览器或 curl 访问curl http://localhost:8080/mcp/ai/generateStream?chatIdtest001message我的坐标是东经114.05,北纬22.55,附近1000米有什么好评率较高的烧烤店,推荐一下预期结果是模型先判断需要调用高德 MCP 的周边搜索工具传入经纬度和关键词拿到 POI 列表后再用自然语言组织返回。日志里能看到工具调用的入参和返回 JSON最终流式输出门店名称、地址、评分等信息。这一步跑通说明整条链路是通的Spring AI → MCP Client → 高德 MCP Server → 高德地图 API。模型侧走的是 TaoToken 的接口工具侧走的是高德 Key两边各司其职。5. 本篇常见错排查接 MCP 的过程中报错基本集中在几个地方逐个说。第一个npx找不到或命令执行失败。Windows 下必须用cmd /c npx直接写npx会报CreateProcess error2。macOS/Linux 则相反写cmd反而找不到。另外确认 Node.js 版本不要太老建议 18 以上。第二个高德返回INVALID_USER_KEY或USERKEY_PLAT_NOMATCH。前者是 Key 填错或没生效后者是 Key 的平台类型不对。MCP 服务必须用Web 服务类型的 Key去高德控制台重新确认。第三个模型不触发工具调用。如果日志里只有模型回复、没有工具调用记录通常是模型能力问题。部分小模型对 Function Calling 支持不好换个支持工具调用的模型试试。另外确认toolcallback.enabled是true且 ChatClient 确实注入了ToolCallbackProvider。第四个MCP Server 启动超时。首次运行 npx 需要下载amap/amap-maps-mcp-server包网络慢会超时。可以先在命令行手动执行一次npx -y amap/amap-maps-mcp-server把包缓存下来再启动项目就快了。第五个模型侧 401。如果报鉴权失败检查 TaoToken 的 Key 是否填对、base-url是否是https://taotoken.net/api不要多加斜杠或路径。Key 可以在 API Keys 页面重新生成https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_campaignrewrite 。排查时建议把SimpleLoggerAdvisor打开请求和响应都能看到定位问题快很多。6. 后续怎么走按场景选入口配置跑通之后接下来无非是两件事把模型侧管好把工具侧扩起来。模型侧如果你只是偶尔调一下、验证效果直接用模型对话页面试就行不用写代码https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_campaignrewrite 。想快速验证某个模型对 MCP 工具调用的支持程度这里最省事。如果你是要长期做编码类、Agent 类项目模型调用量大、还要多模型切换那更适合用 Coding Plan 把额度固定下来https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_campaignrewrite 。这样模型侧的成本和 Key 都稳定工具侧继续按 MCP 的方式一个个接。接入过程中遇到具体报错或者想看 MCP Client 更细的配置项文档里有完整说明https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_campaignrewrite 。Key 的管理和生成都在控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_campaignrewrite 。回到这篇的主题Spring AI 整合 MCP Client 调高德地图 MCP 服务难点从来不是某一行代码而是 Key 散落导致的维护成本。把模型侧收敛到 TaoToken工具侧按 MCP 标准各自配置链路就清晰了。下一步你可以照着同样的骨架把天气、搜索、数据库这些 MCP Server 一个个接进来ChatClient 那边几乎不用改。