@@ -616,6 +616,13 @@ def __post_init__(self) -> None:
616616 source = "sdk" ,
617617 behavior = "Closing the transport fails all in-flight requests with a connection-closed error." ,
618618 ),
619+ "protocol:error:handler-error-passthrough" : Requirement (
620+ source = "sdk" ,
621+ behavior = (
622+ "An MCPError raised by a request handler is returned to the caller as a JSON-RPC error "
623+ "carrying the handler-chosen code and message verbatim."
624+ ),
625+ ),
619626 "protocol:error:internal-error" : Requirement (
620627 source = f"{ SPEC_BASE_URL } /basic#responses" ,
621628 behavior = (
@@ -679,12 +686,23 @@ def __post_init__(self) -> None:
679686 "extension."
680687 ),
681688 ),
682- "meta:request-to-handler" : Requirement (
689+ "protocol: meta:request-to-handler" : Requirement (
683690 source = f"{ SPEC_BASE_URL } /basic#_meta" ,
684691 behavior = "The _meta object the client attaches to a request is visible to the server handler." ,
685- arm_exclusions = (ArmExclusion (reason = "asserts-legacy-handshake" , spec_version = "2026-07-28" ),),
692+ arm_exclusions = (
693+ ArmExclusion (
694+ reason = "legacy-only-vocabulary" ,
695+ spec_version = "2026-07-28" ,
696+ note = (
697+ "The pass-through itself holds at 2026, but the modern envelope merges the reserved "
698+ "io.modelcontextprotocol/* keys into every request's _meta, so the test's "
699+ "nothing-else-injected equality assertion only holds on the legacy wire; needs an "
700+ "era-aware assertion before re-admission."
701+ ),
702+ ),
703+ ),
686704 ),
687- "meta:result-to-client" : Requirement (
705+ "protocol: meta:result-to-client" : Requirement (
688706 source = f"{ SPEC_BASE_URL } /basic#_meta" ,
689707 behavior = "The _meta object a handler attaches to its result is delivered to the client." ,
690708 ),
@@ -1081,7 +1099,7 @@ def __post_init__(self) -> None:
10811099 # ═══════════════════════════════════════════════════════════════════════════
10821100 # MCPServer: Context helpers (SDK)
10831101 # ═══════════════════════════════════════════════════════════════════════════
1084- "mcpserver:context:logging " : Requirement (
1102+ "mcpserver:context:log-from-handler " : Requirement (
10851103 source = "sdk" ,
10861104 behavior = (
10871105 "The Context logging helpers (debug/info/warning/error) send log message notifications at the "
@@ -1094,7 +1112,7 @@ def __post_init__(self) -> None:
10941112 "Context.report_progress sends a progress notification against the requesting client's progress token."
10951113 ),
10961114 ),
1097- "mcpserver:context:elicit" : Requirement (
1115+ "mcpserver:context:elicit-from-handler " : Requirement (
10981116 source = "sdk" ,
10991117 behavior = (
11001118 "Context.elicit sends a form elicitation built from a typed schema and returns a typed "
@@ -1165,8 +1183,11 @@ def __post_init__(self) -> None:
11651183 behavior = "resources/read returns text contents carrying uri, mimeType, and the text." ,
11661184 ),
11671185 "resources:read:unknown-uri" : Requirement (
1168- source = f"{ SPEC_BASE_URL } /server/resources#error-handling" ,
1169- behavior = "resources/read for an unknown URI returns JSON-RPC error -32002 (resource not found)." ,
1186+ source = f"{ SPEC_2026_BASE_URL } /server/resources#error-handling" ,
1187+ behavior = (
1188+ "resources/read for a URI matching no registered resource returns JSON-RPC error -32602 "
1189+ "(invalid params) with the requested URI in error.data, per SEP-2164."
1190+ ),
11701191 ),
11711192 "resources:subscribe" : Requirement (
11721193 source = f"{ SPEC_BASE_URL } /server/resources#subscriptions" ,
@@ -1325,13 +1346,6 @@ def __post_init__(self) -> None:
13251346 "by resources/read, receiving the parameters extracted from the requested URI."
13261347 ),
13271348 ),
1328- "mcpserver:resource:unknown-uri" : Requirement (
1329- source = f"{ SPEC_BASE_URL } /server/resources#error-handling" ,
1330- behavior = (
1331- "resources/read for a URI matching no registered resource returns JSON-RPC error -32602 "
1332- "(invalid params) with the requested URI in error.data, per SEP-2164."
1333- ),
1334- ),
13351349 # ═══════════════════════════════════════════════════════════════════════════
13361350 # Prompts
13371351 # ═══════════════════════════════════════════════════════════════════════════
@@ -1656,23 +1670,23 @@ def __post_init__(self) -> None:
16561670 "rejects every tool-enabled request before it is sent."
16571671 ),
16581672 ),
1659- "sampling:create-message :audio-content" : Requirement (
1673+ "sampling:create:audio-content" : Requirement (
16601674 source = f"{ SPEC_BASE_URL } /client/sampling#audio-content" ,
16611675 behavior = "Sampling messages can carry audio content: base64 data with a mimeType." ,
16621676 arm_exclusions = (
16631677 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
16641678 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
16651679 ),
16661680 ),
1667- "sampling:create-message :image-content" : Requirement (
1681+ "sampling:create:image-content" : Requirement (
16681682 source = f"{ SPEC_BASE_URL } /client/sampling#image-content" ,
16691683 behavior = "Sampling messages can carry image content: base64 data with a mimeType." ,
16701684 arm_exclusions = (
16711685 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
16721686 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
16731687 ),
16741688 ),
1675- "sampling:create-message :not-supported" : Requirement (
1689+ "sampling:create:not-supported" : Requirement (
16761690 source = f"{ SPEC_BASE_URL } /client/sampling#capabilities" ,
16771691 behavior = (
16781692 "A sampling request to a client that did not declare the sampling capability fails with an "
@@ -1960,20 +1974,28 @@ def __post_init__(self) -> None:
19601974 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
19611975 ),
19621976 ),
1963- "elicitation:url:basic" : Requirement (
1964- source = f"{ SPEC_BASE_URL } /client/elicitation#url-mode-elicitation-requests" ,
1965- behavior = (
1966- "A url-mode elicitation delivers the elicitation id and URL to the client callback exactly as "
1967- "the server sent them."
1968- ),
1977+ "elicitation:url:action:cancel" : Requirement (
1978+ source = f"{ SPEC_BASE_URL } /client/elicitation#response-actions" ,
1979+ behavior = "A URL-mode elicitation answered with cancel returns the action with no content." ,
19691980 arm_exclusions = (
19701981 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
19711982 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
19721983 ),
19731984 ),
1974- "elicitation:url:cancel " : Requirement (
1985+ "elicitation:url:action:decline " : Requirement (
19751986 source = f"{ SPEC_BASE_URL } /client/elicitation#response-actions" ,
1976- behavior = "A URL-mode elicitation answered with cancel returns the action with no content." ,
1987+ behavior = "A URL-mode elicitation answered with decline returns the action with no content." ,
1988+ arm_exclusions = (
1989+ ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
1990+ ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
1991+ ),
1992+ ),
1993+ "elicitation:url:basic" : Requirement (
1994+ source = f"{ SPEC_BASE_URL } /client/elicitation#url-mode-elicitation-requests" ,
1995+ behavior = (
1996+ "A url-mode elicitation delivers the elicitation id and URL to the client callback exactly as "
1997+ "the server sent them."
1998+ ),
19771999 arm_exclusions = (
19782000 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
19792001 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
@@ -2001,14 +2023,6 @@ def __post_init__(self) -> None:
20012023 removed_in = "2026-07-28" ,
20022024 note = "removed in 2026-07-28 (spec PR #2891); notifications/elicitation/complete removed, no replacement." ,
20032025 ),
2004- "elicitation:url:decline" : Requirement (
2005- source = f"{ SPEC_BASE_URL } /client/elicitation#response-actions" ,
2006- behavior = "A URL-mode elicitation answered with decline returns the action with no content." ,
2007- arm_exclusions = (
2008- ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
2009- ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
2010- ),
2011- ),
20122026 "elicitation:url:not-supported" : Requirement (
20132027 source = f"{ SPEC_BASE_URL } /client/elicitation#error-handling" ,
20142028 behavior = (
@@ -3644,7 +3658,7 @@ def __post_init__(self) -> None:
36443658 transports = ("streamable-http" ,),
36453659 note = "OAuth is HTTP-only." ,
36463660 ),
3647- "client-auth:403- scope-union" : Requirement (
3661+ "client-auth:stepup: scope-union" : Requirement (
36483662 source = f"{ SPEC_BASE_URL } /basic/authorization#step-up-authorization-flow" ,
36493663 behavior = (
36503664 "On a 403 insufficient_scope step-up, the re-authorization request carries the union of the "
@@ -3687,7 +3701,7 @@ def __post_init__(self) -> None:
36873701 ),
36883702 ),
36893703 ),
3690- "client-auth:authorize :offline-access-consent " : Requirement (
3704+ "client-auth:scope :offline-access-gate " : Requirement (
36913705 source = "sdk" ,
36923706 behavior = (
36933707 "When the authorization server's metadata advertises offline_access in scopes_supported and "
@@ -3721,7 +3735,7 @@ def __post_init__(self) -> None:
37213735 transports = ("streamable-http" ,),
37223736 note = "OAuth is HTTP-only." ,
37233737 ),
3724- "client-auth:dcr:registration-error-surfaces " : Requirement (
3738+ "client-auth:dcr:registration-rejected-error " : Requirement (
37253739 source = "sdk" ,
37263740 behavior = (
37273741 "A 400 from the registration endpoint surfaces to the caller as an OAuthRegistrationError "
@@ -3896,7 +3910,7 @@ def __post_init__(self) -> None:
38963910 transports = ("streamable-http" ,),
38973911 note = "OAuth is HTTP-only." ,
38983912 ),
3899- "client-auth:authorization-response: iss-verify " : Requirement (
3913+ "client-auth:iss:mismatch-reject " : Requirement (
39003914 source = f"{ SPEC_2026_BASE_URL } /basic/authorization#authorization-response-validation" ,
39013915 behavior = (
39023916 "The client validates the RFC 9207 iss authorization-response parameter against the "
0 commit comments