上手开发AI-MCP工作流
一、介绍
本章使用 Spring AI MCP,实现服务端 MCP 和 客户端 MCP,完成相应功能开发,体验 AI 工作流完成的指令动作。
本节功能服务包括;
- Spring AI MCP 框架接入。
- 对接,Spring AI MCP 共用服务端,如;https://smithery.ai/、https://glama.ai/mcp/servers
- 开发,Spring AI MCP 个人客户端,基于 Java 实现客户端。这块是一个独立的新工程组件。
- 注意,你需要安装 nodejs 环境。否则没法执行 npx 脚本。
二、对接MCP服务
首先完成MCP 服务端的对接使用,通过AI完成 MCP 接口执行和调用。
扩展了解 MCP 是什么;https://modelcontextprotocol.io/introduction
1. POM文件中引入依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>
在 app 模块下,增加 MCP 框架的引入。
注意Spring AI 每个版本引入依赖的方式名称会有所改变。
2. 配置MCP
2.1 配置 json

- mcp 的服务可以由nodejs、python、java等语言实现。
- https://smithery.ai/、https://glama.ai/mcp/servers 可以搜索公用的 MCP 服务。
- 本章只对接处理文件的 mcp 服务,就是 AI 对话的过程中可以读取、设置、操作你的文件。
- 注意这里的文件夹路径要修改为你的,有效的,有权限的。否则 MCP 服务启动报错。
2.2 引入 json
mcp-servers-config.json:
{
"mcpServers": {
"filesystem-mcp-server": {
"command": "D:\\Public_software\\Nvm_nodejs\\nvm\\nvm\\v18.20.4\\npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\Dell\\Desktop",
"C:\\Users\\Dell\\Desktop"
]
}
}
}
以上文件内容可以从以下两个地址获取:
https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem
https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html
在 Spring AI 中,MCP 的对接,可以通过 json 文件的方式进行配置,也可以通过代码配合数据库的方式设置 MCP 服务。
3. 构建客户端
@Configuration
public class OpenAIConfig {
// ... 引入其它配置
@Bean
public ChatClient.Builder chatClientBuilder(OpenAiChatModel openAiChatModel) {
return new DefaultChatClientBuilder(openAiChatModel, ObservationRegistry.NOOP, (ChatClientObservationConvention) null);
}
}
由于使用的是 Spring AI 服务,内置有多套 AI 对话模型,包括;OpenAI、Anthropic,那么 ChatClient.Builder 的实现类,就会不知道要用拿到对话模型。所以这里要指定用哪家的模型进行对话!
4. 测试MCP
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class MCPTest {
@Resource
private ChatClient.Builder chatClientBuilder;
@Autowired
private ToolCallbackProvider tools;
@Test
public void test_tool() {
String userInput = "有哪些工具可以使用";
var chatClient = chatClientBuilder
.defaultToolCallbacks(tools)
.defaultOptions(OpenAiChatOptions.builder()
.model("gpt-4o")
.build())
.build();
System.out.println("\n>>> QUESTION: " + userInput);
System.out.println("\n>>> ASSISTANT: " + chatClient.prompt(userInput).call().content());
}
@Test
public void test_workflow() {
String userInput = "获取电脑配置";
userInput = "在 /Users/Dell/Desktop 文件夹下,创建 电脑.txt";
var chatClient = chatClientBuilder
.defaultToolCallbacks(tools)
.defaultOptions(OpenAiChatOptions.builder()
.model("gpt-4o")
.build())
.build();
System.out.println("\n>>> QUESTION: " + userInput);
System.out.println("\n>>> ASSISTANT: " + chatClient.prompt(userInput).call().content());
}
}
测试:test_tool:
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
>>> QUESTION: 有哪些工具可以使用
>>> ASSISTANT: 您可以使用以下工具:
1. **读取文件内容**:
- `spring_ai_mcp_client_filesystem_mcp_server_read_file`:读取单个文件的完整内容。
- `spring_ai_mcp_client_filesystem_mcp_server_read_multiple_files`:同时读取多个文件的内容。
2. **写入和编辑文件**:
- `spring_ai_mcp_client_filesystem_mcp_server_write_file`:创建新文件或用新内容完全覆盖现有文件。
- `spring_ai_mcp_client_filesystem_mcp_server_edit_file`:对文本文件进行基于行的编辑。
3. **文件和目录操作**:
- `spring_ai_mcp_client_filesystem_mcp_server_create_directory`:创建新目录或确保目录存在。
- `spring_ai_mcp_client_filesystem_mcp_server_list_directory`:获取指定路径中所有文件和目录的详细列表。
- `spring_ai_mcp_client_filesystem_mcp_server_directory_tree`:获取文件和目录的递归树视图。
- `spring_ai_mcp_client_filesystem_mcp_server_move_file`:移动或重命名文件和目录。
- `spring_ai_mcp_client_filesystem_mcp_server_search_files`:递归搜索匹配特定模式的文件和目录。
- `spring_ai_mcp_client_filesystem_mcp_server_get_file_info`:检索有关文件或目录的详细元数据。
4. **目录权限**:
- `ing_ai_mcp_client_filesystem_mcp_server_list_allowed_directories`:返回该服务器允许访问的目录列表。
5. **并行使用多个工具**:
- `multi_tool_use.parallel`:同时运行多个工具。
这些工具主要用于文件系统的操作,包括读取、写入、编辑、搜索和管理文件及目录。
以上输出的工具都是可以调用的。
测试:test_workflow:
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
>>> QUESTION: 在 C:\Users\Dell\Desktop 文件夹下,创建 电脑.txt
>>> ASSISTANT: 文件 `电脑.txt` 已成功创建在 `C:\Users\Dell\Desktop` 文件夹下。
注意 :在 windows 下 userInput 中提示的地址需要是绝对地址,不然会出现创建文件失败没有权限问题!

可以通过准确的指令描述,让AI完成系列动作,操作 tools 工具。这个 tools 工具加载的就是 mcp 配置的服务。
三、开发实现MCP服务
使用 Java 语言配合Spring AI 框架开发一个简单的 MCP 服务,获得当前电脑的配置信息。
1. 项目结构

2. 引入POM
2. 添加依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>
**注意:**对照 mcp-server-computer 工程下的 pom 文件来看,需要引入 spring-ai-starter-mcp-server 服务开发组件,另外注意 pom.xml 还要排除掉一些 lombok 组件,不用打包到整个工程里。
3. 服务实现和启动
package cn.cactusli.compute.domain.service;
import cn.cactusli.compute.domain.model.ComputerFunctionRequest;
import cn.cactusli.compute.domain.model.ComputerFunctionResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
import java.util.Properties;
/**
* Package: cn.cactusli.compute.domain.service
* Description:
*
* @Author 仙人球⁶ᴳ |
* @Date 2025/6/16 10:51
* @Github https://github.com/lixuanfengs
*/
@Slf4j
@Service
public class ComputerService {
@Tool(description = "获取电脑配置")
public ComputerFunctionResponse queryConfig(ComputerFunctionRequest request) {
log.info("获取电脑配置信息 {}", request.getComputer());
// 获取系统属性
Properties properties = System.getProperties();
// 操作系统名称
String osName = properties.getProperty("os.name");
// 操作系统版本
String osVersion = properties.getProperty("os.version");
// 操作系统架构
String osArch = properties.getProperty("os.arch");
// 用户的账户名称
String userName = properties.getProperty("user.name");
// 用户的主目录
String userHome = properties.getProperty("user.home");
// 用户的当前工作目录
String userDir = properties.getProperty("user.dir");
// Java 运行时环境版本
String javaVersion = properties.getProperty("java.version");
String osInfo = "";
// 根据操作系统执行特定的命令来获取更多信息
if (osName.toLowerCase().contains("win")) {
// Windows特定的代码
osInfo = getWindowsSpecificInfo();
} else if (osName.toLowerCase().contains("mac")) {
// macOS特定的代码
osInfo = getMacSpecificInfo();
} else if (osName.toLowerCase().contains("nix") || osName.toLowerCase().contains("nux")) {
// Linux特定的代码
osInfo = getLinuxSpecificInfo();
}
ComputerFunctionResponse response = new ComputerFunctionResponse();
response.setOsName(osName);
response.setOsVersion(osVersion);
response.setOsArch(osArch);
response.setUserName(userName);
response.setUserHome(userHome);
response.setUserDir(userDir);
response.setJavaVersion(javaVersion);
response.setOsInfo(osInfo);
return response;
}
private String getWindowsSpecificInfo() {
StringBuilder cache = new StringBuilder();
// Windows特定的系统信息获取
try {
Process process = Runtime.getRuntime().exec("systeminfo");
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
cache.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return cache.toString();
}
private static String getMacSpecificInfo() {
StringBuilder cache = new StringBuilder();
// macOS特定的系统信息获取
try {
Process process = Runtime.getRuntime().exec("system_profiler SPHardwareDataType");
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
cache.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return cache.toString();
}
private static String getLinuxSpecificInfo() {
StringBuilder cache = new StringBuilder();
// Linux特定的系统信息获取
try {
Process process = Runtime.getRuntime().exec("lshw -short");
java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
cache.append(line);
}
} catch (Exception e) {
e.printStackTrace();
}
return cache.toString();
}
}
注意,你的服务方法必须配置
@Tool(description = "获取电脑配置")
你有多少个方法,就给方法配置这个注解。这个注解是可以被 Spring AI 识别。
@Slf4j
@SpringBootApplication
public class McpServerComputerApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(McpServerComputerApplication.class, args);
}
@Bean
public ToolCallbackProvider computerTools(ComputerService computerService) {
return MethodToolCallbackProvider.builder().toolObjects(computerService).build();
}
@Override
public void run(String... args) throws Exception {
log.info("mcp server computer success!");
}
}
在 Application 或者 config 配置类,增加你的工具类启动,
toolObjects
可以设置你所有的工具包,ComputerService、XxxService 等。
4. 生成Jar包并对接服务

对接 MCP 服务前,需要通过 install 名称生成 jar。
{
"mcpServers": {
"filesystem-mcp-server": {
"command": "D:\\Public_software\\Nvm_nodejs\\nvm\\nvm\\v18.20.4\\npx.cmd",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"C:\\Users\\Dell\\Desktop",
"C:\\Users\\Dell\\Desktop"
]
},
"mcp-server-computer": {
"command": "D:\\Public_software\\Java_jdk\\17\\bin\\java.exe",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-jar",
"E:\\maven_repository\\cn\\cactusli\\mcp-server-compute\\1.0.0\\mcp-server-compute-1.0.0.jar"
]
}
}
}
mcp-server-computer 是开发的服务对接,这里引入下对接的 Jar,替换为你的路径。
**注意:**这是在 Window 系统中的配置方式。在其它系统中请注意路径问题!!!
四、AI 工作流测试
@Test
public void test_work() {
String userInput = "获取电脑配置";
userInput = "获取电脑配置 在 C:\\Users\\Dell\\Desktop 文件夹下,创建 电脑.txt 把电脑配置写入 电脑.txt";
var chatClient = chatClientBuilder
.defaultToolCallbacks(tools)
.defaultOptions(OpenAiChatOptions.builder()
.model("gpt-4o")
.build())
.build();
System.out.println("\n>>> QUESTION: " + userInput);
System.out.println("\n>>> ASSISTANT: " + chatClient.prompt(userInput).call().content());
}

到这里我们测试下,获取电脑配置,之后创建一个文件,再把获取的配置信息写入到文件里,AI 执行完成后,就可以调用我们的工具,执行接口 API 把数据写入到文件中。