Serve MCP over streamable HTTP on /mcp (MCP_TRANSPORT=http) - #114
Conversation
Adds a runStreamableHttp() mode next to stdio and legacy SSE. Stateless by design: every request gets its own Server + StreamableHTTPServerTransport (sessionIdGenerator: undefined) and nothing is remembered between requests — the tool surface is genuinely stateless (servers and caches are module-level), so sessions would buy nothing but bookkeeping: a Map to leak on unclean disconnects and 404s after a restart. Constructing a Server is handler registration only; it opens no sockets. The endpoint parsing (MCP_HOST/MCP_PORT) and the non-loopback warning are factored out of runSse() and shared. /mcp and /mcp/ are both accepted (clients differ; the Python EIC servers' Starlette router redirects rather than 404s), everything else 404s. An unknown MCP_TRANSPORT value used to fall back to stdio silently, which made an HTTP launcher hang until its readiness probe timed out; it now fails loudly.
Mirrors sse.test.ts over StreamableHTTPClientTransport, plus stateless-mode specifics: sequential clients work independently, /nope 404s, /mcp/ (trailing slash) does not.
MCP_TRANSPORT was previously undocumented. Also fixes the stale build/index.js path in QUICKSTART (the artifact is build/src/index.js).
There was a problem hiding this comment.
Pull request overview
This PR adds a new stateless Streamable HTTP transport option for the MCP server at /mcp (selected via MCP_TRANSPORT=http), alongside existing stdio (default) and legacy sse. It also updates documentation and bumps the project version to v0.2.0 in preparation for the no-supergateway migration.
Changes:
- Add Streamable HTTP server mode (
/mcp) with loopback-exposure warning and explicit failure on unknownMCP_TRANSPORT. - Add an HTTP smoke test validating tool listing, stateless sequential clients, 404 behavior, and
/mcp/handling. - Update docs/examples and container metadata for the new transport; bump version to
0.2.0.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/http.test.ts | Adds a smoke test for the new Streamable HTTP transport. |
| src/index.ts | Implements Streamable HTTP mode (/mcp), refactors HTTP bind parsing, makes invalid MCP_TRANSPORT fail loudly, bumps in-code version strings. |
| README.md | Documents available transports and provides HTTP client configuration example. |
| QUICKSTART.md | Updates standalone path and adds Streamable HTTP usage snippet. |
| package.json | Bumps package version to 0.2.0. |
| package-lock.json | Keeps lockfile version in sync with 0.2.0. |
| Dockerfile | Exposes port 9102 and documents how to run HTTP mode in Docker. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Added two more comments (same issue). Do we need version number? |
|
indeed, removed it, kept only the one MCP needs |
|
Not sure why this didn't want to auto merge... |
Adds a stateless streamable-HTTP mode (fresh Server + transport per request) next to stdio and legacy SSE;
MCP_HOST/MCP_PORTas before, endpoint127.0.0.1:9102/mcp. UnknownMCP_TRANSPORTnow fails loudly instead of silently using stdio. Tests: 91/91 incl. newhttp.test.ts.Part of the no-supergateway migration (eic-spack#986, containers#357). Tag
v0.2.0after merge.