Re-vendor 2026-07-28 schema at spec ead35b59 (SubscriptionsListenResult) (#3006)

This commit is contained in:
Max
2026-06-27 10:15:34 +02:00
committed by GitHub
parent 3b78f86886
commit e942d00b98
10 changed files with 124 additions and 15 deletions
+33
View File
@@ -3220,6 +3220,9 @@
{
"$ref": "#/$defs/ReadResourceResult"
},
{
"$ref": "#/$defs/SubscriptionsListenResult"
},
{
"$ref": "#/$defs/ListPromptsResult"
},
@@ -3389,6 +3392,36 @@
],
"type": "object"
},
"SubscriptionsListenResult": {
"description": "The response to a {@link SubscriptionsListenRequestsubscriptions/listen}\nrequest, signalling that the subscription has ended gracefully (for example,\nduring server shutdown). Because the listen stream is long-lived, this result\nis sent only when the server tears the subscription down; an abrupt transport\nclose carries no response. The result body is otherwise empty.",
"properties": {
"_meta": {
"$ref": "#/$defs/SubscriptionsListenResultMeta"
},
"resultType": {
"description": "Indicates the type of the result, which allows the client to determine\nhow to parse the result object.\n\nServers implementing this protocol version MUST include this field.\nFor backward compatibility, when a client receives a result from a\nserver implementing an earlier protocol version (which does not include\n`resultType`), the client MUST treat the absent field as `\"complete\"`.",
"type": "string"
}
},
"required": [
"_meta",
"resultType"
],
"type": "object"
},
"SubscriptionsListenResultMeta": {
"description": "Extends {@link MetaObject} with the subscription-stream identifier carried by a\n{@link SubscriptionsListenResult}. All key naming rules from `MetaObject` apply.",
"properties": {
"io.modelcontextprotocol/subscriptionId": {
"$ref": "#/$defs/RequestId",
"description": "Identifies the subscription stream this response closes, so the client can\ncorrelate it with the originating subscription — mirroring the same key on\nthe stream's notifications. The value is the JSON-RPC ID of the\n`subscriptions/listen` request that opened the stream (and equals this\nresponse's `id`)."
}
},
"required": [
"io.modelcontextprotocol/subscriptionId"
],
"type": "object"
},
"TextContent": {
"description": "Text provided to or from an LLM.",
"properties": {
+2 -2
View File
@@ -8,7 +8,7 @@
{
"protocol_version": "2026-07-28",
"source_path_in_spec_repo": "schema/draft/schema.json",
"spec_commit": "2852f30e26ca5fb779565741ec042094cb110abd",
"sha256": "ed1ad4ba94aaeb2068b78969ef901b1150f7b2f06cf86472b3032abee1380b6a"
"spec_commit": "ead35b59b4fda8b32e276810025d8f92bdcec1b6",
"sha256": "e00f675287e8cf078688c26c8a89d283ff2613da3b76d5cd15aff9d189df639c"
}
]
+9 -1
View File
@@ -85,7 +85,15 @@ SCHEMA_PATCHES: dict[str, list[tuple[str, Any, Any]]] = {
OPEN_CLASSES: dict[str, frozenset[str]] = {
"2025-11-25": frozenset({"Meta", "InputSchema", "OutputSchema", "Result", "GetTaskPayloadResult", "Data"}),
"2026-07-28": frozenset(
{"MetaObject", "NotificationMetaObject", "RequestMetaObject", "InputSchema", "OutputSchema", "Result"}
{
"MetaObject",
"NotificationMetaObject",
"RequestMetaObject",
"SubscriptionsListenResultMeta",
"InputSchema",
"OutputSchema",
"Result",
}
),
}
+2
View File
@@ -160,6 +160,7 @@ from mcp_types._types import (
SubscriptionsAcknowledgedNotificationParams,
SubscriptionsListenRequest,
SubscriptionsListenRequestParams,
SubscriptionsListenResult,
Task,
TaskMetadata,
TasksCallCapability,
@@ -385,6 +386,7 @@ __all__ = [
"ListTasksResult",
"ListToolsResult",
"ReadResourceResult",
"SubscriptionsListenResult",
# Error data payloads
"MissingRequiredClientCapabilityErrorData",
"UnsupportedProtocolVersionErrorData",
+16
View File
@@ -1063,6 +1063,21 @@ class SubscriptionsAcknowledgedNotification(
params: SubscriptionsAcknowledgedNotificationParams
class SubscriptionsListenResult(Result):
"""Signals that a `subscriptions/listen` stream has ended gracefully (2026-07-28).
Because the listen stream is long-lived, this result is sent only when the
server tears the subscription down (for example during shutdown); an abrupt
transport close carries no response. The body is otherwise empty: the
`_meta["io.modelcontextprotocol/subscriptionId"]` key is required on the
wire and equals the JSON-RPC id of the originating `subscriptions/listen`
request.
"""
result_type: ResultType = "complete"
"""See `ResultType`. Always serialized; older peers ignore it."""
class ListPromptsRequest(PaginatedRequest[Literal["prompts/list"]]):
"""Sent from the client to request a list of prompts and prompt templates the server has."""
@@ -2156,6 +2171,7 @@ ServerResult = (
| ReadResourceResult
| CallToolResult
| ListToolsResult
| SubscriptionsListenResult
| InputRequiredResult
)
"""Union of every result payload a server can return for a client request.
+2 -2
View File
@@ -292,7 +292,7 @@ SERVER_RESULTS: Final[Mapping[tuple[str, str], type[BaseModel] | UnionType]] = M
("resources/read", "2026-07-28"): v2026.AnyReadResourceResult,
("resources/templates/list", "2026-07-28"): v2026.ListResourceTemplatesResult,
("server/discover", "2026-07-28"): v2026.DiscoverResult,
("subscriptions/listen", "2026-07-28"): v2026.EmptyResult,
("subscriptions/listen", "2026-07-28"): v2026.SubscriptionsListenResult,
("tools/call", "2026-07-28"): v2026.AnyCallToolResult,
("tools/list", "2026-07-28"): v2026.ListToolsResult,
}
@@ -396,7 +396,7 @@ MONOLITH_RESULTS: Final[Mapping[str, type[types.Result] | UnionType]] = MappingP
# smart-union ties resolve leftmost. Pinned by tests/types/test_methods.py.
"sampling/createMessage": types.CreateMessageResult | types.CreateMessageResultWithTools,
"server/discover": types.DiscoverResult,
"subscriptions/listen": types.EmptyResult,
"subscriptions/listen": types.SubscriptionsListenResult,
"tools/call": types.CallToolResult | types.InputRequiredResult,
"tools/list": types.ListToolsResult,
}
@@ -1,7 +1,7 @@
"""Internal wire-shape models for protocol 2026-07-28. Generated; do not edit.
Regenerate with `scripts/gen_surface_types.py` from `schema/2026-07-28.json`
(sha256 `ed1ad4ba94aaeb2068b78969ef901b1150f7b2f06cf86472b3032abee1380b6a`)."""
(sha256 `e00f675287e8cf078688c26c8a89d283ff2613da3b76d5cd15aff9d189df639c`)."""
# pyright: reportIncompatibleVariableOverride=false, reportGeneralTypeIssues=false
from __future__ import annotations
@@ -909,6 +909,25 @@ class SubscriptionFilter(WireModel):
"""
class SubscriptionsListenResultMeta(WireModel):
"""
Extends {@link MetaObject} with the subscription-stream identifier carried by a
{@link SubscriptionsListenResult}. All key naming rules from `MetaObject` apply.
"""
model_config = ConfigDict(
extra="allow",
)
io_modelcontextprotocol_subscription_id: Annotated[RequestId, Field(alias="io.modelcontextprotocol/subscriptionId")]
"""
Identifies the subscription stream this response closes, so the client can
correlate it with the originating subscription — mirroring the same key on
the stream's notifications. The value is the JSON-RPC ID of the
`subscriptions/listen` request that opened the stream (and equals this
response's `id`).
"""
class TextResourceContents(WireModel):
model_config = ConfigDict(
extra="ignore",
@@ -2056,6 +2075,31 @@ class SubscriptionsAcknowledgedNotificationParams(WireModel):
"""
class SubscriptionsListenResult(WireModel):
"""
The response to a {@link SubscriptionsListenRequestsubscriptions/listen}
request, signalling that the subscription has ended gracefully (for example,
during server shutdown). Because the listen stream is long-lived, this result
is sent only when the server tears the subscription down; an abrupt transport
close carries no response. The result body is otherwise empty.
"""
model_config = ConfigDict(
extra="ignore",
)
meta: Annotated[SubscriptionsListenResultMeta, Field(alias="_meta")]
result_type: Annotated[str, Field(alias="resultType")]
"""
Indicates the type of the result, which allows the client to determine
how to parse the result object.
Servers implementing this protocol version MUST include this field.
For backward compatibility, when a client receives a result from a
server implementing an earlier protocol version (which does not include
`resultType`), the client MUST treat the absent field as `"complete"`.
"""
class TextContent(WireModel):
"""
Text provided to or from an LLM.
@@ -3544,6 +3588,7 @@ class ServerResult(
| ListResourcesResult
| ListResourceTemplatesResult
| ReadResourceResult
| SubscriptionsListenResult
| ListPromptsResult
| GetPromptResult
| ListToolsResult
@@ -3558,6 +3603,7 @@ class ServerResult(
| ListResourcesResult
| ListResourceTemplatesResult
| ReadResourceResult
| SubscriptionsListenResult
| ListPromptsResult
| GetPromptResult
| ListToolsResult
+3 -3
View File
@@ -182,7 +182,7 @@ class Server(Generic[LifespanResultT]):
| None = None,
on_subscriptions_listen: Callable[
[ServerRequestContext[LifespanResultT], types.SubscriptionsListenRequestParams],
Awaitable[types.EmptyResult],
Awaitable[types.SubscriptionsListenResult],
]
| None = None,
on_list_prompts: Callable[
@@ -264,7 +264,7 @@ class Server(Generic[LifespanResultT]):
| None = None,
on_subscriptions_listen: Callable[
[ServerRequestContext[LifespanResultT], types.SubscriptionsListenRequestParams],
Awaitable[types.EmptyResult],
Awaitable[types.SubscriptionsListenResult],
]
| None = None,
on_list_prompts: Callable[
@@ -355,7 +355,7 @@ class Server(Generic[LifespanResultT]):
| None = None,
on_subscriptions_listen: Callable[
[ServerRequestContext[LifespanResultT], types.SubscriptionsListenRequestParams],
Awaitable[types.EmptyResult],
Awaitable[types.SubscriptionsListenResult],
]
| None = None,
on_list_prompts: Callable[
+9 -6
View File
@@ -268,7 +268,7 @@ EXPECTED_SERVER_RESULTS: dict[tuple[str, str], type[BaseModel] | tuple[type[Base
("resources/read", "2026-07-28"): (v2026.ReadResourceResult, v2026.InputRequiredResult),
("resources/templates/list", "2026-07-28"): v2026.ListResourceTemplatesResult,
("server/discover", "2026-07-28"): v2026.DiscoverResult,
("subscriptions/listen", "2026-07-28"): v2026.EmptyResult,
("subscriptions/listen", "2026-07-28"): v2026.SubscriptionsListenResult,
("tools/call", "2026-07-28"): (v2026.CallToolResult, v2026.InputRequiredResult),
("tools/list", "2026-07-28"): v2026.ListToolsResult,
}
@@ -290,9 +290,7 @@ EXPECTED_CLIENT_RESULTS: dict[tuple[str, str], type[BaseModel] | tuple[type[Base
("sampling/createMessage", "2025-11-25"): v2025.CreateMessageResult,
}
EMPTY_SERVER_RESPONSE_METHODS = frozenset(
{"logging/setLevel", "ping", "resources/subscribe", "resources/unsubscribe", "subscriptions/listen"}
)
EMPTY_SERVER_RESPONSE_METHODS = frozenset({"logging/setLevel", "ping", "resources/subscribe", "resources/unsubscribe"})
EMPTY_CLIENT_RESPONSE_METHODS = frozenset({"ping"})
# Pre-2026 versions share the 2025-11-25 surface package.
@@ -404,7 +402,10 @@ RESULT_BODY_FIXTURES: dict[type[BaseModel] | UnionType, dict[str, Any]] = {
"ttlMs": 0,
"cacheScope": "private",
},
v2026.EmptyResult: {"resultType": "complete"},
v2026.SubscriptionsListenResult: {
"resultType": "complete",
"_meta": {"io.modelcontextprotocol/subscriptionId": 1},
},
v2026.ListPromptsResult: {"prompts": [], "resultType": "complete", "ttlMs": 0, "cacheScope": "private"},
v2026.ListResourcesResult: {"resources": [], "resultType": "complete", "ttlMs": 0, "cacheScope": "private"},
v2026.ListResourceTemplatesResult: {
@@ -844,7 +845,9 @@ MONOLITH_RESULT_FIXTURES: dict[str, types.Result] = {
ttl_ms=0,
cache_scope="private",
),
"subscriptions/listen": types.EmptyResult(result_type="complete"),
"subscriptions/listen": types.SubscriptionsListenResult.model_validate(
{"_meta": {"io.modelcontextprotocol/subscriptionId": 1}}
),
"tools/call": types.CallToolResult(content=[]),
"tools/list": types.ListToolsResult(tools=[], ttl_ms=0, cache_scope="private"),
}
+1
View File
@@ -122,6 +122,7 @@ SKIP: frozenset[str] = frozenset(
"v2026_07_28.RequestedSchema",
"v2026_07_28.ResourceRequestParams",
"v2026_07_28.StringSchema",
"v2026_07_28.SubscriptionsListenResultMeta",
"v2026_07_28.TitledMultiSelectEnumSchema",
"v2026_07_28.TitledSingleSelectEnumSchema",
"v2026_07_28.UnsupportedProtocolVersionError",