spring-ai
spring-ai copied to clipboard
Optimize SSE Transport Configuration to Prevent Duplicate Connections
Overview
This PR addresses the issue of duplicate SSE connections and MCP tools creation when both WebFlux and HTTP Client implementations are available.
Current Issues
-
Duplicate SSE Connections Problem
- When both WebFlux and HTTP Client are available,
McpClientAutoConfigurationloads both implementations SseWebFluxTransportAutoConfigurationandSseHttpClientTransportAutoConfigurationcreate duplicate connections- Results in unnecessary resource consumption and potential performance issues
- When both WebFlux and HTTP Client are available,
-
Duplicate MCP Tools Creation
- Multiple identical MCP tools are created due to duplicate transport implementations
- Affects system efficiency and resource utilization
- May cause confusion in tool management and callbacks
Solution
-
Transport Mode Configuration
public enum SseTransportMode { WEBFLUX, // Default implementation HTTP_CLIENT } -
Configuration Property
spring.ai.mcp.client.sse.transport-mode=WEBFLUX # Default # or spring.ai.mcp.client.sse.transport-mode=HTTP_CLIENT -
Implementation Details
- Added transport mode selection in
McpSseClientProperties - Used conditional loading to ensure single implementation
- Optimized tool creation process
- Maintained backward compatibility
- Added transport mode selection in
Benefits
-
Resource Efficiency
- Single SSE connection per endpoint
- Optimized tool initialization
- Reduced memory footprint
-
Better Configuration Control
- Explicit transport mode selection
- Clear configuration options
- IDE support with metadata
-
Improved Stability
- Prevents duplicate connections
- Streamlined tool management
- Better error handling
Testing Done
- Verified single transport initialization
- Tested tool creation and management
- Validated configuration switching
- Checked backward compatibility
Related Files
McpClientAutoConfiguration.javaMcpSseClientProperties.javaSseWebFluxTransportAutoConfiguration.javaSseHttpClientTransportAutoConfiguration.javaadditional-spring-configuration-metadata.json
Additional Notes
- This change is backward compatible
- Added configuration metadata for better IDE support
- Documentation has been updated accordingly
在版本 v1.0.0-M6, 我临时解决方案是在 application.properties 中添加以下内容,使其不加载 SseHttpClientTransportAutoConfiguration
spring.autoconfigure.exclude = org.springframework.ai .autoconfigure.mcp.client.SseHttpClientTransportAutoConfiguration
在版本 v1.0.0-M6, 我临时解决方案是在 application.properties 中添加以下内容,使其不加载 SseHttpClientTransportAutoConfiguration
spring.autoconfigure.exclude = org.springframework.ai .autoconfigure.mcp.client.SseHttpClientTransportAutoConfiguration
@SpringBootApplication(exclude = { org.springframework.ai.autoconfigure.mcp.client.SseHttpClientTransportAutoConfiguration.class }) 多种实现方案,我修改了源代码,并提交了,也进行了测试
@aliyun1024qjc The SseHttpClientTransportAutoConfiguration and SseWebFluxTransportAutoConfiguration should be mutually exclusive based on this condition.
Even if both spring-ai-starter-mcp-client and spring-ai-starter-mcp-client-webflux are in your POM, they shouldn't be active simultaneously, avoiding any "duplication."
Could you clarify your configuration and how to reproduce this issue?
@aliyun1024qjc根据这个条件,
SseHttpClientTransportAutoConfiguration和SseWebFluxTransportAutoConfiguration应该是互斥的。即使
spring-ai-starter-mcp-client和spring-ai-starter-mcp-client-webflux都在您的POM中,它们也不应该同时处于活动状态,以避免任何“重复”。"您能否说明您的配置以及如何重现此问题?
@tzolov Thank you for your feedback! I've created a sample project to demonstrate the issue:
Repository: https://github.com/aliyun1024qjc/spring-ai-bug-sse
Issue Demonstration
The repository contains a minimal setup that clearly shows both auto-configurations are activated simultaneously in certain scenarios, leading to duplicate SSE connections and tool registrations.
Key Findings
- Both transport implementations (
SseHttpClientTransportAutoConfigurationandSseWebFluxTransportAutoConfiguration) are activated when the WebFlux dependency is present - This occurs regardless of the
typesetting (SYNC or ASYNC)
Evidence
Scenario 1: SYNC Mode
- When
type: SYNCis configured, the application fails to start - Error:
Multiple tools with the same name (get_addr_date) - Logs show two client connections being created:
[ient-1-Worker-2][ient-2-Worker-0]
Scenario 2: ASYNC Mode
- When
type: ASYNCis configured, the application starts - But accessing
/getServerListendpoint shows duplicate tools - Logs confirm two separate connections:
工具名称: get_addr_date, 描述: 获取指定地点的当前时间 工具名称: get_addr_date, 描述: 获取指定地点的当前时间
Root Cause
The issue is in McpClientAutoConfiguration which doesn't ensure mutually exclusive activation of transport implementations:
java
@AutoConfiguration(after = {
StdioTransportAutoConfiguration.class,
SseHttpClientTransportAutoConfiguration.class,
SseWebFluxTransportAutoConfiguration.class
})
How to Reproduce
- Clone the repository:
git clone https://github.com/aliyun1024qjc/spring-ai-bug-sse.git - Open in your IDE
- Run the client application with different configurations:
- Change
type: SYNCin application.yml to see startup failure - Use
type: ASYNCand access/getServerListto see duplicate tools
- Change
My PR adds explicit transport mode configuration (spring.ai.mcp.client.sse.transport-mode) to ensure only one implementation is active at a time, preventing these issues.
Would you like me to provide any additional information?
How to Reproduce
- Clone the repository:
git clone https://github.com/aliyun1024qjc/spring-ai-bug-sse.git - Open in your IDE
- Run the client application with different configurations:
- Change
type: SYNCin application.yml to see startup failure - Use
type: ASYNCand access/getServerListto see duplicate tools
- Change
My PR adds explicit transport mode configuration (spring.ai.mcp.client.sse.transport-mode) to ensure only one implementation is active at a time, preventing these issues.
Would you like me to provide any additional information?
@markpollack Thank you for reviewing my PR and adding it to the 1.0.0-RC1 milestone.
I've noticed that this PR shows conflicts that need to be resolved, but I'm unable to click the "Resolve conflicts" button in the GitHub interface to address these conflicts. I'm happy to help resolve these conflicts to move the PR forward.
Could you please advise:
- Would you like me to resolve these conflicts?
- If so, what's the recommended approach to resolve them? Should I handle them locally and push updates, or is there another preferred method?
Thank you for your guidance and assistance!
@aliyun1024qjc I looked in this again and I'm not convinced that there is a issue. You should use either the :
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
or the
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>
You should never use both dependencies together. They are mutually excludable!
If you use the spring-ai-starter-mcp-client-webflux dependency only the SseWebFluxTransportAutoConfiguration is activated (the SseHttpClientTransportAutoConfiguration is not).
Wise verse if you use the spring-ai-starter-mcp-client dependency only the SseHttpClientTransportAutoConfiguration is activated and the SseWebFluxTransportAutoConfiguration.
Are you saying that if you use spring-ai-starter-mcp-client-webflux you see both SseWebFluxTransportAutoConfiguration and SseHttpClientTransportAutoConfiguration?
@aliyun1024qjc我又看了一遍,觉得没什么问题。 你可以使用以下方法之一:
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-client</artifactId> </dependency>或
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-client-webflux</artifactId> </dependency>切勿同时使用这两个依赖项。它们是互斥的!
如果您使用
spring-ai-starter-mcp-client-webflux依赖项,则仅SseWebFluxTransportAutoConfiguration激活 (SseHttpClientTransportAutoConfiguration不激活)。 明智的做法是,如果您使用spring-ai-starter-mcp-client依赖项,则仅SseHttpClientTransportAutoConfiguration激活 ,并且SseWebFluxTransportAutoConfiguration。您是说如果您使用 spring-ai-starter-mcp-client-webflux 您会看到
SseWebFluxTransportAutoConfiguration和SseHttpClientTransportAutoConfiguration?
https://github.com/aliyun1024qjc/spring-ai-bug-sse
This is the case I provided, along with relevant information. I don't know if you have carefully reviewed my demo. I didn't use any of the situations you mentioned. Could you please carefully check the case I gave? thank you @tzolov
@aliyun1024qjc there was in issue in M6 causing that duplications, but this was resolved in the follow up releases: I've submitted a PR to your repository: https://github.com/aliyun1024qjc/spring-ai-bug-sse/pull/1 that upgrades to M8 and as you can see there is no issue there.
I'm closing this as resolved as shown by https://github.com/aliyun1024qjc/spring-ai-bug-sse/pull/1 @aliyun1024qjc please feel free to reopen it if i've missed something.
maybe i met the same issue with you, i wanna check with you. in my project, my mcp-client wants call 2 different mcp-server,the first one is used by chatClient that type is sync, the second one is used by mcpClientTransport that type is async, the demo call amap. i just found that i can not use the client by sse sync the same time with async client. 我的工程中想用两个不同的客户端调用不同的server,一个是异步的一个是同步的,我发现是不是不能在工程中用sse模式调用的时候这两者并存,按理说底层应该是可以隔离http调用的,那应该也可以异步调用和同步调用并存吧。我发现我重写了McpClientAutoConfiguration以后,加载调用的时候还是失败,会在加载异步客户端的时候block的时候阻塞超时,同时我看了会把sync同步的client也加载一份,会出现两个,看上去和你上面描述的一致。请问是否有解法了呢