mcpField
项
项目依赖

项目依赖

本地服务
github.com/AJobs-coding开发工具179 周前更新

关于 项目依赖

这份项目说明记录了 Spring AI MCP 服务的 SSE 会话定制与运维方案,涉及会话清理、优雅关闭消息、客户端标识及连接异常后的客户端重建。

主要功能

  1. 01自定义 SSE 会话超时配置
  2. 02将 SSE sessionId 传入工具
  3. 03优雅关闭会话消息
  4. 04可选的定时客户端 ping 检查
  5. 05客户端重连处理说明

适用场景

  1. 01设置服务端会话超时
  2. 02优雅关闭 SSE 会话
  3. 03客户端重启后替换旧会话
  4. 04SSE 异常后重新初始化客户端

MCP 相关

说明基于 SSE 传输的 Spring AI MCP 服务定制,包括会话处理和自定义关闭消息,并记录相应的客户端改动。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

来自项目 README

项目依赖

spring ai 1.0.0-M7

版本异常问题

配置问题

org.springframework.ai.mcp.server.autoconfigure.McpServerProperties 中出现的一下配置属性不生效

  • baseUrl
  • sseMessageEndpoint

解决办法:
重写类

  • mcp.server.autoconfiguration.McpWebMvcServerTransportAutoConfiguration
  • io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider
    img.png

自定义功能

透传sse的sessionId到工具中

工具参数名在未使用 @SseSessionId 注释的情况下不允许使用 sseSessionId
img.png

session没有timeout功能

解决办法:

  • org.springframework.ai.mcp.server.autoconfigure.McpServerProperties 新增 sessionTimeOutSecond 属性,单位:秒 img.png
  • 重写: io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider
    1.充血 构造函数
    img_1.png
    2.io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider.handleMessage
    img_2.png

新增手动清除session的message

message种类: mcp.server.constant.MessageEnum
message注入形式: io.modelcontextprotocol.server.transport.McpServerUtil

client需要新增代码,这里用java的客户端 McpAsyncClient 为例,新增方法:

	/**
	 * 会话优雅关闭
	 * @return
	 */
	public Mono<McpSchema.JSONRPCResponse> sessionCloseGracefully() {
		return this.mcpSession.sendRequest(MessageEnum.sessionCloseGracefully.name(), null,
				new TypeReference<>() {
				});
	}

待解决问题

sse中mcp server需要维护一个session进行消息推送。问题来了,后端session释放时机????
mcp客户端主动释放:
mcp客户端新增一个自定义 mcp message(“sessionCloseGracefully”)(
https://github.com/modelcontextprotocol/java-sdk
官方的mcp message: io.modelcontextprotocol.spec.McpSchema
),示例代码:

// io.modelcontextprotocol.client.McpSyncClient#sessionCloseGracefully
/**
	 * 会话优雅关闭
	 * @return
	 */
public Mono<McpSchema.JSONRPCResponse> sessionCloseGracefully() {
    return this.mcpSession.sendRequest("sessionCloseGracefully", null,
                                       new TypeReference<>() {
                                       });
}

问题:mcp客户端重启, 导致mcp server内存泄露
解决方案: 每个mcp客户端的 sse endpoint 可以加上唯一标识:比如"/sse?clientId=osrunner (osrunner-1、lab、lab-1.......)"。 当mcp客户端重启并建立sse时,因为存在唯一标识,所以 mcp server可覆盖之前旧的session。
后端兼容代码位置:io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider.handleSseConnection
img.png

你以为完美解决了吗?
不,当mcp server多服务,则存在负载均衡问题。导致mcp server内存泄露
解决方案: 摆了,资源浪费很有限
当然还有一种解决方案: 定时去让服务端去ping客户端,出现异常后,服务端会清除无效的session(Bean注入默认关闭),代码维护:
mcp.server.autoconfiguration.McpCustomConfiguration.mcpScheduleTask
mcp.server.McpScheduleTask.checkPing

我们假设mcp client是单一且长期存在的。
问题: mcp server重启,mcp客户端sse连接出现异常
1、创建完成sse连接后,mcp server重启期间,mcp客户端请求mcp message响应:
io.modelcontextprotocol.client.transport.HttpClientSseClientTransport -- Error sending message: 404
2、mcp server未启动,客户端请求建立sse, 请求响应:
io.modelcontextprotocol.client.transport.HttpClientSseClientTransport -- SSE connection error
解决方案: mcp客户端 触发轮询重新构造,覆盖老的mcp客户端对象。

综上所诉:

  • 客户端遇见异常时,要有轮询重新初始化操作兜底
  • 客户端建立sse连接需要有唯一标识 /sse?clientId=xxxxx. (多机mcp server会出现内存泄露,但是可控)
  • 客户端关闭sse连接前,向mcp server发送优雅关闭的mcp message (上文提到的sessionCloseGracefully)(本地客户端测试)

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。