跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaAIjava

Spring AI + MCP 将后端服务改造成 MCP 服务实践

基于 Spring AI 和 MCP 协议将后端服务改造为 MCP 服务的实践方案。内容涵盖服务端工具注册配置、客户端大模型连接及调用流程。通过示例展示了如何使用@Tool 注解暴露业务方法,并通过 ChatClient 实现自然语言调用后端接口,最终由 AI 自动编排工具执行顺序。

HadoopMan发布于 2026/2/4更新于 2026/7/106.9K 浏览
Spring AI + MCP 将后端服务改造成 MCP 服务实践

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>
</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 中配置项目信息
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;
    }
}

为了演示方便,这里的数据都是虚构的,实际应用中直接从数据库获取,上述代码中涉及到的实体类如下:

员工信息实体 EmployeeVO

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() {
        //这里可以添加多个服务类,多个的时候直接在 toolObjects 里面传多个即可
        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 能够自动的去识别和编排工具(方法)的调用顺序,服务端的日志如下:

此致,整个案例的落地分享结束。

目录

  1. Spring AI + MCP 将后端服务改造成 MCP 服务实践
  2. 一、SpringBoot 版本要求
  3. 二、服务端(Server)开发
  4. 1. 在 pom.xml 中添加 Maven 依赖和 spring-ai 相关配置
  5. 2. 在 application.yml 中配置项目信息
  6. 3. 编写 Service,并标注为 MCP 工具
  7. 4. 编写配置类,将 Service 里面的工具暴露出来
  8. 三、客户端(Client)开发
  9. 1. 在 pom.xml 中添加 Maven 依赖和 spring-ai 相关配置以及 deepseek 的依赖配置
  10. 2. 在 application.yml 中配置项目信息以及 deepseek 配置
  11. 3. 编写 Controller 提供对外访问的统一接口
  12. 四、效果演示
  13. 1. 启动服务端(8888 端口)
  14. 2. 启动客户端(8880 端口)
  15. 3. 访问客户端 controller 里面的 /chat/ask 接口,通过聊天方式调用你的 MCP 服务。
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 为什么要做大语言模型:技术原理与行业价值深度解析
  • MySQL 数据库数据类型选型避坑指南
  • 学术写作 AIGC 降重工具功能对比与选择指南
  • 深度学习项目实战:从模型训练到部署全流程
  • AI 智能体驾驭工程(Harness Engineering)全解析
  • OpenStack 版本发布周期与系列概览
  • 2022 互联网春招备战:Android 开发核心面试题与优化指南
  • 2024 AI 大模型常见面试问题及参考答案
  • 大模型落地应用:难点分析与破局之道
  • Cursor Chat Browser:管理 AI 聊天历史的 Web 应用
  • Copilot Cowork 核心逻辑解析:使用 Kotlin 构建 AI Agent
  • GTC 2026 前瞻:Rubin 平台与 AI 工厂架构解析
  • Midjourney 5 个实用技巧提升生成效率
  • AIGC 赋能现代教育:从课件生成到个性化学习
  • 大语言模型 (LLM) 快速理解
  • 网络安全人才缺口巨大为何招聘却少?深度解析行业现状
  • SQL Server 中生成雪花 ID(Snowflake ID) 的方法
  • 无人机视觉任务常用数据集汇总:检测与分割
  • VR + 具身智能 + 人形机器人:通往现实世界的智能接口
  • C++ 笔试刷题:排序子序列、消减整数与最长上升子序列

相关免费在线工具

  • 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