用Spring Boot搭建企业MCP工具网关:统一接入、租户隔离、白名单与审计

发布时间:2026/7/30 17:57:07

用Spring Boot搭建企业MCP工具网关:统一接入、租户隔离、白名单与审计 文章摘要企业接入多个MCP Server后如果让每个Agent直接连接订单、仓储、客户、知识库和文件工具会快速出现认证分散、工具重名、权限不一致、审计缺失和服务端地址泄露等问题。本文使用Spring Boot设计一个MCP工具网关上游连接多个MCP Server下游向Agent提供统一工具目录并在调用前执行租户校验、工具白名单、风险审批、参数脱敏、超时和审计。文章给出核心数据模型、路由代码和生产配置思路。一、为什么需要MCP工具网关没有网关时Agent A ├─ 订单MCP ├─ 仓储MCP ├─ CRM MCP └─ 知识库MCP Agent B ├─ 订单MCP ├─ 仓储MCP └─ 财务MCP问题包括每个Agent保存多套凭证MCP Server地址暴露给业务应用权限规则分散工具名称冲突无法统一限流无法统一审计Server升级需要修改多个客户端模型可能看到不该看到的工具故障降级困难。引入网关Agent → MCP Tool Gateway → Order MCP → WMS MCP → CRM MCP → Knowledge MCP网关成为控制面而不是简单反向代理。二、网关应该负责什么MCP Server注册 工具发现 工具名称规范化 租户与用户权限 工具白名单 风险分级 审批 限流 超时 重试 幂等 审计 可观测性 降级网关不应该承载所有业务逻辑。订单查询逻辑仍在订单服务网关只负责是否允许调用以及如何安全路由。三、项目结构mcp-tool-gateway ├── config │ ├── McpClientConfig.java │ └── SecurityConfig.java ├── catalog │ ├── ToolCatalog.java │ ├── ToolDescriptor.java │ └── ToolCatalogRefresher.java ├── policy │ ├── ToolPolicyService.java │ ├── RiskLevel.java │ └── PermissionDecision.java ├── routing │ ├── ToolRouter.java │ └── UpstreamMcpServer.java ├── execution │ ├── ToolExecutionService.java │ ├── IdempotencyService.java │ └── ApprovalService.java ├── audit │ ├── ToolAuditService.java │ └── ToolAuditEvent.java └── web ├── ToolCatalogController.java └── ToolExecutionController.java四、依赖dependencyManagementdependenciesdependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-bom/artifactIdversion2.0.0/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementdependenciesdependencygroupIdorg.springframework.ai/groupIdartifactIdspring-ai-starter-mcp-client-webflux/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-webflux/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-security/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-actuator/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactId/dependency/dependencies五、上游Server配置enterprise:mcp:servers:order:url:https://internal.example.com/order/mcptimeout:20sname-prefix:orderwarehouse:url:https://internal.example.com/wms/mcptimeout:30sname-prefix:wmsknowledge:url:https://internal.example.com/knowledge/mcptimeout:15sname-prefix:knowledge不要把Token直接写进YAML。使用VaultKubernetes Secret云Secret ManagerOAuth客户端凭证工作负载身份。六、统一工具描述模型publicrecordToolDescriptor(StringgatewayToolName,StringupstreamServer,StringupstreamToolName,Stringdescription,StringinputSchema,RiskLevelriskLevel,SetStringrequiredScopes,booleanapprovalRequired,Durationtimeout){}风险等级publicenumRiskLevel{LOW,MEDIUM,HIGH,CRITICAL}示例knowledge_search_policy → LOW order_query_status → LOW order_cancel → HIGH finance_refund → CRITICAL七、工具名称规范化上游可能都存在search get_status create网关统一命名order_get_status wms_get_inventory crm_search_customer knowledge_search_policy映射publicStringgatewayName(Stringprefix,StringupstreamName){returnnormalize(prefix)_normalize(upstreamName);}名称一旦对模型开放应保持稳定。上游改名时网关可以保留旧别名避免Prompt和评测集全部失效。八、工具目录刷新ComponentpublicclassToolCatalogRefresher{privatefinalToolCatalogcatalog;privatefinalListMcpSyncClientclients;Scheduled(fixedDelayString${enterprise.mcp.refresh:PT5M})publicvoidrefresh(){for(McpSyncClientclient:clients){refreshClient(client);}}privatevoidrefreshClient(McpSyncClientclient){varresultclient.listTools();catalog.replace(client.getServerInfo().name(),result.tools());}}生产代码需要处理单个Server失败不清空旧目录保存最后成功版本记录刷新时间校验工具Schema检查高风险工具是否有策略支持listChanged主动刷新。九、租户和用户上下文publicrecordGatewayRequestContext(StringrequestId,StringtenantId,StringuserId,SetStringscopes,StringclientId){}这些信息应从认证系统获取而不是信任模型生成的参数。错误{tenantId:T002}模型可以随意修改。正确Access Token → SecurityContext → GatewayRequestContext十、工具白名单每个租户可以配置允许工具 禁止工具 按环境允许 按用户角色允许数据模型publicrecordToolAccessPolicy(StringtenantId,StringtoolName,booleanenabled,SetStringallowedRoles,SetStringrequiredScopes,intcallsPerMinute){}决策publicPermissionDecisiondecide(GatewayRequestContextcontext,ToolDescriptortool){if(!tenantPolicy.enabled(tool.gatewayToolName())){returnPermissionDecision.deny(租户未启用该工具);}if(!context.scopes().containsAll(tool.requiredScopes())){returnPermissionDecision.deny(缺少必要Scope);}returnPermissionDecision.allow();}十一、执行前参数校验模型提交参数后先做JSON Schema校验 Bean Validation 业务范围校验 资源归属校验 敏感字段检测例如publicrecordCancelOrderArgs(NotBlankStringorderId,NotBlankStringreason){}还要验证订单是否属于当前租户 订单是否允许取消 当前用户是否有操作权限JSON Schema合法并不代表业务合法。十二、高风险工具审批if(tool.approvalRequired()){ApprovalRequestapprovalapprovalService.create(context,tool,sanitizedArguments);returnToolExecutionResult.pendingApproval(approval.id());}审批页面展示工具名称业务影响参数当前用户当前租户风险原因幂等键预计执行结果。批准后重新读取最新权限与业务状态不能直接使用旧审批上下文永久执行。十三、幂等设计写操作需要幂等键tenantId toolName businessObjectId requestIntentHashpublicStringbuildIdempotencyKey(GatewayRequestContextcontext,ToolDescriptortool,StringobjectId,StringargumentHash){returnString.join(:,context.tenantId(),tool.gatewayToolName(),objectId,argumentHash);}重复请求返回第一次执行结果 而不是再次取消订单或重复退款十四、调用路由ServicepublicclassToolRouter{privatefinalMapString,McpSyncClientclients;privatefinalToolCatalogcatalog;publicCallToolResultroute(StringgatewayToolName,MapString,Objectarguments){ToolDescriptordescriptorcatalog.require(gatewayToolName);McpSyncClientclientclients.get(descriptor.upstreamServer());returnclient.callTool(descriptor.upstreamToolName(),arguments);}}实际API方法应按使用的MCP Java SDK版本调整但架构原则一致。十五、超时与重试查询类工具可有限重试写操作只有确认幂等后才能重试策略工具超时重试知识检索10秒1次订单查询5秒1次取消订单15秒默认0次退款30秒默认0次不要让HTTP客户端、MCP客户端、网关和Agent四层同时重试。十六、审计事件publicrecordToolAuditEvent(StringrequestId,StringtenantId,StringuserId,StringtoolName,StringupstreamServer,StringargumentHash,StringresultStatus,longdurationMs,StringapprovalId,Instanttimestamp){}日志中不要直接记录密码Token身份证银行卡完整客户隐私文件正文。保存脱敏参数 参数Hash 结果状态 影响对象ID十七、向Agent暴露工具网关可以有两种方式方式一网关本身作为MCP ServerAgent MCP Client → Gateway MCP Server → Upstream MCP Servers优点是协议统一。方式二转换为Spring AI ToolCallbackChatClient → ToolCallback → Gateway内部路由适合只服务Spring AI应用。企业更通用的方式是让网关对外暴露标准MCP Server。十八、健康检查每个上游记录connected protocol_version tool_count last_refresh last_success error_rate P95_latency网关整体不能因为一个非核心Server失败就完全不可用。工具级降级知识工具不可用 → 隐藏知识工具 订单查询不可用 → 返回明确错误 退款工具不可用 → 禁止执行并转人工十九、监控指标mcp_gateway_tool_call_count mcp_gateway_tool_denied_count mcp_gateway_approval_count mcp_gateway_upstream_latency mcp_gateway_upstream_error mcp_gateway_catalog_tool_count mcp_gateway_catalog_refresh_failure mcp_gateway_idempotency_hit mcp_gateway_cross_tenant_denied二十、生产检查清单□ 上游Server统一注册 □ 工具名称稳定且不冲突 □ 凭证不下发给业务Agent □ 工具目录按租户过滤 □ 执行时再次鉴权 □ 高风险工具要求审批 □ 写操作具有幂等键 □ 参数和结果日志已脱敏 □ 超时与重试按工具配置 □ 上游故障支持工具级降级 □ 每次调用可以追溯 □ 跨租户请求默认拒绝总结企业MCP工具网关的价值不是把多个URL合并成一个URL而是建立统一的工具控制面发现 命名 权限 审批 幂等 审计 观测当工具数量、Agent数量和租户数量增长后这一层会成为MCP进入生产环境的关键基础设施。

相关新闻