docs: add upcoming transport WG tracks roadmap (#50)

This commit is contained in:
Kurtis Van Gent 2026-08-25 11:04:12 -06:00 • committed by GitHub
commit f1bad2f384
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

364
roadmaps/2026-12-15.md Normal file
View file

@ -0,0 +1,364 @@
# Transports WG: 2026-12-15 Roadmap
This document is a high-level outline of the tracks the Transports Working Group
is taking up for the **2026-12-15** specification release. Each track gets a
short brief: the goal (what problem it solves), the core idea of the solution,
key requirements, and the open questions we still need to answer. As tracks
mature, each brief should graduate into a full problem statement or proposal
under `proposals/`.
Tracks are grouped into three tiers — **Priority**, **Best Effort**, and **Not
Planned** — and numbered in priority order across the document.
## Alignment with the MCP roadmap
The core maintainers' [MCP
roadmap](https://blog.modelcontextprotocol.io/posts/mcp-roadmap/) names five
priority areas for the next specification release and beyond. SEPs that fall
within those areas get expedited review and the best chance of acceptance;
proposals outside them compete for scarce maintainer review time. These items
are marked below as "MCP priority".
# Priority
Targeted for the 2026-12-15 release.
## 1. Tool/Primitive Versioning
**MCP priority** - HTTP-native transport hardening.
**Outcome:** Allow clients to indicate which version of a primitive definition
they are using, and allow servers to adjust behavior, reroute the request, or
refuse execution based on that version.
**Approach:** Add an ETag-like version identifier to primitive definitions.
Clients return the identifier when invoking a primitive. Servers use it to
preserve the behavior described by that version, route the request to a
compatible implementation, or reject the request if the version cannot be
honored.
The identifier can also support conditional list requests. `ttlMs` determines
when a client should revalidate a cached list; the identifier determines whether
the list or an individual definition has changed.
**Requirements:**
* An opaque version identifier for primitive definitions.
* A standard way for clients to include the identifier when invoking a
primitive.
* Defined server behavior when the requested version differs from the current
version: preserve compatible behavior, reroute the request, or reject it.
* A standard version-mismatch error that is distinct from execution errors and
tells the client whether to refresh and retry. The code should come from the
registry defined by the Error Standardization track.
* Conditional revalidation for cacheable list results, integrated with `ttlMs`
and `cacheScope`.
* Equivalent behavior across transports, including transports without HTTP
headers.
**Open decisions:**
* Must clients include the version when invoking a primitive, or is it optional
for backward compatibility?
* What changes are compatible, and who decides whether to preserve behavior,
reroute, or reject the request?
* How long should a server retain support for older versions, if at all?
* Which parts of a definition determine its version: the entire definition or
only fields that affect behavior? How should localized text be handled?
* Should HTTP use `ETag` and `If-None-Match` directly, map them to in-band
fields, or support both?
* Do list-level and primitive-level versions use the same mechanism?
* How does revalidation work with shared caches using `cacheScope: "public"`?
---
## 2. HTTP over STDIO
**MCP priority** - HTTP-native transport unification and hardening.
**Outcome:** Reduce protocol divergence, maintenance work, and wire overhead by
using the same HTTP transport model for local subprocesses and network
connections. Features should not require separate stdio behavior or duplicate
values in both JSON-RPC `_meta` and HTTP headers.
**Approach:** Run Streamable HTTP over a subprocess's stdin and stdout. Clients
continue to manage the server process, but exchange HTTP messages instead of
newline-delimited JSON-RPC. With both standard transports using HTTP semantics,
implementations can share transport logic and encode transport metadata once in
headers.
**Requirements:**
* Preserve the same protocol behavior across subprocess and network
connections.
* Support concurrent requests and server-initiated messages over one process.
* Define one canonical representation for transport metadata rather than
requiring duplicate `_meta` fields and HTTP headers.
* Distinguish HTTP-over-stdio servers from legacy stdio servers during startup.
* Define process startup, shutdown, failure, and stderr behavior.
* Keep the implementation practical for small servers and SDKs across
languages.
**Open decisions:**
* Should the pipe carry HTTP/1.1 with additional conventions or HTTP/2?
* How should server-initiated requests use an HTTP connection over stdin and
stdout?
* Should this be a **new** transport, or can clients negotiate between legacy
and HTTP-based versions over stdio?
* Which `_meta` fields can move exclusively to HTTP headers, and how should
older implementations be supported?
* Which HTTP authentication semantics, if any, apply to local subprocesses?
* What is the minimum conforming implementation?
---
## 3. Pluggable Transports
**Outcome:** Keep Streamable HTTP as MCP's primary transport, the focus of
upcoming protocol designs, and the only transport every client must support.
Developers with requirements it cannot meet should have an escape hatch for
custom transports, allowing MCP to be adopted without expanding the baseline
for every implementation.
**Approach:** Separate the MCP data model from its wire representation enough
for SDKs to expose a custom transport interface. Streamable HTTP remains the
reference binding and default design target; custom transports are optional
extensions for specialized environments.
**Requirements:**
* Define the logical message interface shared by all transports.
* Define transport responsibilities such as serialization, framing, delivery,
ordering, bidirectional communication, and metadata.
* Keep the MCP data model and application APIs independent of the selected
transport.
* Identify optional transport features and behavior when they are unavailable.
* Define how startup, shutdown, failure, and reconnection map onto the transport
interface.
* Custom transports must not impose new requirements on clients that support
only Streamable HTTP.
* Provide conformance criteria for third-party transport implementations.
**Open decisions:**
* Where is the exact boundary between the data model and transport behavior?
* Which delivery and ordering guarantees must every transport provide?
* How should logical metadata map to transports without HTTP-style headers?
* How should implementations name, select, and negotiate transport bindings?
* Should Tier 1 SDKs be required to expose a pluggable transport interface to
encourage a consistent extension mechanism across widely used clients?
* How prescriptive should the interface guidance be while still allowing
idiomatic, language-specific APIs?
* Should conformance use a checklist, a shared test suite, or both?
---
# Best Effort
Lower priority. We will advance these if capacity allows, but they are not
commitments for the 2026-12-15 release.
## 4. Error Standardization
**Outcome:** Give clients and infrastructure consistent, machine-readable errors
across transports. Implementations should not need to invent codes or match
message text.
**Approach:** Define a normative registry that assigns each protocol error a
name, JSON-RPC code, HTTP status where applicable, and retry guidance. Prefer
standard JSON-RPC codes when they fit; allocate MCP-specific codes from the
range reserved by the [2026-07-28
specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/index#error-codes).
Error messages remain flexible, human-readable text.
**Requirements:**
* Assign each defined error condition a name, JSON-RPC code, HTTP mapping, and
retry classification.
* Provide generic fallback codes for conditions without a specific entry.
* Define how JSON-RPC errors and HTTP statuses are used together.
* Reuse standard JSON-RPC codes when they accurately describe the condition.
* Define a clear boundary between protocol errors and application errors,
including when invalid input produces a JSON-RPC error versus a tool result
reporting failure.
**Open decisions:**
* When should an error use a non-200 HTTP status instead of a JSON-RPC error in a
`200` response?
* Are HTTP status mappings required or recommended?
* Which failures are protocol errors, and which should be represented as
application-level results?
* How should extensions and implementations allocate error codes?
* Should the registry define the structure of `error.data`?
* How should retryability and delay information be represented?
* How do content-language rules apply to human-readable error messages?
---
## 5. Incremental Tool Results
**Outcome:** Allow tools to return results incrementally or just in time instead
of buffering the complete result. This supports cases such as streaming video
while it is generated and delivering large database query results as rows become
available.
**Approach:** Associate an ordered sequence of result chunks with a tool call,
followed by a terminal outcome. Each chunk can contain standard MCP content or
structured data and is delivered as soon as it becomes available. Because
JSON-RPC normally permits one response per request, this track must also define
how chunks are represented and correlated before that final response.
**Requirements:**
* Associate every chunk with its tool call, preserve ordering, and distinguish
chunks from the terminal success or error.
* Support structured data and binary content without requiring clients to
reconstruct one in-memory result.
* Define a JSON-RPC-compatible mechanism for delivering multiple chunks before
the terminal response.
* Support cancellation and flow control with defined cleanup behavior.
* Resolve the overlap with Tasks, including when an operation should use
incremental results, a Task, or both, and whether Task output can use the same
mechanism.
* Negotiate support without breaking clients that accept only terminal results.
**Open decisions:**
* Where is the boundary between incremental tool results and Tasks?
* Can a Task produce incremental output using the same mechanism?
* Should JSON-RPC chunks use notifications, extend progress notifications, or
introduce a new message type?
* How are chunks correlated with the original request while preserving
JSON-RPC's single terminal response?
* How do chunks combine into a final result?
* What happens to delivered chunks if the operation later fails?
* Do incremental results need resumability?
* Should flow control be defined by MCP or delegated to the transport?
* How should large binary content, such as generated video, be represented
efficiently?
---
## 6. Content Language Negotiation
**Open PR** -
[transports-wg#42](https://github.com/modelcontextprotocol/transports-wg/pull/42)
**Outcome:** Allow clients to request a language for human-readable content and
servers to identify the language returned. Language selection should happen per
request so it can change without creating session state.
**Approach:** Use stateless language negotiation based on RFC 9110
`Accept-Language` and `Content-Language` semantics. The open PR proposes
corresponding `_meta` fields and HTTP header mappings. The final design should
work across transports while avoiding duplicate wire representations where
possible.
**Requirements:**
* Use standard `Accept-Language` matching rather than defining a custom
algorithm.
* Define which fields are user-facing, model-facing, or machine-interpreted and
which categories may be translated.
* Never translate identifiers, names, URIs, enum values, or other
machine-interpreted data.
* Allow clients and servers without language-negotiation support to continue
operating normally.
* Define consistent language metadata across transport bindings.
* Ensure language-aware responses interact correctly with caching and primitive
versioning.
**Open decisions:**
* Which model-facing fields, such as descriptions, may be translated?
* Should language be represented in `_meta`, HTTP headers, or mapped between
them?
* How should language affect cache keys, validators, and primitive versions?
* Does language negotiation require errors beyond the standard header-mismatch
error?
* How should content-language rules apply to error messages?
* Do we need guidance for evaluating tool-selection behavior across languages?
---
## 7. Tool Capability Requirements
**Open PR** -
[transports-wg#31](https://github.com/modelcontextprotocol/transports-wg/pull/31)
**Outcome:** Allow clients to identify tools that require capabilities they do
not support before presenting those tools to the model. Tool lists should remain
client-independent and cacheable.
**Approach:** Servers annotate tools with their required client capabilities
using `requiredCapabilities` in `_meta`. Clients compare those requirements with
their capabilities and decide whether to filter, disable, or expose each tool.
Servers validate the requirements again when the tool is called.
Tools that can operate without a capability do not declare it as required.
**Requirements:**
* Support requirements for core and extension capabilities.
* Use annotations only for capabilities required for the tool to operate.
* Return the same tool list to every client without requiring clients to
disclose their capabilities.
* Keep capability-dependent presentation a client responsibility.
* Require servers to validate capabilities when a tool is called.
* Return a standard protocol error when a required capability is unavailable.
* Preserve compatibility with clients that ignore the annotation.
**Open decisions:**
* Should clients filter unavailable tools, show them as disabled, or allow calls
to fail?
* Is client-side filtering sufficient, or is server-side filtering needed for
more advanced adaptation?
* How should servers advertise fallback or substitute tools?
* How should nested and extension capabilities be matched consistently across
SDKs?
* Should the same requirement mechanism apply to prompts or resources?
* If server-side filtering is supported, how should capability-dependent lists
interact with caching and primitive versioning?
---
# Not Planned
## 8. Sessions / Conversation IDs
> **Note — not planned for the 2026-12-15 release.** Protocol-level sessions and
> the initialization handshake were removed in 2026-07-28. The WG will only
> reconsider something session-shaped if compelling, concrete use cases cannot
> be addressed by narrower mechanisms. Until that bar is met, this track remains
> problem-definition work rather than protocol design.
**References** - [Sessions Reintroduction Problem
Statement](../docs/sessions-reintroduction-problem-statement.md) and [Sessions
vs. Sessionless Decision](../docs/sessions-vs-sessionless-decision.md)
**Outcome:** Determine whether documented needs for correlation, routing, and
cross-request state require any new protocol primitives.
**Approach:** Separate correlation and routing from state scope and lifecycle.
Evaluate each against existing mechanisms such as client-carried state, Tasks,
caching, and server-minted handles before considering a new design.
**Requirements for reconsideration:**
* Identify the specific use cases a proposal addresses.
* Explain why existing sessionless mechanisms do not address them.
* Keep sessionless operation first-class.
* Define creation, expiration, and termination for any stateful mechanism.
* Keep routing identifiers visible to HTTP infrastructure.
* Avoid overlapping mechanisms for state in Sessions, MRTR, and Tasks.
**Open decisions:**
* Does MCP need a routing identifier, a state-scoping context, both, or neither?
* If an identifier is needed, should the client or server create it?
* Are server-minted handles passed through ordinary tool arguments sufficient?
* Should session-like state, MRTR state, and Task state share one mechanism?
* Does MCP need explicit mapping to A2A `contextId`?