Spring AI 实战系列(十):MCP深度集成 —— 工具暴露与跨服务调用

张开发
2026/4/9 22:00:20 15 分钟阅读

分享文章

Spring AI 实战系列(十):MCP深度集成 —— 工具暴露与跨服务调用
一、系列回顾与本篇定位1.1 系列回顾第一篇至第九篇我们完整掌握了Spring AI的核心能力 —— 基础集成、ChatClient、多模型共存、Prompt 工程、结构化输出、Tool Calling、Chat Memory、多模态能力以及最终的 RAG 检索增强生成。核心痛点在Tool Calling实战中我们的工具是与Spring Boot应用强绑定的无法跨语言、跨服务复用也无法接入社区丰富的第三方工具生态。1.2 本篇定位而MCP (Model Context Protocol)正是解决这一痛点的开放标准它定义了一套标准化的协议让大模型能以统一的方式连接外部工具、数据源和服务实现工具的跨语言、跨服务复用同时接入社区丰富的 MCP 生态。值得庆幸的是Spring AI 1.0 版本已原生支持MCP协议我们可以用极低的成本将现有的 Spring 服务暴露为MCP Server或者作为MCP Client调用本地 / 远程的 MCP 工具。本篇是系列进阶实战篇我们将深度拆解 Spring AI 与 MCP 的集成从核心原理出发理解什么是MCP、为什么要用MCP以及它与Tool Calling的关系。基于现有代码实现本地 Spring 服务暴露为 MCP 工具。实现Spring AI 作为MCP Client调用本地工具与远程MCP Server。覆盖 MCP 配置、安全管控、生产最佳实践与高频踩坑避坑指南。二、核心概念拆解MCP 与 Spring AI 的集成2.1 什么是 MCP (Model Context Protocol)MCP (Model Context Protocol) 是由 Anthropic 推出的开放协议它的核心目标是为大模型提供一套标准化的 “插件系统”让大模型能以统一的方式连接外部世界。简单来说MCP 定义了两个核心角色MCP Server暴露工具、资源和提示词模板的服务可以是任何语言编写的Python、Java、Go 等。MCP Client连接 MCP Server调用其暴露的工具的客户端如 Claude Desktop、Spring AI。2.2 MCP vs 传统 Tool Calling有什么区别对比维度传统Tool CallingMCP (Model Context Protocol)绑定关系工具与应用强绑定无法跨服务复用工具通过标准化协议暴露跨语言、跨服务复用生态需自行开发所有工具可接入社区丰富的 MCP 生态如文件系统、浏览器、数据库等标准化各框架实现不统一开放协议所有兼容 MCP 的客户端 / 服务端都能互通Spring AI 支持原生支持通过Tool注解1.0 版本原生支持可作为 Server 或 Client2.3 Spring AI 对 MCP 的支持Spring AI 1.0 版本对 MCP 提供了双向支持作为 MCP Server将 Spring Bean 中的Tool方法通过ToolCallbackProvider暴露为 MCP 工具。作为 MCP Client通过配置连接本地或远程的 MCP Server调用其暴露的工具。三、实战落地Spring AI 集成 MCP 全流程3.1 环境前提已完成 JDK 17、Spring Boot 3.2.x 环境搭建已配置阿里云百炼 API Key 环境变量DASHSCOPE_API_KEY已在pom.xml中引入Spring AI Alibaba Starter与MCP相关依赖!-- Spring AI Alibaba Starter -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-starter-dashscope/artifactId version1.0.0.2/version /dependency !-- Spring AI MCP Client -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-mcp-client/artifactId /dependency3.2 实战一将本地 Spring 服务暴露为 MCP 工具首先我们将一个普通的 Spring Service通过Tool注解和ToolCallbackProvider暴露为 MCP 工具。第一步定义工具服务创建WeatherService使用Tool注解标记可调用的方法import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; import java.util.Map; /** * 天气查询服务暴露为MCP工具 */ Service public class WeatherService { /** * 根据城市名称获取天气预报 * param city 城市名称 * return 天气预报信息 */ Tool(description 根据城市名称获取天气预报) public String getWeatherByCity(String city) { // 模拟天气数据生产环境可对接真实天气API MapString, String weatherData Map.of( 北京, 降雨频繁其中今天和后天雨势较强需注意, 上海, 多云,15℃~27℃,南风3级当前温度27℃。, 深圳, 阴16天雨30天晴3天 ); return weatherData.getOrDefault(city, 抱歉未查询到对应城市的天气信息); } }第二步配置 MCP Server 暴露工具创建McpServerConfig将WeatherService注册为ToolCallbackProviderimport org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.ai.tool.method.MethodToolCallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * MCP Server配置类将本地工具暴露给外部调用 */ Configuration public class McpServerConfig { /** * 将WeatherService中的Tool方法暴露为MCP工具 */ Bean public ToolCallbackProvider weatherTools(WeatherService weatherService) { return MethodToolCallbackProvider.builder() .toolObjects(weatherService) // 传入包含Tool方法的Bean .build(); } }第三步配置 ChatClient 集成 MCP 工具修改LLMConfig将 MCP 工具集成到ChatClient中import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * ChatModelChatClientMCP集成配置类 */ Configuration public class LLMConfig { /** * 配置带MCP工具支持的ChatClient */ Bean public ChatClient chatClient(ChatModel chatModel, ToolCallbackProvider tools) { return ChatClient.builder(chatModel) // 核心将MCP工具注册到ChatClient .defaultToolCallbacks(tools.getToolCallbacks()) .build(); } }3.3 实战二Spring AI 作为 MCP Client 调用工具现在我们编写 Controller测试带 MCP 支持的ChatClient与普通ChatModel的区别。第一步配置 MCP Client可选连接远程 MCP Server在application.properties中配置MCP Client支持连接远程MCP Serverserver.port8002 # 编码格式配置 server.servlet.encoding.enabledtrue server.servlet.encoding.forcetrue server.servlet.encoding.charsetUTF-8 spring.application.nameSAA-15LocalMcpClient # Spring AI Alibaba 配置 spring.ai.dashscope.api-key${DASHSCOPE_API_KEY} # MCP Client 配置 spring.ai.mcp.client.typeasync spring.ai.mcp.client.request-timeout60s spring.ai.mcp.client.toolcallback.enabledtrue # 可选连接远程MCP Server示例连接本地8001端口的MCP Server spring.ai.mcp.client.sse.connections.mcp-server1.urlhttp://localhost:8001第二步编写测试接口创建McpClientController对比带 MCP 支持和不带 MCP 支持的效果import jakarta.annotation.Resource; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; /** * MCP Client测试接口 */ RestController public class McpClientController { // 带MCP工具支持的ChatClient Resource(name chatClient) private ChatClient chatClient; // 普通ChatModel无MCP工具支持 Resource private ChatModel chatModel; /** * 带MCP支持的对话接口 * 访问示例http://localhost:8002/mcpclient/chat?msg上海的天气怎么样 */ GetMapping(/mcpclient/chat) public FluxString chat(RequestParam(name msg, defaultValue 北京) String msg) { System.out.println(✅ 使用了MCP工具支持); return chatClient.prompt(msg).stream().content(); } /** * 普通对话接口无MCP支持 * 访问示例http://localhost:8002/mcpclient/chat2?msg上海的天气怎么样 */ GetMapping(/mcpclient/chat2) public FluxString chat2(RequestParam(name msg, defaultValue 北京) String msg) { System.out.println(❌ 未使用MCP工具支持); return chatModel.stream(msg); } }接口测试说明测试带 MCP 支持的接口访问http://localhost:8015/mcpclient/chat?msg上海的天气怎么样大模型会自动识别需要调用getWeatherByCity工具获取天气信息后生成回答。测试普通接口访问http://localhost:8015/mcpclient/chat2?msg上海的天气怎么样大模型没有工具支持只能基于通用知识回答可能会编造或说不知道。四、进阶场景连接远程 MCP ServerSpring AI MCP Client 不仅能调用本地工具还能连接远程的 MCP Server接入社区丰富的 MCP 生态。4.1 连接远程 MCP Server 的配置在application.properties中添加远程 MCP Server 的连接配置# 连接多个远程MCP Server spring.ai.mcp.client.sse.connections.mcp-filesystem.urlhttp://localhost:8001 spring.ai.mcp.client.sse.connections.mcp-browser.urlhttp://localhost:80034.2 调用远程 MCP Server 的工具配置完成后远程 MCP Server 暴露的工具会自动注册到ChatClient中你可以像调用本地工具一样调用远程工具无需修改任何代码。五、实践建议5.1 安全管控工具权限控制给不同的工具设置不同的权限确保只有授权的用户能调用敏感工具。MCP Server 认证如果连接远程 MCP Server务必开启认证如 API Key、OAuth2避免未授权访问。输入输出校验对工具的输入参数和输出结果进行严格校验防止注入攻击和敏感数据泄露。5.2 监控与运维工具调用监控记录每次工具调用的时间、参数、结果、耗时用于排查问题和优化性能。MCP 连接监控监控远程 MCP Server 的连接状态及时发现和处理连接中断。日志记录记录详细的 MCP 交互日志便于调试和审计。5.3 工具管理工具文档化给每个工具添加清晰的description说明工具的用途、参数含义和返回值格式。工具版本管理对工具进行版本管理避免工具变更影响现有业务。工具降级当工具调用失败时提供降级方案确保大模型仍能给出合理的回答。六、避坑指南6.1 工具未被识别现象大模型不会调用工具提示 “没有可用的工具”。原因忘记将ToolCallbackProvider注册到ChatClient中。Tool注解的方法不是public的。方法参数类型不支持大模型无法自动转换。解决方案检查SaaLLMConfig中是否调用了defaultToolCallbacks(tools.getToolCallbacks())。确保Tool注解的方法是public的。使用简单的参数类型如String、int避免复杂对象。6.2 远程MCP Server连接失败现象启动服务时报错提示无法连接到远程 MCP Server。原因远程 MCP Server 未启动。配置文件中的 URL 错误。网络不通或防火墙阻止了连接。解决方案检查远程 MCP Server 是否正常启动。核对配置文件中的 URL。检查网络连接和防火墙规则。6.3 大模型仍然编造信息现象即使有MCP工具大模型仍然编造信息。原因系统提示词不够严格。工具的description不够清晰大模型不知道什么时候调用。温度设置得太高。解决方案在系统提示词中明确要求 “如果有工具可用请优先调用工具不要编造信息”。优化工具的description清晰说明工具的用途和适用场景。调低温度至 0.1-0.3。七、本篇总结本篇我们深度掌握了Spring AI与MCP (Model Context Protocol) 的集成从核心原理出发理解了什么是 MCP、为什么要用 MCP以及它与传统 Tool Calling 的区别。基于现有代码实现了本地 Spring 服务暴露为MCP 工具。实现了Spring AI 作为MCP Client调用本地工具与远程MCP Server。覆盖了 MCP 配置、安全管控、生产最佳实践与高频踩坑避坑指南。MCP 是大模型应用开发的未来趋势它让我们能以标准化的方式连接外部工具和数据源接入社区丰富的生态大幅提升开发效率。如果本系列教程对你有帮助欢迎点赞、收藏、评论、转发让更多的 Java 开发者能快速上手 Spring AI

更多文章