Files
reverse-engineering-anything/docs/specs/agent-environments/http-transport/plan.md
T
Edgar Arakelyanandgensokyo-dev 60bd646478 feat(mcp): add opt-in streamable HTTP transport (#4955)
Add an explicit Streamable HTTP entry for environment/gateway hosts while keeping stdio registrations and default behavior. Preserve the shared provider/session owner across DELETE and replacement; fence and drain tool/completion work before handover or teardown.

Bound HTTP input and plain-response admission, cancel refused bodies, join whole exchanges and asynchronous response cleanup before provider hooks, gate startup readiness, and reject queued HTTP/1.1 pipelining while retaining sequential keep-alive.

Validation: 8 static/build tasks, 83 adapter tests and registry metadata pass. A real installed gh binary produces seven equivalent CLI/stdio/HTTP reports with DELETE/replacement and clean signal shutdown. Broader local native-provider/ownership failures reproduce on clean main and are documented with limitations in the PR.

Co-authored-by: Edgar Arakelyan <edgar.arakelyan@scale.com>
Co-authored-by: gensokyo-dev <342580529+gensokyo-dev@users.noreply.github.com>
2026-10-19 23:58:51 +08:00

33 lines
2.0 KiB
Markdown

# Implementation plan
1. Widen the runtime `serve` dependency to a transport-neutral factory that may
bind asynchronously. `startMcpTransport` awaits it, hands it the server
logger, and keeps stdio as the default; the shutdown handle type loses its
stdio name.
2. Add `src/server/http/nodeHttpBridge.ts` to turn an IncomingMessage into a web
Request (headers, streamed body, abort on client close) and to pipe a web
Response back with flushed headers, and `src/server/http/serveStreamableHttp.ts`
to own one `McpServer` instance and one stateful transport per session,
ended by `DELETE` or replaced by the next client's `initialize` without
running the instance's shutdown hooks, plus plain routes, loopback Host
validation, the listening log line and idempotent close. The typed listen
error lives in its own module so the stdio entry never loads the listener.
3. Parse `--http`, `--host` and `--port` in `src/main/mcpHttpArguments.ts` from
one schema that also renders help; resolve `MCP_HOST`/`MCP_PORT` in
`src/config/mcpHttpEndpoint.ts` as a `Result` that names rejected settings
without their values.
4. Route the dispatcher to `runMcpHttpEntrypoint` when the `mcp` entry carries
`--http`; compose HTTP dependencies in `src/main.ts` with the shared
`run()` path so configuration, session, providers and shutdown stay common.
5. Register signals only for HTTP mode through `registerSignalShutdown`, a
projection of `registerProcessShutdown` without stdin that sets the signal
exit status before the idempotent shutdown runs; stdio keeps its stdin
end/close triggers.
6. Document the transport in docs/mcp-contracts.md and docs/cli.md, relabel the
architecture diagram, and cover each boundary with adapters, dispatcher,
mcp-boundary and process-boundary tests plus a Python SDK client exchange.
No new dependency is introduced: the transport, Host validation and body bound
come from the already pinned `@modelcontextprotocol/server` root export. Tool
contracts, catalog digests, response budgets and stdio behaviour are unchanged.