Skip to content

fix(client): close stdio read sources during shutdown#798

Open
jstar0 wants to merge 1 commit into
modelcontextprotocol:mainfrom
jstar0:fix/stdio-client-close-blocking-read
Open

fix(client): close stdio read sources during shutdown#798
jstar0 wants to merge 1 commit into
modelcontextprotocol:mainfrom
jstar0:fix/stdio-client-close-blocking-read

Conversation

@jstar0

@jstar0 jstar0 commented Jun 4, 2026

Copy link
Copy Markdown

Summary

Fixes StdioClientTransport.close() so shutdown does not hang when the stdin read loop is blocked waiting for input.

Root Cause / Context

StdioClientTransport.closeResources() stopped the transport coroutine scope and then waited for the scope job to finish. On the JVM, a Source.readAtMostTo() call backed by a blocking Java stream does not necessarily return when the coroutine is cancelled. If the read loop stayed blocked, close() could wait indefinitely.

Changes

  • Close the stdin source during stdio client shutdown before waiting for transport coroutines to finish.
  • Also close the optional stderr source during shutdown.
  • Keep source-close failures non-fatal and log them at debug level.
  • Add a JVM regression test with a RawSource that blocks in readAtMostTo() until close() is called.
  • Assert the close path completes, emits onClose, and does not invoke onError.

Scope / Risk

This is limited to StdioClientTransport shutdown behavior. It does not change the public API or server transports. The regression coverage is JVM-focused because the reported hang is caused by a blocking Java stream read.

Verification

./gradlew :integration-test:jvmTest --tests 'io.modelcontextprotocol.kotlin.sdk.client.StdioClientTransportTest'
./gradlew :kotlin-sdk-client:jvmTest
./gradlew :kotlin-sdk-client:ktlintCheck :integration-test:ktlintCheck :kotlin-sdk-client:detekt :integration-test:detekt :kotlin-sdk-client:apiCheck

Closes #514

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

StdioClientTransport fails to close gracefully when Java stream hangs in blocking read

1 participant