Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

[Bug]: MCP SSE transport rejects concurrent requests on connect with "Received request before initialization was complete" (-32602)

未关闭
#2,233 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
66/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
活跃
技术栈
python

调研方向

Start with /app/mcp_bridge.py, comparing the /mcp/ws initialization gate with the SSE /mcp/sse and /mcp/messages flow through SseServerTransport. Reproduce with parallel tools/call requests during the initialize handshake and inspect the resulting session behavior. Done means concurrent SSE requests no longer fail with the pre-initialization -32602 response.

由索引模型根据 Issue 内容生成。

描述

⚙️ In-progress 🐞 Bug 📌 Root caused
crawl4ai version

0.9.2 (Docker server, unclecode/crawl4ai:latest)

Expected Behavior

When an MCP client (such as OpenCode, Claude Code, or multi-agent runtimes) connects over SSE (/mcp/sse) and issues tool calls, inbound requests arriving while initialization is completing should either be briefly buffered/queued or await initialization before processing, similar to how /mcp/ws gates incoming traffic.

Current Behavior

When a client establishes an SSE connection and dispatches tool calls concurrently (e.g. parallel fan-out upon connecting), the requests hit /mcp/messages/?session_id=... before the initialize -> notifications/initialized handshake has completed inside mcp.server.session.ServerSession.

This causes mcp/server/session.py to raise:

WARNING - Failed to validate request: Received request before initialization was complete

The client receives:

{"jsonrpc": "2.0", "id": 1, "error": {"code": -32602, "message": "Invalid request parameters"}}

The error code -32602 misleads clients into reporting that tool call parameters are malformed, when in reality the arguments were never validated because the transport rejected the uninitialized session state.

Context & Contrast with WebSocket

In /app/mcp_bridge.py, the WebSocket handler (/mcp/ws) explicitly mitigates this race condition by synchronizing on initialization:

# /app/mcp_bridge.py (WebSocket handler)
first = adapter.validate_python(await ws.receive_json())
await c2s_send.send(first)
await init_done.wait()          # <-- explicitly waits for server readiness
while True:
    data = await ws.receive_json()
    await c2s_send.send(adapter.validate_python(data))

However, the SSE transport (/mcp/sse + /mcp/messages) directly passes through Starlette to SseServerTransport:

sse = SseServerTransport(f"{base}/messages/")

Without any gating on incoming POST requests during the handshake window, any concurrent requests arriving in the first ~100–500ms get rejected.

Upstream References

This is a known race condition in the underlying Python SDK:

Suggested Fix

A minimal fix in mcp_bridge.py for the SSE transport:

  1. Wrap or intercept incoming POST messages to /mcp/messages to await session initialization (with a small timeout, e.g. 2.0s) before feeding them to the read stream writer, OR
  2. Provide an init_done event per SSE session matching the WebSocket pattern.
Steps to Reproduce
  1. Connect an MCP client over SSE (/mcp/sse).
  2. Immediately upon receiving the endpoint SSE event, dispatch 3+ parallel tools/call requests in under 50ms alongside initialize.
  3. Observe Received request before initialization was complete in Docker logs and -32602 returned to the client.
Environment
  • Docker container unclecode/crawl4ai:latest (0.9.2)
  • Python 3.12 (inside container)
  • Client: OpenCode / Claude Code via SSE transport
主要语言
Python
星标
84.5k
派生
8.7k
平均合并
3 天 9 小时
30 天内合并 PR
17

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

unclecode/crawl4ai 的其他 Issue

查看 unclecode/crawl4ai 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。