Skip to content

feat: add HTTP/SSE transport support for MCP server#105

Open
m2ux wants to merge 1 commit intomainfrom
feat/101-http-sse-transport
Open

feat: add HTTP/SSE transport support for MCP server#105
m2ux wants to merge 1 commit intomainfrom
feat/101-http-sse-transport

Conversation

@m2ux
Copy link
Copy Markdown
Owner

@m2ux m2ux commented Apr 20, 2026

Summary

Switch the MCP server to HTTP/SSE transport and remove the signed session token (~500+ chars) from all tool response content, eliminating persistent JWT bloat from the LLM context window. The token remains accessible via _meta.session_token for SDK-level auto-threading and as a required tool parameter.

🎫 Ticket 📐 Engineering 🧪 Test Plan


Motivation

The server currently uses stdio transport. Workflow state is encoded as a signed JWT session token (~500+ chars) and returned in tool call result content on every tool call. This token is visible to the LLM and persists in the context window for the entire workflow session, consuming tokens on every turn. For workflows with 10-30+ tool calls, this results in kilobytes of repeated token content.

Switching to HTTP/SSE transport with StreamableHTTPServerTransport (already present in the MCP TypeScript SDK v1.25.2) provides a separate metadata channel. The session token is removed entirely from response content and carried only in _meta.session_token, which is accessible to SDK-level client tooling but not shown to the LLM. The server remains fully stateless — no session store is added.

Key design decision: The Mcp-Session-Id header is not used because its strict validation rejects mutating tokens (confirmed in SDK source analysis DD-1). Instead, sessionIdGenerator: undefined disables the header entirely (stateless mode), and _meta.session_token serves as the authoritative token source.


Changes

Implementation (coming next):

  • Configtransport, httpPort, httpHost fields already added to ServerConfig with TRANSPORT, HTTP_PORT, HTTP_HOST env vars in src/config.ts:14-18,34-44 (T1 complete, uncommitted)
  • Entrypoint — Refactor src/index.ts to conditionally create StdioServerTransport (default) or StreamableHTTPServerTransport based on config.transport (T2)
  • Content removal (workflow-tools.ts) — Remove session_token from 6 JSON response objects, 3 TOON header prefixes; remove checkpoint_handle from 3 JSON objects and 1 TOON object (13 sites total). Keep client_session_token in dispatch_workflow. (T3)
  • Content removal (resource-tools.ts) — Remove session_token from 1 JSON response object, 3 TOON header prefixes (4 sites total) (T4)
  • Test updates — Update 19 content-body assertion and token-read sites in tests/mcp-server.test.ts to read from _meta instead of parsed content (required — A-12/A-17 invalidated: 8 assertions + 11 token reads currently parse content text) (T5)
  • Verification — Run npm test and npm run typecheck; all must pass (T6)

Retained (not removed):

  • _meta.session_token — remains in all 16 relevant tool responses as the authoritative token source
  • session_id (UUID, 36 chars) — remains in start_session response for stale-session detection
  • client_session_token — remains in dispatch_workflow response (one-time dispatch, not per-call bloat)
  • session_token as a tool input parameter — remains required on all tools that need it

Assumptions reconciliation (plan-prepare):

  • 8 validated, 3 invalidated, 2 partially validated, 4 open (stakeholder-dependent)
  • Key risk: stdio agents depend on MCP client auto-threading from _meta (A-09, same as A-06) — medium risk, mitigated by _meta mechanism working at SDK level (confirmed by test helpers)

📌 Submission Checklist

  • Changes are backward-compatible (or flagged if breaking)
  • Pull request description explains why the change is needed
  • Self-reviewed the diff
  • I have included a change file, or skipped for this reason: no changelog process
  • If the changes introduce a new feature, I have bumped the node minor version
  • Update documentation (if relevant)
  • No new todos introduced

🔱 Fork Strategy

  • Node Runtime Update
  • Node Client Update
  • Other
  • N/A

🗹 TODO before merging

  • Implement transport config changes (T1 — already in working tree)
  • Add StreamableHTTPServerTransport to entrypoint (T2)
  • Remove session_token from content bodies (T3, T4)
  • Update test assertions to read from _meta (T5)
  • Verify tests and typecheck pass (T6)
  • Ready for review

Add StreamableHTTPServerTransport as an alternative to the default
stdio transport, enabling remote MCP client connections over HTTP.
Transport is selectable via TRANSPORT env var (stdio|http) or
--transport CLI flag.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant