fix(server): add timeout to MCP connection initialization#2922
Open
hobostay wants to merge 1 commit into
Open
Conversation
The MCP connection handler waited indefinitely on `ready_event.wait()` when establishing SSE, stdio, or HTTP transports. If the transport hung during initialization (e.g. unresponsive MCP server), the handler would block forever. Add a 30-second timeout using `asyncio.wait_for()`. On timeout, the background task is cancelled and a 504 response is returned to the client. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
1 issue found across 1 file
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="backend/chainlit/server.py">
<violation number="1" location="backend/chainlit/server.py:1490">
P1: The timeout path can still hang because it awaits the cancelled MCP task without any second timeout.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| except asyncio.TimeoutError: | ||
| task.cancel() | ||
| try: | ||
| await task |
Contributor
There was a problem hiding this comment.
P1: The timeout path can still hang because it awaits the cancelled MCP task without any second timeout.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At backend/chainlit/server.py, line 1490:
<comment>The timeout path can still hang because it awaits the cancelled MCP task without any second timeout.</comment>
<file context>
@@ -1482,7 +1482,20 @@ async def _mcp_session_runner() -> None:
+ except asyncio.TimeoutError:
+ task.cancel()
+ try:
+ await task
+ except BaseException:
+ pass
</file context>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ready_event.wait()in the MCP connection handler to prevent indefinite hangs when an MCP server is unresponsive.Why
When establishing an MCP connection (SSE, stdio, or HTTP transport), the handler calls
await ready_event.wait()to wait for the background task to finish initialization. If the MCP server hangs or is unresponsive, this wait is indefinite, effectively blocking the server handler.While the
finallyblock in the background task does setready_eventon errors, a hung transport connection (e.g. TCP connection that never completes) would never reach thefinallyblock, causing the wait to hang forever.On timeout, the background task is cancelled and a 504 Gateway Timeout response is returned.
Test plan
🤖 Generated with Claude Code
Summary by cubic
Add a 30-second timeout to MCP connection initialization (SSE, stdio, HTTP) to prevent hangs when the MCP server is unresponsive. On timeout, cancel the background task and return a 504 Gateway Timeout to the client.
Written for commit a895c6c. Summary will update on new commits.