MCP(Model Context Protocol,模型上下文协议)是一种开放协议,旨在实现 大型语言模型(LLM) 应用与外部数据源、工具和服务之间的无缝集成,类似于网络中的 HTTP 协议或邮件中的 SMTP 协议。
MCP 协议通过标准化模型与外部资源的交互方式,提升 LLM 应用的功能性、灵活性和可扩展性。
MCP 的架构由四个关键部分组成:
MCP 关键特性
MCP 与 Function Calling 的区别:
特性 | MCP | Function Calling |
---|---|---|
性质 | 协议 | 功能 |
范围 | 通用(多数据源、多功能) | 特定场景(单一数据源和功能) |
目标 | 统一接口,实现互操作 | 扩展模型能力 |
实现 | 基于标准协议(JSON-RPC 2.0,标准请求、响应和通知消息) | 依赖于特定模型实现 |
通信机制 | MCP 支持多种传输机制,包括本地的标准输入/输出(Stdio)和基于HTTP的服务器发送事件(SSE)。 | Function Calling 使用 HTTP 作为通信机制。 |
开发复杂度 | 低:通过统一协议实现多源兼容 | 高:需要为每个任务单独开发函数 |
复杂性 | 高:一次开发,可多场景使用 | 低:函数通常为特定任务设计 |
灵活性 | 高:支持动态适配和扩展 | 低:功能扩展需要额外开发 |
常见场景 | 复杂场景,如跨平台数据访问与整合 | 简单任务,如天气查询、翻译等 |
整合难度 | 一次标准化整合 | 每个API单独整合 |
实时双向通讯 | 支持 | 不支持 |
动态发现工具 | 支持 | 不支持 |
Spring AI MCP,它是模型上下文协议(Model Context Protocol,MCP)的 Java SDK 实现。Spring AI 生态系统的这一新成员为 Java 平台带来了标准化的 AI 模型集成能力。
MCP 的核心是客户端-服务器(CS)架构,一个应用可以连接多个服务器。
Spring AI MCP 采用模块化架构,包含以下组件:
第一步:引入 spring-ai 依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
第二步:开发 MCP Tool,并注册暴露 MCP Server
// 开发 MCP Tool
@Service
public class WeatherService {
@Tool(description = "根据城市名称获取天气预报")
public String getWeatherByCity(@ToolParam(description = "城市名称") String city) {
if (Objects.isNull(city)) {
return "抱歉:城市名称不能为空!";
}
// 模拟天气数据
Map<String, String> mockData = Map.of(
"西安", "晴天",
"北京", "小雨",
"上海", "大雨"
);
return mockData.getOrDefault(city, "抱歉:未查询到对应城市!");
}
}
// 注册暴露 MCP Server
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
第三步:自测验证(SSE方式)
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
// 初始化 SSE Client
var client = McpClient.sync(new HttpClientSseClientTransport("http://localhost:8080")).build(
// 发起请求
CallToolResult getWeatherByCity = client.callTool(new CallToolRequest("getWeatherByCity", Map.of("city", "上海")));
System.out.println("上海天气是:" + getWeatherByCity);
第四步:自测验证(STDIO方式)
// 初始化 STDIO Client
var stdioParams = ServerParameters.builder("java")
.args("-Dspring.ai.mcp.server.stdio=true", "-Dspring.main.web-application-type=none",
"-Dlogging.pattern.console=", "-jar",
"/Users/admin/program/git-space/project/abc-demo/spring-ai-mcp/mcp-server/target/mcp-server-1.0.0-SNAPSHOT.jar")
.build();
var client = McpClient.sync(new StdioClientTransport(stdioParams)).build(
// 发起请求
CallToolResult getWeatherByCity = client.callTool(new CallToolRequest("getWeatherByCity", Map.of("city", "上海")));
System.out.println("上海天气是:" + getWeatherByCity);
第五步:查看日志输出
// MCP服务 Tools列表:
Available Tools = ListToolsResult[tools=[Tool[name=getWeatherByCity, description=根据城市名称获取天气预报, inputSchema=JsonSchema[type=object, properties={arg0={type=string, description=城市名称}}, required=[arg0], additionalProperties=false]]], nextCursor=null]
// MCP服务 天气查询结果:
上海 天气为:CallToolResult[content=[TextContent[audience=null, priority=null, text="小雨"]], isError=false]
当前,大型语言模型(LLM)并非普遍支持模型上下文协议(MCP),本文选择已支持MCP的 Qwen2.5 模型基座,使用 Cherry Studio 作为模型工具。
另外,由于上文示例过于简单,为确保演示效果从 glama.ai(已收集1K+MCP服务)选择2个开源 MCP服务进行集成演示。
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。