上一篇文章Spring AI MCP入门:手写一个Jdbc MCP Server中介绍了如何使用Spring AI MCP 开发一个MCP Server 及遇到的问题,这篇文章将介绍使用Spring AI MCP 开发MCP 客户端来调用MCP Server 。
引入依赖
客户端需要通过AI大模型调用MCP Server ,需要引入大模型的依赖,我这里使用的是硅基流动中的 DeepSeek-V3 模型,引入的是spring-ai-starter-model-openai
,大模型基本上使用的都是openai 的接口规范,所以引入openai也是可以用的。具体依赖信息如下:
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>site.sunlong</groupId>
<artifactId>mcp-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mcp-client</name>
<description>mcp-client</description>
<properties>
<java.version>17</java.version>
<spring-ai.version>1.0.0-M7</spring-ai.version>
</properties>
<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-openai</artifactId>
</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>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
mcp client 依赖也分为两类:
- spring-ai-starter-mcp-client :不管是使用stdio 还是http形式的SSE 都要引入该依赖。
- spring-ai-starter-mcp-client-webflux:如果是使用响应式的SSE,引入该依赖
这里选择spring-ai-starter-mcp-client依赖,使用http形式调用。
调用的MCP Server
此次使用3个不同开发语言的MCP Server:
- nodejs版本MCP Server: modelcontextprotocol/server-filesystem :操作本地文件系统的,这里使用stdio形式调用
- Python 版本MCP Server: excel-mcp-server :操作本地Excel文件的,这里使用SSE形式调用。
- Java版本MCP Server: jdbc-mcp-server :上篇文章使用 Spring AI MCP 开发的MCP Server demo,这里使用SSE形式调用。
配置介绍
本文用到的配置文件如下:
bash
# 大模型相关依赖
spring.ai.openai.base-url=https://api.siliconflow.cn
spring.ai.openai.api-key=sk-ltopg
spring.ai.openai.chat.options.model=deepseek-ai/DeepSeek-V3
# 客户端类型;ASYNC(异步)或者SYNC(同步)
spring.ai.mcp.client.type=SYNC
# MCP Client超时时间
spring.ai.mcp.client.request-timeout=1800s
spring.ai.mcp.client.toolcallback.enable=true
# stdio 形式 MCP Server配置
spring.ai.mcp.client.stdio.servers-configuration=classpath:mcp-servers.json
# stdio 形式 MCP Server配置
spring.ai.mcp.client.sse.connections.excel-mcp-server.url=http://localhost:8000
spring.ai.mcp.client.sse.connections.jdbc-mcp-server.url=http://localhost:9090
简单解释一下部分配置:
spring.ai.mcp.client.request-timeout
:客户端请求超时时间。我这里配置的是1800s,即30分钟,之前设置过几分钟的,不知道是我这里的网不好还是因为使用的免费的token,请求贼慢,设置时间请求成功概率就大了很多。spring.ai.mcp.client.stdio.servers-configuration
:使用stdio方式调用MCP Server时指定的配置文件,内容如下
bash
{
"mcpServers": {
"server-filesystem": {
"command": "npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"D:\\projects\\excel-mcp-server-main\\excel_files"
]
}
}
}
如果不想使用这么方式,也可以写在配置文件中,形式如下,个人建议还是用上面的方式比较方便:
yaml
spring:
ai:
mcp:
client:
stdio:
root-change-notification: true
connections:
server1:
command: npx.cmd
args:
- -y
- @modelcontextprotocol/server-filesystem
- D:\\projects\\excel-mcp-server-main\\excel_files
env:
API_KEY: your-api-key
DEBUG: "true"
-
spring.ai.mcp.client.sse.connections.excel-mcp-server.url
:sse方式调用时,MCP Server的url地址,不需要后面再加sse前缀 -
spring.ai.mcp.client.toolcallback.enable=true
:启用或禁用 MCP 客户端对 工具回调(Tool Callback) 的自动配置和集成。
这里只是简单介绍一下,具体可以看 官网
实现
注入ChatClient:
java
@Configuration
public class McpClientConfiguration {
@Bean
ChatClient chatClient(OpenAiChatModel chatModel, List<McpSyncClient> mcpClients ) {
var mcpToolProvider = new SyncMcpToolCallbackProvider(mcpClients);
return ChatClient
.builder(chatModel)
.defaultTools(mcpToolProvider)
.build();
}
}
java
@RestController
@RequestMapping("qwen")
public class QwenChatController {
@Autowired
private ChatClient chatClient;
@GetMapping("/ai/generate")
public Map<String, String> generate(@RequestParam(value = "message") String message) {
String content = this.chatClient.prompt()
.user(message)
.call()
.content();
return Map.of("generation", content);
}
}
测试
客户端启动之后向服务端发起请求,在控制台可以看到服务端响应信息。
接下来进行测试:
-
测试secure-filesystem-server
对应的盘符下就可以看到mcp.txt 文件且文件内容也是正确的。
-
测试jdbc-mcp-server 问一下数据库中有哪些表
-
综合测试 多个MCP Server 最终要配合起来使用才是王道,下面问这样一个问题,看最终的效果:
先在D:\projects\excel-mcp-server-main\excel_files文件夹下创建一个名为db.xlsx的文件,然后查询数据库中i18n_msg表中的数据,最后把查到的数据写入到db.xlsx文件中
可以看到结果还是可以
遇到的问题
使用stdio方式启动jdbc-mcp-server失败
刚开始使用sse 的方式调用jdbc-mcp-server 成功,我想再试试通过stdio方式看看可不可以,结果失败。
mcp-servers.json
配置如下:
json
{
"mcpServers": {
"server-filesystem": {
"command": "npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"D:\\projects\\excel-mcp-server-main\\excel_files"
]
},
"jdbc-mcp-server": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dspring.main.banner-mode=off",
"-Dspring.main.web-application-type=none",
"-jar",
"D:\\projects\\jdbc-mcp-server\\target\\jdbc-mcp-server-0.0.1-SNAPSHOT.jar"
]
}
}
}
启动会报如下错误: 通过在
StdioClientTransport
类中找到报错后,通过调试发现是把jdbc-mcp-server 控制台打印的信息做为了响应信息导致解析失败,下图1是server-filesystem 正确的响应的信息,图2是jdbc-mcp-server响应的信息:
看了网上的帖子,感觉该配置的也配置了,不知道为什么。
引入webflux依赖时,启动报错
当引入 spring-ai-starter-mcp-client-webflux
,启动会报如下错误
目前Spring AI MCP相关方面的版本还没有正式发布,这里也不过多深究。上述问题不知道是否是bug, 如果有知道原因或者解决方案的同学麻烦在评论区留言告诉我一下,谢谢。
至此,本篇使用Spring AI MCP Client连接MCP Server的简单示例到此就完成了,可以看到操作并不复杂,不过想了解更多内容的可以去官网看一下。