Spring Boot 集成 Spring AI:实现可被大模型调用的 MCP Server


项目代码: Github


文章目录

  • [1. 本文概述](#1. 本文概述)
  • [2. MCP简介](#2. MCP简介)
  • [3. 环境配置](#3. 环境配置)
    • [3.1 项目依赖](#3.1 项目依赖)
    • [3.2 模拟Service类](#3.2 模拟Service类)
  • [4. 构建MCP Server](#4. 构建MCP Server)
    • [4.1 修改application.yaml启动MCP Server](#4.1 修改application.yaml启动MCP Server)
    • [4.2 新增McpTool类,提供Tools](#4.2 新增McpTool类,提供Tools)
  • [5. MCP应用测试](#5. MCP应用测试)
    • [5.1 配置MCP Server](#5.1 配置MCP Server)
    • [5.2 和大模型对话测试效果](#5.2 和大模型对话测试效果)
  • [6. 用户鉴权token](#6. 用户鉴权token)
    • [6.1 MCP Tool获取用户token](#6.1 MCP Tool获取用户token)
    • [6.2 全局鉴权与权限管理](#6.2 全局鉴权与权限管理)
  • 参考文献

1. 本文概述

大家都知道利用大模型可以做Agent,让用户通过和大模型对话来实现工具调用。但是,很多企业想自己实现一个调用自己业务系统的大模型却不知道如何做。

看完本文你将会学会如下内容:

  1. 什么是MCP。
  2. 使用Spring AI将Spring Boot项目作为MCP Server,将部分接口提供给大模型调用。
  3. 使用大模型实现查询用户信息、下单等行为。
  4. MCP Server接口如何获取用户token。

注:本文只实现MCP Server部分。Client使用Cherry Studio进行演示,后续会写如何自己实现MCP Client。

最终实现效果:

2. MCP简介

MCP(Model Context Protocol)是大模型上下文协议的简称,其实就是Anthropic公司(开发Claude的)定的一个规范,大家都按这个规范来。

MCP协议包含两个主要部分:

  • MCP Server:它为大模型提供了可以调用的工具。例如:查询天气,下单等。
  • MCP Client:负责帮助大模型调用工具的客户端。其实就是和大模型聊天的那个东西,里面增加了调用工具的能力。目前市面上和大模型聊天的工具基本都支持MCP,也就是说都可以作为MCP Client使用,例如Cursor,Client,Claude Code等。

本文主要介绍如何将自己的Spring Boot的部分接口提供给大模型使用。

3. 环境配置

3.1 项目依赖

要使用Spring AI,首先要对Java,Spring Boot进行升级。

  1. Java版本 >= 17,建议使用Java 21.
  2. Spring Boot版本 >= 3.5.0

升级完项目后,增加Spring AI依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
    <version>1.1.0</version>
</dependency>

3.2 模拟Service类

假设我们有一个Service类,提供了查询订单信息下订单的两个接口,代码如下:

java 复制代码
@Service
public class OrderService {

    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

    public Map<String, String> getOrderInfo(String orderCode) {
        logger.info("Query order info: {}", orderCode);
        return Map.of(
                "orderCode", orderCode,
                "createDate", "2025-11-19",
                "itemName", "Toy Car",
                "price", "$5.23"
        );
    }

    public void makeOrder(String itemName, Integer num) {
        logger.info("Make an order; itemName: {}, num: {}", itemName, num);
    }

}

截止目前准备工作已经做完了。

4. 构建MCP Server

4.1 修改application.yaml启动MCP Server

首先,在application.yaml中增加如下配置:

yaml 复制代码
spring:
  ai:
    mcp:
      server:
        enabled: true  # 启动MCP Server
        protocol: STATELESS  # 使用Stateless streamable HTTP方式
        annotation-scanner:
          enabled: true  # 启动注解扫描,用于扫描@McpTool注解
        streamable-http:
          mcp-endpoint: /api/mcp-endpoint  # 定义endpoint,MCP Client通过该endpoint获取有哪些工具可以用
        capabilities:
          tool: true  # 说明该MCP Server提供tool能力

如果你看以前的文章,可能使用的是SSE方式。这种方式以后会被淘汰,因为太耗服务器资源了。

4.2 新增McpTool类,提供Tools

在MVC项目中,我们会提供一个Controller类供前端调用。类似的,现在作为MCP Server,我们可以提供一个McpTool类供MCP Client调用。

要将一个方法声明成一个工具,只需要使用@McpTool注解即可。该方法主要有两个重要参数:

  • name: 工具的名字。不传的话,会使用当前方法名作为该工具的名字。
  • description: 工具的描述。描述该工具是干什么的

对于方法参数,使用@McpToolParam注解,参数如下:

  • description: 该参数的描述
  • required: 是否必传。默认为 true

样例如下:

java 复制代码
import com.iioSnail.shop.service.OrderService;
import org.springaicommunity.mcp.annotation.McpTool;
import org.springaicommunity.mcp.annotation.McpToolParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class OrderMcpTools {

    @Autowired
    private OrderService orderService;

    @McpTool(name = "获取订单信息", description = "根据订单号获取订单信息")
    public Map<String, String> getOrderInfo(@McpToolParam(description = "订单号") String orderCode) {
        return orderService.getOrderInfo(orderCode);
    }

    @McpTool(name = "下单", description = "")
    public void makeOrder(@McpToolParam(description = "商品名称") String itemName,
                          @McpToolParam(description = "数量", required = false) Integer num) {
        if (num == null) {
            num = 1;
        }
        orderService.makeOrder(itemName, num);
    }

}

到这里,我们这个简单的MCP Server就已经构造完毕了。正常启动项目就行了。

5. MCP应用测试

本文使用Cherry Studio作为MCP Client来和MCP Server进行交互。具体安装过程就不再展示了。

5.1 配置MCP Server

Cherry Studio看起来和大部分大模型聊天框差不多。进入之后,点击设置。

然后选择MCP -> Add -> Quick Create:

在该配置页面,我们需要配置如下内容:

  1. Name:随便起一个名字
  2. Type:选择Streamable HTTP。因为我们构建的就是这种类型的MCP Server。
  3. URL :填写mcp-endpoint。就是application.yaml中配置的那个

配置结束后,我们点击右上角的开关,如果弹出"Server updated successfully",说明配置成功了

接下来开启即可:

注意,如果你是首次使用Cherry Studio,(1)位置可能是"x",点进去安装对应的东西即可。

如果配置没问题,重新点进去这个MCP Server,选择Tools,我们就可以看到我们配置的两个工具了。

5.2 和大模型对话测试效果

回到对话页面,选择要使用的MCP工具:

之后就可尝试对话了,我们来测试下:


看起来很成功,我们来看下后台的日志。后台日志如下:

复制代码
2025-11-19T15:30 ... OrderService   : Query order info: 2131244214
2025-11-19T15:31 ... OrderService   : Make an order; itemName: 气球, num: 3

按照预期正确调用了接口。

6. 用户鉴权token

6.1 MCP Tool获取用户token

上述的例子中,大模型与后端交互的过程中,并没有传递任何用户token信息,这样后端是不知道这个行为是哪个用户做的,这显然不符合实际场景。本节将说明如何增加token信息。

本项目中使用的MCP交互类型为Stateless Streamable HTTP,本质还是http调用。因此,只需要MCP Client在Http请求时传入header头即可。

对于后端服务,获取token的方法与传统的http调用基本没有区别。样例里如下:

java 复制代码
@Service
public class UserInfoTools {

    @McpTool(name = "获取用户信息", description = "获取当前登录用户的基本信息")
    public Map<String, String> getUserInfo() {
        // 从RequestContextHolder获取当前请求
        ServletRequestAttributes attributes =
            (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 获取headers
        String token = request.getHeader("token");

        if ("zhangsan123".equals(token)) {
            return Map.of(
                    "name", "张三",
                    "年龄", "23",
                    "余额", "130元"
            );
        } else if ("lisi123".equals(token)) {
            return Map.of(
                    "name", "李四",
                    "年龄", "75",
                    "余额", "3991元"
            );
        } else {
            throw new RuntimeException("未获取用户信息,清重新登录");
        }
    }

}

这里我们新增了一个获取用户信息的类,该接口根据MCP Client传的token来判断当前登录用户。

接下来我们使用Cherry Studio进行测试。首先,我们不做任何配置:

由于我们没有在header中配置token,因此获取余额信息失败了。

接下来我们配置好token,还是在MCP Server中配置。

配置好token后,我们重新尝试:

这次正确获取到了结果。

6.2 全局鉴权与权限管理

实际项目中,我们不可能对每个接口做权限校验。我们需要通过全局的拦截器或切面进行权限验证和管理。这个和大部分Spring项目区别不大,这里就不做具体演示了。

我使用切面形式做了样例。详情请参考源码.


参考文献

相关推荐
vx_bisheyuange3 小时前
基于SpringBoot的宠物商城网站的设计与实现
spring boot·后端·宠物
一个处女座的程序猿O(∩_∩)O3 小时前
Spring Boot、Redis、RabbitMQ 在项目中的核心作用详解
spring boot·redis·java-rabbitmq
唐诗4 小时前
使用 LangChain 创建一个简单的 Agent
前端·langchain·llm
大模型教程4 小时前
2025年AI大模型开发生态白皮书|附123页PDF文件下载
程序员·llm·agent
大模型教程4 小时前
2025年企业级AI Agent(智能体)价值及应用报告|附77页PDF文件下载
程序员·llm·agent
AI大模型5 小时前
工程师学AI之起始篇:理论与实践学习计划
程序员·llm·agent
AI大模型5 小时前
工程师学AI之第二篇:AI大模型vs数学理论
程序员·llm·agent
元Y亨H6 小时前
Spring Boot 路由踩坑:当“通配符”吞掉了你的“固定路径”
spring boot
Learn-Share_HY6 小时前
[Python]如何用uv套件建置python專案與虛擬環境?
python·ai·virtualenv·uv·server·mcp·cline
q***65696 小时前
使用 java -jar 命令启动 Spring Boot 应用时,指定特定的配置文件的几种实现方式
java·spring boot·jar