SpringAI——整合MCP案例

前言

有了之前的基础,我们现在已经知道了如何 通过调用自己定义的 工具 对AI 的功能进行拓展,但是面对一些我们不能自己编写解决方案的场景时,这个工具调用 貌似就有点鸡肋了,作用有限。
所以,我们这篇文章讲讲,MCP 服务的调用。(第三方 提供的 特殊的工具集)

什么是MCP

MCP,实际上是一种协议,它定义了 AI 和 第三方工具集之间进行交互的 统一标准。
实际上,就是为了避免第三方工具集 千奇百怪 的返回值与要求的参数 对AI造成困扰 而制定的统一标准,可以参考 统一度量衡全国推行普通话 ,只不过对象变成了 各种第三方 和 AI。

MCP 服务,就是指第三方 为AI开放的专属服务,只有AI进去了才能获得 正确的结果。

搭建

首先,我们要明白,MCP服务的搭建 分为两部分,Server(服务端) 和 Client(客户端) 。

Server 通过向 Client 暴露工具集 来让 Client 注册
Client 注册完工具集后 将这些 列入自己回答的参考

Server 和 Client 的连接方式 有 stdio sse 两种.

stdio 是本地的方式,在启动的时候 需要添加 Server服务的 jar 包
sse 是Web连接的方式,在启动的时候 需要同时启动 Server 和Client ,Server需要持续监听

Other: 其实我们自己写的 包含工具的服务 也可以理解为 是暴露了工具集的 Server 和 Client 的结合体

这篇文章中 采用 SSE 。(为了具备 后续远程 MCP 的知识基础)
所以开始我们的搭建: (最好分成两个模块,这样好管理 )

大致项目图:

Server (服务端)

新增 Server 模块

引入依赖

引入依赖:

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

如果出现了 依赖加载不了的情况,可以考虑在 父模块中 添加 以下内容:

xml 复制代码
<dependencyManagement>
  <dependencies>
      <dependency>
          <groupId>org.springframework.ai</groupId>
          <artifactId>spring-ai-bom</artifactId>
          <version>1.0.0</version>
          <type>pom</type>
          <scope>import</scope>
      </dependency>
  </dependencies>
</dependencyManagement>

这段内容是 导入 SpringAI 相关的依赖进行管理,当子模块需要的时候 直接分配。scope 一定得是 import

依赖导入完成后,就可以修改相关配置了

修改配置

修改 application.yaml,参考我的配置:

yaml 复制代码
server:
  port: 8085
spring:
  application:
    name: mcp-server
  ai:
    mcp:
      server:
        type: ASYNC
        name: mcp-server
#        stdio: true
        version: "1.0.0"
#        base-url: http://localhost:8085
        enabled: true

其中:

type 是表示 Server 支持 异步(async),还有同步(sync)
name 是方便记忆的 server 名字

version 是表示server 的版本

enabled: 是表示 开启 Server 模式(暴露工具集)

添加工具和配置类 ,将工具注册进 Spring容器,这里直接给出代码,不多做解释.
工具类:

less 复制代码
@Component
@Description("租借图书的 MCP 工具")
public class BookTools {

    @Tool(description = "获取书籍的详细信息")
    public String getBookInfo(@ToolParam(description = "需要获取信息的书的名字") String bookName) {

        String resFormat = """
                书名:%s
                作者:%s
                出版社:%s
                出版日期:%s
             """;
        return String.format(resFormat, bookName, "Alonet", "KiKo 出版社", "2023-01-01");
    }

    @Tool(description = "获取包含特定书籍的书店信息")
    public List<String> getBookStoreInfo(@ToolParam(description = "需要获取信息的书的名字") String bookName) {
        List<String> result = new ArrayList<>();
        String resFormat = """
                店铺名字: %s
                店铺地址: %s
                店铺电话: %s
            """;

        result.add(String.format(resFormat, "StavyTaff Shop", "1234 Street, LoShanJi,America", "18337067077771"));
        result.add(String.format(resFormat,"KiKoRepub Shop", "1234 Street,XiNi,Australia", "1921219054307765"));


        return result;
    }

    @Tool(description = "获取特定店铺特定书籍的租借信息")
    public String getBookRentInfo(@ToolParam(description = "需要获取信息的书的名字") String bookName, @ToolParam(description = "需要获取信息的店铺名字") String storeName) {
        String resFormat = """
                书名:%s
                店铺:%s
                存量:%d
                租借价格:%s
                可租借时长:%s
             """;

        return String.format(resFormat,bookName,storeName,5,"free","3个月");
    }

}

配置类:

kotlin 复制代码
@Configuration
public class McpConfiguration {


    @Bean
    public ToolCallbackProvider weatherTools(BookTools bookTools) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(bookTools)
                .build();
    }
}

启动服务

直接启动 Server 就可以,正常情况下 日志应该会有类似于下图中的输出出现:

包含 Registered tools: 3 。 表示 已经成功注册了 三个工具,然后在 8085端口 对请求进行监听

Client

由于我们采用的是 SSE 的连接方式,Client 这边有比较多的 概念,慢慢来
先创建 Client 模块 ,我这里直接使用 之前的项目作为 客户端了。

引入依赖

对比于之前的 依赖,这一次要加的有:

xml 复制代码
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>

基于 WebFlux (流式传输) 的 MCP SSE 依赖。后续方便维护。
tips: 这里如果提示没有版本,可以前往 Server配置 中参考 父模块添加bom依赖 ,或者直接指定 1.0.0

修改配置

参考以下配置,在原有基础上新增

yaml 复制代码
spring:
    ai:
        mcp:
          client:
            toolcallback:
              enabled: true
            name: mcp-client
            sse:
              connections:
                server1:
                  url: http://localhost:8085
            enabled: true
            type: async

其中部分属性的作用:

toolcallback.enable = true : 允许接收 toolcallback 类型的工具集对象
name: Client 的名字

sse.connections : 内部的 server1 是用户自定义的属性名,表示 Client中 server的名字,内部的url 表示该服务的 监听地址 ,server 名字可以不一样,但是要有 url属性

enabled : 允许启用客户端

type :客户端的类型(异步 or 同步)

不需要添加配置类,因为 工具是 从Server 中传递过来的。

添加测试

添加 Controller 用来测试

less 复制代码
@RestController
@RequestMapping("/mcp")
public class MCPController extends AIController{

    @Autowired
    ToolCallbackProvider mcpToolProvider;

    @Autowired
    ChatClient chatClient;
    
    @GetMapping("/push")
    public String push(@RequestParam("message") String message) {
        ChatResponse response = chatClient.prompt()
                .user(message)
                .toolCallbacks(mcpToolProvider)
                .call()
                .chatResponse();
//
//
        String text = response.getResult().getOutput().getText();
        System.out.println("text = " + text);
        return text;
   }
   
}

这里直接注入就行,框架内部会自动帮我们聚合所有工具 ,包括 ClientServer

启动服务

服务正常启动后,Server 中应该有以下内容:

应该包含 Client 的注册信息 ,Client 中应该包含 Server 的响应信息

测试

朝 Client 发送 请求,可以获得:

请求成功,MCP 搭建完毕。

总结

没什么要总结的,就这样。后续就是关于 远程MCP服务 的连接知识库多模态了.

相关推荐
雾林小妖18 分钟前
springboot集成deepseek
java·spring boot·后端
知识浅谈1 小时前
基于Dify构建本地化知识库智能体:从0到1的实践指南
后端
愿你天黑有灯下雨有伞1 小时前
枚举策略模式实战:优雅消除支付场景的if-else
java·开发语言·策略模式
网络安全打工人1 小时前
CentOS7 安装 rust 1.82.0
开发语言·后端·rust
Dcs1 小时前
gRPC性能陷阱:低延迟网络下的客户端瓶颈揭秘
java
梦兮林夕1 小时前
04 gRPC 元数据(Metadata)深入解析
后端·go·grpc
探索java2 小时前
深入解析 Spring 获取 XML 验证模式的过程
xml·java·spring
pe7er2 小时前
RESTful API 的规范性和接口安全性如何取舍
前端·后端
找不到、了2 小时前
Java设计模式之<装饰器模式>
java·设计模式·装饰器模式
java叶新东老师2 小时前
解决windows系统下 idea、CLion 控制台中文乱码问题
java·windows·intellij-idea