4545"""A protocol version the suite parametrizes over. Both values are typed even though only one is
4646on the active axis (SPEC_VERSIONS) until the 2026-07-28 implementation lands."""
4747
48- SPEC_VERSIONS : tuple [SpecVersion , ...] = ("2025-11-25" ,)
48+ SPEC_VERSIONS : tuple [SpecVersion , ...] = ("2025-11-25" , "2026-07-28" )
4949"""The active spec-version matrix axis, ordered oldest to newest. Every entry must be in KNOWN_PROTOCOL_VERSIONS."""
5050
5151SPEC_BASE_URL = "https://modelcontextprotocol.io/specification/2025-11-25"
9696 "unimplemented."
9797)
9898
99+ _MODERN_NOTIFY_DROP = (
100+ "SingleExchangeDispatcher.notify() no-ops on the modern streamable-http driver; handler-emitted "
101+ "logging/progress notifications never reach the per-request SSE response. Passes once SSE "
102+ "response mode lands."
103+ )
104+
99105
100106@dataclass (frozen = True , kw_only = True )
101107class Divergence :
@@ -212,29 +218,41 @@ def __post_init__(self) -> None:
212218 "Connecting sends initialize with the protocol version, client capabilities, and client "
213219 "info; the server responds with its own and the connection is established."
214220 ),
221+ removed_in = "2026-07-28" ,
222+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
215223 ),
216224 "lifecycle:initialize:server-info" : Requirement (
217225 source = f"{ SPEC_BASE_URL } /basic/lifecycle#initialization" ,
218226 behavior = "The initialize result identifies the server: name and version, plus title when declared." ,
227+ removed_in = "2026-07-28" ,
228+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
219229 ),
220230 "lifecycle:initialize:instructions" : Requirement (
221231 source = f"{ SPEC_BASE_URL } /basic/lifecycle#initialization" ,
222232 behavior = "A server may include an instructions string in the initialize result; the client exposes it." ,
233+ removed_in = "2026-07-28" ,
234+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
223235 ),
224236 "lifecycle:initialize:capabilities:from-handlers" : Requirement (
225237 source = f"{ SPEC_BASE_URL } /basic/lifecycle#capability-negotiation" ,
226238 behavior = (
227239 "The server advertises a capability for each feature area it has a registered handler for, "
228240 "and omits the capability for areas it does not."
229241 ),
242+ removed_in = "2026-07-28" ,
243+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
230244 ),
231245 "lifecycle:initialize:capabilities:minimal" : Requirement (
232246 source = f"{ SPEC_BASE_URL } /basic/lifecycle#capability-negotiation" ,
233247 behavior = "A server with no feature handlers advertises no feature capabilities." ,
248+ removed_in = "2026-07-28" ,
249+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
234250 ),
235251 "lifecycle:initialize:client-info" : Requirement (
236252 source = f"{ SPEC_BASE_URL } /basic/lifecycle#initialization" ,
237253 behavior = "The client's name, version, and title are visible to server handlers after initialization." ,
254+ removed_in = "2026-07-28" ,
255+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
238256 arm_exclusions = (ArmExclusion (reason = "requires-session" , transport = "streamable-http-stateless" ),),
239257 ),
240258 "lifecycle:initialize:client-capabilities" : Requirement (
@@ -243,6 +261,8 @@ def __post_init__(self) -> None:
243261 "The client capabilities visible to the server reflect which client callbacks are configured "
244262 "(sampling, elicitation, roots)."
245263 ),
264+ removed_in = "2026-07-28" ,
265+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
246266 arm_exclusions = (ArmExclusion (reason = "requires-session" , transport = "streamable-http-stateless" ),),
247267 ),
248268 "lifecycle:initialized-notification" : Requirement (
@@ -251,6 +271,8 @@ def __post_init__(self) -> None:
251271 "After successful initialization, the client sends exactly one initialized notification, "
252272 "before any non-ping request."
253273 ),
274+ removed_in = "2026-07-28" ,
275+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
254276 ),
255277 "lifecycle:ping" : Requirement (
256278 source = f"{ SPEC_BASE_URL } /basic/utilities/ping#behavior-requirements" ,
@@ -276,6 +298,8 @@ def __post_init__(self) -> None:
276298 behavior = (
277299 "A request other than ping sent before the initialization handshake completes is rejected with an error."
278300 ),
301+ removed_in = "2026-07-28" ,
302+ note = "initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it." ,
279303 ),
280304 "lifecycle:pre-initialization-ordering" : Requirement (
281305 source = f"{ SPEC_BASE_URL } /basic/lifecycle#initialization" ,
@@ -304,27 +328,35 @@ def __post_init__(self) -> None:
304328 "When the server returns an older supported protocol version, the client downgrades to it "
305329 "and the connection succeeds at that version."
306330 ),
331+ removed_in = "2026-07-28" ,
332+ note = "initialize-time version negotiation removed at 2026-07-28; version carried per-request in _meta." ,
307333 ),
308334 "lifecycle:version:match" : Requirement (
309335 source = f"{ SPEC_BASE_URL } /basic/lifecycle#version-negotiation" ,
310336 behavior = (
311337 "When the server supports the requested protocol version it echoes that version in the "
312338 "initialize result, and the connection proceeds at that version."
313339 ),
340+ removed_in = "2026-07-28" ,
341+ note = "initialize-time version negotiation removed at 2026-07-28; version carried per-request in _meta." ,
314342 ),
315343 "lifecycle:version:server-fallback-latest" : Requirement (
316344 source = f"{ SPEC_BASE_URL } /basic/lifecycle#version-negotiation" ,
317345 behavior = (
318346 "An initialize request carrying a protocol version the server does not support is answered "
319347 "with another version the server supports — the latest one — rather than an error."
320348 ),
349+ removed_in = "2026-07-28" ,
350+ note = "initialize-time version negotiation removed at 2026-07-28; version carried per-request in _meta." ,
321351 ),
322352 "lifecycle:version:reject-unsupported" : Requirement (
323353 source = f"{ SPEC_BASE_URL } /basic/lifecycle#version-negotiation" ,
324354 behavior = (
325355 "A client that receives an initialize response carrying a protocol version it does not "
326356 "support fails initialization with an error rather than proceeding with the session."
327357 ),
358+ removed_in = "2026-07-28" ,
359+ note = "initialize-time version negotiation removed at 2026-07-28; version carried per-request in _meta." ,
328360 ),
329361 "lifecycle:stateless:request-envelope" : Requirement (
330362 source = f"{ SPEC_2026_BASE_URL } /basic/lifecycle#stateless-operation" ,
@@ -482,6 +514,17 @@ def __post_init__(self) -> None:
482514 "leaks str(exc) as the error message."
483515 ),
484516 ),
517+ arm_exclusions = (
518+ ArmExclusion (
519+ reason = "modern-error-surface" ,
520+ spec_version = "2026-07-28" ,
521+ note = (
522+ "The modern entry maps Exception->INTERNAL_ERROR (-32603) with an opaque message, so the "
523+ "2026 arm SATISFIES this requirement; the test pins the legacy code-0 divergence and "
524+ "needs an era-aware assertion before re-admission."
525+ ),
526+ ),
527+ ),
485528 ),
486529 "protocol:error:invalid-params" : Requirement (
487530 source = f"{ SPEC_BASE_URL } /basic#responses" ,
@@ -537,6 +580,7 @@ def __post_init__(self) -> None:
537580 "Progress notifications emitted by a handler during a request are delivered to the caller's "
538581 "progress callback, in order, with their progress, total, and message."
539582 ),
583+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
540584 ),
541585 "protocol:progress:token-injected" : Requirement (
542586 source = f"{ SPEC_BASE_URL } /basic/utilities/progress#progress-flow" ,
@@ -549,6 +593,7 @@ def __post_init__(self) -> None:
549593 "protocol:progress:token-unique" : Requirement (
550594 source = f"{ SPEC_BASE_URL } /basic/utilities/progress#progress-flow" ,
551595 behavior = ("Concurrent in-flight requests that each supply a progress callback carry distinct progress tokens." ),
596+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
552597 ),
553598 "protocol:progress:monotonic" : Requirement (
554599 source = f"{ SPEC_BASE_URL } /basic/utilities/progress#progress-flow" ,
@@ -561,6 +606,7 @@ def __post_init__(self) -> None:
561606 "handler that emits non-increasing values has them forwarded to the callback unchanged."
562607 ),
563608 ),
609+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
564610 ),
565611 "protocol:progress:stops-after-completion" : Requirement (
566612 source = f"{ SPEC_BASE_URL } /basic/utilities/progress#behavior-requirements" ,
@@ -594,6 +640,7 @@ def __post_init__(self) -> None:
594640 "protocol:progress:client-to-server" : Requirement (
595641 source = f"{ SPEC_BASE_URL } /basic/utilities/progress#progress-flow" ,
596642 behavior = "A progress notification sent by the client is delivered to the server's progress handler." ,
643+ arm_exclusions = (ArmExclusion (reason = "requires-session" , spec_version = "2026-07-28" ),),
597644 ),
598645 "protocol:timeout:basic" : Requirement (
599646 source = f"{ SPEC_BASE_URL } /basic/lifecycle#timeouts" ,
@@ -697,13 +744,15 @@ def __post_init__(self) -> None:
697744 "Log notifications emitted by a tool handler during execution reach the client's logging "
698745 "callback before the tool result returns."
699746 ),
747+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
700748 ),
701749 "tools:call:progress" : Requirement (
702750 source = f"{ SPEC_BASE_URL } /basic/utilities/progress#progress-flow" ,
703751 behavior = (
704752 "Progress notifications emitted by a tool handler reach the caller's progress callback before "
705753 "the tool result returns."
706754 ),
755+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
707756 ),
708757 "tools:call:sampling-roundtrip" : Requirement (
709758 source = f"{ SPEC_BASE_URL } /client/sampling#creating-messages" ,
@@ -924,12 +973,14 @@ def __post_init__(self) -> None:
924973 "The Context logging helpers (debug/info/warning/error) send log message notifications at the "
925974 "corresponding severity."
926975 ),
976+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
927977 ),
928978 "mcpserver:context:progress" : Requirement (
929979 source = "sdk" ,
930980 behavior = (
931981 "Context.report_progress sends a progress notification against the requesting client's progress token."
932982 ),
983+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
933984 ),
934985 "mcpserver:context:elicit" : Requirement (
935986 source = "sdk" ,
@@ -1091,6 +1142,7 @@ def __post_init__(self) -> None:
10911142 "mcpserver:resource:read-throws-surfaced" : Requirement (
10921143 source = "sdk" ,
10931144 behavior = "A resource function that raises is surfaced to the caller as a JSON-RPC error response." ,
1145+ arm_exclusions = (ArmExclusion (reason = "modern-error-surface" , spec_version = "2026-07-28" ),),
10941146 ),
10951147 "mcpserver:resource:static" : Requirement (
10961148 source = "sdk" ,
@@ -1115,6 +1167,7 @@ def __post_init__(self) -> None:
11151167 "the low-level server converts to error code 0."
11161168 ),
11171169 ),
1170+ arm_exclusions = (ArmExclusion (reason = "modern-error-surface" , spec_version = "2026-07-28" ),),
11181171 ),
11191172 # ═══════════════════════════════════════════════════════════════════════════
11201173 # Prompts
@@ -1145,6 +1198,7 @@ def __post_init__(self) -> None:
11451198 "which the low-level server converts to error code 0 with the exception text as the message."
11461199 ),
11471200 ),
1201+ arm_exclusions = (ArmExclusion (reason = "modern-error-surface" , spec_version = "2026-07-28" ),),
11481202 ),
11491203 "prompts:get:multi-message" : Requirement (
11501204 source = f"{ SPEC_BASE_URL } /server/prompts#getting-a-prompt" ,
@@ -1187,6 +1241,7 @@ def __post_init__(self) -> None:
11871241 "mcpserver:prompt:args-validation" : Requirement (
11881242 source = f"{ SPEC_BASE_URL } /server/prompts#implementation-considerations" ,
11891243 behavior = "prompts/get arguments that fail the prompt's argument schema are rejected before the function runs." ,
1244+ arm_exclusions = (ArmExclusion (reason = "modern-error-surface" , spec_version = "2026-07-28" ),),
11901245 ),
11911246 "mcpserver:prompt:decorated" : Requirement (
11921247 source = "sdk" ,
@@ -1218,6 +1273,7 @@ def __post_init__(self) -> None:
12181273 "ValueError, which the low-level server converts to error code 0."
12191274 ),
12201275 ),
1276+ arm_exclusions = (ArmExclusion (reason = "modern-error-surface" , spec_version = "2026-07-28" ),),
12211277 ),
12221278 # ═══════════════════════════════════════════════════════════════════════════
12231279 # Completion
@@ -1284,13 +1340,15 @@ def __post_init__(self) -> None:
12841340 "logging:message:all-levels" : Requirement (
12851341 source = f"{ SPEC_BASE_URL } /server/utilities/logging#log-levels" ,
12861342 behavior = "All eight RFC 5424 severity levels are deliverable as log message notifications." ,
1343+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
12871344 ),
12881345 "logging:message:fields" : Requirement (
12891346 source = f"{ SPEC_BASE_URL } /server/utilities/logging#log-message-notifications" ,
12901347 behavior = (
12911348 "A log message sent by a server handler is delivered to the client's logging callback with its "
12921349 "severity level, logger name, and data."
12931350 ),
1351+ known_failures = (KnownFailure (spec_version = "2026-07-28" , note = _MODERN_NOTIFY_DROP , issue = None ),),
12941352 ),
12951353 "logging:message:filtered" : Requirement (
12961354 source = f"{ SPEC_BASE_URL } /server/utilities/logging#setting-log-level" ,
@@ -1910,6 +1968,16 @@ def __post_init__(self) -> None:
19101968 "client cannot learn that the set changed without polling."
19111969 ),
19121970 ),
1971+ known_failures = (
1972+ KnownFailure (
1973+ spec_version = "2026-07-28" ,
1974+ note = (
1975+ "List-mutation assertions hold; only the sentinel ctx.info() never reaches the client. "
1976+ + _MODERN_NOTIFY_DROP
1977+ ),
1978+ issue = None ,
1979+ ),
1980+ ),
19131981 ),
19141982 # ═══════════════════════════════════════════════════════════════════════════
19151983 # Pagination
0 commit comments