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

Spring AI 1.x 系列【40】MCP 客户端 Spring Boot 启动器

1. 概述

Spring AI提供的模型上下文协议(MCP)客户端 Spring Boot 启动器,可为Spring Boot应用自动配置MCP客户端能力。该组件同时支持同步、异步客户端实现,并兼容多种通信传输方式。

本启动器具备以下能力:

  • 支持管理多个客户端实例
  • 可配置客户端自动初始化
  • 兼容多种命名传输方式:标准输入输出(STDIO)、HTTP/SSE、流式 HTTP
  • 无缝集成Spring AI工具调用框架
  • 提供工具过滤能力,可按需启用/屏蔽指定工具
  • 支持自定义工具名称前缀生成,避免命名冲突
  • 完善的生命周期管理:应用上下文关闭时自动释放资源
  • 支持通过自定义扩展器定制客户端创建逻辑

2. 启动器依赖

2.1 标准 MCP 客户端

标准启动器可通过进程内STDIOSSE、流式HTTP、无状态流式HTTP多种方式,同时连接一个或多个MCP服务端。其中SSE与流式HTTP基于JDK原生HttpClient实现。

每一条MCP服务端连接都会创建独立客户端实例,可选择同步(SYNC)或异步(ASYNC)模式(两种模式不可混用)。

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client</artifactId></dependency>

生产环境推荐搭配spring-ai-starter-mcp-client-webflux,使用基于WebFluxSSE/流式HTTP连接。

2.2 WebFlux 客户端

功能与标准启动器一致,但底层基于WebFlux实现流式HTTP、无状态流式HTTPSSE传输。

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client-webflux</artifactId></dependency>

3. 配置项说明

3.1 通用配置

配置前缀:spring.ai.mcp.client

配置项说明默认值
enabled开启/关闭 MCP 客户端true
nameMCP 客户端实例名称spring-ai-mcp-client
versionMCP 客户端版本1.0.0
initialized创建客户端时是否自动初始化true
request-timeout客户端请求超时时间20s
type客户端类型:SYNC(同步) / ASYNC(异步),全局只能选一种SYNC
root-change-notification开启/关闭所有客户端的根路径变更通知true
toolcallback.enabled开启/关闭 MCP 工具回调与 Spring AI 工具框架的集成true

3.2 MCP 注解配置

配置前缀:spring.ai.mcp.client.annotation-scanner

配置项说明默认值
enabled开启/关闭 MCP 客户端注解自动扫描true

3.3 标准输入输出(STDIO)传输配置

配置前缀:spring.ai.mcp.client.stdio

配置项说明默认值
servers-configurationJSON 格式的 MCP 服务端配置文件地址
connections命名式 STDIO 连接配置集合
connections.[name].command启动 MCP 服务端的执行命令
connections.[name].args命令行参数列表
connections.[name].env服务端进程环境变量

配置示例(YAML):

spring:ai:mcp:client:stdio:root-change-notification:trueconnections:server1:command:/path/to/serverargs:---port=8080---mode=productionenv:API_KEY:your-api-keyDEBUG:"true"

引用外部 JSON 配置文件(兼容 Claude Desktop 格式):

spring:ai:mcp:client:stdio:servers-configuration:classpath:mcp-servers.json

mcp-servers.json示例:

{"mcpServers":{"filesystem":{"command":"npx","args":["-y","@modelcontextprotocol/server-filesystem","/Users/username/Desktop","/Users/username/Downloads"]}}}

3.3.1 Windows 平台特殊适配

Windows系统中,npxnpmnodepython等均为批处理文件(.cmd),JavaProcessBuilder无法直接执行批处理,必须通过cmd.exe /c包裹命令。

Windows 配置示例(JSON):

{"mcpServers":{"filesystem":{"command":"cmd.exe","args":["/c","npx","-y","@modelcontextprotocol/server-filesystem","C:\\Users\\username\\Desktop"]}}}

Linux / macOS 配置示例(JSON):

{"mcpServers":{"filesystem":{"command":"npx","args":["-y","@modelcontextprotocol/server-filesystem","/Users/username/Desktop"]}}}

跨平台代码式配置:

通过代码判断操作系统,实现一套配置兼容全平台,同时添加@ConditionalOnMissingBean避免与配置文件自动配置冲突:

@Bean(destroyMethod="close")@ConditionalOnMissingBean(McpSyncClient.class)publicMcpSyncClientmcpClient(){ServerParametersstdioParams;if(isWindows()){// Windows 系统:使用 cmd.exe 包装命令varwinArgs=newArrayList<>(Arrays.asList("/c","npx","-y","@modelcontextprotocol/server-filesystem","target"));stdioParams=ServerParameters.builder("cmd.exe").args(winArgs).build();}else{// Linux / Mac 系统:直接执行命令stdioParams=ServerParameters.builder("npx").args("-y","@modelcontextprotocol/server-filesystem","target").build();}returnMcpClient.sync(newStdioClientTransport(stdioParams,McpJsonMapper.createDefault())).requestTimeout(Duration.ofSeconds(10)).build().initialize();}// 判断当前系统是否为 WindowsprivatestaticbooleanisWindows(){returnSystem.getProperty("os.name").toLowerCase().contains("win");}

路径使用说明:

  • 相对路径(推荐,可移植性强):基于应用运行目录解析
  • 绝对路径(Windows):使用反斜杠\或转义正斜杠/

Windows 下需要cmd.exe包裹的常用批处理:

npx.cmdnpm.cmdpython.cmdpip.cmdmvn.cmdgradle.cmd及自定义.cmd/.bat脚本。

3.4 流式 HTTP(Streamable-HTTP)传输配置

配置前缀:spring.ai.mcp.client.streamable-http

配置项说明默认值
connections命名式流式 HTTP 连接配置集合
connections.[name].urlMCP 服务端基础地址
connections.[name].endpoint接口后缀路径/mcp

配置示例:

spring:ai:mcp:client:streamable-http:connections:server1:url:http://localhost:8080server2:url:http://otherserver:8081endpoint:/custom-sse

3.5 SSE(服务端推送事件)传输配置

配置前缀:spring.ai.mcp.client.sse

配置项说明默认值
connections命名式 SSE 连接配置集合
connections.[name].urlMCP 服务端基础地址
connections.[name].sse-endpointSSE 接口后缀路径/sse

配置示例:

spring:ai:mcp:client:sse:connections:server1:url:http://localhost:8080server2:url:http://otherserver:8081sse-endpoint:/custom-sse

URL 拆分规则:

完整 SSE 地址需拆分为基础URL+接口后缀

完整地址基础 urlsse-endpoint 后缀
http://localhost:3000/mcp-hub/sse/token123localhost:3000/mcp-hub/sse/token123
https://api.service.com/v2/events?key=secretapi.service.com/v2/events?key=secret
http://localhost:8080/sselocalhost:8080/sse(可省略)

SSE 连接排错(404 错误):

  1. 拆分地址时,基础 URL 仅保留协议、域名、端口
  2. 接口后缀必须以/开头,包含完整路径与请求参数
  3. 先通过浏览器或 curl 直接访问完整地址,验证接口可用性

4. 核心功能详解

4.1 同步/异步客户端

  • 同步客户端(默认 SYNC):适用于传统阻塞式请求响应场景,仅注册同步类型 MCP 注解方法,异步方法会被忽略。
  • 异步客户端(ASYNC):适用于响应式非阻塞应用,仅注册异步类型 MCP 注解方法,同步方法会被忽略。

4.2 客户端自定义扩展

通过扩展接口可深度定制客户端行为,支持超时配置、事件监听、消息处理等。

支持两类扩展接口:

  • McpSyncClientCustomizer:同步客户端扩展
  • McpAsyncClientCustomizer:异步客户端扩展

可自定义能力:

  1. 请求超时配置
  2. LLM 采样处理器
  3. 文件根路径权限管理
  4. 交互式信息收集处理器
  5. 各类事件监听器(工具/资源/提示词变更、进度通知、日志通知等)

同步客户端扩展示例:

@ComponentpublicclassCustomMcpSyncClientCustomizerimplementsMcpSyncClientCustomizer{@Overridepublicvoidcustomize(StringserverConfigurationName,McpClient.SyncSpecspec){// 自定义超时时间spec.requestTimeout(Duration.ofSeconds(30));// 根路径配置spec.roots(roots);// 采样请求处理spec.sampling(request->{/* 业务逻辑 */});// 信息收集请求处理spec.elicitation(request->{/* 业务逻辑 */});// 进度通知监听spec.progressConsumer(progress->{/* 业务逻辑 */});// 工具列表变更监听spec.toolsChangeConsumer(tools->{/* 业务逻辑 */});// 资源列表变更监听spec.resourcesChangeConsumer(resources->{/* 业务逻辑 */});// 提示词列表变更监听spec.promptsChangeConsumer(prompts->{/* 业务逻辑 */});// 日志消息监听spec.loggingConsumer(log->{/* 业务逻辑 */});}}

4.3 传输方式支持

传输方式标准启动器WebFlux 启动器
STDIO 标准输入输出
HttpClient 版 HTTP/SSE、流式 HTTP
WebFlux 版 HTTP/SSE、流式 HTTP

4.4 工具过滤

实现McpToolFilter接口,可根据连接信息、工具属性动态过滤工具(启用/禁用),全局仅允许一个过滤 Bean。

@ComponentpublicclassCustomMcpToolFilterimplementsMcpToolFilter{@Overridepublicbooleantest(McpConnectionInfoconnectionInfo,McpSchema.Tooltool){// 过滤指定客户端的所有工具if("restricted-client".equals(connectionInfo.clientInfo().name())){returnfalse;}// 仅保留名称前缀为 allowed_ 的工具if(tool.name().startsWith("allowed_")){returntrue;}// 过滤标注为实验性的工具if(tool.getDescription()!=null&&tool.getDescription().contains("experimental")){returnfalse;}returntrue;}}

4.5 工具名称前缀生成

通过McpToolNamePrefixGenerator为工具名添加前缀,解决多服务端工具重名冲突

框架内置实现:

  • DefaultMcpToolNamePrefixGenerator(默认):自动去重、特殊字符转下划线、超长截断,保证全局唯一
  • noPrefix():不添加前缀(多服务端场景不推荐,易引发冲突)

自定义前缀规则示例:

@ComponentpublicclassCustomToolNamePrefixGeneratorimplementsMcpToolNamePrefixGenerator{@OverridepublicStringprefixedToolName(McpConnectionInfoconnectionInfo,Tooltool){StringserverName=connectionInfo.initializeResult().serverInfo().name();StringserverVersion=connectionInfo.initializeResult().serverInfo().version().replace(".","_");// 格式:服务名_版本_工具名returnserverName+"_v"+serverVersion+"_"+tool.name();}}

关闭前缀功能:

@ConfigurationpublicclassMcpConfiguration{@BeanpublicMcpToolNamePrefixGeneratormcpToolNamePrefixGenerator(){returnMcpToolNamePrefixGenerator.noPrefix();}}

4.6 工具上下文与元数据转换

通过ToolContextToMcpMetaConverter,将 Spring AI 工具上下文转为 MCP 调用元数据,可传递用户ID、令牌、追踪标识等上下文。

框架内置:

  • 默认转换器:过滤空值与内置上下文 Key
  • noOp():禁用上下文转换

4.7 关闭工具回调自动配置

配置spring.ai.mcp.client.toolcallback.enabled=false,将不再自动创建工具回调实例。


5. MCP 客户端注解

使用注解以声明式方式处理 MCP 各类事件与请求:

注解用途
@McpLogging接收服务端日志通知
@McpSampling处理 LLM 采样/补全请求
@McpElicitation向用户收集补充信息
@McpProgress接收长任务进度通知
@McpToolListChanged工具列表变更通知
@McpResourceListChanged资源列表变更通知
@McpPromptListChanged提示词列表变更通知

使用示例:

@ComponentpublicclassMcpClientHandlers{@McpLogging(clients="server1")publicvoidhandleLoggingMessage(LoggingMessageNotificationnotification){System.out.println("日志:"+notification.level()+" - "+notification.data());}@McpSampling(clients="server1")publicCreateMessageResulthandleSamplingRequest(CreateMessageRequestrequest){// 处理LLM请求并返回结果returnCreateMessageResult.builder().role(Role.ASSISTANT).content(newTextContent("响应内容")).model("gpt-4").build();}@McpProgress(clients="server1")publicvoidhandleProgress(ProgressNotificationnotification){doublepercent=notification.progress()*100;System.out.printf("执行进度:%.2f%% %s%n",percent,notification.message());}}

注解同步/异步方法均支持,可通过clients属性指定绑定的客户端实例。


6. 项目使用示例

6.1 完整 YAML 配置

spring:ai:mcp:client:enabled:truename:my-mcp-clientversion:1.0.0request-timeout:30stype:SYNCsse:connections:server1:url:http://localhost:8080server2:url:http://otherserver:8081streamable-http:connections:server3:url:http://localhost:8083endpoint:/mcpstdio:root-change-notification:falseconnections:server1:command:/path/to/serverargs:---port=8080---mode=productionenv:API_KEY:your-api-keyDEBUG:"true"

6.2 代码注入使用

// 同步客户端注入@AutowiredprivateList<McpSyncClient>mcpSyncClients;// 异步客户端注入@AutowiredprivateList<McpAsyncClient>mcpAsyncClients;// 工具回调注入@AutowiredprivateSyncMcpToolCallbackProvidertoolCallbackProvider;

http://www.jsqmd.com/news/971249/

相关文章:

  • 【分享】C4droid 安卓C++编译器 手机编程超便捷
  • 高端制造行业先进封装测试技术岗测试开发工程师成长为CTO要经历哪些职位?
  • 从前做NLP要8天,现在写几个Prompt20分钟搞定
  • Python Scrapy 爬虫实战:整站科普栏目分层遍历采集全攻略
  • 万亿级数据迁移实战与生产事故复盘
  • 2026年沈阳路灯行业专业评估报告:技术驱动与场景适配下的优选解析 - 品牌发掘
  • 西门子S7-1500通过Profinet直连图尔克TBEN-S2 RFID读写头(含128字节通信工程与说明)
  • 北京高端软装机构排行:北京装修设计事务所、北京装修设计工作室、北京装修设计师、北京软装设计师、北京高档装修、北京高端别墅设计师 选择指南 - 优质品牌商家
  • 园林装饰施工公司口碑哪家好 - myqiye
  • 重庆名酒回收电话评测:重庆各类红酒回收/重庆各类酒水回收/重庆名酒回收电话/重庆生肖茅台酒回收/重庆红酒回收/重庆茅台酒上门回收/选择指南 - 优质品牌商家
  • 机器人仿真终极指南:使用Gazebo Sim快速构建真实机器人系统
  • Notepad-- 终极使用指南:跨平台文本编辑器的完整掌握手册
  • 终极指南:如何在Windows 11上完美运行经典DirectX游戏
  • 【LeetCode刷题日记】93.复原IP地址
  • 2026年室内装饰施工推荐,靠谱的品牌有哪些? - myqiye
  • CSDN爆款内容生成器背后的黑箱被拆解了:基于LSTM+时序聚类的选题生命周期预测模型(附训练数据集脱敏样本)
  • 踩坑实录:多仓工程下AI Agent的七大治理原则
  • Python 爬虫项目 asyncio 协程异步抓取多页面公开资讯
  • TOP5头部机构汇总:五大GEO优化服务商实力竞逐:选型参考与决策指南(2026年6月) - GEO优化
  • 成都涡轮快速门技术细节拆解与靠谱厂家判定逻辑:成都工业快速门、成都快速卷帘门、成都快速堆积门、成都快速提升门、成都快速门安装选择指南 - 优质品牌商家
  • 2026年上海附近上门名酒回收机构排行及选择指南:上海五粮液回收/上海名酒回收电话/上海礼品回收/上海红酒回收/选择指南 - 优质品牌商家
  • 终极指南:如何在Linux上完美驱动Realtek WiFi 7网卡
  • 【飞机】飞机俯仰控制系统仿真【含Matlab源码 15598期】
  • 2026 年机器人咖啡行业代表性企业盘点:技术与场景双驱动的行业标杆 - 中媒介
  • 2025-2026 国内 GEO 优化服务商口碑排行:5 家标杆企业全维度选型评测 - GEO优化
  • ComfyUI MixLab:革命性AI创作工作流转换器的创新突破
  • 2026 成都防水补漏服务商口碑测评榜单|全屋渗漏维修机构优选指南(6 月最新) - 宅安选房屋修缮
  • 2026年IP防护审核测试口碑排名,宏科检测口碑好 - myqiye
  • AI编程15-重构与AI辅助代码改进:让AI帮你还技术债,代码可维护性提升200%
  • Windows窗口切换效率低下?X-Mouse Controls帮你实现鼠标悬停即激活终极指南