关于 项目依赖
这份项目说明记录了 Spring AI MCP 服务的 SSE 会话定制与运维方案,涉及会话清理、优雅关闭消息、客户端标识及连接异常后的客户端重建。
主要功能
- 01自定义 SSE 会话超时配置
- 02将 SSE sessionId 传入工具
- 03优雅关闭会话消息
- 04可选的定时客户端 ping 检查
- 05客户端重连处理说明
适用场景
- 01设置服务端会话超时
- 02优雅关闭 SSE 会话
- 03客户端重启后替换旧会话
- 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

自定义功能
透传sse的sessionId到工具中
工具参数名在未使用 @SseSessionId 注释的情况下不允许使用 sseSessionId

session没有timeout功能
解决办法:
- org.springframework.ai.mcp.server.autoconfigure.McpServerProperties 新增 sessionTimeOutSecond 属性,单位:秒

- 重写: io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider
1.充血 构造函数

2.io.modelcontextprotocol.server.transport.WebMvcSseServerTransportProvider.handleMessage

新增手动清除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

你以为完美解决了吗?
不,当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)(本地客户端测试)
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。