Skip to content

Latest commit

 

History

History
137 lines (95 loc) · 7.83 KB

File metadata and controls

137 lines (95 loc) · 7.83 KB

Transport Lifecycle Policy

This document is the authoritative reference for which transport modes OpenChrome supports, what stability guarantees apply to each, and how deprecations are announced and enforced.


Supported transports

OpenChrome exposes three transport modes. The package CLI uses stdio by default, enables HTTP with --http [port], and can select explicit modes with the OPENCHROME_TRANSPORT environment variable.

Transport Selector Status Since Sunset Recommended use case
stdio default or OPENCHROME_TRANSPORT=stdio stable v1.0.0 Default. Single MCP client over stdin/stdout. Use for Claude Code, Codex CLI, Cursor, Windsurf, and any stdio-native MCP client.
Streamable HTTP daemon --http [port] or OPENCHROME_TRANSPORT=http stable v1.0.0 Long-running daemon serving multiple MCP clients over Streamable HTTP. Binds a local port; auth via bearer token or per-tenant API key.
Dual (stdio + HTTP) OPENCHROME_TRANSPORT=both stable v1.0.0 Run stdio and HTTP simultaneously. Intended for dashboard integrations that need both a direct MCP pipe and an HTTP fan-out endpoint.

Note on SSE: The /mcp/sse endpoint is the notification delivery channel inside the HTTP transport — it is not a separate transport mode. When a client connects via GET /mcp/sse, it receives server-initiated notifications over a persistent SSE stream while issuing requests via POST /mcp. Operators should not conflate /mcp/sse with a distinct transport; the lifecycle of that endpoint is tied to the http transport above.

Streamable HTTP: --http is OpenChrome's current Streamable HTTP transport surface. Use POST /mcp for JSON-RPC requests and GET /mcp or GET /mcp/sse for server-sent event streams.


Stability commitments

A transport listed as stable carries the following guarantees across all patch and minor releases within the same major version:

  1. Message-shape compatibility. The JSON-RPC 2.0 wire format, method names, and parameter shapes for all requests and responses remain unchanged. A client that works against v1.x.0 will continue to work against v1.x.y and v1.(x+1).0 without modification.

  2. Guaranteed events. The following server-initiated notification types are guaranteed to remain available on all stable transports:

    • notifications/tools/list_changed — emitted when the tool list changes at runtime.
    • Lifecycle error notifications emitted via console.error to stderr (never to stdout, which carries MCP JSON-RPC).
  3. Minor-version allowance. Within a major version, minor releases may:

    • Add new optional fields to existing messages (additive change, backward-compatible).
    • Add new notification types (clients that do not handle them ignore them per the MCP spec).
    • Change default port bindings, keepalive intervals, or internal routing — provided the observable wire protocol is unchanged.
    • Update authentication mechanisms in an additive way (new auth scheme available; existing scheme continues to work until a separate deprecation notice).
  4. What is NOT guaranteed. Internal implementation details — HTTP handler internals, keepalive ping interval, rate-limiter queue depth, SSE connection book-keeping — are not part of the stability contract and may change in any release.


Deprecation policy

Minimum overlap window: 3 minor versions or 6 months, whichever is longer.

When a transport (or a specific transport feature) is deprecated:

  1. A GitHub issue is opened announcing the deprecation, the sunset version, and the recommended migration target.
  2. The transport row in the Supported transports table above is updated to deprecated, and the Sunset column is filled in.
  3. Starting with the release that announces the deprecation, the server emits a boot-time deprecation warning on stderr whenever the deprecated transport is selected (see Boot-time deprecation warnings).
  4. The transport is removed no earlier than the later of:
    • Three minor version increments after the deprecation announcement (e.g., deprecated in v1.11.0 → earliest removal is v1.14.0), or
    • Six calendar months after the deprecation announcement date.

Concrete example

Suppose http were deprecated in v1.11.0 on 2026-05-12.

  • Earliest removal by minor-version rule: v1.14.0 (three increments: v1.11 → v1.12 → v1.13 → v1.14).
  • Earliest removal by calendar rule: 2026-11-12 (six months later).
  • Actual earliest removal: whichever date is later. If v1.14.0 ships on 2026-08-01 (before the 6-month mark), removal is deferred to a release on or after 2026-11-12. If v1.14.0 ships on 2026-12-01 (after the 6-month mark), removal may proceed in v1.14.0.

No transport is currently deprecated. This example is illustrative only.


Boot-time deprecation warnings

When the server starts with a deprecated transport selected, it emits a single line to stderr:

[openchrome] DEPRECATION WARNING: transport "<name>" is deprecated as of v<announcement-version>. Sunset: v<sunset-version>. Migrate before that release. See: https://github.com/shaun0927/openchrome/blob/main/docs/transport-lifecycle.md

This line:

  • Is emitted via console.error() (stderr), never console.log() (stdout). stdout carries MCP JSON-RPC and must not be polluted.
  • Contains the marker string DEPRECATION WARNING for easy grep in CI log scanners.
  • Names the exact sunset version so operators have a concrete calendar target.
  • Links to this document for migration instructions.

Implementation note: The warning emitter is not yet present in the codebase (as of v1.11.0). It will be added in a follow-up code PR when the first transport is actually deprecated. This section specifies the contract that implementation must satisfy.

Current state: No transport is deprecated in v1.11.0. Zero deprecation warnings are emitted at boot for any supported transport.


Migration recipes

stdio → Streamable HTTP

Switch from the default stdio mode to the Streamable HTTP daemon for multi-client or IDE use cases.

Before (stdio):

# Claude Code auto-configures stdio by default
openchrome serve --auto-launch

After (Streamable HTTP daemon):

# Start the HTTP daemon on port 3100 (default) with bearer-token authentication
OPENCHROME_AUTH_TOKEN="$(openssl rand -hex 32)" openchrome serve --auto-launch --http

# Or specify a custom port and non-loopback bind address
OPENCHROME_AUTH_TOKEN="$(openssl rand -hex 32)" OPENCHROME_HTTP_HOST=0.0.0.0 openchrome serve --auto-launch --http 4000

Configure your MCP client to connect over Streamable HTTP:

{
  "mcpServers": {
    "openchrome": {
      "type": "http",
      "url": "http://localhost:4000/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}

For unauthenticated loopback-only development, explicitly opt in and keep the bind address on loopback. Non-loopback HTTP binds require authentication.

OPENCHROME_ALLOW_UNAUTHENTICATED_HTTP=1 openchrome serve --auto-launch --http

Streamable HTTP endpoint behavior

--http starts OpenChrome's current Streamable HTTP transport. Clients issue JSON-RPC requests with POST /mcp. Clients that need server-initiated notifications can open GET /mcp or GET /mcp/sse as an SSE stream. No additional migration flag is required; the http transport selector remains stable and has no sunset date.


See also