Description
When running an MCP server with StdioServerTransport inside a Docker container,
the server.onClose and session.onClose callbacks are never triggered when the
MCP client (opencode) closes the connection by closing stdin.
Steps to Reproduce
- Start an MCP server using
StdioServerTransport
- Connect a client via stdio (e.g. opencode)
- Close the client
Expected Behavior
server.onClose or session.onClose callback is called, allowing the server
process to exit gracefully.
Actual Behavior
Neither server.onClose nor session.onClose is triggered. The log shows
session removal:
[DefaultDispatcher-worker-3] INFO ServerSessionRegistry - Removing session: 3a737289-2a49-454d-9cb1-a692c646634b
But the process continues to hang indefinitely.
Workaround
Wrapping System.in to detect EOF manually:
class EofDetectingInputStream(
private val delegate: InputStream,
private val onEof: () -> Unit,
) : InputStream() {
override fun read(): Int {
val b = delegate.read()
if (b == -1) onEof()
return b
}
override fun read(b: ByteArray, off: Int, len: Int): Int {
val n = delegate.read(b, off, len)
if (n == -1) onEof()
return n
}
}
val transport = StdioServerTransport(
inputStream = EofDetectingInputStream(System.`in`) { exitProcess(0) }.asSource().buffered(),
outputStream = System.out.asSink().buffered(),
)
Environment
- kotlin-sdk version: (укажи свою)
- Kotlin version: (укажи свою)
- OS: Linux (Docker container)
- JVM: Eclipse Temurin 17
Description
When running an MCP server with
StdioServerTransportinside a Docker container,the
server.onCloseandsession.onClosecallbacks are never triggered when theMCP client (opencode) closes the connection by closing stdin.
Steps to Reproduce
StdioServerTransportExpected Behavior
server.onCloseorsession.onClosecallback is called, allowing the serverprocess to exit gracefully.
Actual Behavior
Neither
server.onClosenorsession.onCloseis triggered. The log showssession removal:
[DefaultDispatcher-worker-3] INFO ServerSessionRegistry - Removing session: 3a737289-2a49-454d-9cb1-a692c646634b
But the process continues to hang indefinitely.
Workaround
Wrapping
System.into detect EOF manually:Environment