Skip to content

Commit 518a337

Browse files
committed
Tighten requirements-catalog divergence notes to match current SDK behaviour
- resources:annotations: drop the stale lastModified divergence; the model now carries the field and it round-trips. - lifecycle:capability:client-not-declared: narrow to the one remaining gap (the deprecated send_roots_list_changed path); the handler half is correct by construction. - lifecycle:pre-initialization-ordering: mark removed_in=2026-07-28; the initialize handshake is gone in the new spec. - client-transport:http:session-404-reinitialize: reword as an intentional cross-SDK choice (404 surfaced to caller), not a missed MUST. - test_resources: drop the now-redundant lastModified xfail.
1 parent 3945bdd commit 518a337

2 files changed

Lines changed: 13 additions & 16 deletions

File tree

tests/interaction/_requirements.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,15 @@ def __post_init__(self) -> None:
184184
),
185185
divergence=Divergence(
186186
note=(
187-
"The client does not check its own declared capabilities before sending notifications or "
188-
"serving callbacks; nothing prevents a caller from violating the spec's MUST."
187+
"The handler half is correct by construction -- the client derives its declared "
188+
"capabilities from the callbacks registered at construction, so it cannot serve a "
189+
"capability it did not declare. Only the deprecated send_roots_list_changed notification "
190+
"is ungated: a caller can send it without having registered a roots callback."
189191
),
190192
),
191193
deferred=(
192-
"Not implemented in the SDK: the client does not check its own declared capabilities before "
193-
"sending notifications or serving callbacks."
194+
"Not implemented in the SDK: the deprecated send_roots_list_changed notification is not "
195+
"gated on a declared roots capability."
194196
),
195197
),
196198
"lifecycle:capability:server-not-advertised": Requirement(
@@ -306,6 +308,8 @@ def __post_init__(self) -> None:
306308
"Before initialization completes, the client sends no requests other than pings, and the "
307309
"server sends no requests other than pings and logging."
308310
),
311+
removed_in="2026-07-28",
312+
note="initialize handshake removed at 2026-07-28; per-request _meta envelope replaces it.",
309313
divergence=Divergence(
310314
note=(
311315
"The server's send methods (create_message / elicit_form / list_roots) do not check "
@@ -1098,12 +1102,6 @@ def __post_init__(self) -> None:
10981102
"resources:annotations": Requirement(
10991103
source=f"{SPEC_BASE_URL}/server/resources#annotations",
11001104
behavior="Resource annotations supplied by the server round-trip to the client in the list result.",
1101-
divergence=Divergence(
1102-
note=(
1103-
"The SDK Annotations model is missing the schema's lastModified field; MCPModel uses the "
1104-
"pydantic default extra='ignore', so the value is silently dropped on parse."
1105-
),
1106-
),
11071105
),
11081106
"resources:capability:declared": Requirement(
11091107
source=f"{SPEC_BASE_URL}/server/resources#capabilities",
@@ -3207,8 +3205,9 @@ def __post_init__(self) -> None:
32073205
transports=("streamable-http",),
32083206
divergence=Divergence(
32093207
note=(
3210-
"The client surfaces the 404 as an error to the caller instead of re-initializing a new "
3211-
"session; the spec's MUST is not satisfied."
3208+
"The 404 is intentionally surfaced to the caller; this matches the TypeScript, C#, and "
3209+
"Go SDKs. The 2025-11-25 MUST was removed in the 2026 spec (SEP-2567), and the transport "
3210+
"layer cannot safely re-initialize without replaying the caller's request."
32123211
),
32133212
),
32143213
deferred=(

tests/interaction/lowlevel/test_resources.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,8 @@
3939
async def test_list_resources_returns_registered_resources(connect: Connect) -> None:
4040
"""Listed resources reach the client with their URIs, names, and optional descriptive fields intact.
4141
42-
The fully-populated entry includes annotations, so the snapshot also proves they round-trip.
43-
The SDK's Annotations model omits the schema's lastModified field (see the divergence on
44-
resources:annotations); the input is built via model_validate with lastModified set so the
45-
snapshot pins the drop and will fail once the SDK adds the field.
42+
The fully-populated entry includes annotations (audience, priority, last_modified), so the
43+
snapshot also proves they round-trip.
4644
"""
4745

4846
async def list_resources(

0 commit comments

Comments
 (0)