Spring AI MCP网关实战项目

Spring AI MCP网关实战项目 该提问与当前博客内容无直接关联。为了提供一个能实际运行的 Spring AI Alibaba MCP Gateway 工程我们将构建一个完整的示例包含一个模拟的存量 HTTP 服务、Nacos 配置中心以及 MCP Gateway 网关本身。此工程将演示从零开始如何将一个无需改造的 RESTful 服务暴露给 AI Agent。一、工程结构与组件说明我们将创建三个独立的 Spring Boot 应用模块共同构成一个可运行的演示系统。mcp-gateway-demo/ ├── legacy-order-service/ # 模块一模拟存量订单服务零改造 ├── mcp-gateway/ # 模块二MCP 网关核心 ├── nacos-server/ # 模块三Nacos 服务器Docker 化 └── pom.xml # Maven 父工程技术栈:Java 17Spring Boot 3.xSpring AI Alibaba MCP Gateway 1.0.0.3-SNAPSHOTNacos Server 2.2.3 (通过 Docker 运行)二、详细实现步骤1. 父工程配置 (pom.xml)首先创建一个 Maven 父工程来管理依赖和模块。?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.example/groupId artifactIdmcp-gateway-demo/artifactId version1.0-SNAPSHOT/version packagingpom/packaging nameMCP Gateway Demo/name modules modulelegacy-order-service/module modulemcp-gateway/module /modules properties maven.compiler.source17/maven.compiler.source maven.compiler.target17/maven.compiler.target spring-boot.version3.2.5/spring-boot.version spring-ai-alibaba.version1.0.0.3-SNAPSHOT/spring-ai-alibaba.version /properties dependencyManagement dependencies !-- Spring Boot BOM -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-dependencies/artifactId version${spring-boot.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement /project2. 模拟存量订单服务 (legacy-order-service)此模块模拟一个已稳定运行多年的订单查询服务对外提供标准的 REST API。其代码无需为接入 AI 做任何修改。2.1pom.xml(模块级)?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd parent groupIdcom.example/groupId artifactIdmcp-gateway-demo/artifactId version1.0-SNAPSHOT/version /parent modelVersion4.0.0/modelVersion artifactIdlegacy-order-service/artifactId dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency /dependencies /project2.2 订单实体与控制器 (OrderController.java)package com.example.legacyorderservice; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.*; RestController RequestMapping(/api/orders) public class OrderController { // 模拟内存数据库 private final MapString, Order orderDatabase new HashMap(); public OrderController() { // 初始化一些测试数据 orderDatabase.put(ORD-1001, new Order(ORD-1001, USER-001, 299.99, SHIPPED, LocalDateTime.now().minusDays(2))); orderDatabase.put(ORD-1002, new Order(ORD-1002, USER-002, 150.50, PROCESSING, LocalDateTime.now().minusDays(1))); orderDatabase.put(ORD-1003, new Order(ORD-1003, USER-001, 89.99, DELIVERED, LocalDateTime.now().minusDays(5))); } GetMapping(/{orderId}) public ApiResponseOrder getOrderById(PathVariable String orderId) { Order order orderDatabase.get(orderId); if (order ! null) { return ApiResponse.success(order); } else { return ApiResponse.error(404, Order not found: orderId); } } GetMapping(/user/{userId}) public ApiResponseListOrder getOrdersByUser(PathVariable String userId) { ListOrder userOrders orderDatabase.values().stream() .filter(order - order.userId().equals(userId)) .toList(); return ApiResponse.success(userOrders); } // 订单实体记录 public record Order(String orderId, String userId, Double amount, String status, LocalDateTime createTime) {} // 统一API响应格式 public record ApiResponseT(Integer code, String message, T data) { public static T ApiResponseT success(T data) { return new ApiResponse(200, success, data); } public static T ApiResponseT error(Integer code, String message) { return new ApiResponse(code, message, null); } } }2.3 应用配置与启动 (application.yml)server: port: 8081 spring: application: name: legacy-order-service # 可选注册到Nacos方便网关发现此处演示不依赖注册中心网关直接配置地址 # cloud: # nacos: # discovery: # server-addr: 127.0.0.1:88482.4 启动类 (LegacyOrderServiceApplication.java)package com.example.legacyorderservice; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class LegacyOrderServiceApplication { public static void main(String[] args) { SpringApplication.run(LegacyOrderServiceApplication.class, args); System.out.println(存量订单服务已启动: http://localhost:8081); System.out.println(API示例: GET http://localhost:8081/api/orders/ORD-1001); } }3. MCP 网关工程 (mcp-gateway)这是核心组件负责协议转换。3.1pom.xml(模块级)?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd parent groupIdcom.example/groupId artifactIdmcp-gateway-demo/artifactId version1.0-SNAPSHOT/version /parent modelVersion4.0.0/modelVersion artifactIdmcp-gateway/artifactId dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI Alibaba MCP Gateway 核心依赖 -- dependency groupIdcom.alibaba.cloud.ai/groupId artifactIdspring-ai-alibaba-mcp-gateway/artifactId version${spring-ai-alibaba.version}/version /dependency !-- Nacos MCP Server 集成依赖 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-alibaba-starter-nacos-mcp-server/artifactId version${spring-ai-alibaba.version}/version /dependency /dependencies /project注意spring-ai-alibaba-mcp-gateway的稳定版本可能已发布请关注官方仓库更新版本号。3.2 网关配置 (application.yml)server: port: 8080 spring: application: name: mcp-gateway ai: alibaba: mcp: nacos: server-addr: 127.0.0.1:8848 namespace: public username: nacos password: nacos gateway: # 这里配置的是Nacos中注册的MCP Server数据ID前缀对应的服务名。 # 我们将在Nacos中创建配置其DataId为 mcp-server.legacy-order-service.get_order service-names: - legacy-order-service # 日志配置便于调试 logging: level: com.alibaba.cloud.ai.mcp: DEBUG3.3 启动类 (McpGatewayApplication.java)package com.example.mcpgateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; SpringBootApplication public class McpGatewayApplication { public static void main(String[] args) { SpringApplication.run(McpGatewayApplication.class, args); System.out.println(MCP Gateway 已启动: http://localhost:8080); System.out.println(MCP SSE 端点: http://localhost:8080/mcp/sse); System.out.println(请确保Nacos(8848)已运行并已添加相关配置。); } }4. 启动 Nacos 并配置 MCP Tool4.1 启动 Nacos Server使用 Docker 快速启动一个 Nacos 服务器。docker run -d \ --name nacos-standalone \ -p 8848:8848 \ -e MODEstandalone \ -e JVM_XMS512m \ -e JVM_XMX512m \ nacos/nacos-server:v2.2.3访问http://localhost:8848/nacos使用账号nacos/nacos登录。4.2 在 Nacos 中创建 MCP Tool 配置进入配置管理 - 配置列表。点击“”新建配置。Data ID:mcp-server.legacy-order-service.get_order(命名规则:mcp-server.{service-name}.{tool-name})Group:DEFAULT_GROUP配置格式:JSON配置内容:{ name: get_order, description: 根据订单ID查询订单详情, inputSchema: { type: object, properties: { orderId: { type: string, description: 订单编号例如ORD-1001 } }, required: [orderId] }, requestTemplate: { url: http://localhost:8081/api/orders/{{ .args.orderId }}, method: GET, headers: { Content-Type: application/json } }, responseTemplate: { body: 订单ID: {{ .data.orderId }}, 用户ID: {{ .data.userId }}, 金额: {{ .data.amount }}, 状态: {{ .data.status }} } }点击发布。配置解释requestTemplate.url: 指向我们刚刚启动的legacy-order-service的真实端点。responseTemplate.body: 定义了如何将后端返回的 JSON ({code:200, message:success, data:{...}}) 转换为一段自然语言描述。{{ .data.xxx }}指向了ApiResponse中的data字段。5. 运行与测试启动服务在 IDE 或命令行中依次启动LegacyOrderServiceApplication(端口 8081) 和McpGatewayApplication(端口 8080)。验证存量服务访问http://localhost:8081/api/orders/ORD-1001应返回原始的 JSON 数据。验证 MCP Gateway使用MCP Inspector工具进行测试。这是一个图形化的 MCP 客户端。下载并运行 MCP Inspector。在连接设置中选择SSE (Server-Sent Events)模式URL 填写http://localhost:8080/mcp/sse。连接成功后你将在工具列表中看到get_order工具。在工具输入框中填入{orderId: ORD-1001}并调用。预期结果MCP Inspector 将收到经过网关转换后的自然语言响应订单ID: ORD-1001, 用户ID: USER-001, 金额: 299.99, 状态: SHIPPED。三、工程总结与扩展至此一个完整的、可运行的“零改造接入”演示工程已经构建完成。其核心价值在于存量服务 (legacy-order-service)未做任何代码修改保持了纯粹的 REST API。MCP 网关 (mcp-gateway)作为独立进程通过读取 Nacos 中的配置动态地将 MCP 协议调用翻译为对存量服务的 HTTP 调用并将响应格式化。AI Agent可以通过标准的 MCP 协议连接到网关像调用本地函数一样调用远端的订单查询服务。扩展建议增加更多工具仿照上述步骤在 Nacos 中为getOrdersByUser接口添加另一个 MCP Tool 配置。集成真实 AI Agent使用StructuredPrompt或 Claude Desktop、Cursor 等支持 MCP 的客户端配置连接到http://localhost:8080/mcp/sse即可在 AI 对话中直接使用get_order工具。安全与生产化为网关端点添加 Spring Security 认证将 Nacos 中的敏感信息移至加密配置考虑将存量服务注册到 Nacos使网关通过服务名而非硬编码 IP 进行发现和负载均衡。此工程清晰地展示了 Spring AI Alibaba MCP Gateway 如何作为非侵入性的适配层在企业现有技术栈与新兴 AI 能力之间架起桥梁。参考来源存量服务零改造接入 MCPSpring AI Alibaba MCP Gateway 架构深度解析