Repository navigation
Stop MCP client receive loop from spinning after transport closes - #171
longseespace wants to merge 1 commit into
Conversation
|
Thanks for your contribution, @longseespace. My PR #175 addresses the same root cause with a more comprehensive fix. If you think I've missed something, or if you have any feedback on my PR, please let me know. Rather than adding My PR also removes the now-redundant EAGAIN handling (transports handle this internally), adds |
|
Maintainer triage on February 24, 2026: low-risk merge candidate (small focused Client.swift fix, mergeable, no failing checks). |
|
Hi @longseespace, thank you for this contribution. We're consolidating overlapping PRs. #221 fixes the same receive-loop spin after the transport closes, and it already has an approval. The loop's EAGAIN retry isn't needed there, since We plan to close this PR once #221 is merged, so the fix isn't lost in between. If you think something here isn't covered by #221, please comment there or here and we'll make sure it's carried over. |
Motivation and Context
When an MCP server process exited,
Client.connectkept callingconnection.receive()inside arepeat…while trueloop even though the underlying stream had already finished. That resulted in a tight loop consuming ~100% CPU per disconnected server (e.g., killing 8 servers spiked to ~800% CPU). Breaking out when the stream finishes stops the runaway task and lets reconnect logic create a fresh transport instead.How Has This Been Tested?
Tested in the BoltAI macOS client using this local package:
Breaking Changes
No breaking API changes. Existing clients automatically benefit from the fix and still receive the same stream/error handling behavior.
Types of changes
Checklist
Additional context
The fix keeps the transient “resource temporarily unavailable” retry path intact, so transports that briefly report EAGAIN will still retry. Only a fully finished receive stream now terminates the loop, which matches MCP transport semantics.