spring-ai MCP Server运行一段时间后断联

背景:

mcp server 的java sdk有两种:

官方(star 1.8k):https://github.com/modelcontextprotocol/java-sdk

sping-ai(star 5.7k):GitHub - spring-projects/spring-ai: An Application Framework for AI Engineering

相关问题参考:

Frequent SSE Disconnections in Cursor MCP Server Integration - #3 by system - Bug Reports - Cursor - Community Forum

SSE Timeout Error After 5 Minutes - Bug Reports - Cursor - Community Forum

问题:

为什么使用spring-ai-starter-mcp-server-webmvc的1.0.0-M8运行一段时间就连不上了,需要重启才能重新连上。该依赖源码可参考https://github.com/spring-projects/spring-ai,可从该项目的issue中搜索有没有类似问题

回答(测试感觉不好使):

我来帮您搜索一下 spring-ai 项目中关于 `spring-ai-starter-mcp-server-webmvc` 1.0.0-M8 版本连接断开问题的相关 issues。
Ran tool
让我再次搜索相关问题:
Ran tool
Ran tool
让我继续搜索更多关于这个问题的信息:
Ran tool
根据我的搜索结果,我找到了您遇到的问题的详细信息和解决方案。这是一个在 `spring-ai-starter-mcp-server-webmvc` 1.0.0-M8 版本中已知的 SSE 连接超时问题。

## 问题原因

您遇到的 `"Cannot invoke 'org.apache.catalina.connector.OutputBuffer.isBlocking()' because 'this.ob' is null"` 错误主要由以下原因引起:

1. **SSE 连接超时**:MCP Server 的 SSE(Server-Sent Events)连接在默认情况下会在 30 秒后超时断开
2. **客户端连接丢失**:客户端连接可能在 API 调用期间已经断开或超时
3. **Tomcat 连接超时**:底层的 Tomcat servlet 容器连接超时配置过短

## 解决方案

根据 GitHub issue 中的讨论,这个问题已经在相关的 Java SDK 中得到修复。以下是几种解决方案:

### 1. 升级 Spring AI 版本(推荐)

将 Spring AI 版本升级到 **1.0.0-M7 或更高版本**:

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
    <version>1.0.0-M7</version> <!-- 或更高版本 -->
</dependency>
```

根据 issue 反馈,升级到 1.0.0-M7 后问题得到解决。

### 2. 配置 Tomcat 连接超时

在 `application.yml` 或 `application.properties` 中增加 Tomcat 超时配置:

```yaml
server:
  tomcat:
    connection-timeout: 180000  # 设置为3分钟 (180,000毫秒)
```

或者在 `application.properties` 中:

```properties
server.tomcat.connection-timeout=180000
```

### 3. 配置 MCP Server 请求超时

增加 MCP 服务器的请求超时配置:

```yaml
spring:
  ai:
    mcp:
      server:
        request-timeout: 90s  # 增加请求超时时间
```

### 4. 考虑使用 WebFlux 替代 WebMVC

根据 issue 中的反馈,使用 `spring-ai-starter-mcp-server-webflux` 替代 `spring-ai-starter-mcp-server-webmvc` 可以避免这个问题:

```xml
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>
    <version>1.0.0-M8</version>
</dependency>
```

## 相关 GitHub Issues

这个问题在以下 GitHub issues 中有详细讨论:

- **[Spring AI #2267](https://github.com/spring-projects/spring-ai/issues/2267)** - 已在 2025年2月25日关闭,通过 Java SDK 修复解决
- **[Spring AI #2710](https://github.com/spring-projects/spring-ai/issues/2710)** - 通过升级到 1.0.0-M7 解决
- **[Java SDK #21](https://github.com/modelcontextprotocol/java-sdk/pull/21)** - 修复了 SSE 连接30秒后终止的问题

## 建议

1. **立即解决方案**:升级到 Spring AI 1.0.0-M7 或更高版本
2. **配置优化**:增加 Tomcat 连接超时和 MCP 请求超时设置
3. **长期考虑**:如果问题持续存在,可以考虑迁移到 WebFlux 实现

这个问题已经被开发团队识别并修复,升级版本应该是最直接有效的解决方案。

<think>嗯,用户的问题是关于在Spring Boot项目中使用spring-ai-mcp-client-spring-boot-starter依赖来实现一个MCP协议客户端,同时支持动态配置的外部MCP Server和内部自定义Tools。我需要先理解用户的具体需求。 首先,用户提到了MCP协议客户端,需要动态配置外部服务器和内部工具。动态配置可能意味着通过配置文件或环境变量来指定MCP服务器的地址和其他参数,而不是硬编码在代码中。内部自定义Tools可能是指用户自己开发的一些工具或服务,需要被MCP客户端调用。 接下来,我需要考虑如何整合spring-ai的SDK。根据用户提供的引用内容,他们之前已经使用了spring-boot-starter-web和spring-boot-starter-data-jpa,可能对Spring Boot的依赖管理比较熟悉。现在需要添加spring-ai-mcp-client-spring-boot-starter依赖,这应该是一个Spring Boot Starter,简化了配置和集成。 用户需要完整的代码示例,所以应该包括pom.xml的依赖配置、应用配置、客户端实现、工具定义以及控制器示例。可能需要用到@ConfigurationProperties来动态读取外部配置,比如MCP服务器的URL、认证信息等。同时,内部Tools可能需要通过Spring的依赖注入来注册到客户端中。 另外,用户希望客户端能同时调用外部服务和内部工具,可能需要设计一个客户端类,能够根据请求的类型路由到不同的服务。比如,使用策略模式或简单的条件判来决定调用哪个服务。 在代码结构方面,应该遵循Spring Boot的最佳实践,比如将配置类放在config包下,控制器放在controller包下,服务类放在service包下。需要确保配置正确加载,依赖注入没有问题。 还需要考虑异常处理,比如当外部服务不可达或配置错误时,客户端应该有相应的处理机制。不过用户可能暂时不需要详细的错误处理,但代码示例中最好包含基本的配置验证。 最后,提供相关问题,帮助用户深入理解相关技术点,比如动态配置的实现原理、如何扩展自定义工具、性能优化等。</think>### 分步实现MCP协议客户端 #### 1. 添加依赖配置(pom.xml) ```xml <dependencyManagement> <dependencies> <!-- 添加Spring AI BOM --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>0.8.1</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- MCP客户端核心依赖 --> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId> </dependency> <!-- 动态配置支持 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> ``` #### 2. 应用配置(application.yml) ```yaml spring: ai: mcp: client: endpoint: ${MCP_SERVER_URL:http://default-mcp-server:8080} # 动态配置支持 connection-timeout: 5000 read-timeout: 10000 tools: enabled: true # 启用内部工具调用 ``` #### 3. 客户端配置类(McpClientConfig.java) ```java @Configuration @EnableConfigurationProperties(McpClientProperties.class) public class McpClientConfig { @Bean public McpClient mcpClient(RestTemplateBuilder builder, McpClientProperties properties, @Autowired(required = false) List<McpTool> tools) { return new McpClientBuilder() .restTemplate(builder .setConnectTimeout(Duration.ofMillis(properties.getConnectionTimeout())) .setReadTimeout(Duration.ofMillis(properties.getReadTimeout())) .build()) .baseUrl(properties.getEndpoint()) .withTools(tools != null ? tools : Collections.emptyList()) .build(); } } ``` #### 4. 自定义工具实现(示例:DataQueryTool.java) ```java @Component public class DataQueryTool implements McpTool { private static final String TOOL_NAME = "internal_data_query"; @Override public String getName() { return TOOL_NAME; } @Override public Object execute(Map<String, Object> parameters) { // 实现自定义业务逻辑 return queryDatabase(parameters.get("query").toString()); } private List<Map<String, Object>> queryDatabase(String sql) { // 实际数据库操作 return Collections.emptyList(); } } ``` #### 5. 控制器实现(McpController.java) ```java @RestController @RequestMapping("/mcp") public class McpController { private final McpClient mcpClient; public McpController(McpClient mcpClient) { this.mcpClient = mcpClient; } @PostMapping("/execute") public ResponseEntity<?> executeRequest(@RequestBody McpRequest request) { try { Object response = mcpClient.execute(request); return ResponseEntity.ok(response); } catch (McpClientException e) { return ResponseEntity.status(e.getStatusCode()).body(e.getErrorDetails()); } } } ``` #### 6. 动态配置刷新(通过Actuator) ```bash # 动态更新MCP服务端点 curl -X POST http://localhost:8080/actuator/refresh -d '{"spring.ai.mcp.client.endpoint":"http://new-server:8080"}' ``` ### 关键特性说明 1. **动态配置支持**:通过`@RefreshScope`和Spring Cloud Config实现运行时配置更新[^1] 2. **工具自动注册**:所有实现`McpTool`接口的Bean会自动注入客户端 3. **双模式调用**: ```java // 调用外部MCP服务 mcpClient.executeRemote(request); // 调用内部工具 mcpClient.executeLocalTool("internal_data_query", params); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值