当前位置: 首页 > news >正文

【AI智能体】Spring AI MCP 从使用到操作实战详解

目录

一、前言

二、MCP 介绍

2.1 什么是MCP

2.2 MCP 核心特点

2.3 MCP 核心价值

2.4 MCP 与Function Calling 区别

三、Spring AI MCP 架构介绍

3.1 整体架构

3.1.1 三层架构实现说明

3.2 服务端与客户端

3.2.1 MCP 服务端

3.2.1 MCP 客户端

3.3 MCP中SSE和STDIO区别

3.3.1 SSE模式介绍

3.3.2 STDIO模式介绍

3.3.3 SSE 与STDIO对比

四、Spring AI MCP 案例操作演示

4.1 开发环境准备

4.2 构建MCP Server服务

4.2.1 pom导入下面的依赖

4.2.2 添加配置文件

4.2.3 提供一个Tool 工具类

4.2.4 注册工具类

4.3 构建MCP Client服务

4.3.1 导入核心依赖

4.3.2 增加配置信息

4.3.3 增加一个对话接口

4.3.4 效果测试

4.4 MCP 底层原理解析

4.4.1 server端底层执行逻辑

4.4.2 client 端底层执行逻辑

五、写在文末


一、前言

Spring AI MCP 是 Spring 框架对模型上下文协议(Model Context Protocol, MCP)的官方实现,它为 Java 开发者提供了标准化集成大型语言模型(LLM)与外部数据源和工具的能力。本文将全面介绍 Spring AI MCP 的核心概念、架构设计以及实际应用方法。

二、MCP 介绍

2.1 什么是MCP

MCP ,即模型上下文协议(Model Context Protocol, MCP),由 Anthropic 公司(Claude 大模型母公司)在 2024 年 11 月推出的开放协议,旨在标准化大型语言模型与外部数据源和工具之间的交互方式。MCP 被形象地比喻为 AI 领域的"USB-C 接口",因为它提供了连接各类服务的统一框架。从而增强模型的实时交互和任务执行能力。

2.2 MCP 核心特点

MCP 具备如下核心特点:

  • 标准化集成

    • MCP统一了不同AI模型(如Claude、GPT等)与外部工具(如数据库、API、浏览器等)的交互方式,避免了传统定制化API开发的重复劳动

  • 双向通信

    • 不同于传统AI只能被动接收数据,MCP支持AI主动检索信息并执行操作(如更新数据库、触发工作流),实现真正的“代理式AI”

  • 动态上下文管理

    • MCP允许AI在会话中持续携带上下文信息(如用户偏好、历史记录),使多步骤任务(如“查询天气→推荐行程→预订酒店”)能自动串联执行

  • 安全与灵活性

    • MCP支持本地或云端部署,通过OAuth 2.1认证和数据沙箱机制保障敏感信息的安全访问

2.3 MCP 核心价值

MCP 解决了 AI 应用开发中的几个关键问题:

  • 打破数据孤岛:让大模型可以直接访问实时数据和本地资源(如数据库、文件系统)

  • 降低开发成本:开发者只需编写一次 MCP 服务端,所有兼容 MCP 的模型都能调用

  • 提升安全性:内置权限控制和加密机制,比直接开放数据库更安全

  • 促进生态统一:类似 USB 接口,让不同厂商的工具能"即插即用"

2.4 MCP 与Function Calling 区别

与传统的 Function Calling 相比,MCP 具有以下优势:

  • 复用性:Function Calling 通常与具体 AI 应用紧密绑定,难以复用;而 MCP 设计用于跨系统、跨工具场景

  • 交互能力:MCP 着重解决系统间交互问题,使数据和功能能在不同系统间灵活传递

  • 协议标准化:MCP 通过协议标准化简化了分布式系统开发

三、Spring AI MCP 架构介绍

spring官网在大模型开始火热的时候,推出了Spring AI,与时俱进,随着MCP的热度走高,Spring AI MCP也随之推出与大众见面,官网入口:Model Context Protocol (MCP) :: Spring AI Reference

3.1 整体架构

Spring 官网对于MCP给出了下面的架构图

Spring AI MCP 采用模块化架构,包含以下核心组件:

  • Spring AI 应用程序:使用 Spring AI 框架构建的生成式 AI 应用

  • Spring MCP 客户端:MCP 协议的 Spring AI 实现,与服务器保持 1:1 连接

  • MCP 服务器:轻量级程序,通过标准化协议公开特定功能

  • 本地数据源:MCP 服务器可安全访问的计算机文件、数据库和服务

  • 远程服务:MCP 服务器可通过互联网(如 API)连接的外部系统

3.1.1 三层架构实现说明

Java MCP 实现遵循三层架构:

  • 客户端/服务器层:McpClient 处理客户端操作,McpServer 管理服务器端协议操作

  • 会话层(McpSession):管理通信模式和状态

  • 传输层(McpTransport):处理 JSON-RPC 消息的序列化和反序列化,支持多种传输方式

3.2 服务端与客户端

在实际开发和使用时,MCP的开发主要涉及到服务端与客户端,两者的作用各有差异,下面分别做说明。

3.2.1 MCP 服务端

MCP 服务端主要负责下面的功能:

  • 服务端协议操作实现

  • 工具暴露与发现

  • 基于 URI 的资源管理

  • 提示词模板的提供与处理

  • 客户端并发连接管理

3.2.1 MCP 客户端

MCP 客户端是架构中的关键组件,其主要负责下面的功能:

  • 协议版本协商

  • 能力协商以确定可用功能

  • 消息传输和 JSON-RPC 通信

  • 工具发现和执行

  • 资源访问和管理

  • 支持同步和异步操作

3.3 MCP中SSE和STDIO区别

在Spring AI的MCP实现中,SSE和STDIO是两种主要的通信方式,它们各自适用于不同的场景,下面我们来详细分析两者的区别。

3.3.1 SSE模式介绍

SSE全称,Server-Sent Events,是一种服务器推送技术,允许服务器向客户端推送实时更新。在MCP中,SSE主要用于流式返回AI模型生成的内容。其主要特点如下:

  • 单向通信:服务器向客户端发送数据,客户端不能通过SSE向服务器发送数据

  • 实时性:支持服务器实时推送数据到客户端

  • 自动重连:客户端断开连接后会自动尝试重新连接

  • 基于HTTP:使用标准HTTP协议,易于穿越防火墙

  • 轻量级:相比WebSocket更加轻量,适合单向通信场景

在AI大模型中的交互使用场景:

  • 流式返回模型生成的文本,实现类似打字机的效果;

  • 提供实时反馈,如生成进度、中间结果等;

  • 减少首字节时间(TTFB),提升用户体验;

SSE的HTTP格式示例:

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alivedata: {"content":"这是第一段对话"}data: {"content":"这是第二段对话"}data: {"content":"这是最后一段对话"}data: [DONE]

3.3.2 STDIO模式介绍

STDIO全称,Standard Input/Output,STDIO 是指标准输入输出流,是一种最基本的程序通信机制。在MCP中,STDIO主要用于与本地部署的模型或通过命令行工具访问的模型进行交互。STDIO主要有如下特点:

  • 双向通信

    • 程序可以通过标准输入接收数据,通过标准输出发送数据

  • 进程间通信

    • 通常用于父子进程之间的通信

  • 无网络依赖

    • 不依赖网络协议,适合本地应用场景

  • 命令行友好

    • 与命令行工具天然集成

  • 低开销

    • 通信开销小,适合高性能场景

在AI大模型中的交互使用场景:

  • 与本地部署大模型交互,如Ollama、LLaMA.cpp等

  • 通过命令行工具访问AI大模型服务

  • 构建管道式AI处理流程

STDIO 通信流程如下示例:

应用程序 -> 标准输入 -> AI模型进程 -> 标准输出 -> 应用程序

3.3.3 SSE 与STDIO对比

SSE 与STDIO两种模式具有如下差异:

特征项

SSE

STDIO

通信方向

单向 :服务器到客户端

双向

网络依赖

依赖HTTP

不依赖网络

部署要求

需要网络服务

本地即可

性能开销

较高(HTTP开销)

较低

扩展性

支持多客户端

一对一通信

实现复杂度

中等

简单

错误恢复

自动重连机制

需手动处理

应用场景

网络API通信

本地进程通信

四、Spring AI MCP 案例操作演示

接下来通过一个实际案例详细演示基于SSE 这种模式下Spring AI MCP是如何使用的。

mcp项目分为server服务端(提供mcp服务),client客户端(去请求mcp服务)

4.1 开发环境准备

本地开发环境相关的组件依赖版本如下:

  • JDK17

  • maven 3.6.2

  • springBoot 3.4.4

  • springAi 1.0.0-M7

4.2 构建MCP Server服务

下面以SSE模式为例演示下如何在springboot项目中集成并使用MCP

4.2.1 pom导入下面的依赖

创建一个springboot的server端项目,导入下面的核心依赖

<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-ai.version>1.0.0-M7</spring-ai.version>
</properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version><relativePath/>
</parent><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-M7</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><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></dependency>
</dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build><repositories><repository><id>central</id><url>https://maven.aliyun.com/repository/central</url><releases><enabled>true</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><repository><name>Central Portal Snapshots</name><id>central-portal-snapshots</id><url>https://central.sonatype.com/repository/maven-snapshots/</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository>
</repositories>

4.2.2 添加配置文件

在配置文件中添加如下信息

spring:ai:mcp:server:name: mcp-serverversion: 1.0.0type: ASYNCsse-message-endpoint: /mcp/messages

4.2.3 提供一个Tool 工具类

在MCP的实现中,Tool 是一个很重要的连接点,借助Tool ,客户端调用具体的服务时,可以理解为MCP就能找到符合要求的Tool 实现,从而给客户端预期的响应结果,在server项目启动的时候,会将相关的Tool工具进行注册,统一汇聚在一个类似于服务注册中心的列表上去,客户端通过配置Server的地址后,就能进行调用,在下面的类中,提供了2个工具方法,第一个是模拟调用天气的API获取天气信息,第二个是获取用户所在的时区时间。

package com.congge.tool;import org.springframework.ai.tool.annotation.Tool;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;import java.time.LocalDateTime;@Service("weatherServiceTool")
public class WeatherServiceTool {@Tool(description = "获取指定城市的天气")public String getWeather(String cityName){if(cityName.equals("北京")){return "晴天";}else if(cityName.equals("上海")){return "阴天";}else {return "未知";}}@Tool(description = "获取当前用户所在的时区时间")String getCurrentDateTime() {return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();}}

4.2.4 注册工具类

提供一个配置类,将上述的Tool工具类进行注册

package com.congge.config;import com.congge.tool.WeatherServiceTool;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.ai.tool.method.MethodToolCallbackProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ToolCallbackProviderConfig {@Beanpublic ToolCallbackProvider toolCallbackProvider(WeatherServiceTool weatherServiceTool) {return MethodToolCallbackProvider.builder().toolObjects(weatherServiceTool).build();}
}

其实到这里基本上就结束了,如果在server工程中,还需要提供接口,继续添加即可,在实际开发中,server端主要是提供针对各类场景下的tool服务,接下来启动工程,在控制台的启动日志中可以看到成功注册了两个服务。

4.3 构建MCP Client服务

4.3.1 导入核心依赖

在pom文件中导入下面的核心依赖,基本和server端的相同,注意版本号保持一致,在client端,主要增加了mcp-client的依赖,以及阿里的spring-ai的依赖,参考下面的依赖信息:

<properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-ai.version>1.0.0-M7</spring-ai.version>
</properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version><relativePath/>
</parent><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M6.1</version></dependency><!--<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId><version>1.0.0-M6</version></dependency>--><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</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency>
</dependencies><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository><repository><name>Central Portal Snapshots</name><id>central-portal-snapshots</id><url>https://central.sonatype.com/repository/maven-snapshots/</url><releases><enabled>false</enabled></releases><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository>
</repositories><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>1.0.0-M7</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

4.3.2 增加配置信息

在配置文件中增加下面的信息

server:port: 8082spring:ai:dashscope:api-key: 你的apikey  #这里使用阿里云百炼平台的apikeymcp:client:sse:connections:server1:url: http://localhost:8080toolcallback:enabled: true

4.3.3 增加一个对话接口

增加一个测试用的聊天对话接口,用于测试客户端调用server的服务是否正常,参考下面的代码

package com.congge.web;import jakarta.annotation.Resource;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/client/ai")
public class ChatController {private final ChatClient chatClient;public ChatController(ChatClient.Builder chatClientBuilder) {this.chatClient = chatClientBuilder.build();}@Resourceprivate ToolCallbackProvider toolCallbackProvider;//localhost:8082/client/ai/chat?message=今天北京的天气如何//localhost:8082/client/ai/chat?message=你是谁//localhost:8082/client/ai/chat?message=当前时间是多少@GetMapping("/chat")public String chat(String message){return chatClient.prompt().user(message).tools(toolCallbackProvider.getToolCallbacks()).call().content();}
}

4.3.4 效果测试

启动上面client的服务,依次调用几个接口测试下是否能够成功调用到server端的服务。

1)测试效果一

调用接口:localhost:8082/client/ai/chat?message=今天北京的天气如何 ,在server端,提供了一个获取天气信息的模拟接口,所以在下面的接口响应中可以看到正常返回结果

2)测试效果二

调用接口:localhost:8082/client/ai/chat?message=你是谁 ,这是一个与server端2个工具方法无关的问题,所以最后由大模型返回的响应结果

3)测试效果三

调用接口:localhost:8082/client/ai/chat?message=当前时间是多少 ,server中提供了获取时间的工具方法,所以在调用结果中可以看到返回了预期的结果

4.4 MCP 底层原理解析

在上面的案例中,演示了如何在client端调用server端的tool服务,于是细心的伙伴会问,这是怎么实现的呢?clent端怎么就能准确的调用到server端提供的服务了呢?下面简单说明下其底层的实现原理。

4.4.1 server端底层执行逻辑

在server端工程中,代码中搜索这个McpAsyncServer类,server端项目启动的时候,通过这个类的执行,将tool的相关方法注册到一个指定的位置,然后暴露出去,从而客户端只要配置了与server端的连接,即可获取到这些tool列表,类似于我们在使用nacos之类的服务注册中心时候,只要服务消费者连上注册中心,就可以获取并使用上面注册的服务列表类似的道理。

在这个类中,提供了多个与Tool相关的方法,如下:

启动server工程,首先进入了该类的构造方法中,走到构造方法中,可以看到获取到了工程中提供的2个tool方法

同时在下面这段代码中,暴露了一个重要的端口: tools/list ,简单理解就是为客户端暴露了一个获取server端工具列表的接口

  • tools/list ,暴露工具列表;

  • tools/call,执行工具调用;

4.4.2 client 端底层执行逻辑

在客户端,在上面的案例演示中看到,在配置文件中配置了连接server端的IP+端口号,然后在接口中注入相关的类就可以调用了,简单理解就是,通过这样的配置之后,客户端在发起对server端的tool方法调用时,从tool列表中找到合适的tool,然后执行调用,从而返回预期的结果。

在client端代码中,通过ToolCallbackProvider这个接口进入,可以看到,这是一个接口,里面对应了多个具体的实现类,不同的实现对应了不同场景下对于tool的调用模式,在上述的案例代码中,对应的便是下面这个SyncMcpToolCallbackProvider类的代码执行

在启动工程之后,通过一次接口调用后,来到下面的McpSyncClient这个类的代码中,首先会执行下面的listTools方法,获取当前客户端能够拿到的tool列表,通过debug代码可以看到已经拿到了server端提供的2个tool

通过中间一些列的过滤、筛选得到具体执行的那个tool,然后执行本类中的callTool方法,而且是一个同步阻塞方法,需要等待执行结果的返回

继续往下走,就看到了在上一个解析server端源码中的那个 tools/call的接口了,在这里相当于是客户端找到了具体的执行tool之后,向server端发起request,然后等待server的执行结果

五、写在文末

本文详细介绍了Spring AI MCP的相关技术,并通过一个实际案例操作演示了在SSE模式下MCP的实战应用,事实上,使用Spring AI对接和整合MCP还有很多技能可以解锁,比如stdio模式下的使用,整合第三方的MCP服务等,限于篇幅原因,有兴趣的同学可以基于此继续深入研究,在后续的篇章中也会逐渐丰富和完善,本篇到此结束,感谢观看。

相关文章:

  • 概率统计:AI大模型的数学支柱
  • 【HW系列】—安全设备介绍(开源蜜罐的安装以及使用指南)
  • 做好 4个基本动作,拦住性能优化改坏原功能的bug
  • 数据库系统概论(十二)SQL 基于派生表的查询 超详细讲解(附带例题表格对比带你一步步掌握)
  • 【C#】Quartz.NET怎么动态调用方法,并且根据指定时间周期执行,动态配置类何方法以及Cron表达式,有请DeepSeek
  • 智启未来:当知识库遇见莫奈的调色盘——API工作流重构企业服务美学
  • 我爱学算法之—— 前缀和(上)
  • 分布式锁剖析
  • STM32 笔记 _《GPIO配置从低层走向高层》
  • 盲盒经济2.0:数字藏品开箱是否适用赌博法规
  • 牛客2025年儿童节比赛
  • 不使用绑定的方法
  • 打卡day42
  • 计算机网络技术
  • vscode编辑器怎么使用提高开发uVision 项目的效率,如何编译Keil MDK项目?
  • 28 C 语言作用域详解:作用域特性(全局、局部、块级)、应用场景、注意事项
  • iOS安全和逆向系列教程 第18篇:iOS应用脱壳技术详解与实战
  • C语言 — 文件
  • QtWidgets,QtCore,QtGui
  • 系统思考:整体观和心智模式
  • 电子书网站 跟我学做家常菜800/百度一下手机版
  • wordpress图片主题破解版/厦门seo专业培训学校
  • 武汉网站建设组织/google下载安装
  • 互联网营销师题库/网站手机优化
  • 怎么做色情网站赚钱/微信营销的优势
  • 吉林省软环境建设网站/东莞seo建站如何推广