Skip to content

MCP Spec 28-7-2026 Design - #1089

Open
omarmahamid wants to merge 2 commits into
modelcontextprotocol:mainfrom
omarmahamid:feat/28-7-mcp-spec
Open

MCP Spec 28-7-2026 Design#1089
omarmahamid wants to merge 2 commits into
modelcontextprotocol:mainfrom
omarmahamid:feat/28-7-mcp-spec

Conversation

@omarmahamid

@omarmahamid omarmahamid commented Aug 13, 2026

Copy link
Copy Markdown

Summary

Adds a design proposal — docs/design/2026-07-28-spec-support.md — for implementing the
2026-07-28 MCP specification
revision in this SDK.

Link for md viewer:

https://github.com/omarmahamid/java-sdk/blob/feat/28-7-mcp-spec/docs/design/2026-07-28-spec-support.md

Docs-only. No production code changes. The intent is to agree the shape of the work
before implementation, per CONTRIBUTING.md:

For non-trivial changes, clarify scope with maintainers in an issue before investing in an
implementation.

Why a design document rather than PRs

The SDK currently implements 2024-11-05 through 2025-11-25. Every one of those revisions
shares one structural assumption: an MCP conversation is a session established by an
initialize handshake
, over which either party may originate JSON-RPC requests.

2026-07-28 removes that assumption. Six of its nine major changes are removals or
inversions of mechanisms mcp-core models as load-bearing types — McpServerSession,
McpStreamableServerSession, LifecycleInitializer, McpTransportSession,
McpTransportStream, and the client-side request handlers for roots/list,
sampling/createMessage and elicitation/create:

# Change SEP
1 Remove protocol-level sessions and Mcp-Session-Id SEP-2567
2 Remove the initialize / notifications/initialized handshake; per-request _meta envelope SEP-2575
3 Add server/discover (servers MUST implement) SEP-2575
4 Replace HTTP GET + resources/subscribe with subscriptions/listen SEP-2575
5 Remove ping, logging/setLevel, notifications/roots/list_changed SEP-2575
6 Move tasks to the io.modelcontextprotocol/tasks extension SEP-2663
7 MRTR replaces server-initiated requests SEP-2322
8 Required resultType on every result SEP-2322
9 Remove SSE resumability (Last-Event-ID) SEP-2575

Three properties make piecemeal delivery actively harmful:

  • The changes are coupled. resultType is meaningless without MRTR; MRTR is
    unimplementable without the _meta envelope; the envelope is unverifiable without header
    mirroring. Landing them independently produces intermediate states that are on no protocol
    revision at all.
  • The era boundary must be decided once. Whether "modern vs. legacy" is a runtime flag, a
    parallel type hierarchy, or separate modules determines the shape of every subsequent PR.
  • It is a major version. Per VERSIONING.md, three independent triggers apply, so the
    removals must be batched into one release.

The finding the design rests on

This SDK already ships a stateless server. McpStatelessAsyncServer's own Javadoc:

"It allows simple horizontal scalability since it does not maintain a session and does not
require initialization. Each instance of the server can be reached with no prior knowledge
and can serve the clients with the capabilities it supports."

That is close to a verbatim description of the 2026-07-28 server model. The proposal
therefore does not add a parallel server implementation — it promotes the existing
stateless server to be the canonical modern server, and leaves the session-based classes as
a deprecated legacy path. Two additive SPI extensions are needed: answer one request with a
stream (subscriptions/listen), and answer one request with "I need more input"
(MRTR).

Without that existing asset, 2026-07-28 support would be a ground-up rewrite. This is the
main reason the proposal is tractable.

What the document contains

Structured as a design proposal (Motivation → Public Interfaces → Proposed Changes →
Security → Compatibility/Migration → Test Plan → Rejected Alternatives → FAQ):

  • Gap analysis of mcp-core at 8ee8ccbc, requirement by requirement, each classified
    additive / structural / wire-format / removal.
  • Full public API surface: ProtocolVersions.MCP_2026_07_28, McpMetaKeys, new
    ErrorCodes (-32020 / -32021 / -32022), DiscoverResult, InputRequiredResult,
    InputRequests / InputResponses, ListRootsRequest, SubscriptionsListenRequest,
    CacheableResult, McpRequestContext, McpSubscription, McpSubscriptionSink,
    McpRequestStateCodec, McpHeaderCodec, McpParamHeaderExtractor, new exceptions.
  • Seven keyed design decisions (D1–D7), each with the alternative it rejects.
  • Five implementation phases, each independently reviewable and each leaving main on a
    coherent protocol revision. P1–P2 are non-breaking and could ship in a 2.x minor.
  • Behaviour matrix resolving the spec's client/server era matrix to concrete SDK
    behaviour.
  • Test plan covering unit, integration and conformance, including per-record cases derived
    from the Case A / Case B rules in CONTRIBUTING.md.
  • Six rejected alternatives with reasoning.

Design decisions worth reviewer attention

D3 — MRTR is resolved inside the client session layer. Sampling / elicitation / roots
handler signatures do not change; the same handlers are invoked from a bounded retry loop
instead of from an inbound-request dispatcher. This keeps callTool() returning
CallToolResult rather than a union type, so existing callers recompile unchanged. RA-3
argues the alternative.

D4 — resultType must be a real record component. A default method on Result would not
serialize (Jackson emits record components), so every result the SDK emitted would be
missing a spec-required field. That means ~15 records under the CONTRIBUTING.md Case B
rules. The interface default is still added, for uniform reading across eras.

D1 — era dispatch at the transport front door, not a boolean modern flag on the existing
session types. The spec says a dual-era server "selects its behavior from how the client
opens" — that is a routing decision on the first message and belongs in one place.

D6 — the modern client needs a tool-definition cache, because x-mcp-header mirroring
requires the tool's inputSchema at tools/call time and tools/call does not carry it. The
same cache is what makes ttlMs / cacheScope actionable.

Open questions for maintainers

  1. Is HTTP+SSE removal in scope for the major release? SEP-2596 reclassifies it as
    Deprecated, not Removed, and the feature-lifecycle policy allows a twelve-month window.
    The document proposes removal (the release is already breaking) but explicitly flags
    deprecate-now / remove-next-major as the conservative option and does not insist.
  2. Is the dual-era default correct, versus modern-only with legacy behind a flag?
  3. Should mcp-ext-tasks be a new module, or should tasks stay in mcp-core behind the
    extension capability?
  4. Should an escape hatch expose InputRequiredResult directly? The document defers it
    under CONTRIBUTING.md's "concrete, not speculative" principle, but a real use case would
    change that.
  5. Phasing: P1–P2 are non-breaking. Ship them in a 2.x minor to shorten the major-release
    critical path, or hold everything for the major?

Known behaviour change

One change cannot be made backward-compatible: on the modern path, notifications/message is
suppressed for requests that omit io.modelcontextprotocol/logLevel. The spec states servers
MUST NOT emit it in that case. It leads the migration guide, and logLevel is settable
once on the client builder to restore log flow with a one-line change.

What this PR does not do

  • No production code, no schema changes, no dependency changes.
  • Does not commit the project to the proposed API — the naming and shape are a starting point
    for discussion.
  • Does not supersede the spec-revision GitHub Project board referenced in ROADMAP.md; it is
    intended to complement it.

Checklist

  • Docs-only; ./mvnw clean compile -DskipTests unaffected
  • No formatting impact (spring-javaformat applies to Java sources only)
  • ROADMAP.md update to retarget the focus area from 2025-11-25 to 2026-07-28 — folded
    into this PR or filed as a follow-up, reviewer's preference
  • Spec references verified against modelcontextprotocol.io/specification/2026-07-28
    (changelog, versioning, MRTR, subscriptions, discover, Streamable HTTP)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant