Spring AI 实现MCP简单案例
引言
随着大型语言模型(LLM)在企业应用中的普及,如何有效地连接模型与外部工具、数据和服务成为了开发人员面临的重要挑战。2024年11月,Anthropic推出了模型上下文协议(Model Context Protocol,简称MCP),这一开放标准为解决AI系统中组件协同问题提供了全新的解决方案。本文将深入探讨MCP的核心概念,并通过一个实际的Spring AI示例项目展示其强大功能。
MCP协议简介
MCP(Model Context Protocol)是一种专为人工智能模型设计的通信协议,旨在解决复杂AI系统中多个模型或组件之间的协同工作问题。你可以把MCP想象成AI领域的"USB接口",它提供了一种统一的方式将AI模型连接到各种工具和数据源。
MCP的核心优势
- 标准化通信:定义了模型与外部工具交互的标准接口
- 自动发现能力:客户端可以自动发现并使用服务端提供的工具
- 跨平台兼容:任何实现MCP的系统都可以无缝集成
- 降低集成成本:开发者无需为每个模型重新实现工具调用逻辑
- 增强安全性:提供了安全的数据交换机制
Spring AI中的MCP实现
Spring AI框架已经内置了对MCP协议的支持,使Java开发者能够轻松构建MCP服务器和客户端应用。在本文中,我们将通过一个实际的示例项目来演示Spring AI如何实现MCP功能。
项目架构概览
我们的示例项目mcp-demos包含两个主要模块:
- mcp-server-demo:实现了MCP服务器,提供天气查询等工具服务
- mcp-client-demo:实现了MCP客户端,连接到本地Ollama模型并自动发现服务器提供的工具
服务端实现详解
创建MCP服务器
MCP服务器是一个基于Spring Boot的应用程序,通过简单的配置即可启用MCP功能。
首先,让我们看看主应用类的实现:
java
@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
public record TextInput(String input) {}
@Bean
public ToolCallback toUpperCase() {
return FunctionToolCallback.builder("toUpperCase", (TextInput input) -> input.input().toUpperCase())
.inputType(TextInput.class)
.description("Put the text to upper case")
.build();
}
}
在这段代码中,我们看到了两个关键的Bean定义:
weatherTools:将WeatherService类中标记为工具的方法注册为MCP服务toUpperCase:创建了一个简单的文本转换工具,用于将文本转换为大写
实现工具服务
下面是WeatherService类的核心实现,展示了如何定义MCP工具方法:
java
@Service
public class WeatherService {
private static final String BASE_URL = "https://api.weather.gov";
private final RestClient restClient;
// 构造函数初始化RestClient...
@Tool(description = "Get weather forecast for a specific latitude/longitude")
public String getWeatherForecastByLocation(double latitude, double longitude) {
// 实现天气查询逻辑...
}
@Tool(description = "Get weather alerts for a US state. Input is Two-letter US state code (e.g. CA, NY)")
public String getAlerts(String state) {
// 实现天气警报查询逻辑...
}
}
关键技术点:
- 使用
@Tool注解标记可被MCP发现的方法 description参数提供了工具的描述,帮助模型理解工具的功能和使用方式- 方法参数和返回类型会被自动转换为适合模型理解的格式
服务端配置
服务端的MCP功能通过application.properties文件进行配置:
properties
spring.ai.mcp.server.name=mcp-server-demo
spring.ai.mcp.server.version=0.0.1
spring.ai.mcp.server.protocol=SSE
spring.ai.mcp.server.capabilities.resource=true
spring.ai.mcp.server.capabilities.tool=true
spring.ai.mcp.server.capabilities.completion=true
spring.ai.mcp.server.capabilities.prompt=true
spring.ai.mcp.server.streamable-http.mcp-endpoint=/mcp
配置说明:
spring.ai.mcp.server.name:服务器名称spring.ai.mcp.server.protocol:通信协议,这里使用SSE(Server-Sent Events)spring.ai.mcp.server.capabilities.*:声明服务器支持的功能spring.ai.mcp.server.streamable-http.mcp-endpoint:MCP端点路径
客户端实现详解
创建MCP客户端
MCP客户端连接到本地Ollama模型,并自动发现服务端提供的工具:
java
@Configuration
public class OllamaConfig {
@Value("${ai.user.input}")
private String userInput;
@Bean
public ChatClient.Builder chatClientBuilder(OllamaChatModel ollamaChatModel) {
return ChatClient.builder(ollamaChatModel);
}
@Bean
public CommandLineRunner predefinedQuestions(ChatClient.Builder chatClientBuilder
, ToolCallbackProvider tools, ConfigurableApplicationContext context) {
System.out.println(tools.getToolCallbacks());
return args -> {
var chatClient = chatClientBuilder
.defaultToolCallbacks(tools)
.build();
System.out.println("\n>>> QUESTION: " + userInput);
System.out.println("\n>>> ASSISTANT: " + chatClient.prompt(userInput).call().content());
context.close();
};
}
}
关键技术点:
- 通过
ToolCallbackProvider自动获取所有可用的工具(包括通过MCP发现的远程工具) - 将这些工具配置到
ChatClient中,使其可以在与模型交互时自动选择合适的工具
客户端配置
客户端的配置同样在application.properties文件中:
properties
spring.ai.model.chat=ollama
spring.ai.ollama.base-url=http://localhost:11434
spring.ai.ollama.chat.options.model=llama3.2:1b
spring.ai.mcp.client.name=mcp-client-demo
spring.ai.mcp.client.toolcallback.enabled=true
spring.ai.mcp.client.sse.connections.mcp-server-demo.url=http://localhost:8080
ai.user.input=What tools are available?
配置说明:
spring.ai.model.chat=ollama:使用Ollama作为聊天模型spring.ai.ollama.*:配置Ollama连接信息spring.ai.mcp.client.toolcallback.enabled=true:启用MCP工具回调spring.ai.mcp.client.sse.connections.*:配置MCP服务器连接
实际使用示例
示例1:获取天气预报
当用户发送如下请求时:
rust
What's the weather forecast for New York City?
系统的执行流程如下:
- 客户端将请求发送给Ollama模型
- 模型分析请求,发现需要获取纽约的天气预报
- 模型识别到可以使用
getWeatherForecastByLocation工具 - 客户端调用该工具(通过MCP协议)
- 服务端执行天气查询并返回结果
- 模型处理结果并返回给用户
示例2:使用文本转换工具
当用户发送如下请求时:
sql
Please convert 'hello world' to uppercase.
系统会使用toUpperCase工具将文本转换为大写,整个过程对用户完全透明。
MCP的工作原理
MCP协议的工作原理可以概括为以下几个步骤:
- 服务注册:MCP服务器启动时,会注册所有标记为工具的方法
- 客户端发现:MCP客户端连接到服务器后,自动发现可用的工具
- 工具调用:当模型需要使用工具时,通过MCP协议调用远程工具
- 结果处理:工具执行结果通过MCP返回给客户端,然后由模型进行处理
这种机制使得模型可以无缝地使用各种外部工具,而不需要了解工具的具体实现细节。
实现细节与最佳实践
工具方法设计
在设计MCP工具方法时,应遵循以下最佳实践:
- 清晰的描述 :使用详细的
description参数,帮助模型理解工具的用途 - 合理的参数:使用简单明了的参数类型和名称
- 结构化返回:返回格式良好的结构化数据
- 错误处理:妥善处理可能发生的异常
性能优化
对于生产环境的MCP应用,可以考虑以下性能优化策略:
- 工具缓存:缓存工具发现结果,减少重复发现开销
- 请求批处理:批量处理相关的工具调用
- 异步执行:使用异步方式执行耗时的工具调用
- 连接池管理:合理管理MCP连接池
MCP与其他方案的对比
相比传统的API集成方式,MCP具有以下优势:
| 特性 | MCP | 传统API |
|---|---|---|
| 自动发现 | ✓ | ✗ |
| 标准接口 | ✓ | 各厂商不同 |
| 模型理解 | 描述性元数据 | 无 |
| 跨平台兼容 | ✓ | 需要适配 |
| 集成复杂度 | 低 | 高 |
未来发展与趋势
随着MCP协议的不断发展,我们可以期待:
- 更多框架和平台对MCP的支持
- 更丰富的工具生态系统
- 安全性和隐私保护的增强
- 更高效的通信协议和机制
结论
MCP协议为AI模型与外部工具的交互提供了一种标准化、高效的解决方案。通过Spring AI的实现,Java开发者可以轻松构建支持MCP的应用程序,实现模型与工具的无缝集成。本文介绍的示例项目展示了MCP的基本功能和使用方法,希望能为开发者提供有价值的参考。
随着AI技术的不断发展,MCP这样的标准化协议将在AI应用生态系统中发挥越来越重要的作用,推动AI应用的普及和创新。
参考文献
- MCP官方文档
- Spring AI MCP文档
- Anthropic, "Model Context Protocol: A New Standard for AI Tool Integration", 2024