很多 Java 团队第一次做 AI 工具调用时容易把问题简化成一句话把内部接口注册成工具让大模型自己决定什么时候调用。Demo 阶段这没问题但一进入企业系统很快会遇到三个现实问题哪些工具能被调用、调用前后怎么审计、模型误调用时怎么兜底。MCP 的价值不只是“让模型能调用工具”。它更像一层工具协议把文件、数据库、内部 API、业务系统能力包装成 AI 应用可发现、可调用的上下文能力。而 Spring AI 的价值是把这些能力纳入 Spring Boot 熟悉的配置、Bean、Advisor、Observability 和权限治理体系里。本文只讲一个核心问题在 Spring AI 里接入 MCP 时不要把 MCP 工具裸塞给 ChatClient应该把工具调用放进可治理的调用链。1. MCP 解决的不是接口调用而是工具协议统一如果只是让大模型调用一个 Java 方法Spring AI 自身的 Tool Calling 已经够用。比如把一个 Tool 方法暴露给模型模型根据上下文选择是否调用。但企业系统里工具来源往往不止一种本地 Java 方法远程订单系统 APICRM、工单、知识库、数据库查询文件系统、浏览器、DevOps 平台不同团队维护的工具服务如果每个工具都按模型厂商的 function calling 格式单独接入最终会变成一堆适配器。MCP 的思路是把这些能力抽象成标准协议由 MCP Server 暴露工具、资源、提示词等能力MCP Client 负责连接和调用。在 Spring AI 中应用可以作为 MCP Client 连接一个或多个 MCP Server并把服务端暴露出来的工具转换成 Spring AI 的 Tool Callback交给 ChatClient 使用。一个典型链路如下这条链路里最容易被忽略的是 Advisor。很多示例会直接把工具挂到 ChatClient 上但真实项目中Advisor 往往才是工具治理的关键位置。2. 为什么不能直接裸用 MCP 工具假设我们接入了一个订单 MCP Server里面有这些工具queryOrderrefundOrderupdateShippingAddressqueryUserProfile如果直接把全部工具交给模型风险很明显模型可能在用户只是咨询时触发写操作也可能在没有权限校验的情况下查询敏感信息。更稳妥的做法是把工具分层只读工具允许模型在问答中自动调用比如订单查询、库存查询。高风险工具需要业务确认比如退款、改地址、创建工单。敏感工具需要额外鉴权比如用户画像、合同、财务数据。禁用工具当前业务场景不暴露给模型。MCP 负责统一工具协议Spring AI 负责把这些工具放进工程治理体系。二者结合时不应该让模型成为最终权限决策者。3. Spring Boot 中的接入方式Spring AI 官方文档提供了 MCP Client Boot Starter。具体依赖名称和配置项可能随 Spring AI 版本变化实际项目应以当前官方文档为准。下面代码展示的是接入思路而不是完整脚手架。Maven 依赖可以类似这样组织dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency一个常见配置是通过 stdio 或 SSE 连接 MCP Server。例如本地 stdio 方式通常会引用一个 MCP Server 配置文件spring: ai: openai: api-key: ${OPENAI_API_KEY} mcp: client: stdio: servers-configuration: classpath:/mcp-servers.jsonmcp-servers.json 可以描述要启动或连接的 MCP Server。不同 MCP Server 的启动命令不同比如 Node、Python 或独立二进制程序{ mcpServers: { order-tools: { command: java, args: [ -jar, order-mcp-server.jar ] } } }在 Spring AI 中MCP Client 可以把远端工具转换为 ToolCallbackProvider再交给 ChatClientConfiguration class AiConfig { Bean ChatClient chatClient( ChatClient.Builder builder, ToolCallbackProvider toolCallbackProvider ) { return builder .defaultSystem( 你是订单客服助手。 查询类问题可以使用工具。 涉及退款、改地址、取消订单时必须先向用户确认。 ) .defaultToolCallbacks(toolCallbackProvider) .build(); } }这段代码的重点不是 API 本身而是边界系统提示词声明业务规则工具回调提供可调用能力但这还不够。因为提示词不是权限系统不能只靠它防止误调用。4. 用 Advisor 给工具调用加一道工程边界Spring AI 的 Advisor 机制可以参与 ChatClient 调用链适合放置记忆、RAG、日志、策略控制等逻辑。对于 MCP 工具调用Advisor 可以承担三类职责请求前根据用户、租户、场景决定允许哪些工具。调用中记录模型选择工具的原因、参数、耗时。响应后检查是否出现敏感字段、危险操作或异常结果。示意代码如下Component class ToolGovernanceService { SetString allowedTools(String userRole, String scene) { if (customer_service.equals(userRole)) { return Set.of(queryOrder, queryLogistics); } if (manager.equals(userRole)) { return Set.of(queryOrder, queryLogistics, createRefundRequest); } return Set.of(); } void audit(String userId, String toolName, MapString, Object args) { // 写入审计日志用户、工具名、参数摘要、traceId、时间 } }真实项目中工具过滤最好不要写死在 Prompt 里而应该落在服务端策略中。原因很简单Prompt 可以被用户输入干扰而服务端权限判断必须稳定、可测试、可追踪。如果当前版本的 Spring AI 暂时不能满足你对“动态过滤工具”的细粒度要求也可以在 MCP Server 层做隔离不同业务场景连接不同 MCP Server或者同一个 Server 根据调用方身份只暴露部分工具。5. MCP Server 侧也要控制工具粒度很多团队设计 MCP Server 时会直接把内部 API 一比一暴露成工具。这通常不是好设计。比如内部订单系统可能有一个接口POST /internal/order/update它可以更新地址、备注、状态、金额等多个字段。如果直接包装成一个 MCP 工具模型就拥有了一个过宽的操作面。更合理的做法是面向 AI 场景重新设计工具public class OrderTools { Tool(description 根据订单号查询订单基础信息只返回客服问答需要的字段) public OrderView queryOrder(String orderNo) { // 调用内部订单服务并裁剪敏感字段 } Tool(description 创建退款申请不直接执行退款需要人工或规则系统审核) public RefundTicket createRefundRequest(String orderNo, String reason) { // 只创建申请不直接退款 } }工具不是内部接口的透传层而是 AI 应用的业务能力边界。它应该具备三个特征参数少且语义明确。返回值经过裁剪不泄露无关字段。高风险操作改成“提交申请”或“生成草稿”不要直接执行最终动作。这也是 Java 后端经验能发挥价值的地方。AI 应用不是绕过工程体系而是更依赖工程体系。6. 实际落地时的几个坑第一个坑是把 MCP 当成 API 网关。MCP 不是替代 REST、RPC 或消息队列的通用网关它面向的是 AI Client 与工具之间的上下文协议。业务系统仍然应该保留原有 API 边界、鉴权、限流和审计。第二个坑是只记录最终回答不记录工具调用。AI 应用排查问题时只看模型回复基本没用。至少要记录用户问题、模型选择的工具、工具参数摘要、工具响应摘要、耗时、异常和 traceId。第三个坑是把写操作交给模型自动执行。即使模型能力再强也不应该让它在没有确认机制的情况下完成退款、删除、发券、改配置等动作。更稳的方案是“模型生成操作意图业务系统执行规则判断”。第四个坑是工具描述写得太像接口文档。工具描述是给模型看的不是给后端开发看的。它应该说明“什么时候用、不能用来做什么、参数怎么填”而不是只写“查询订单接口”。7. 一个更稳的企业架构企业项目里可以把 Spring AI MCP 工具调用拆成四层Chat 层负责会话、流式响应、用户体验。Governance 层负责 Advisor、权限、审计、工具策略。MCP 层负责连接不同 MCP Server。Business Tool 层负责真正访问订单、CRM、知识库等系统。这样做的好处是职责清楚。模型负责理解意图和组织回答MCP 负责工具协议Spring Boot 负责治理和集成业务系统负责最终规则。MCP 让 AI 应用接入工具变得统一但统一不等于放开。对 Java 后端团队来说真正值得投入的不是把更多接口暴露给模型而是把工具设计成可控、可审计、可回滚的业务能力。只有这样Spring AI 接入 MCP 才不会停留在 Demo而是能进入真实系统的生产链路。
Spring AI 接入 MCP:工具调用不是“能调就行”,关键是边界治理
很多 Java 团队第一次做 AI 工具调用时容易把问题简化成一句话把内部接口注册成工具让大模型自己决定什么时候调用。Demo 阶段这没问题但一进入企业系统很快会遇到三个现实问题哪些工具能被调用、调用前后怎么审计、模型误调用时怎么兜底。MCP 的价值不只是“让模型能调用工具”。它更像一层工具协议把文件、数据库、内部 API、业务系统能力包装成 AI 应用可发现、可调用的上下文能力。而 Spring AI 的价值是把这些能力纳入 Spring Boot 熟悉的配置、Bean、Advisor、Observability 和权限治理体系里。本文只讲一个核心问题在 Spring AI 里接入 MCP 时不要把 MCP 工具裸塞给 ChatClient应该把工具调用放进可治理的调用链。1. MCP 解决的不是接口调用而是工具协议统一如果只是让大模型调用一个 Java 方法Spring AI 自身的 Tool Calling 已经够用。比如把一个 Tool 方法暴露给模型模型根据上下文选择是否调用。但企业系统里工具来源往往不止一种本地 Java 方法远程订单系统 APICRM、工单、知识库、数据库查询文件系统、浏览器、DevOps 平台不同团队维护的工具服务如果每个工具都按模型厂商的 function calling 格式单独接入最终会变成一堆适配器。MCP 的思路是把这些能力抽象成标准协议由 MCP Server 暴露工具、资源、提示词等能力MCP Client 负责连接和调用。在 Spring AI 中应用可以作为 MCP Client 连接一个或多个 MCP Server并把服务端暴露出来的工具转换成 Spring AI 的 Tool Callback交给 ChatClient 使用。一个典型链路如下这条链路里最容易被忽略的是 Advisor。很多示例会直接把工具挂到 ChatClient 上但真实项目中Advisor 往往才是工具治理的关键位置。2. 为什么不能直接裸用 MCP 工具假设我们接入了一个订单 MCP Server里面有这些工具queryOrderrefundOrderupdateShippingAddressqueryUserProfile如果直接把全部工具交给模型风险很明显模型可能在用户只是咨询时触发写操作也可能在没有权限校验的情况下查询敏感信息。更稳妥的做法是把工具分层只读工具允许模型在问答中自动调用比如订单查询、库存查询。高风险工具需要业务确认比如退款、改地址、创建工单。敏感工具需要额外鉴权比如用户画像、合同、财务数据。禁用工具当前业务场景不暴露给模型。MCP 负责统一工具协议Spring AI 负责把这些工具放进工程治理体系。二者结合时不应该让模型成为最终权限决策者。3. Spring Boot 中的接入方式Spring AI 官方文档提供了 MCP Client Boot Starter。具体依赖名称和配置项可能随 Spring AI 版本变化实际项目应以当前官方文档为准。下面代码展示的是接入思路而不是完整脚手架。Maven 依赖可以类似这样组织dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-client/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency一个常见配置是通过 stdio 或 SSE 连接 MCP Server。例如本地 stdio 方式通常会引用一个 MCP Server 配置文件spring: ai: openai: api-key: ${OPENAI_API_KEY} mcp: client: stdio: servers-configuration: classpath:/mcp-servers.jsonmcp-servers.json 可以描述要启动或连接的 MCP Server。不同 MCP Server 的启动命令不同比如 Node、Python 或独立二进制程序{ mcpServers: { order-tools: { command: java, args: [ -jar, order-mcp-server.jar ] } } }在 Spring AI 中MCP Client 可以把远端工具转换为 ToolCallbackProvider再交给 ChatClientConfiguration class AiConfig { Bean ChatClient chatClient( ChatClient.Builder builder, ToolCallbackProvider toolCallbackProvider ) { return builder .defaultSystem( 你是订单客服助手。 查询类问题可以使用工具。 涉及退款、改地址、取消订单时必须先向用户确认。 ) .defaultToolCallbacks(toolCallbackProvider) .build(); } }这段代码的重点不是 API 本身而是边界系统提示词声明业务规则工具回调提供可调用能力但这还不够。因为提示词不是权限系统不能只靠它防止误调用。4. 用 Advisor 给工具调用加一道工程边界Spring AI 的 Advisor 机制可以参与 ChatClient 调用链适合放置记忆、RAG、日志、策略控制等逻辑。对于 MCP 工具调用Advisor 可以承担三类职责请求前根据用户、租户、场景决定允许哪些工具。调用中记录模型选择工具的原因、参数、耗时。响应后检查是否出现敏感字段、危险操作或异常结果。示意代码如下Component class ToolGovernanceService { SetString allowedTools(String userRole, String scene) { if (customer_service.equals(userRole)) { return Set.of(queryOrder, queryLogistics); } if (manager.equals(userRole)) { return Set.of(queryOrder, queryLogistics, createRefundRequest); } return Set.of(); } void audit(String userId, String toolName, MapString, Object args) { // 写入审计日志用户、工具名、参数摘要、traceId、时间 } }真实项目中工具过滤最好不要写死在 Prompt 里而应该落在服务端策略中。原因很简单Prompt 可以被用户输入干扰而服务端权限判断必须稳定、可测试、可追踪。如果当前版本的 Spring AI 暂时不能满足你对“动态过滤工具”的细粒度要求也可以在 MCP Server 层做隔离不同业务场景连接不同 MCP Server或者同一个 Server 根据调用方身份只暴露部分工具。5. MCP Server 侧也要控制工具粒度很多团队设计 MCP Server 时会直接把内部 API 一比一暴露成工具。这通常不是好设计。比如内部订单系统可能有一个接口POST /internal/order/update它可以更新地址、备注、状态、金额等多个字段。如果直接包装成一个 MCP 工具模型就拥有了一个过宽的操作面。更合理的做法是面向 AI 场景重新设计工具public class OrderTools { Tool(description 根据订单号查询订单基础信息只返回客服问答需要的字段) public OrderView queryOrder(String orderNo) { // 调用内部订单服务并裁剪敏感字段 } Tool(description 创建退款申请不直接执行退款需要人工或规则系统审核) public RefundTicket createRefundRequest(String orderNo, String reason) { // 只创建申请不直接退款 } }工具不是内部接口的透传层而是 AI 应用的业务能力边界。它应该具备三个特征参数少且语义明确。返回值经过裁剪不泄露无关字段。高风险操作改成“提交申请”或“生成草稿”不要直接执行最终动作。这也是 Java 后端经验能发挥价值的地方。AI 应用不是绕过工程体系而是更依赖工程体系。6. 实际落地时的几个坑第一个坑是把 MCP 当成 API 网关。MCP 不是替代 REST、RPC 或消息队列的通用网关它面向的是 AI Client 与工具之间的上下文协议。业务系统仍然应该保留原有 API 边界、鉴权、限流和审计。第二个坑是只记录最终回答不记录工具调用。AI 应用排查问题时只看模型回复基本没用。至少要记录用户问题、模型选择的工具、工具参数摘要、工具响应摘要、耗时、异常和 traceId。第三个坑是把写操作交给模型自动执行。即使模型能力再强也不应该让它在没有确认机制的情况下完成退款、删除、发券、改配置等动作。更稳的方案是“模型生成操作意图业务系统执行规则判断”。第四个坑是工具描述写得太像接口文档。工具描述是给模型看的不是给后端开发看的。它应该说明“什么时候用、不能用来做什么、参数怎么填”而不是只写“查询订单接口”。7. 一个更稳的企业架构企业项目里可以把 Spring AI MCP 工具调用拆成四层Chat 层负责会话、流式响应、用户体验。Governance 层负责 Advisor、权限、审计、工具策略。MCP 层负责连接不同 MCP Server。Business Tool 层负责真正访问订单、CRM、知识库等系统。这样做的好处是职责清楚。模型负责理解意图和组织回答MCP 负责工具协议Spring Boot 负责治理和集成业务系统负责最终规则。MCP 让 AI 应用接入工具变得统一但统一不等于放开。对 Java 后端团队来说真正值得投入的不是把更多接口暴露给模型而是把工具设计成可控、可审计、可回滚的业务能力。只有这样Spring AI 接入 MCP 才不会停留在 Demo而是能进入真实系统的生产链路。