fix: MCP SDK 1.29 compat — SSE deadlock, rawHeaders, protocol version
Three bugs that make the ChatGPT connector hang forever on "Create". All three surface with @modelcontextprotocol/sdk >=1.29, which rewrote the Node transport as a wrapper around WebStandardStreamableHTTPServerTransport via @hono/node-server. 1. SSE stream deadlock (root cause of the hang) enqueueSessionOp() serialises every operation per session. A spec compliant client opens a long lived GET SSE stream right after initialize; that request only resolves when the stream closes, so it held the per session lock forever and every later POST (tools/list, tools/call) queued behind it. Now only POST/DELETE are serialised. This is invisible to curl, which never opens the GET stream — the MCP SDK client reproduces it every time. 2. Session recovery patched the wrong header bag tryRecoverStale() set req.headers, but @hono/node-server builds the fetch Headers from incoming.rawHeaders. The session id therefore never reached the transport, warm up "succeeded" and the replayed request still got 400 Mcp-Session-Id header is required. Patch both. 3. Unsupported protocol version was propagated ChatGPT (openai-mcp/1.0.0) sends MCP-Protocol-Version: 2026-07-28 on its discovery probe. The SDK supports up to 2025-11-25, so the warm up notifications/initialized was rejected with 400. Clamp to a version the SDK actually supports. Also adds optional hardening, both opt in via .env: - HOST (default 127.0.0.1) — the server used to bind 0.0.0.0, exposing a full shell to the whole LAN. BREAKING for anyone relying on LAN access; set HOST=0.0.0.0 to restore. - MCP_TOKEN (default empty, behaviour unchanged when unset) — serves MCP at /mcp/<token>; bare /mcp and / return 404. Deliberately 404 and not 401, since 401 is the MCP OAuth trigger and makes clients hunt for metadata. Docs: document HOST/MCP_TOKEN, add macOS/Linux setup (the .bat/.ps1 scripts are Windows only), add a Pinggy tunnel option for networks that block cloudflared's port 7844, and flag in AGENTS.md the 14 tools that only exist in the `full` profile — the default `slim` profile does not expose them, so the agent was being told to call tools it cannot see. Verified with a spec compliant MCP SDK client over both localhost and a public tunnel: connect, tools/list (23 tools), tools/call run_command, close. Test suite 39/39.
H
Hoang Tran - mac pro committed
b7f2ed93fb98f1196705761d73e532c551b7c1c1
Parent: 81a53c9