Skip to content

D5: Streamable HTTP transport validation spike #22

@viktor-shcherb

Description

@viktor-shcherb

Goal

Highest schedule risk — runs first against localhost, NOT after full deploy is wired. Validate end-to-end that the MCP TS SDK's Streamable HTTP transport works through Cloudflare Tunnel for a real Claude Code session.

References

  • DESIGN.md §5.2 (validation row), §6.2 (Streamable HTTP note)

Why first

If the transport doesn't work, every M-series test that touches MCP needs replumbing AND D1-D4 rework. Validate before sinking days into full deploy.

Minimum dependency from M0

Only the header constants (X-Murmur-Subcommand, X-Murmur-Claim-Token, Authorization header constant) need to be locked in for the spike. The full TS+Python types packages are not required. M0's docs/contracts.md header-name section can be the only blocker.

Scope

  1. Stand up a minimal Murmur (M1 + M3 stub + M6 stub returning canned tool list) on localhost
  2. A temporary Cloudflare Tunnel (named murmur-spike, separate from prod tunnel) routes a temporary hostname to localhost:8080
  3. Configure a real Claude Code client with mcp.json pointing at the temporary URL
  4. List tools → confirm 3 static tools appear
  5. Call a synthetic pull_task that returns a stub
  6. Call task_tool with synthetic args; round-trip 5-10s of work
  7. Idle 60s → next request still works (keepalive holds)
  8. Force cloudflared restart mid-session → reconnect succeeds
  9. Document in docs/transport-spike.md

Required structure of docs/transport-spike.md

The doc MUST have these 7 H2 headers (each non-empty):

  1. Versions tested@modelcontextprotocol/sdk@<v>, cloudflared@<v>, Claude Code build SHA, Node version
  2. Working mcp.json — verbatim snippet users will paste
  3. Keepalive cadence — observed interval that survives Cloudflare's idle timeout (with the actual measured timeout)
  4. Reconnect timing — milliseconds from drop to re-initialize succeeding
  5. SDK quirks — list of any session-id, Last-Event-Id, or transport-level oddities encountered, with workaround references
  6. Failure modes — every failure scenario tried (forced disconnect, slow tool, oversized response, malformed request) and observed behavior
  7. Decision — confirm Streamable HTTP is the right choice for the demo, OR document the alternative

Verification gates

  • A real Claude Code session lists pull_task, submit_result, task_tool from the spike URL
  • A round-trip task_tool call returns within 15s
  • Idle-then-resume works (manually verified, time recorded)
  • Forced cloudflared restart followed by an MCP request → reconnect succeeds
  • All 7 H2 headers in docs/transport-spike.md non-empty
  • A screenshot or short screencast of the working session is in the PR

If the spike fails

  • Document the failure mode reproducibly under header 6
  • Update header 7 with the alternative chosen
  • Open a follow-up issue for the alternative
  • Update DESIGN.md §6.2 if the transport choice changes
  • Treat as a hard blocker — do not proceed with D2-D4 until resolved

Definition of done

  • Spike doc committed with all 7 headers populated
  • Real Claude Code session demonstrated (screenshot or recording in PR)
  • If Streamable HTTP works: D1, D2, D4 unblocked. If not: alternative documented with a follow-up issue

Parent: #2
Blocked by: #34 M0 header-constants section only (NOT the full contracts package), and minimal #6 (M1) + minimal stub for #11 (M6)
Blocks: #18 (D1), #19 (D2), #21 (D4)

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:murmurWork on the murmur server packagetype:infraDeploy / CI / ops

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions