当前位置: 首页 > news >正文

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 17
  • Spring Boot 3.x
  • Spring AI Alibaba MCP Gateway 1.0.0.3-SNAPSHOT
  • Nacos Server 2.2.3 (通过 Docker 运行)

二、详细实现步骤

1. 父工程配置 (pom.xml)

首先,创建一个 Maven 父工程来管理依赖和模块。

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>mcp-gateway-demo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <name>MCP Gateway Demo</name> <modules> <module>legacy-order-service</module> <module>mcp-gateway</module> </modules> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <spring-boot.version>3.2.5</spring-boot.version> <spring-ai-alibaba.version>1.0.0.3-SNAPSHOT</spring-ai-alibaba.version> </properties> <dependencyManagement> <dependencies> <!-- Spring Boot BOM --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
2. 模拟存量订单服务 (legacy-order-service)

此模块模拟一个已稳定运行多年的订单查询服务,对外提供标准的 REST API。其代码无需为接入 AI 做任何修改

2.1pom.xml(模块级)

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>mcp-gateway-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>legacy-order-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> </project>

2.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 Map<String, 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 ApiResponse<Order> 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 ApiResponse<List<Order>> getOrdersByUser(@PathVariable String userId) { List<Order> 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 ApiResponse<T>(Integer code, String message, T data) { public static <T> ApiResponse<T> success(T data) { return new ApiResponse<>(200, "success", data); } public static <T> ApiResponse<T> 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:8848

2.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 version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>mcp-gateway-demo</artifactId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>mcp-gateway</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring AI Alibaba MCP Gateway 核心依赖 --> <dependency> <groupId>com.alibaba.cloud.ai</groupId> <artifactId>spring-ai-alibaba-mcp-gateway</artifactId> <version>${spring-ai-alibaba.version}</version> </dependency> <!-- Nacos MCP Server 集成依赖 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-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: DEBUG

3.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 Tool

4.1 启动 Nacos Server
使用 Docker 快速启动一个 Nacos 服务器。

docker run -d \ --name nacos-standalone \ -p 8848:8848 \ -e MODE=standalone \ -e JVM_XMS=512m \ -e JVM_XMX=512m \ nacos/nacos-server:v2.2.3

访问http://localhost:8848/nacos,使用账号nacos/nacos登录。

4.2 在 Nacos 中创建 MCP Tool 配置

  1. 进入配置管理 -> 配置列表
  2. 点击“+”新建配置。
    • 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 }}" } }
  1. 点击发布

配置解释

  • requestTemplate.url: 指向我们刚刚启动的legacy-order-service的真实端点。
  • responseTemplate.body: 定义了如何将后端返回的 JSON ({"code":200, "message":"success", "data":{...}}) 转换为一段自然语言描述。{{ .data.xxx }}指向了ApiResponse中的data字段。
5. 运行与测试
  1. 启动服务
    • 在 IDE 或命令行中,依次启动LegacyOrderServiceApplication(端口 8081) 和McpGatewayApplication(端口 8080)。
  2. 验证存量服务
    • 访问http://localhost:8081/api/orders/ORD-1001,应返回原始的 JSON 数据。
  3. 验证 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 协议连接到网关,像调用本地函数一样调用远端的订单查询服务。

扩展建议

  1. 增加更多工具:仿照上述步骤,在 Nacos 中为getOrdersByUser接口添加另一个 MCP Tool 配置。
  2. 集成真实 AI Agent:使用@StructuredPrompt或 Claude Desktop、Cursor 等支持 MCP 的客户端,配置连接到http://localhost:8080/mcp/sse,即可在 AI 对话中直接使用get_order工具。
  3. 安全与生产化:为网关端点添加 Spring Security 认证;将 Nacos 中的敏感信息移至加密配置;考虑将存量服务注册到 Nacos,使网关通过服务名而非硬编码 IP 进行发现和负载均衡。

此工程清晰地展示了 Spring AI Alibaba MCP Gateway 如何作为非侵入性的适配层,在企业现有技术栈与新兴 AI 能力之间架起桥梁。


参考来源

  • 存量服务零改造接入 MCP?Spring AI Alibaba MCP Gateway 架构深度解析
http://www.jsqmd.com/news/855182/

相关文章:

  • SystemVerilog测试套件从IP到SoC的重用:架构设计与工程实践
  • Ps 去除双下巴的最好方法,5 分钟无痕修复
  • RabbitMQ工作模式实践
  • BGA底部填充胶:嵌入式主控板可靠性设计与工艺全解析
  • C++哈希介绍
  • C#学习笔记-入门篇
  • Perplexity写作辅助响应延迟骤增?紧急修复指南:5步定位模型层瓶颈(含实时诊断脚本)
  • 深入解析中断与异常:从概念到x86/ARM/RISC架构实践
  • 非 CTP 柜台连接天勤:众期融航易达等网关差异备忘
  • 超实用!PS 修改截图文字最简单方法,自然无破绽
  • 香橙派Lite全解析:从硬件到应用,玩转ARM开发板与物联网项目
  • 保姆级教程:用Python+OpenCV实现无人机吊舱图像与卫星地图的自动匹配(附代码)
  • uni-app项目上架前必做:手把手教你用Android Studio生成正式签名APK(从证书到发布)
  • 在ai应用开发中利用taotoken实现多模型聚合与成本优化
  • CAN总线接口电路设计实战:从差分信号原理到PCB布局避坑指南
  • 视频融合平台:服务正常运行但没有画面
  • 硬件研发必看:钡特电源 DF2-15S03XT 与金升阳 F1503XT-2WR3 属工业标准模块电源封装与性能
  • AI提速中国品牌全球化:供应链、组织、营销、本地化全面升级!
  • S32K3 FlexCAN驱动避坑指南:从波特率计算到邮箱锁定的实战心得
  • VCSA 8.0部署卡在初始化VCS服务、认证失败?NTP+DNS一招解决
  • COLMAP重建翻车实录:当你的相机内外参已知,却卡在database.db和images.txt对不上?
  • Java Snowy框架CI/CD云效自动化部署流程
  • Skeyevss 视频调阅使用说明
  • 16位微控制器:电池供电与物联网节点的性能功耗平衡之道
  • 3.1 vss-performance 多协议监听与SIP发送流水线异步化
  • Perplexity音乐搜索效率提升300%:实测5种专业级查询语法与避坑清单(附2024最新API响应数据)
  • CPU、MPU、MCU与SoC:从核心概念到实战选型全解析
  • 告别Navicat!用VSCode的Database Client插件搞定MySQL、Redis连接与可视化操作
  • 从开发者视角分享Taotoken文档与示例代码的上手便捷度
  • 【大模型12步学习路线 · 第10步 · ①原理篇】LLM 微调全景:Full FT / LoRA / QLoRA / DoRA / DPO,从 PEFT 到偏好对齐