ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring AI 接入外部 MCP 服务器实战:让高德地图 MCP 工具在应用里跑起来

Spring AI 接入外部 MCP 服务器实战:让高德地图 MCP 工具在应用里跑起来 1. 为什么要在 Spring AI 里接外部 MCP 服务器如果你正在用 Spring AI 写应用大概率会遇到一个尴尬模型本身能聊天但一让它查实时信息就抓瞎。比如问“帮我找重庆沙坪坝附近 5 公里内的约会地点”模型只能凭训练数据瞎编给不出真实地点。MCPModel Context Protocol就是来解决这个问题的——它把外部工具地图、搜索、数据库以标准协议暴露出来Spring AI 作为客户端去连接这些 MCP 服务器模型就能在对话中自动调用工具。这篇聚焦一个具体场景Spring AI 应用通过配置连接外部 MCP 服务器并调用高德地图 MCP 工具。适合已经会用 Spring AI 搭基础对话、但还没跑通 MCP 工具链路的同学。我会给出可复制的application.yml、MCP 客户端 Bean 骨架、请求定制器以及一次真实的高德地图工具调用与返回验证。跑通之后你就能把任意符合 MCP 协议的外部工具接进自己的应用。需要提前说明MCP 服务器地址和鉴权方式由服务提供方决定本文以高德地图 MCP 为例演示配置结构实际地址和 Key 请以你开通的服务为准。另外模型调用本身需要一个大模型 API Key我这边用的是 TaoToken 提供的统一接入官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_end 它兼容 OpenAI 风格接口Spring AI 配置起来比较省事。2. 前置准备依赖、Key 与 MCP 服务开通动手之前先把三样东西备齐否则后面报错会很难定位。第一是Spring AI 版本。MCP 客户端支持在 Spring AI 1.0 之后才稳定我实测用的是 1.1.8建议不要低于 1.0.0。版本不一致会导致McpSyncHttpClientRequestCustomizer这个接口找不到这是最常见的坑。第二是大模型 API Key。Spring AI 的ChatClient需要底层模型我用 TaoToken 的 Key 接入它的 API 地址是 https://taotoken.net/api 兼容 OpenAI 协议所以在 Spring AI 里配置openai相关属性即可。你需要在 TaoToken 控制台创建一个 API Key控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 后面配置里会用到。第三是高德地图 MCP 服务。这个服务需要在对应平台开通后才能拿到 SSE 端点。开通后你会得到两部分信息一个是 MCP 服务器的根地址比如https://dashscope.aliyuncs.com一个是 SSE 路径比如/api/v1/mcps/amap-maps/sse。注意这两者要拼在一起用很多人只填了根地址结果连接一直 404。提示MCP 服务的鉴权通常走Authorization: Bearer key请求头。这个 key 可能是大模型平台的 Key也可能是 MCP 服务单独的 Key以你开通时的说明为准。本文示例统一用同一个 Key 演示。依赖方面pom.xml里引入 MCP 客户端 starterdependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency版本管理建议用 Spring AI 的 BOM避免各 starter 版本打架dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version1.1.8/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement3. 可复制的 application.yml 与 MCP 客户端配置配置分两块模型接入和 MCP 客户端连接。先看完整的application.ymlspring: ai: openai: base-url: https://taotoken.net/api api-key: ${TAOTOKEN_API_KEY} chat: options: model: gpt-4o-mini mcp: client: enabled: true name: spring-ai-mcp-client version: 1.0.0 type: SYNC sse: connections: amap-maps: url: https://dashscope.aliyuncs.com sse-endpoint: /api/v1/mcps/amap-maps/sse几个关键点解释一下。type: SYNC表示用同步客户端对应McpSyncHttpClientRequestCustomizer如果你用异步接口名不一样。sse.connections下面可以挂多个 MCP 服务器amap-maps是自定义名称工具发现时会带上这个前缀。url和sse-endpoint分开写Spring AI 会自动拼接。接下来是请求定制器用来给每个 MCP 请求加上鉴权头。这是最容易漏的一步不加的话 MCP 服务器会返回 401import io.modelcontextprotocol.client.transport.customizer.McpSyncHttpClientRequestCustomizer; import io.modelcontextprotocol.common.McpTransportContext; import org.springframework.stereotype.Component; import java.net.URI; import java.net.http.HttpRequest; Component public class McpSyncHttpClientRequestCustomizerImpl implements McpSyncHttpClientRequestCustomizer { Override public void customize(HttpRequest.Builder builder, String method, URI endpoint, String body, McpTransportContext context) { builder.headers(Authorization, Bearer System.getenv(TAOTOKEN_API_KEY)); } }这里我把 Key 从环境变量读避免硬编码进仓库。customize方法会在每次 MCP 请求前被调用你可以在这里加任意 header比如自定义的 trace-id 方便排查。工具发现是自动的。Spring AI 启动时会连接sse-endpoint拉取该 MCP 服务器暴露的所有工具封装成ToolCallbackProvider。你不需要手动注册每个工具只要注入这个 Bean 就能用。4. 发起一次高德地图工具调用并验证返回配置就绪后写一个 Service 把ToolCallbackProvider挂到ChatClient上。核心代码如下import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatResponse; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; Service public class MapChatService { Resource private ChatClient chatClient; Resource private ToolCallbackProvider toolCallbackProvider; public String doChatWithMcp(String message, String chatId) { ChatResponse response chatClient.prompt() .user(message) .toolCallbacks(toolCallbackProvider) .call() .chatResponse(); return response.getResult().getOutput().getText(); } }注意.toolCallbacks(toolCallbackProvider)这一行是灵魂它把 MCP 发现的所有工具交给模型。模型会根据用户问题自动决定是否调用、调用哪个工具、传什么参数。写个测试跑一下import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.UUID; SpringBootTest class MapChatServiceTest { Autowired private MapChatService mapChatService; Test void testAmapMcp() { String chatId UUID.randomUUID().toString(); String message 我的另一半居住在重庆沙坪坝请帮我找到5公里内合适的约会地点; String answer mapChatService.doChatWithMcp(message, chatId); System.out.println(模型返回 answer); } }实测下来模型会先调用高德地图的“周边搜索”类工具传入关键词和坐标拿到 POI 列表后再组织成自然语言回答。返回结果大概长这样根据高德地图的搜索结果沙坪坝附近 5 公里内适合约会的地点有 1. 磁器口古镇约 2.3 公里—— 适合散步、拍照有很多特色小吃 2. 三峡广场约 1.8 公里—— 商圈电影院和餐厅集中 3. 歌乐山森林公园约 4.5 公里—— 适合喜欢户外的情侣 ...如果你看到类似带真实地点名和距离的回答说明整条链路通了Spring AI → MCP 客户端 → 高德地图 MCP 服务器 → 工具执行 → 模型总结。5. 本篇常见报错与排查清单跑不通的时候按下面顺序排查基本能覆盖 90% 的问题。报错一McpSyncHttpClientRequestCustomizer找不到类。这是 Spring AI 版本太低。1.0.0 之前没有这个接口升级到 1.1.x 即可。检查spring-ai-bom版本。报错二连接 MCP 服务器返回 404。大概率是url和sse-endpoint拼错了。Spring AI 拼接规则是url sse-endpoint所以url不要带结尾斜杠sse-endpoint要以斜杠开头。用 curl 先验证一下地址能不能通curl -N -H Authorization: Bearer $TAOTOKEN_API_KEY \ https://dashscope.aliyuncs.com/api/v1/mcps/amap-maps/sse能持续输出event: endpoint之类的 SSE 流就说明地址对。报错三401 Unauthorized。请求定制器没生效或者 Key 不对。确认McpSyncHttpClientRequestCustomizerImpl被Component扫描到且 Key 环境变量在启动时已注入。可以在customize方法里打日志确认它被调用了。报错四模型不调用工具直接瞎编答案。两个原因一是toolCallbacks没挂上检查是否注入了ToolCallbackProvider二是模型本身不支持 function calling换一个支持工具调用的模型。报错五工具调用超时。MCP 服务器响应慢或者网络问题。可以在application.yml里调大超时spring: ai: mcp: client: request-timeout: 30s注意MCP 工具调用会消耗额外的 token工具描述 调用参数 返回结果都算如果发现费用比纯聊天高这是正常的。6. 把链路固化下来后续怎么扩展跑通高德地图之后你会发现这套结构是通用的。想接第二个 MCP 服务器只要在sse.connections下加一段配置换个名称和地址就行ToolCallbackProvider会自动聚合所有服务器的工具。模型在对话时能看到全部工具按需选择。如果你打算长期在编码或 Agent 场景里用这套链路建议关注 TaoToken 的 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 里面有 Spring AI 和其他框架的配置示例。想先验证模型对话是否正常可以直接用模型对话页面https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 测一下 Key 是否可用。最后留一个我踩过的坑MCP 工具返回的数据结构可能和模型预期不一致导致模型解析失败。遇到这种情况先在customize里把body打出来看看实际返回再决定是调工具参数还是换工具。工具调用不是黑盒日志打全了问题都好定位。
返回列表