MCP协议与Spring AI框架实战
MCP协议
1. MCP协议的定义与诞生背景
- MCP,即Model Context Protocol,也就是模型上下文协议,是由Anthropic公司(Claude大模型的母公司)于2024年11月推出的一项开放协议。在当时,大模型与外部工具、数据源之间的交互接口缺乏统一标准,开发效率低下,数据孤岛问题严重,MCP协议正是为了解决这些痛点而诞生,旨在规范大模型(LLM)与外部工具、数据源之间的标准化交互接口。
- MCP协议官方文档提供了详细的规范和示例,帮助开发者理解并实现基于MCP的模型交互。
1.2 MCP协议架构
- MCP 的核心遵循客户端-服务器架构,其中主机应用程序可以连接到多个服务器:
- MCP Hosts: 希望通过 MCP 访问数据的 Claude Desktop、IDE 或 AI 工具等程序
- MCP Clients: 与服务器保持 1:1 连接的协议客户端
- MCP Servers: 轻量级程序,每个程序都通过标准化的 Model Context Protocol 公开特定功能
- Local Data Sources: MCP 服务器可以安全地访问你的计算机文件、数据库和服务
- Remote Services: MCP 服务器可以连接到的 Internet 上可用的外部系统(例如,通过 API)
1.3 MCP协议的通信模式
MCP(Model Context Protocol)模型上下文协议提供三种核心的通信模式:STDIO、SSE和Streamable HTTP,在不同的场景中为开发者提供了灵活且高效的数据传输方式
-
STDIO 模式
STDIO(Standard Input and Output)是最基本的输入输出方式,广泛应用于命令行工具、脚本编程以及本地调试过程中。它通过标准输入、输出和错误流来进行数据的传输。 -
SSE 模式
SSE(Server-Sent Events)是一种基于HTTP协议的单向数据流传输方式。它允许服务器主动向客户端推送实时数据。SSE通过保持一个持久的HTTP连接,将数据流式传输到客户端,特别适合需要持续更新的实时场景。 -
Streamable HTTP 模式
Streamable HTTP(是一种基于HTTP协议的流式传输技术,专门用于大文件(如视频、音频)的分段传输。与SSE不同,Streamable HTTP允许文件在传输的同时被处理,使客户端可以边接收数据边处理,避免等待整个文件加载完成。
1.4 MCP协议的核心要素
1.4.1 Prompts
- Prompts用于传递结构化的用户指令与上下文,它就像是给大模型下达任务时附带的详细说明,让大模型能够准确理解用户需求。
1.4.2 Resources
- Resources支持模型动态、安全地加载和利用外部数据源,如数据库信息、API返回结果、文件内容、日志文件等。这意味着大模型不再局限于自身已有的知识,能够实时获取最新的外部数据。
1.4.3 Tools
- Tools实现模型调用预先定义好的功能或服务以执行具体任务,如代码执行、API调用。
1.5 MCP协议的功能定位与优势
1.5.1 功能定位
- MCP致力于成为AI模型与外部世界交互的“通用接口”,作用类似硬件领域的USB - C标准,在架构设计上采用客户端 - 服务器模式(MCP Client调用工具,MCP Server对接数据源或执行操作),实现模型与异构资源(数据库、API、本地软件等)的双向通信和数据整合。
1.5.2 优势
- MCP的核心优势在于解决当前AI应用中工具调用接口碎片化、非标准化的问题。开发者通过遵循MCP协议,理论上无需为每个模型或工具单独编写复杂的适配代码,转而通过统一的协议规范进行调度。基于JSON - RPC 2.0等成熟标准,MCP协议支持动态加载外部数据,并明确定义工具的操作能力,从而扩展大模型的实际应用边界,增强其解决复杂问题的能力。
1.5.3 MCP与Toll Calling (Function Calling)的区别与联系
- 模型上下文协议(MCP)——“AI界的‘USB-C’标准”
MCP(Model Context Protocol)目标是让不同大模型(如Claude、GPT等)能像“插USB-C接口”一样,无缝连接各种工具和数据源。它强调标准化和生态兼容性,通过客户端-服务器架构,实现模型与外部资源的灵活交互。
核心特点:
- 统一接口:遵循JSON-RPC 2.0标准,跨模型通用。
- 多能力整合:支持工具调用、数据访问、提示管理等多种功能。
- 上下文管理:擅长处理多步骤任务,保持对话连贯性。
- Function Calling——“模型专属的‘快捷指令’”
Function Calling是某OpenAI等模型厂商提供的API功能,允许模型根据需求自动调用开发者定义的函数(如天气查询、发邮件)。它更像“为特定模型定制的工具箱”,特点如下:
- 轻量化集成:只需定义函数参数,模型即可智能触发调用。
- 场景专注:适用于简单、明确的单次任务(如查数据、执行API)。
- 依赖模型生态:功能受限于特定模型(如GPT系列)的支持
{"content": "","refusal": null,"role": "assistant","audio": null,"function_call": null,"tool_calls": [{"id": "call_6596dafa2a6a46f7a217da","function": {"arguments": "{\"location\": \"上海\"}","name": "get_current_weather"},"type": "function","index": 0}]
}
Spring AI框架
2. Spring AI框架的概述
- Spring AI是一个人工智能工程的应用框架,由Spring官方社区推出,旨在简化Java AI应用程序的开发。其目标是将Spring生态系统的设计原则,如可移植性和模块化设计,应用于人工智能领域。它就像是一个强大的工具箱,为Java开发者提供了一系列便捷的工具和组件,让他们能够轻松地将AI技术集成到自己的项目中。
- Spring AI官方文档提供了详细的开发指南和API参考,帮助开发者深入了解并使用该框架。
2.1 Spring AI框架的优势
2.1.1 易于集成
- 如果你熟悉 Spring Boot、Spring Data、Spring Web 等,那么你几乎可以零成本地学习和使用 Spring AI。它沿用了 Spring 家族一贯的"约定优于配置"和"开箱即用"的特性,大大降低了学习曲线
2.1.2 抽象与统一的 API
- 无论是 OpenAI、DeepSeek、Hugging Face 还是 Azure OpenAI,Spring AI 都提供了一套统一的 API 接口。这意味着你可以在不修改核心业务逻辑的情况下,轻松切换不同的 AI 模型提供商,这对于模型的选择和未来的扩展性至关重要
2.1.3 企业级特性支持
- 作为 Spring 家族的一员,Spring AI 自然继承了 Spring Boot 在可观测性(Metrics, Tracing)、配置管理、安全性等方面的强大能力,使得构建生产级别的 AI 应用变得更加可靠。
2.1.4 模块化与可扩展性
- Spring AI 设计精巧,各个功能模块(如 Chat Client, Embedding, Tool Calling, RAG)都是独立的,你可以根据需求选择性地引入和使用,并且可以轻松扩展自定义功能。
2.1.5 社区支持
- 活跃社区:作为 Spring 官方项目的一部分,拥有庞大的开发者社区和丰富的资源支持。
- 持续更新:定期发布新版本,修复 bug 并引入新特性,保持项目的活力和竞争力。
2.2 Spring AI框架的主要功能模块
2.2.1 AI 模型集成模块
- 大型语言模型(LLM)支持:支持 OpenAI(如 ChatGPT 和 DALL-E)、Azure OpenAI、DeepSeek、QianWen、Anthropic Claude、Mistral AI、Ollama、Vertex AI Gemini 等多种流行的大型语言模型服务。
- 嵌入模型:支持 Vertex AI Embeddings、Amazon Bedrock、PostgresML、Transformers(ONNX)等多种嵌入模型,能够将文本或多模态内容转换为向量表示,为语义搜索、推荐系统等应用提供基础支持。
- 图像生成模型:支持 Stability AI 和 OpenAI DALL-E 等图像生成模型。
- 模型上下文协议(MCP)支持:提供 MCP 服务器和客户端支持,方便模型之间的通信和协作。
2.2.2 向量数据库支持模块
- Spring AI 支持丰富的向量数据库集成选项,包括 SQL 数据库向量支持(如 PGvector、MariaDB Vector Database、Oracle Vector Database)、NoSQL 数据库向量支持(如 MongoDB Atlas Vector Database、Elasticsearch Vector Database、Redis Search and Query、Neo4j Vector Database、Apache Cassandra Vector Database)、专用向量数据库(如 Pinecone、Weaviate、Qdrant、Milvus、Chroma、Typesense)以及云服务向量数据库(如 Azure AI Search、Azure Cosmos DB Vector Store)。这些向量数据库能够高效地存储和检索嵌入向量,为 AI 应用中的语义搜索、知识检索等功能提供有力支持
2.2.3 文档处理模块
- Spring AI 提供了多种文档读取和处理工具,能够从不同格式的文档(如 Markdown、PDF 等)中提取文本并转换为 Spring AI Document 对象。这为后续的知识注入、内容分析等操作奠定了基础,方便开发者将各种文档资料整合到 AI 应用中,使模型能够基于这些文档内容生成更准确、更有价值的响应。
2.2.4 对话记忆存储模块
- 该模块用于管理和存储聊天对话的历史记录,为模型提供上下文信息,使生成的对话更具连贯性和一致性。通过合理利用对话记忆,模型可以更好地理解用户的需求和意图,从而提供更个性化、更优质的对话服务
2.2.5 RGA插件
- 支持RAG(Retriever - Augmented Generation)能力的基础组件,包括DocumentLoader、TextSplitter、EmbeddingClient、VectorStore等。在一个知识问答系统中,RAG能力可以帮助系统从大量的文档中检索相关信息,并结合大模型的生成能力,为用户提供准确的答案。
2.3 Spring AI框架之MCP
MCP Java SDK 提供了模型上下文协议的 Java 实现,通过同步和异步通信模式实现与人工智能模型和工具的标准化交互。
Spring AI MCP 通过与 Spring Boot 集成扩展了 MCP Java SDK,提供了客户端和服务器启动器。使用 Spring Initializer 创建支持 MCP 的人工智能应用程序。
MCP 客户端负责与 MCP 服务器建立和管理连接。它实现了协议的客户端部分,处理以下方面:
- 协议版本协商,以确保与服务器兼容
- 能力协商,以确定可用功能
- 消息传输和 JSON-RPC 通信
- 工具发现与执行
- 资源访问与管理
- 提示系统交互
- 可选功能:
- 根目录管理
- 采样支持
- 同步和异步操作
- 传输选项:
- 基于标准输入输出(Stdio)的传输,用于基于进程的通信
- 基于 Java HttpClient 的服务器发送事件(SSE)客户端传输
- 用于响应式 HTTP 流的 WebFlux SSE 客户端传输
MCP 服务器为客户端提供工具、资源和功能。它实现了该协议的服务器端,负责:
- 服务器端协议操作的实现
- 工具展示与发现
- 基于统一资源标识符(URI)访问的资源管理
- 提示模板的提供与处理
- 与客户端的功能协商
- 结构化日志记录与通知
- 并发客户端连接管理
- 同步和异步应用程序编程接口(API)支持
- 传输实现:
- 基于标准输入输出(Stdio)的传输,用于基于进程的通信
- 基于 Servlet 的服务器发送事件(SSE)服务器传输
- 用于响应式 HTTP 流的 WebFlux SSE 服务器传输
- 用于基于 Servlet 的 HTTP 流的 WebMVC SSE 服务器传输
使用Spring AI开发MCP服务
3. 开发前的准备工作
3.1 环境搭建
- 确保开发环境满足Spring AI的要求,通常需要Java 17和Spring Boot 3.2.4等版本。如果使用Maven进行项目管理,还需要在pom.xml文件中添加Spring AI相关依赖,例如:
<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.1</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
3.2 理解MCP服务架构
- MCP服务采用客户端 - 服务器模式,MCP Client负责处理客户端操作,与用户或其他应用程序进行交互,将用户的请求发送给MCP Server;McpServer则管理服务器端协议操作,对接数据源或执行操作,为客户端提供工具、资源和功能。
3.1 构建MCP Server
3.1.1 创建Spring Boot项目
- 首先访问Spring Initializr官网,按照提示填写项目的相关信息,如项目名称、包名、Spring Boot版本等,并添加Spring AI相关依赖,然后下载项目压缩包,解压到指定目录。
3.1.2 引入MCP Server依赖
根据实际需求,选择合适的MCP Server依赖。MCP Server依赖有三种类型:
- 标准输入/输出 (STDIO):spring-ai-starter-mcp-server;
- Spring MVC(服务器发送的事件):spring-ai-starter-mcp-server-webmvc;
- Spring WebFlux(响应式SSE):spring-ai-starter-mcp-server-webflux。如果项目需要实现实时数据推送等功能,可以选择Spring WebFlux类型的依赖。
<dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webflux</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
3.1.3 设置MCP配置信息
- MCP Server包含以下配置信息:name用于标识服务器名称,默认值为mcp-server;version表示服务器版本,默认值为1.0.0;type指定服务器类型 (SYNC/ASYNC),默认值为SYNC等。在配置文件中设置这些参数,以满足项目的需求。例如:
spring.ai.mcp.server.name=webflux-mcp-server
spring.ai.mcp.server.version=1.0.0
spring.ai.mcp.server.type=ASYNC
3.1.4 编写MCP Server服务代码
- 使用@Tool注解将业务方法标记为可被大模型调用的工具。例如,创建一个CommonTool类,其中包含获取天气预报和获取IP地址详细信息的方法:
@Service
public class CommonTool {@Tool(description = "获取当前天气预报")WeatherResponse getCurrentWeather(WeatherRequest request) {System.err.printf("准备查询【%s】天气预报%n", request.city());RestClient client = RestClient.create(URI.create("https://api.vvhan.com"));Map<?,?> result = client.get().uri("/api/weather?city={0}", request.city()).retrieve().body(Map.class);try {return new WeatherResponse(new ObjectMapper().writeValueAsString(result));} catch (JsonProcessingException e) {throw new RuntimeException(e);}}@Tool(description = "获取IP地址详细信息")String getIpAddressInfo(String ip) {System.err.printf("准备查询【%s】详细信息%n", ip);RestClient client = RestClient.create(URI.create("https://api.vvhan.com"));Map<?,?> result = client.get().uri("/api/ipInfo?ip={0}", ip).retrieve().body(Map.class);try {return new ObjectMapper().writeValueAsString(result);} catch (JsonProcessingException e) {throw new RuntimeException(e);}}
}
3.1.5 注册工具
- 创建一个配置类ToolsConfig,使用@Bean注解将工具注册到Spring容器中,例如:
@Configuration
public class ToolsConfig {@Beanpublic ToolCallbackProvider myToolCallBackProvider(CommonTool commonTool) {return MethodToolCallbackProvider.builder().toolObjects(commonTool).build();}
}
3.2 构建MCP Client
3.2.1 引入MCP Client依赖
- 在项目的pom.xml文件中添加MCP Client相关依赖:
- spring-ai-starter-mcp-client - Core starter providing STDIO and HTTP-based SSE support
- spring-ai-starter-mcp-client-webflux - WebFlux-based SSE transport implementation
<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-webflux</artifactId></dependency><!-- Spring AI Alibaba(通义大模型支持) --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version></dependency><!-- 其他依赖 -->
</dependencies>
3.2.2 配置MCP服务器地址
- 在配置文件中配置MCP服务端地址,如果有多个服务器,也可以按照相应格式进行配置。例如:
spring.ai.mcp.client.name=webflux-mcp-client
spring.ai.mcp.client.type = ASYNC
spring.ai.mcp.client.request-timeout=60s
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8089
spring.ai.mcp.client.toolcallback.enabled = true
spring.ai.dashscope.api-key: xxxx
spring.ai.dashscope.chat.model: qwq-32b
3.2.3 提供http请求接口
- 对外提供http请求接口,以便调用mcp服务:
@RestController
public class McpController {@Autowiredprivate DashScopeChatModel dashScopeChatModel;@Autowiredprivate ToolCallbackProvider myToolCallBackProvider;@GetMapping("/ai/generate")public String generate(@RequestParam(value = "message") String message) {ChatClient chatClient = ChatClient.builder(dashScopeChatModel).defaultTools(myToolCallBackProvider.getToolCallbacks()).build();return chatClient.prompt(message).call().content();}
}