跳到主要内容 Spring AI + MCP 将后端服务改造成 MCP 服务实践 | 极客日志
Java AI java
Spring AI + MCP 将后端服务改造成 MCP 服务实践 基于 Spring AI 和 MCP 协议将后端服务改造为 MCP 服务的实践方案。内容涵盖服务端工具注册配置、客户端大模型连接及调用流程。通过示例展示了如何使用@Tool 注解暴露业务方法,并通过 ChatClient 实现自然语言调用后端接口,最终由 AI 自动编排工具执行顺序。
HadoopMan 发布于 2026/2/4 更新于 2026/4/18 6.8K 浏览Spring AI + MCP 将后端服务改造成 MCP 服务实践
本文主要介绍 Spring AI 与 MCP 的集成实践。
一、SpringBoot 版本要求
接下来介绍如何将我们的后端服务改造成 MCP 服务,首先,SpringAI 对 SpringBoot 版本有要求,需要 SpringBoot 3.4.x 及以上版本,本文案例使用 3.4.12 版本。如果原有服务版本不是 3.4.x 的,需要升级,JDK 版本最低需要 JAVA 17。我们可以先创建一个简单的项目来帮助我们了解 MCP 的落地效果,然后再慢慢升级已有的服务。
二、服务端(Server)开发
看过 MCP 文档的都知道,MCP 主要包含 服务端(Server)和 客户端 (Client),我们先创建一个服务端的 springboot 项目 spring-ai-mcp-server,注意 springboot 的版本需要 3.4.x 或以上。
1. 在 pom.xml 中添加 Maven 依赖和 spring-ai 相关配置
<dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.ai</groupId >
<artifactId > spring-ai-starter-mcp-server-webmvc</artifactId >
</dependency >
<dependency >
<groupId > org.projectlombok</groupId >
<artifactId > lombok</artifactId >
<optional > true</optional >
</dependency >
</ >
org.springframework.ai
spring-ai-bom
${spring-ai.version}
pom
import
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
dependencies
<dependencyManagement >
<dependencies >
<dependency >
<groupId >
</groupId >
<artifactId >
</artifactId >
<version >
</version >
<type >
</type >
<scope >
</scope >
</dependency >
</dependencies >
</dependencyManagement >
2. 在 application.yml 中配置项目信息 spring:
application:
name: spring-ai-mcp-server
ai:
mcp:
server:
name: spring-ai-mcp-server
version: 1.0 .0
server:
port: 8888
3. 编写 Service,并标注为 MCP 工具 这里的 Service 和我们后端服务的 Service 一样的,就是多了 MCP 工具标注@Tool。
package com.example.springaimcpserver.service;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
import com.example.springaimcpserve.pojo.param.EmployeeQueryParam;
import com.example.springaimcpserve.pojo.vo.EmployeeVO;
@Slf4j
@Service
public class MyMcpService {
@Tool(name = "get-company-info", description = "获取公司全称")
public String getCompanyInfo () {
log.info("获取公司全称" );
return "xxx 有限责任公司" ;
}
@Tool(name = "get-dep-info", description = "获取部门列表")
public List<String> getDepList () {
log.info("获取部门列表" );
return List.of("研发部" , "人事部" , "销售部" , "广告部" , "......" );
}
@Tool(name = "get-all-employee-list", description = "获取所有员工列表")
public List<String> getAllEmployeeList () {
log.info("获取所有员工列表" );
return List.of("张三" , "李四" , "小明" , "小红" , "小花" , "小军" , "小勇" , "小兰" );
}
@Tool(name = "get-dep-employee-list", description = "获取部门员工列表")
public List<EmployeeVO> getDepEmployeeList (EmployeeQueryParam param) {
log.info("获取{}部门员工列表" , param.getDepartment());
Map<String, List<EmployeeVO>> map = new HashMap <>();
map.put("研发部" , List.of(new EmployeeVO ("张三" , "研发部" ), new EmployeeVO ("李四" , "研发部" )));
map.put("人事部" , List.of(new EmployeeVO ("小明" , "人事部" ), new EmployeeVO ("小红" , "人事部" )));
map.put("销售部" , List.of(new EmployeeVO ("小花" , "销售部" ), new EmployeeVO ("小军" , "销售部" )));
map.put("广告部" , List.of(new EmployeeVO ("小勇" , "广告部" ), new EmployeeVO ("小兰" , "广告部" )));
return map.get(param.getDepartment());
}
@Tool(name = "get-employee-count", description = "获取员工数量")
public Integer getEmployeeCount () {
log.info("获取员工数量" );
return 8 ;
}
}
为了演示方便,这里的数据都是虚构的,实际应用中直接从数据库获取,上述代码中涉及到的实体类如下:
package com.example.springaimcpserver.pojo.vo;
import lombok.Data;
import org.springframework.ai.tool.annotation.ToolParam;
@Data
public class EmployeeVO {
@ToolParam(description = "姓名")
private String name;
@ToolParam(description = "部门")
private String department;
public EmployeeVO (String name, String department) {
this .name = name;
this .department = department;
}
}
员工信息查询参数 EmployeeQueryParam
package com.example.springaimcpserver.pojo.param;
import lombok.Data;
import org.springframework.ai.tool.annotation.ToolParam;
@Data
public class EmployeeQueryParam {
@ToolParam(description = "部门")
private String department;
}
上面的 Service 和相关实体仅仅只是比我们平常开发多了 MCP 的相关注解,不影响 Controller 的调用,也就是可以同时使用接口直接调用,也可以通过 MCP 调用,后面继续讲解如何实现 MCP 方式调用。
服务编写好之后,我们需要将该服务里面的方法配置成可以调用的 MCP 工具,可以理解成工具注册。
4. 编写配置类,将 Service 里面的工具暴露出来 package com.example.springaimcpserver.config;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.example.springaimcpserver.service.MyMcpService;
@Configuration
public class ToolCallbackProviderConfig {
@Autowired
private MyMcpService myMcpService;
@Bean
public ToolCallbackProvider toolCallbackProvider () {
return MethodToolCallbackProvider.builder().toolObjects(myMcpService).build();
}
}
上面的代码都编写好以后,我们的 MCP 的服务端就开发好了,接下来开发客户端。
三、客户端(Client)开发 创建一个新的 springboot 项目 spring-ai-mcp-client,注意 springboot 的版本需要 3.4.x 或以上。MCP 架构是大模型驱动的,所以我们还需大模型的支持,这里使用的是 deepseek。
然后去 API keys 里面创建一个 key,用来调用 deepseek 的接口(Spring AI 自动调用,我们不需要手动调用,只需要配置到我们的项目中即可,后面会讲到配置在什么地方)。
1. 在 pom.xml 中添加 Maven 依赖和 spring-ai 相关配置以及 deepseek 的依赖配置 <dependencies >
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.ai</groupId >
<artifactId > spring-ai-starter-mcp-client</artifactId >
</dependency >
<dependency >
<groupId > org.springframework.ai</groupId >
<artifactId > spring-ai-starter-model-deepseek</artifactId >
</dependency >
<dependency >
<groupId > org.projectlombok</groupId >
<artifactId > lombok</artifactId >
<optional > true</optional >
</dependency >
</dependencies >
<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 >
2. 在 application.yml 中配置项目信息以及 deepseek 配置 spring:
application:
name: spring-ai-mcp-client
ai:
mcp:
client:
name: spring-ai-mcp-client
version: 1.0 .0
toolcallback:
enabled: true
type: sync
sse:
connections:
server1:
url: http://localhost:8888
deepseek:
api-key: "这里替换成你的 API key"
server:
port: 8880
上面配置了我们的 MCP 服务端的地址以及使用的大模型 deepseek 的 API key。
3. 编写 Controller 提供对外访问的统一接口 package com.example.springaimcpclient.controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.mcp.SyncMcpToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/chat")
public class MyChatController {
@Autowired
private ChatClient.Builder builder;
@Autowired
private SyncMcpToolCallbackProvider provider;
@PostMapping("/ask")
public String ask (@RequestParam("question") String question) {
ChatClient chatClient = builder.defaultSystem(
"你是 xxx 公司的一名行政 AI 助手,你的名字叫小静。你可以帮助用户解答关于 xxx 公司相关的知识" ).build();
return chatClient.prompt().user(question).toolCallbacks(provider.getToolCallbacks()).call().content();
}
}
四、效果演示
1. 启动服务端(8888 端口) 启动成功后,可以看到有五个工具,也就是我们 service 里面加了@Tool 注解的 5 个方法。
2. 启动客户端(8880 端口)
3. 访问客户端 controller 里面的 /chat/ask 接口,通过聊天方式调用你的 MCP 服务。 我这里使用 postman 作为演示工具,输入问题查看效果:公司有多少人?有哪些部门?每个部门有多少人?张三是哪个部门的?
可以看到,我们只有一个聊天的接口,并没有指定去调用服务端的某个方法,使用 MCP 架构之后,AI 能够自动的去识别和编排工具(方法)的调用顺序,服务端的日志如下: