Spring AI Alibaba MCP(Model Context Protocol)模型上下文协议 让AI操作本地文件系统示例

 本文基于Spring AI Alibaba 1.0.0-M5.1 的示例讲解Spring AI (1.0.0-M5前)的实验性内容MCP(Model Context Protocol)组件。

Spring AI Alibaba官方文档:Spring AI Alibaba 模型上下文协议

 介绍

模型上下文协议,规范应用程序如何向LLM提供上下文,实际上是通过统一的方式(JSON-RPC消息格式),将MCP Server (数据/工具提供者)和MCP Client进行通信

 MCP Server多数是基于TypeScript/Python开发的,Spring AI提供了Java和Spring的集成,分模块架构

  1. Spring AI application : Spring AI应用,例如ChatClient

  2. Spring MCP Client: Spring AI下的MCP客户端

  3. MCP Server: MCP服务

  4. Local DataSource: 本地数据源

  5. Remote Server: 远程服务

 在阿里官方的文档中,提供了集成了隐私浏览器Brave的search API的MCP Server与Spring AI ChatClient的注册示例。Brave的计划有2000/月的免费方案,也有3/1000次的付费方案。

官方示例 

使用Spring AI MCP访问本地文件系统

该示例可以通过 MCP 查询或更新本地文件系统,并以文件系统中的数据作为上下文与模型交互。

前提准备

1. 安装 npx (Node Package eXecute): 首先确保本地机器安装了 npm,然后运行如下命令:

npm install -g npx

2. 如果使用官方的示例项目代码,请查看官方的仓库:Spring ai alibaba mcp example 

3. 如果在你自己的项目里尝试,请确保添加了以下依赖(Maven)


	com.alibaba.cloud.ai
	spring-ai-alibaba-starter1.0.0-M5.1



		
			spring-milestones
			Spring Milestones
			https://repo.spring.io/libs-milestone-local
			
				false
			
		
		
			spring-snapshots
			Spring Snapshots
			https://repo.spring.io/snapshot
			
				false
			
		
	

由于在Spring AI 1.0.0-M5版本中,MCP为实验性内容,还需要额外引入该依赖:


    org.springframework.experimental
    spring-ai-mcp
    0.3.0

代码

主要需要配置的组成模块分为三部分:

MCP Client:与MCP Server通信的关键组件

Function Callbacks:MCP专属的Function calling

ChatClient:Spring AI封装的LLM交互类,可视为单个智能体

1. 声明Function Callbacks

像所有工具方法那样,提供给ChatClient前,我们先声明好该Mcp提供了啥工具,此处使用的是McpFunctionCallback,这是spring-ai-mcp对FunctionCallback接口的实现类:

@Bean
public List functionCallbacks(McpSyncClient mcpClient) {
    return mcpClient.listTools(null)
            .tools()
            .stream()
            .map(tool -> new McpFunctionCallback(mcpClient, tool))
            .toList();
}

通过listTools方法,可以拿到MCPClient提供的所有工具,(更详细的内容详情请见源码解析),将McpClient提供的工具类配置为McpFunctionCallback类,并作为列表返回。

2. 声明ChatClient

在声明ChatClient时,和function calling几乎一模一样,提供给chatClient即可

var chatClient = chatClientBuilder
      .defaultFunctions(functionCallbacks)
      .build();

3. 初始化McpClient [关键]

每个提供服务的MCP Server的参数不太一样,但是启动的流程通过Spring AI MCP transport基本上统一了

@Bean(destroyMethod = "close")
    public McpSyncClient mcpClient() {

        // based on
        // https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem
        var stdioParams = ServerParameters.builder("npx")
                .args("-y", "@modelcontextprotocol/server-filesystem", getFilePath())
                .build();

        var mcpClient = McpClient.using(new StdioClientTransport(stdioParams))
                .requestTimeout(Duration.ofSeconds(10)).sync();

        var init = mcpClient.initialize();

        System.out.println("MCP Initialized: " + init);

        return mcpClient;

    }

// 定位本地文件系统路径
private static String getFilePath() {
		String path = System.getenv("MCP_FILE_DIRECTORY_PATH");// 这里通过启动时设置的环境变量,如果没有,默认使用getDbPath方法提供的当前工作目录
		return StringUtils.isEmpty(path) ? getDbPath() : path;
	}

private static String getDbPath() {
		return Paths.get(System.getProperty("user.dir")).toString();
	}

步骤为先使用transport的ServerParameters类构建好参数并运行npx进程,然后新建McpClient与该服务进行连接,将mcpclient注册为bean交给Spring管理生命周期。

4. 使用

@Bean
    public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder,
            List functionCallbacks, ConfigurableApplicationContext context) {

        return args -> {
            var chatClient = chatClientBuilder
                    .defaultFunctions(functionCallbacks.toArray(new McpFunctionCallback[0]))
                    .build();

            System.out.println("Running predefined questions with AI model responses:\n");

            // Question 1
            String question1 = "你能解释一下 spring-ai-mcp-overview. txt 文件的内容吗?";
            System.out.println("QUESTION: " + question1);
            System.out.println("ASSISTANT: " + chatClient.prompt(question1).call().content());

            // Question 2
            String question2 = "请总结 spring-ai-mcp-overview. txt 文件的内容,并将其存储为 Markdown 格式的新 summary.md?";
            System.out.println("\nQUESTION: " + question2);
            System.out.println("ASSISTANT: " +
                    chatClient.prompt(question2).call().content());

            context.close();//通过context关闭Springboot应用

        };
    }

可以发现,注入chatClient后,将提示词给予它,它就会和调用其他function callings一样,调用mcp的function callbacks,并返回操作的结果。

通过以上配置,该chatClient就具备了借助Mcp Client与MCP服务通信的能力。Spring AI Alibaba还提供了一个构建MCP服务访问SQLite的示例,详情请查看官方示例仓库。

你可能感兴趣的:(spring,java,ai)