SpringAI轻松构建MCP Client-Server架构
一、背景与概念
Spring AI 是 Spring Boot 生态下的一个扩展框架,用于简化在 Java 应用中集成大型语言模型(LLM)及外部工具的流程。通过它,我们可以快速创建符合模型上下文协议(MCP,Model Context Protocol)标准的 Client 与 Server,使得大模型能够主动或被动地调用各种资源与工具,从而大幅提升 AI 应用的能力(DeepSeek, 腾讯云)。MCP 将 AI 模型、客户端和服务器抽象成三层架构:
- 客户端(Client):运行在应用方,承担与 LLM 的交互,将用户输入转换为 MCP 请求;
- 服务器(Server):作为中间层,接收 MCP 请求并调用后端资源或功能;
- 资源(Resource):包括数据库、外部 API、业务逻辑等实际可被调用的能力(博客园, 博客园)。
下面我们以 Spring AI MCP 为基础,从环境准备、项目依赖、代码示例和流程图解,详细讲解如何构建一个简单的 MCP Client-Server 架构,并为你提供可复制的代码示例,助你快速上手。
二、环境准备与依赖
1. 系统要求
- Java 17+,Maven 3.6+;
- 操作系统:Linux、macOS 或 Windows(需安装 JDK);
- IDE:IntelliJ IDEA、Eclipse 等。
2. 添加 Maven 依赖
在 Client 与 Server 项目中,我们分别引入 Spring Boot 与 Spring AI MCP Starter。以下是两个项目的 pom.xml
关键片段:
2.1 MCP Server pom.xml
<properties>
<java.version>17</java.version>
<spring-boot.version>3.4.3</spring-boot.version>
<spring-ai.version>1.0.0-M6</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MCP Server Starter(基于 WebMVC) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId>
</dependency>
<!-- Lombok 简化 Getter/Setter(可选) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 辅助库(如 Hutool,可根据需要添加) -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.36</version>
</dependency>
</dependencies>
spring-ai-mcp-server-webmvc-spring-boot-starter
提供了服务器端自动配置与 MCP 协议接口(博客园, DeepSeek);spring-ai-bom
负责统一管理 Spring AI 相关依赖的版本。
2.2 MCP Client pom.xml
<properties>
<java.version>17</java.version>
<spring-boot.version>3.4.3</spring-boot.version>
<spring-ai.version>1.0.0-M6</spring-ai.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>${spring-ai.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MCP Client Starter -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
</dependency>
<!-- 如果需要使用 WebFlux,可引入 reactive 依赖 -->
<!-- <dependency> -->
<!-- <groupId>org.springframework.boot</groupId> -->
<!-- <artifactId>spring-boot-starter-webflux</artifactId> -->
<!-- </dependency> -->
<!-- Lombok、测试类等按需添加 -->
</dependencies>
spring-ai-mcp-client-spring-boot-starter
提供了客户端自动配置、MCP 请求发送与封装框架(Home, 腾讯云);- 两个项目都可以选择引入 WebFlux Starter 来实现异步通信,但本文以 WebMVC 为主。
三、MCP 架构与流程图解
在实际开发中,MCP 架构可以抽象为如下三层关系图:
+------------------+ +--------------------+ +-------------------+
| | | | | |
| AI 大模型 | <---> | MCP Client (前端) | <---> | MCP Server (后端) |
| (DeepSeek/ChatGPT)| | | | |
+------------------+ +--------------------+ +-------------------+
| |
v v
+------------------+ +-------------------+
| 数据库/文件/API | | 外部服务/其他工具 |
+------------------+ +-------------------+
- AI 大模型:通常部署在第三方平台(如 OpenAI、DeepSeek、ChatGPT 等),负责自然语言理解与生成。
- MCP Client:作为模型的前置代理,接收来自前端/用户的指令,转换为 MCP 标准请求(JSON-RPC 2.0),并与 MCP Server 通信。
- MCP Server:接收 MCP Client 发送的请求,根据请求的“能力”( Capability )调用本地资源(如数据库、文件、API 等),并将执行结果返回给 Client。
- Resource(资源层):包含存储、业务系统、工具函数等实际可被调用的内容。
整体流程如下:
- 用户发起问题(如“查询订单状态”)→
- AI 模型生成一段指令(如
{"capability": "order.query", "params": {...}}
)→ - MCP Client 将该指令封装为 JSON-RPC 请求,通过 STDIO、HTTP 等协议发送给 MCP Server→
- MCP Server 根据
capability
调用对应的业务逻辑(如从数据库中查询订单),获取结果→ - MCP Server 将结果以 JSON-RPC 响应形式返回给 Client→
- MCP Client 将调用结果拼接回大模型的上下文,让 AI 模型基于最新信息生成最终回答(博客园, 维基百科)。
四、实现 MCP Server
下面以一个简单的“订单查询”服务为例,演示如何使用 Spring AI MCP Server 构建后端能力提供方。
1. 项目结构概览
mcp-server/
├─ src/
│ ├─ main/
│ │ ├─ java/
│ │ │ └─ com.example.mcpserver/
│ │ │ ├─ McpServerApplication.java // Spring Boot 启动类
│ │ │ ├─ controller/
│ │ │ │ └─ OrderCapabilityController.java // MCP 能力控制器
│ │ │ ├─ service/
│ │ │ │ └─ OrderService.java // 订单业务逻辑
│ │ │ └─ model/
│ │ │ └─ Order.java // 订单领域模型
│ │ └─ resources/
│ │ ├─ application.yml // 配置文件
│ │ └─ data/
│ │ └─ orders.json // 模拟数据库:订单数据
└─ pom.xml
2. 配置文件(application.yml
)
spring:
application:
name: mcp-server
ai:
mcp:
server:
enabled: true # 启用 MCP Server 自动配置
transports:
- name: default
protocol: http # 使用 HTTP 协议
options:
port: 8081 # Server 监听端口
spring.ai.mcp.server.enabled: true
:开启 MCP Server 自动化配置(博客园, DeepSeek);transports
可配置多种传输协议,此处使用 HTTP,监听 8081 端口。
3. 启动类(McpServerApplication.java
)
package com.example.mcpserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
}
- 标准 Spring Boot 启动类,无需额外配置,Spring AI MCP Server Starter 会根据
application.yml
自动注册 MCP Server 对应的 JSON-RPC Endpoint。
4. 领域模型(Order.java
)
package com.example.mcpserver.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
private String orderId;
private String productName;
private Double amount;
private String status;
}
- 简单的订单实体,包含订单号、商品名、金额与状态字段。
5. 业务逻辑(OrderService.java
)
package com.example.mcpserver.service;
import com.example.mcpserver.model.Order;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
@Service
public class OrderService {
private Map<String, Order> orderMap;
@PostConstruct
public void init() throws IOException {
// 从 resources/data/orders.json 读取模拟订单数据
String json = new String(Files.readAllBytes(Paths.get(
getClass().getClassLoader().getResource("data/orders.json").toURI())));
List<Order> orders = new ObjectMapper().readValue(json, new TypeReference<List<Order>>() {});
orderMap = orders.stream().collect(Collectors.toMap(Order::getOrderId, o -> o));
}
public Order queryById(String orderId) {
return orderMap.get(orderId);
}
}
@PostConstruct
注解表示在 Bean 初始化完成后,读取本地 JSON 模拟数据,构建orderMap
;queryById
方法根据订单号查询订单。
6. MCP 能力控制器(OrderCapabilityController.java
)
package com.example.mcpserver.controller;
import com.example.mcpserver.model.Order;
import com.example.mcpserver.service.OrderService;
import org.springframework.ai.mcp.server.annotation.McpCapability;
import org.springframework.ai.mcp.server.annotation.McpController;
import org.springframework.ai.mcp.server.model.McpRequest;
import org.springframework.ai.mcp.server.model.McpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.HashMap;
import java.util.Map;
@McpController
public class OrderCapabilityController {
@Autowired
private OrderService orderService;
/**
* 接收能力请求:capability = "order.query"
* 请求 params 示例:{"orderId":"12345"}
*/
@McpCapability(name = "order.query")
public McpResponse queryOrder(McpRequest request) {
// 从请求中解析参数
String orderId = request.getParams().get("orderId").toString();
Order order = orderService.queryById(orderId);
Map<String, Object> result = new HashMap<>();
if (order != null) {
result.put("orderId", order.getOrderId());
result.put("productName", order.getProductName());
result.put("amount", order.getAmount());
result.put("status", order.getStatus());
} else {
result.put("error", "Order not found");
}
// 返回 MCP 响应
return McpResponse.success(result);
}
}
@McpController
标注该类为 MCP Server 控制器;@McpCapability(name = "order.query")
表示此方法映射到能力名称order.query
;- 方法入参
McpRequest
自动封装 JSON-RPC 中的params
; - 返回值
McpResponse.success(...)
会被序列化为符合 MCP 约定的 JSON-RPC 响应体(博客园, 知乎专栏)。
7. 模拟订单数据(orders.json
)
将以下内容放入 src/main/resources/data/orders.json
:
[
{
"orderId": "10001",
"productName": "无线鼠标",
"amount": 29.99,
"status": "已发货"
},
{
"orderId": "10002",
"productName": "机械键盘",
"amount": 89.50,
"status": "待发货"
}
]
- 该 JSON 列表模拟两个订单,实际项目可替换为数据库或外部 API。
五、实现 MCP Client
MCP Client 负责向 MCP Server 发送请求,并将服务器返回的结果拼接回 AI 模型上下文。下面以向上文 Server 查询订单为例,演示 Client 端如何配置与调用。
1. 项目结构概览
mcp-client/
├─ src/
│ ├─ main/
│ │ ├─ java/
│ │ │ └─ com.example.mcpclient/
│ │ │ ├─ McpClientApplication.java // Spring Boot 启动类
│ │ │ ├─ service/
│ │ │ │ └─ OrderQueryService.java // 订单查询服务
│ │ │ └─ controller/
│ │ │ └─ ClientController.java // 简易 Rest 接口
│ │ └─ resources/
│ │ └─ application.yml // 配置文件
└─ pom.xml
2. 配置文件(application.yml
)
spring:
application:
name: mcp-client
ai:
mcp:
client:
enabled: true
transports:
- name: default
protocol: http # 使用 HTTP 协议
options:
url: http://localhost:8081/mcp # 指向 MCP Server 地址
spring.ai.mcp.client.enabled: true
:开启 MCP Client 自动化配置;transports[0].protocol: http
、url
指定服务端的 MCP Endpoint(注意:默认路径为/mcp
),所以完整地址为http://localhost:8081/mcp
(Home, 腾讯云)。
3. 启动类(McpClientApplication.java
)
package com.example.mcpclient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class McpClientApplication {
public static void main(String[] args) {
SpringApplication.run(McpClientApplication.class, args);
}
}
4. 订单查询服务(OrderQueryService.java
)
package com.example.mcpclient.service;
import org.springframework.ai.mcp.client.McpClient;
import org.springframework.ai.mcp.client.model.McpClientRequest;
import org.springframework.ai.mcp.client.model.McpClientResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class OrderQueryService {
@Autowired
private McpClient mcpClient;
/**
* 调用 MCP Server 的 "order.query" 能力
* @param orderId 订单号
* @return 查询结果 Map
*/
public Map<String, Object> queryOrder(String orderId) {
// 构建 MCP 客户端请求
McpClientRequest request = McpClientRequest.builder()
.capability("order.query")
.params(Map.of("orderId", orderId))
.build();
// 同步调用 MCP Server
McpClientResponse response = mcpClient.call(request);
if (response.isSuccess()) {
return response.getResult();
} else {
return Map.of("error", response.getError().getMessage());
}
}
}
@Autowired private McpClient mcpClient;
:由 Spring AI 自动注入,封装了发送 JSON-RPC 调用的细节;- 使用
McpClientRequest.builder()
,指定capability
与params
,等价于 JSON-RPC 请求中method
与params
字段; mcpClient.call(request)
会将请求通过 HTTP POST 发送到服务器,等待同步返回;- 对
McpClientResponse
进行isSuccess()
判断后,获取结果或错误消息(Home, 腾讯云)。
5. 简易 Rest 接口(ClientController.java
)
package com.example.mcpclient.controller;
import com.example.mcpclient.service.OrderQueryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class ClientController {
@Autowired
private OrderQueryService orderQueryService;
/**
* HTTP GET 接口:/api/order/{id}
* 示例请求:GET http://localhost:8080/api/order/10001
*/
@GetMapping("/order/{id}")
public Map<String, Object> getOrder(@PathVariable("id") String orderId) {
return orderQueryService.queryOrder(orderId);
}
}
- 通过
/api/order/{id}
暴露一个简单的 HTTP 接口,供前端或调用方进行测试; - 当收到请求后,Service 会再调用 MCP Client,将请求转发至 MCP Server,并将最终结果以 JSON 返回给前端。
六、端到端调用流程
下面我们通过一个简化的流程图来说明从 Client 到 Server 的调用步骤:
+-------------+ HTTP POST Index +-------------+
| REST 前端 | GET /api/order/10001 | MCP Client |
| (浏览器/Postman)| ------------------------> | (Spring Boot)|
+-------------+ +-------------+
| |
| 内部调用: |
| mcpClient.call({ |
| "method": "order.query", |
| "params": { "orderId": "10001" } |
| }) |
v v
+-------------+ HTTP POST JSON-RPC +-------------+
| | <-------------------------------- | MCP Server |
| | {"jsonrpc":"2.0", | (Spring Boot)|
| | "method":"order.query", +-------------+
| | "params":{"orderId":"10001"}, |
| 网页/API | "id":1} |
+-------------+ |
| 调用 OrderService.queryById("10001")
v
+-------------+
| 订单数据层 |
+-------------+
|
v
返回结果: {orderId, productName, amount, status}
|
JSON-RPC 响应: {"jsonrpc":"2.0","result":{...},"id":1}
|
v
+-------------+ HTTP 响应: {...} +-------------+
| 前端客户端 | <-------------------------------- | MCP Client |
+-------------+ +-------------+
- 前端(或 Postman、cURL)向 Client 暴露的
/api/order/{id}
发起 GET 请求。 ClientController
调用OrderQueryService.queryOrder(orderId)
,该服务通过McpClient
以 JSON-RPC 方式向服务器发起 HTTP POST 请求(method="order.query"
、params={"orderId":"10001"}
)。- MCP Server 将请求路由到
OrderCapabilityController.queryOrder(...)
,进一步调用OrderService.queryById(...)
查询数据,并将结果封装到McpResponse.success(result)
。 - MCP Server 返回 JSON-RPC 响应体,Client 将结果解析并返回给前端。
七、图示说明
为进一步帮助理解架构,以下是关键流程的简要示意图(采用 ASCII 形式):
┌─────────────────────────────────────────────────────────────────┐
│ 前端浏览器 │
│ GET http://localhost:8080/api/order/10001 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ MCP Client(Spring Boot) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ @RestController │ │
│ │ public Map<String,Object> getOrder(id) { │ │
│ │ return orderQueryService.queryOrder(id); │ │
│ │ } │ │
│ │ │ │
│ │ // 通过 McpClient 调用服务器 │ │
│ │ McpClientRequest req = McpClientRequest.builder() │ │
│ │ .capability("order.query") │ │
│ │ .params(Map.of("orderId", id)) │ │
│ │ .build(); │ │
│ │ McpClientResponse resp = mcpClient.call(req); │ │
│ │ return resp.getResult(); │ │
│ │ │ │
│ │ Spring.ai.mcp.client 自动配置 │ │
│ │ URL = http://localhost:8081/mcp │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ HTTP POST JSON-RPC
▼
┌─────────────────────────────────────────────────────────────────┐
│ MCP Server(Spring Boot) │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ @McpController │ │
│ │ public McpResponse queryOrder(McpRequest req) { │ │
│ │ String orderId = req.getParams().get("orderId"); │ │
│ │ Order o = orderService.queryById(orderId); │ │
│ │ return McpResponse.success(Map.of( │ │
│ │ "orderId", o.getOrderId(), │ │
│ │ "productName", o.getProductName(), │ │
│ │ "amount", o.getAmount(), │ │
│ │ "status", o.getStatus() │ │
│ │ )); │ │
│ │ } │ │
│ │ │ │
│ │ Spring.ai.mcp.server 自动配置 │ │
│ │ Endpoint = /mcp │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ JSON-RPC 响应
▼
┌─────────────────────────────────────────────────────────────────┐
│ MCP Client │
│ // 解析 McpClientResponse 并返回前端结果 │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ 前端浏览器 │
│ // 浏览器接收到最终结果并展示 │
└─────────────────────────────────────────────────────────────────┘
八、常见问题与优化技巧
协议选择:STDIO vs HTTP vs SSE
- STDIO:适用于本地命令行或单机部署,可靠但只能单机调用,不支持跨网络访问(CSDN, 博客园)。
- HTTP(本文示例):最常用,支持分布式部署,通过标准 REST 端点传输 JSON-RPC。
- SSE(Server-Sent Events):适用于服务器主动推送场景,能实现服务器向客户端的异步推送。
并发与性能
- Spring WebMVC 默认采用 Tomcat 容器,典型并发性能可满足大多数场景。若需更高吞吐量,可使用 WebFlux(Reactor Netty)实现异步非阻塞。
- 可以为
McpClient
配置连接池、超时、重试策略等,以保证客户端调用的稳定性与高可用。
安全与鉴权
- 在
application.yml
中可为/mcp
端点添加鉴权过滤器,例如 Basic Auth、OAuth2 等。 - 也可在
@McpCapability
方法中校验McpRequest
中的身份信息,确保只有授权客户端可以调用敏感能力。
- 在
能力扩展
- 除了订单查询外,可以再定义
@McpCapability(name="order.create")
、order.cancel
等方法,Server 端即可对应提供多种功能。 - Client 侧只需调用不同的
capability
,Server 会自动路由至对应方法。
- 除了订单查询外,可以再定义
日志与链路追踪
- Spring AI 提供了对 MCP 通信流程的拦截器,可以将每次请求与响应记录到日志,方便排查问题。
- 推荐集成 Zipkin/Jaeger 等分布式追踪组件,流水线中可追踪每一次从 Client → Server → Resource 的调用时间,以便优化。
九、总结与展望
通过本教程,我们完成了以下内容:
- 理解 MCP 架构:掌握 MCP 将 AI 模型、客户端与服务器解耦的三层架构思想。
- 搭建 MCP Server:利用 Spring AI MCP Server Starter,快速实现能力提供方(订单查询)。
- 构建 MCP Client:使用 Spring AI MCP Client Starter,将 AI 模型与后端能力衔接。
- 端到端测试:通过前端 HTTP 接口,从浏览器或 Postman 发起调用,完成整个请求链路。
未来,你可以基于本文示例进行以下扩展:
- 引入 AI 模型:在 Client 端集成 OpenAI、DeepSeek 或自研 LLM,将用户自然语言直接转为
McpClientRequest
,实现 AI 推理与工具调用闭环。 - 复杂业务场景:Server 端可对接数据库、缓存、中间件,甚至调用外部微服务;并配合异步消息队列,实现大规模分布式任务处理。
- 高级协议特性:使用 SSE 或 WebSocket,构建长连接场景下的实时推送能力(如 AI 生成的中间结果,增量流式返回)。
- 安全与多租户:结合 Spring Security,为不同租户或用户提供隔离的能力访问,并根据角色控制不同的功能。
希望这篇教程能帮助你快速上手 Spring AI MCP,轻松构建符合模型上下文协议的 Client-Server 架构,释放大模型的全部潜力。如有疑问或深入探讨,欢迎随时交流。祝学习愉快!