SIGN IN SIGN UP

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