@@ -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 # ═══════════════════════════════════════════════════════════════════════════
@@ -1625,23 +1639,23 @@ def __post_init__(self) -> None:
16251639 "rejects every tool-enabled request before it is sent."
16261640 ),
16271641 ),
1628- "sampling:create-message :audio-content" : Requirement (
1642+ "sampling:create:audio-content" : Requirement (
16291643 source = f"{ SPEC_BASE_URL } /client/sampling#audio-content" ,
16301644 behavior = "Sampling messages can carry audio content: base64 data with a mimeType." ,
16311645 arm_exclusions = (
16321646 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
16331647 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
16341648 ),
16351649 ),
1636- "sampling:create-message :image-content" : Requirement (
1650+ "sampling:create:image-content" : Requirement (
16371651 source = f"{ SPEC_BASE_URL } /client/sampling#image-content" ,
16381652 behavior = "Sampling messages can carry image content: base64 data with a mimeType." ,
16391653 arm_exclusions = (
16401654 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
16411655 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
16421656 ),
16431657 ),
1644- "sampling:create-message :not-supported" : Requirement (
1658+ "sampling:create:not-supported" : Requirement (
16451659 source = f"{ SPEC_BASE_URL } /client/sampling#capabilities" ,
16461660 behavior = (
16471661 "A sampling request to a client that did not declare the sampling capability fails with an "
@@ -1929,20 +1943,28 @@ def __post_init__(self) -> None:
19291943 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
19301944 ),
19311945 ),
1932- "elicitation:url:basic" : Requirement (
1933- source = f"{ SPEC_BASE_URL } /client/elicitation#url-mode-elicitation-requests" ,
1934- behavior = (
1935- "A url-mode elicitation delivers the elicitation id and URL to the client callback exactly as "
1936- "the server sent them."
1937- ),
1946+ "elicitation:url:action:cancel" : Requirement (
1947+ source = f"{ SPEC_BASE_URL } /client/elicitation#response-actions" ,
1948+ behavior = "A URL-mode elicitation answered with cancel returns the action with no content." ,
19381949 arm_exclusions = (
19391950 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
19401951 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
19411952 ),
19421953 ),
1943- "elicitation:url:cancel " : Requirement (
1954+ "elicitation:url:action:decline " : Requirement (
19441955 source = f"{ SPEC_BASE_URL } /client/elicitation#response-actions" ,
1945- behavior = "A URL-mode elicitation answered with cancel returns the action with no content." ,
1956+ behavior = "A URL-mode elicitation answered with decline returns the action with no content." ,
1957+ arm_exclusions = (
1958+ ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
1959+ ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
1960+ ),
1961+ ),
1962+ "elicitation:url:basic" : Requirement (
1963+ source = f"{ SPEC_BASE_URL } /client/elicitation#url-mode-elicitation-requests" ,
1964+ behavior = (
1965+ "A url-mode elicitation delivers the elicitation id and URL to the client callback exactly as "
1966+ "the server sent them."
1967+ ),
19461968 arm_exclusions = (
19471969 ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
19481970 ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
@@ -1970,14 +1992,6 @@ def __post_init__(self) -> None:
19701992 removed_in = "2026-07-28" ,
19711993 note = "removed in 2026-07-28 (spec PR #2891); notifications/elicitation/complete removed, no replacement." ,
19721994 ),
1973- "elicitation:url:decline" : Requirement (
1974- source = f"{ SPEC_BASE_URL } /client/elicitation#response-actions" ,
1975- behavior = "A URL-mode elicitation answered with decline returns the action with no content." ,
1976- arm_exclusions = (
1977- ArmExclusion (reason = "server-initiated-request" , transport = "streamable-http-stateless" ),
1978- ArmExclusion (reason = "server-initiated-request" , spec_version = "2026-07-28" ),
1979- ),
1980- ),
19811995 "elicitation:url:not-supported" : Requirement (
19821996 source = f"{ SPEC_BASE_URL } /client/elicitation#error-handling" ,
19831997 behavior = (
@@ -3603,7 +3617,7 @@ def __post_init__(self) -> None:
36033617 transports = ("streamable-http" ,),
36043618 note = "OAuth is HTTP-only." ,
36053619 ),
3606- "client-auth:403- scope-union" : Requirement (
3620+ "client-auth:stepup: scope-union" : Requirement (
36073621 source = f"{ SPEC_BASE_URL } /basic/authorization#step-up-authorization-flow" ,
36083622 behavior = (
36093623 "On a 403 insufficient_scope step-up, the re-authorization request carries the union of the "
@@ -3646,7 +3660,7 @@ def __post_init__(self) -> None:
36463660 ),
36473661 ),
36483662 ),
3649- "client-auth:authorize :offline-access-consent " : Requirement (
3663+ "client-auth:scope :offline-access-gate " : Requirement (
36503664 source = "sdk" ,
36513665 behavior = (
36523666 "When the authorization server's metadata advertises offline_access in scopes_supported and "
@@ -3680,7 +3694,7 @@ def __post_init__(self) -> None:
36803694 transports = ("streamable-http" ,),
36813695 note = "OAuth is HTTP-only." ,
36823696 ),
3683- "client-auth:dcr:registration-error-surfaces " : Requirement (
3697+ "client-auth:dcr:registration-rejected-error " : Requirement (
36843698 source = "sdk" ,
36853699 behavior = (
36863700 "A 400 from the registration endpoint surfaces to the caller as an OAuthRegistrationError "
@@ -3855,7 +3869,7 @@ def __post_init__(self) -> None:
38553869 transports = ("streamable-http" ,),
38563870 note = "OAuth is HTTP-only." ,
38573871 ),
3858- "client-auth:authorization-response: iss-verify " : Requirement (
3872+ "client-auth:iss:mismatch-reject " : Requirement (
38593873 source = f"{ SPEC_2026_BASE_URL } /basic/authorization#authorization-response-validation" ,
38603874 behavior = (
38613875 "The client validates the RFC 9207 iss authorization-response parameter against the "
0 commit comments