modelcontextprotocol / modelcontextprotocol/java-sdk
Initialization errors in McpAsyncClient not emitted immediately
还没有人认领这个 Issue。
- 主要语言
- Java
- 星标
- 3.7k
- 派生
- 1.1k
- 平均合并
- 1 天 15 小时
- 30 天内合并 PR
- 9
描述
Bug Description
When subscribing to exceptions from McpAsyncClient.initialize() using onErrorResumein order to catch initialization failures immediately, nothing is emitted. I suspect this is caused by McpAsyncClient not propagating errors downstream.
I’m new to Reactor and don’t know how to fix this. Any simple tips or pointers, like which class or method handles error propagation, would be really helpful so I can send a PR.
Also, I believe this issue may be related to:
- https://github.com/modelcontextprotocol/java-sdk/issues/275
- https://github.com/modelcontextprotocol/java-sdk/issues/377
- https://github.com/modelcontextprotocol/java-sdk/issues/151
Environment
JDK: zulu-21
gradle: 8.10.2
IntelliJ IDEA 2025.1.1.1 (Community Edition) (K2 mode)
io.modelcontextprotocol java-sdk commit: https://github.com/modelcontextprotocol/java-sdk/commit/8a2f97f1b1995880c492159dd1b4c50266d0b579
Steps to reproduce
- Clone and
installthe repo, checkout https://github.com/modelcontextprotocol/java-sdk/commit/8a2f97f1b1995880c492159dd1b4c50266d0b579 - Run the script provided below
- Observe that no immediate exception is thrown
Expected behavior
- When I initialize McpClient with an incorrect transport
- And internally, the
reactor.core.publisher.Operatorslogger reports:
java.lang.RuntimeException: Failed to start process with command: [a, a] - Then I expect the initialization to fail immediately - not after my configured timeout
Minimal Complete Reproducible example
Main.kt:
import io.modelcontextprotocol.client.transport.StdioClientTransport
import io.modelcontextprotocol.client.transport.ServerParameters
import kotlinx.coroutines.reactive.awaitSingle
import mu.KotlinLogging
import reactor.core.publisher.Mono
import java.time.Duration
private val logger = KotlinLogging.logger {}
suspend fun main() {
val params = ServerParameters.builder("a").args("b").build()
val transport = StdioClientTransport(params)
val client = io.modelcontextprotocol.client.McpClient
.async(transport)
.requestTimeout(Duration.ofSeconds(6))
.initializationTimeout(Duration.ofSeconds(5))
.build()
client.initialize()
.doOnError { t -> logger.error { t }; return@doOnError }
.onErrorResume { return@onErrorResume Mono.error(it) }
.awaitSingle()
}
build.gradle.kts:
plugins {
kotlin("jvm") version "2.1.20"
}
group = "com.anything.mcp"
version = "1.0-SNAPSHOT"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation("io.modelcontextprotocol.sdk:mcp:0.11.0-SNAPSHOT")
implementation("io.modelcontextprotocol.sdk:mcp-spring-webflux:0.11.0-SNAPSHOT")
implementation("io.github.microutils:kotlin-logging:3.0.5")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.8.0")
}
kotlin {
jvmToolchain(21)
}
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
首先跟踪 Main.kt 使用的 McpAsyncClient.initialize() 和 StdioClientTransport 启动路径,检查进程启动失败如何到达 Reactor publisher。使用提供的复现步骤和 Operators logger 输出,确认该失败会立即发出,而不是仅在 initializationTimeout 之后才发出;完成的标准是错误无需等待超时即可到达 doOnError/onErrorResume。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- java, kotlin
- 领域
- api, backend
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 冷清
- 描述清晰度
- 基本清楚
- 新手友好度
- 48/100