#7、Spring AI 使用 MCP 客户端(调用高德 MCP) Spring AI 使用 MCP 客户端调用高德 MCP本文以 Spring AI 1.0.0-M6 为例完整演示了如何通过 MCPModel Context Protocol客户端在 Spring AI 应用中接入高德地图 MCP 服务并深入剖析 MCP 与原生 Tool Calling 的区别。什么是 MCPMCP 是Model Context Protocol模型上下文协议的缩写由 Anthropic 于 2024 年 11 月提出并开源的一套开放标准协议。它统一了 AI 应用与外部数据源 工具的连接方式让 AI 应用能够以标准化的手段获取上下文、调用工具、执行操作。我们可以把 MCP 理解为AI 世界的 “USB-C” 接口USB-C 用统一的物理接口让不同设备互通互联MCP 用统一的协议让不同的 AI 应用Claude Desktop、各类 IDE、我们自己的 Spring AI 应用等都能对接同一套工具与数据服务。在 MCP 出现之前每个 AI 应用想要接 N 个外部服务就要针对每个服务写 N 套不同的集成代码应用与工具之间是N × M 的点对点网状耦合N 个应用 × M 个工具。有了 MCP 之后工具提供方只需把能力以MCP Server的形式发布一次任何支持 MCP 的客户端都能直接复用集成关系从网状收敛为星型┌────────────┐ ┌────────────┐ │ AI 应用 A │ │ AI 应用 B │ └─────┬──────┘ └─────┬──────┘ │ 统一协议 │ ▼ ▼ ┌──────────────────────────────┐ │ MCP 协议层 │ └──────┬──────────────┬────────┘ ▼ ▼ ┌──────────┐ ┌──────────┐ │ 高德 MCP │ │ GitHub │ │ Server │ │ MCP │ └──────────┘ └──────────┘一句话总结MCP 是AI 应用的开放接口标准它解决了 AI 应用如何统一、动态、可复用地接入外部工具与数据的问题。有了 Tool Calling 为什么还要 MCP两者的区别、优缺点对比什么是 Tool CallingTool Calling函数调用 / 工具调用是 LLM 本身的一项能力模型在生成回复的过程中可以决定调用开发者在代码里预先定义好的函数由应用程序执行这些函数再把执行结果回填给模型最后由模型总结成自然语言回复。在 Spring AI 中原生 Tool Calling 通常通过Tool注解、FunctionCallback、ToolCallback等实现工具就是一段硬编码在应用里的 Java 代码。两者的本质区别MCP 的本质是 Tool Calling 的标准化 动态化。标准化原生 Tool Calling 的工具定义格式、调用协议、错误处理每个框架/每个应用各写各的MCP 把工具发现、工具调用、结果返回统一成了标准协议。动态化原生 Tool Calling 的工具数量、入参出参在编译期就固定死了新增工具必须改代码、重新打包部署MCP 下工具由外部 Server 在运行时动态下发应用侧只要在配置文件里加一个服务地址重启即获得新能力。而且MCP 调用本质上是借助 Tool Calling 能力实现的工具调用——并不是让 AI 服务器主动去调用 MCP 服务而是通过 MCP 客户端把Server 提供了哪些工具告诉 AIAI 想要使用这些工具时就告诉后端程序去执行后端执行完把结果返回给 AI由 AI 最后总结回复。核心区别与优缺点对比维度原生 Tool CallingMCP工具来源代码内硬编码外部 MCP Server 动态提供标准化程度各框架/各家各自实现统一开放协议新增工具成本改代码 重新打包发版新增/修改一个 MCP Server 配置即可跨应用复用差工具绑死在某个应用里好一次开发处处复用运行时扩展不支持支持工具动态发现listTools运行形态与应用同进程本地子进程stdio或远程服务HTTP接入/学习成本低有一定门槛协议、进程、依赖调试复杂度低相对高多一层子进程/网络栈生态丰富度无生态自己写大量现成 Server高德、GitHub、Slack…安全边界应用自身控制需关注 Server 信任、权限与凭证管理原生 Tool Calling 的优点实现简单、同进程调用性能好、调试容易适合应用内部稳定、私有的小工具集。缺点工具与业务代码强耦合每接一个新工具都要发版无法跨应用共享也无法利用社区生态。MCP 的优点工具开发者可以独立维护 Server应用侧通过配置即可动态接入海量第三方能力工具可跨应用复用便于统一治理与审计。缺点多一层子进程/网络开销本地 stdio 模式依赖 Node.js 等运行时可用性MCP 规范仍在快速演进、存在协议版本兼容问题排障链路更长。什么时候用哪个应用内部、固定不变、私有化的工具如查询自家订单库用原生 Tool Calling简单高效。需要接入大量第三方能力或希望工具跨应用复用、独立演进用 MCP一次接入长期受益。两者并不互斥可以共存——一个应用里完全可以既有Tool注解的原生工具又有通过ToolCallbackProvider注入的 MCP 工具。MCP 核心概念架构组成MCP 采用Client / Server架构包含三个角色角色说明在 Spring AI 中的对应物Host宿主应用用户交互与 AI 推理发生的地方如 Claude Desktop、IDE、我们的 Spring AI 应用ChatClientClient客户端与某个 Server 保持 1:1 连接负责能力协商、发起工具/资源/提示请求spring-ai-mcp-client-spring-boot-starter提供的McpClient、ToolCallbackProviderServer服务端通过原语对外暴露能力可以是本地子进程如npx启动的高德 MCP也可以是远程 HTTP 服务amap/amap-maps-mcp-server等一个 Host 可以同时连接多个 Server一个 Client 只对应一个 Server。核心原语PrimitivesMCP 定义了三大核心能力原语Tools工具可被模型调用执行、并把结果返回给模型的函数类比 Spring AI 的Tool。通过tools/list发现、tools/call调用。这是本文接入高德 MCP 用到的能力。Resources资源可被模型读取的外部数据如文件内容、数据库记录、URL 内容等类比 Spring AI 的Resource。Prompts提示词可复用的提示模板服务端定义好模板客户端按需拉取。传输方式Transport传输方式说明适用场景stdio客户端启动一个子进程通过标准输入/输出与该进程通信本地运行 MCP 服务本文场景Streamable HTTP通过 HTTP含 SSE 流式响应访问远程 MCP Server远程部署、跨机器调用SSE早期基于 Server-Sent Events 的单向推送已被 Streamable HTTP 取代一次完整的 MCP 调用流程① 应用启动读取 mcp-servers.json │ ② Client 拉起/连接各 Serverstdio 子进程 or HTTP │ ③ 能力协商capabilities negotiation→ 拉取工具清单 tools/list │ ④ Spring AI 把工具列表转换为 ToolCallback注入 ChatClient │ ⑤ 用户提问 → 模型判断需要调用工具 → 返回工具调用请求 │ ⑥ Spring AI 客户端执行工具 → Client 调用 Server → Server 调用真实业务接口高德 API │ ⑦ 结果回传 → 回填给模型 → 模型总结并回复用户利用 Spring AI 在程序中使用 MCP环境准备1依赖于 Node.js去 官网 傻瓜式安装即可。由于本地 stdio 模式通过npx启动 MCP ServerNode.js 是必装项。2使用地图 MCP 需要 API Key我们可以到 地图开放平台 创建应用并添加 API Key。引入依赖在pom.xml中加入dependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-mcp-client-spring-boot-starter/artifactIdversion1.0.0-M6/version/dependency版本提示重要示例基于1.0.0-M6。Spring AI 1.0.0 正式版GA发布后MCP 客户端的 starter 已统一更名为spring-ai-starter-mcp-client并建议通过spring-ai-bom统一管理版本配置项spring.ai.mcp.client.stdio.*与用法保持一致。1.0.0-M6对应 Spring Boot 3.4.x使用时请留意 Spring Boot 版本兼容性。配置 MCP 服务在resources目录下新建mcp-servers.json配置定义需要用到的 MCP 服务{mcpServers:{amap-maps:{command:npx,args:[-y,amap/amap-maps-mcp-server],env:{AMAP_MAPS_API_KEY:改成你的 API Key}}}}特别注意在 Windows 环境下命令配置需要添加.cmd后缀如npx.cmd否则会报找不到命令的错误。建议不要把 API Key 明文提交到 Git。可以将env.AMAP_MAPS_API_KEY的值改为引用环境变量/配置占位符的方式注入避免密钥泄露。修改 Spring 配置文件由于是本地运行 MCP 服务所以使用stdio 模式并且要指定 MCP 服务配置文件的位置。在application.yml中加入spring:ai:mcp:client:stdio:servers-configuration:classpath:mcp-servers.jsonMCP 客户端程序启动时会额外启动一个子进程来运行 MCP 服务从而能够实现调用。编写调用代码通过自动注入的ToolCallbackProvider获取到配置中定义的 MCP 服务提供的所有工具并提供给ChatClientResourceprivateToolCallbackProvidertoolCallbackProvider;publicStringdoChatWithMcp(Stringmessage,StringchatId){ChatResponseresponsechatClient.prompt().user(message).advisors(spec-spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY,10))// 开启日志便于观察效果.advisors(newMyLoggerAdvisor()).tools(toolCallbackProvider).call().chatResponse();Stringcontentresponse.getResult().getOutput().getText();log.info(content: {},content);returncontent;}从这段代码我们能够看出MCP 调用的本质就是类似工具调用并不是让 AI 服务器主动去调用 MCP 服务而是告诉 AI “MCP 服务提供了哪些工具”如果 AI 想要使用这些工具完成任务就会告诉我们的后端程序后端程序在执行工具后将结果返回给 AI最后由 AI 总结并回复。测试运行运行效果AI 会根据问题自动决策调用高德 MCP 的search_poi等工具如周边搜索、POI 检索拿到结果后再组织成约会地点推荐的回复。可以在地图开放平台的控制台查看 API Key 的使用量注意控制调用次数避免超出限额。注意的坑1安装好 Node.js 后IDEA 可能识别不到 Node.js最好重启IDEA。2Windows 下命令要加.cmd后缀npx写成npx.cmd否则报找不到命令。3首次运行npx会联网下载依赖包amap/amap-maps-mcp-server耗时较长若网络受限如国内访问 npm 源慢可以配置 npm 镜像如淘宝源后再启动。4工具是启动时动态发现的如果 MCP 子进程启动失败Node.js 未安装、包下载失败、命令写错应用虽然能启动但ToolCallbackProvider里可能是空的模型自然就不会使用工具。遇到这种情况先看启动日志里 MCP 客户端的连接与tools/list结果是否正常。5版本兼容性spring-ai-mcp-client-spring-boot-starter是 Milestone 版本坐标升级到 Spring AI 1.0.0 GA 时starter 更名为spring-ai-starter-mcp-client注意同步调整依赖并核对 Spring Boot 版本。6API Key 额度每次工具调用都会真实消耗高德开放平台的调用次数开发调试时注意控制频率避免超限被限流或扣费。7不要把 API Key 硬编码进mcp-servers.json提交到代码库建议通过环境变量或配置中心注入。8stdio 子进程生命周期MCP 服务子进程随应用一起启动/销毁本地多实例部署时要注意 Node 进程的占用与清理。MCP 服务大全目前已经有很多 MCP 服务市场开发者可以在这些平台上找到各种现成的 MCP 服务MCP.so较为主流提供丰富的 MCP 服务目录GitHub Awesome MCP Servers开源 MCP 服务集合阿里云百炼 MCP 服务市场Spring AI Alibaba 的 MCP 服务市场Glama.ai MCP 服务