docs: add upcoming transport WG tracks roadmap (#50)
This commit is contained in:
parent
6d9b43bd5f
commit
f1bad2f384
1 changed files with 364 additions and 0 deletions
364
roadmaps/2026-12-15.md
Normal file
364
roadmaps/2026-12-15.md
Normal 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`?
|
||||||
Loading…
Reference in a new issue