From f1bad2f384065fd7d5f10084b1ad7a1d15966ff3 Mon Sep 17 00:00:00 2001 From: Kurtis Van Gent <31518063+kurtisvg@users.noreply.github.com> Date: Tue, 25 Aug 2026 11:04:12 -0600 Subject: [PATCH] docs: add upcoming transport WG tracks roadmap (#50) --- roadmaps/2026-12-15.md | 364 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 364 insertions(+) create mode 100644 roadmaps/2026-12-15.md diff --git a/roadmaps/2026-12-15.md b/roadmaps/2026-12-15.md new file mode 100644 index 0000000..d1b1345 --- /dev/null +++ b/roadmaps/2026-12-15.md @@ -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`?