Skip to content

fix(server): add timeout to MCP connection initialization#2922

Open
hobostay wants to merge 1 commit into
Chainlit:mainfrom
hobostay:fix/mcp-connection-timeout
Open

fix(server): add timeout to MCP connection initialization#2922
hobostay wants to merge 1 commit into
Chainlit:mainfrom
hobostay:fix/mcp-connection-timeout

Conversation

@hobostay
Copy link
Copy Markdown

@hobostay hobostay commented May 10, 2026

Summary

  • Add a 30-second timeout to 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 finally block in the background task does set ready_event on errors, a hung transport connection (e.g. TCP connection that never completes) would never reach the finally block, causing the wait to hang forever.

On timeout, the background task is cancelled and a 504 Gateway Timeout response is returned.

Test plan

  • Verify MCP connections to responsive servers still work normally
  • Test with an MCP server that is unreachable to confirm the 504 timeout response
  • Verify existing backend tests pass

🤖 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.

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>
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. backend Pertains to the Python backend. bug Something isn't working labels May 10, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

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

Labels

backend Pertains to the Python backend. bug Something isn't working size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant