Make sure RequestId is not coerced as int (#1178)

This commit is contained in:
Marcelo Trylesinski 2025-07-21 11:57:47 +02:00 • committed by GitHub
commit 7570ba30cf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 12 additions and 3 deletions

View file

@ -36,7 +36,7 @@ DEFAULT_NEGOTIATED_VERSION = "2025-03-26"
ProgressToken = str | int
Cursor = str
Role = Literal["user", "assistant"]
RequestId = Annotated[int | str, Field(union_mode="left_to_right")]
RequestId = Annotated[int, Field(strict=True)] | str
AnyFunction: TypeAlias = Callable[..., Any]
@ -849,7 +849,7 @@ class Tool(BaseMetadata):
"""A JSON Schema object defining the expected parameters for the tool."""
outputSchema: dict[str, Any] | None = None
"""
An optional JSON Schema object defining the structure of the tool's output
An optional JSON Schema object defining the structure of the tool's output
returned in the structuredContent field of a CallToolResult.
"""
annotations: ToolAnnotations | None = None

View file

@ -466,12 +466,21 @@ async def test_request_context_isolation(context_server: None, server_url: str)
def test_sse_message_id_coercion():
"""Test that string message IDs that look like integers are parsed as integers.
"""Previously, the `RequestId` would coerce a string that looked like an integer into an integer.
See <https://github.com/modelcontextprotocol/python-sdk/pull/851> for more details.
As per the JSON-RPC 2.0 specification, the id in the response object needs to be the same type as the id in the
request object. In other words, we can't perform the coercion.
See <https://www.jsonrpc.org/specification#response_object> for more details.
"""
json_message = '{"jsonrpc": "2.0", "id": "123", "method": "ping", "params": null}'
msg = types.JSONRPCMessage.model_validate_json(json_message)
assert msg == snapshot(types.JSONRPCMessage(root=types.JSONRPCRequest(method="ping", jsonrpc="2.0", id="123")))
json_message = '{"jsonrpc": "2.0", "id": 123, "method": "ping", "params": null}'
msg = types.JSONRPCMessage.model_validate_json(json_message)
assert msg == snapshot(types.JSONRPCMessage(root=types.JSONRPCRequest(method="ping", jsonrpc="2.0", id=123)))