@@ -116,6 +116,13 @@ class Requirement:
116116 "requested version with its own latest supported version rather than an error."
117117 ),
118118 ),
119+ "lifecycle:initialize:protocol-version:client-rejects" : Requirement (
120+ source = f"{ SPEC_BASE_URL } /basic/lifecycle#version-negotiation" ,
121+ behavior = (
122+ "A client that receives an initialize response carrying a protocol version it does not "
123+ "support fails initialization with an error rather than proceeding with the session."
124+ ),
125+ ),
119126 "lifecycle:requests-before-initialized" : Requirement (
120127 source = f"{ SPEC_BASE_URL } /basic/lifecycle#initialization" ,
121128 behavior = "A request sent before the initialization handshake completes is rejected with an error." ,
@@ -154,6 +161,19 @@ class Requirement:
154161 "A cancellation notification referencing an unknown or already-completed request is ignored without error."
155162 ),
156163 ),
164+ "cancellation:server-to-client" : Requirement (
165+ source = f"{ SPEC_BASE_URL } /basic/utilities/cancellation#behavior-requirements" ,
166+ behavior = (
167+ "A server that abandons an in-flight server-initiated request (sampling, elicitation, roots) "
168+ "cancels it, and the client stops processing the cancelled request."
169+ ),
170+ deferred = (
171+ "Not expressible through the public API: abandoning a server-side send_request emits no "
172+ "cancellation notification (the same sender-side gap recorded on timeouts:per-request), and "
173+ "the client could not act on one anyway because client callbacks run inline in the receive "
174+ "loop, so a cancellation would not even be read until the callback had already finished."
175+ ),
176+ ),
157177 # ═══════════════════════════════════════════════════════════════════════════
158178 # Progress
159179 # ═══════════════════════════════════════════════════════════════════════════
@@ -325,6 +345,13 @@ class Requirement:
325345 "with the validation failure described in content), not a protocol error."
326346 ),
327347 ),
348+ "tools:call:output-schema-validation" : Requirement (
349+ source = f"{ SPEC_BASE_URL } /server/tools#tool-result" ,
350+ behavior = (
351+ "A tool result whose structuredContent does not conform to the tool's declared outputSchema "
352+ "is rejected by the client: the call raises instead of returning the invalid result."
353+ ),
354+ ),
328355 # ═══════════════════════════════════════════════════════════════════════════
329356 # Completion
330357 # ═══════════════════════════════════════════════════════════════════════════
@@ -473,6 +500,17 @@ class Requirement:
473500 source = f"{ SPEC_BASE_URL } /server/prompts#error-handling" ,
474501 behavior = "prompts/get for an unknown prompt name returns a JSON-RPC error." ,
475502 ),
503+ "prompts:get:missing-arguments" : Requirement (
504+ source = f"{ SPEC_BASE_URL } /server/prompts#error-handling" ,
505+ behavior = "prompts/get with a required argument missing returns a JSON-RPC error." ,
506+ divergence = Divergence (
507+ note = (
508+ "The spec says missing required arguments are answered with -32602 Invalid params; "
509+ "MCPServer's prompt renderer raises a plain ValueError before the prompt function runs, "
510+ "which the low-level server converts to error code 0 with the exception text as the message."
511+ ),
512+ ),
513+ ),
476514 # ═══════════════════════════════════════════════════════════════════════════
477515 # Sampling (server → client)
478516 # ═══════════════════════════════════════════════════════════════════════════
@@ -487,7 +525,7 @@ class Requirement:
487525 source = f"{ SPEC_BASE_URL } /client/sampling#creating-messages" ,
488526 behavior = (
489527 "The sampling parameters supplied by the server (messages, maxTokens, systemPrompt, "
490- "modelPreferences, temperature, stopSequences) reach the client callback intact."
528+ "modelPreferences, temperature, stopSequences, includeContext ) reach the client callback intact."
491529 ),
492530 ),
493531 "sampling:create-message:image-content" : Requirement (
@@ -501,6 +539,13 @@ class Requirement:
501539 "by the server before anything reaches the wire, with an Invalid params error."
502540 ),
503541 ),
542+ "sampling:create-message:tools:message-constraints" : Requirement (
543+ source = f"{ SPEC_BASE_URL } /client/sampling#message-content-constraints" ,
544+ behavior = (
545+ "A sampling request whose messages violate the tool_use/tool_result pairing rules is rejected "
546+ "by the server-side validator before anything reaches the wire."
547+ ),
548+ ),
504549 "sampling:create-message:tools:round-trip" : Requirement (
505550 source = f"{ SPEC_BASE_URL } /client/sampling#sampling-with-tools" ,
506551 behavior = (
@@ -587,6 +632,17 @@ class Requirement:
587632 ),
588633 ),
589634 ),
635+ "elicitation:url:not-supported" : Requirement (
636+ source = f"{ SPEC_BASE_URL } /client/elicitation#capabilities" ,
637+ behavior = (
638+ "A URL-mode elicitation to a client that declared only form-mode support is rejected with an "
639+ "Invalid params error."
640+ ),
641+ deferred = (
642+ "Not expressible through the public API: a Client with an elicitation callback always declares "
643+ "both the form and url sub-capabilities, so a form-only client cannot be constructed."
644+ ),
645+ ),
590646 # ═══════════════════════════════════════════════════════════════════════════
591647 # Roots (server → client)
592648 # ═══════════════════════════════════════════════════════════════════════════
@@ -614,6 +670,10 @@ class Requirement:
614670 ),
615671 ),
616672 ),
673+ "roots:list:client-error" : Requirement (
674+ source = f"{ SPEC_BASE_URL } /client/roots#error-handling" ,
675+ behavior = "A roots callback that answers with an error surfaces to the requesting handler as an MCPError." ,
676+ ),
617677 "roots:list-changed" : Requirement (
618678 source = f"{ SPEC_BASE_URL } /client/roots#root-list-changes" ,
619679 behavior = "A roots/list_changed notification sent by the client is delivered to the server's handler." ,
@@ -671,6 +731,22 @@ class Requirement:
671731 "tests/shared/test_streamable_http.py."
672732 ),
673733 ),
734+ "transport:streamable-http:resumability" : Requirement (
735+ source = f"{ SPEC_BASE_URL } /basic/transports#streamable-http" ,
736+ behavior = "A client that reconnects with Last-Event-ID receives the events it missed." ,
737+ deferred = (
738+ "Replay requires dropping and re-establishing the SSE connection, which the in-process ASGI "
739+ "client cannot express. Covered over a real socket by tests/shared/test_streamable_http.py."
740+ ),
741+ ),
742+ "transport:streamable-http:origin-validation" : Requirement (
743+ source = f"{ SPEC_BASE_URL } /basic/transports#streamable-http" ,
744+ behavior = "Requests with a disallowed Origin or Host header are rejected before reaching the session." ,
745+ deferred = (
746+ "The in-process fixture disables DNS-rebinding protection because no network attack surface "
747+ "exists in-process. Covered by tests/server/test_streamable_http_security.py."
748+ ),
749+ ),
674750 "transport:stdio" : Requirement (
675751 source = f"{ SPEC_BASE_URL } /basic/transports#stdio" ,
676752 behavior = "The interaction round trip works over a stdio subprocess." ,
0 commit comments