前言
有了之前的基础,我们现在已经知道了如何 通过调用自己定义的 工具 对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 模块
引入依赖
引入依赖:
<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>
如果出现了 依赖加载不了的情况,可以考虑在 父模块中 添加 以下内容:
<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,参考我的配置:
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容器,这里直接给出代码,不多做解释.
工具类:
@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个月"); } }
配置类:
@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 模块,我这里直接使用 之前的项目作为 客户端了。
引入依赖
对比于之前的 依赖,这一次要加的有:
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-client-webflux</artifactId> </dependency>
基于 WebFlux (流式传输) 的 MCP SSE 依赖。后续方便维护。
tips: 这里如果提示没有版本,可以前往 Server配置 中参考 父模块添加bom依赖,或者直接指定 1.0.0
修改配置
参考以下配置,在原有基础上新增
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 用来测试
@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; } }
这里直接注入就行,框架内部会自动帮我们聚合所有工具,包括 Client 和 Server 的
启动服务
服务正常启动后,Server 中应该有以下内容:
应该包含 Client 的注册信息,Client 中应该包含 Server 的响应信息:
测试
朝 Client 发送 请求,可以获得:
请求成功,MCP 搭建完毕。
总结
没什么要总结的,就这样。后续就是关于 远程MCP服务 的连接,知识库,多模态了.