Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

`Client.connect` busy-loops at 100% CPU when the transport reaches EOF before `initialize` completes

Abierto
#256 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 7 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
72/100
Tipo de issue
Error
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
swift

Línea de trabajo

Start in Sources/MCP/Client/Client.swift at the message-handling task created by Client.connect and inspect how connection.receive() behaves when its AsyncThrowingStream finishes. Run the described /usr/bin/true StdioTransport reproduction first. Done means EOF stops further receive polling and connect/_initialize throws a connection-closed error instead of hanging.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

If a spawned MCP server dies (or closes its stdout) during startup — before the client's initialize handshake finishes — Client.connect(transport:) never returns and one core sits pinned at 100%.

What I see: a stdio server that exits immediately on launch. ps shows the host process in state R, and sample <pid> shows the spin inside closure #1 in Client.connect → AsyncThrowingStream.Iterator.next().

The message-handling loop in Sources/MCP/Client/Client.swift is (trimmed):

task = Task {
    guard let connection = self.connection else { return }
    repeat {
        if Task.isCancelled { break }
        do {
            let stream = await connection.receive()
            for try await data in stream {
                if Task.isCancelled { break }
                // decode + dispatch
            }
        } catch { break }
    } while true
}
// ...
return try await _initialize()

When the transport hits EOF, the stream from receive() finishes, the for try await completes without throwing, and while true immediately loops back and calls receive() again, which returns another already-finished stream. Nothing sleeps or exits on end-of-stream, so it spins. Meanwhile connect has moved on to await _initialize(), whose response never arrives because the server is gone, so connect is parked forever on a continuation nothing resumes.

Minimal repro: spawn /usr/bin/true via Process with two Pipes, wrap the pipe fds in a StdioTransport(input:output:), build a Client, and try await client.connect(transport:). Just re-ran this against v0.12.1: connect has neither returned nor thrown 8 seconds in, and ps samples the process at ~100% CPU for the whole wait (96.6 / 100.0 / 100.0 / 100.0 over four 1.5s samples).

Two changes would fix it:

  • The loop should stop (or back off) when the underlying stream finishes rather than re-polling a finished stream — a finished transport stream means the connection is gone.
  • connect / _initialize should then fail with a connection-closed error instead of hanging.

For what it's worth, my workaround is to race connect against a timeout and call client.disconnect() on expiry — disconnect() cancels that task and resumes the pending initialize with an error, so connect throws instead of hanging. Separately I had to set signal(SIGPIPE, SIG_IGN), because writing to the dead server's stdin was raising SIGPIPE and taking down the whole host process. I'd be happy to turn the loop-termination part into a PR if that's welcome.

Lenguaje dominante
Swift
Estrellas
1.5k
Forks
252
Métricas de merge de PR
Sin PR fusionados en 30 d

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de modelcontextprotocol/swift-sdk

Todos los issues de modelcontextprotocol/swift-sdk

Issues similares

Más issues de Swift

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.