Initial Checks
Release line
2.x (current stable)
Description
JSON Schema 2020-12 allows a boolean (true / false) anywhere a sub-schema is expected, including as a value under properties. The generated 2025-11-25 wire model types properties as dict[str, dict[str, Any]] on both InputSchema and OutputSchema (src/mcp-types/mcp_types/_v2025_11_25/__init__.py, lines 1361 and 1379), so a tool whose outputSchema contains e.g. "properties": {"result": true} fails surface validation with a pydantic dict_type error.
Because ListToolsResult is validated as a whole, one such tool causes the client to discard the entire tool list for that server on any 2025-11-25-negotiated session (same failure shape as #3337, different trigger).
This is not hypothetical: a publicly reachable server (Microsoft's Azure Resource Manager MCP, https://mcp.management.azure.com) currently returns tools/list where 12 of 17 tools carry
"outputSchema": {"type": "object", "properties": {"result": true}, "required": ["result"]}
and the SDK cannot list any of its tools on a 2025-11-25 session.
The 2026-07-28 surface already accepts this payload: its InputSchema/OutputSchema have no typed properties field (SEP-2106, #2792, made both free-form JSON Schema 2020-12). The 2025-11-25 strictness is an artefact of how schema.ts rendered { [key: string]: object } to JSON, not something the 2025-11-25 spec text requires — that spec also says outputSchema is a JSON Schema object and defaults to the 2020-12 dialect.
Expected: validate_server_result("tools/list", "2025-11-25", ...) accepts boolean property sub-schemas (and the client's list_tools() succeeds), matching 2026-07-28 behaviour and JSON Schema 2020-12.
Proposed fix (happy to open the PR): extend the existing SCHEMA_PATCHES["2025-11-25"] list in scripts/gen_surface_types.py to widen $defs/Tool/properties/{inputSchema,outputSchema}/properties/properties/additionalProperties to anyOf: [<object>, {"type": "boolean"}], then regenerate. The generated diff is exactly two lines (dict[str, dict[str, Any]] → dict[str, dict[str, Any] | bool]) and the 2026-07-28 module is unchanged. Plus a regression test in tests/types/test_methods.py.
Example Code
from mcp_types.methods import validate_server_result
tool = {
"name": "get_resource",
"inputSchema": {"type": "object"},
"outputSchema": {"type": "object", "properties": {"result": True}, "required": ["result"]},
}
validate_server_result(
"tools/list", "2026-07-28", {"tools": [tool], "resultType": "complete", "ttlMs": 0, "cacheScope": "private"}
)
print("2026-07-28: ok")
validate_server_result("tools/list", "2025-11-25", {"tools": [tool]}) # raises
print("2025-11-25: ok")
Output (identical on the released mcp==2.0.0 wheel and on main @ 57394b0):
2026-07-28: ok
Traceback (most recent call last):
...
pydantic_core._pydantic_core.ValidationError: 1 validation error for ListToolsResult
tools.0.outputSchema.properties.result
Input should be a valid dictionary [type=dict_type, input_value=True, input_type=bool]
For further information visit https://errors.pydantic.dev/2.12/v/dict_type
Python & MCP Python SDK
Python 3.13.15
mcp 2.0.0 / mcp-types 2.0.0 (latest release, PyPI), pydantic 2.13.4
also reproduces on main @ 57394b05 (mcp 2.0.1.dev21+57394b05), pydantic 2.12.5
Initial Checks
Release line
2.x (current stable)
Description
JSON Schema 2020-12 allows a boolean (
true/false) anywhere a sub-schema is expected, including as a value underproperties. The generated 2025-11-25 wire model typespropertiesasdict[str, dict[str, Any]]on bothInputSchemaandOutputSchema(src/mcp-types/mcp_types/_v2025_11_25/__init__.py, lines 1361 and 1379), so a tool whoseoutputSchemacontains e.g."properties": {"result": true}fails surface validation with a pydanticdict_typeerror.Because
ListToolsResultis validated as a whole, one such tool causes the client to discard the entire tool list for that server on any 2025-11-25-negotiated session (same failure shape as #3337, different trigger).This is not hypothetical: a publicly reachable server (Microsoft's Azure Resource Manager MCP,
https://mcp.management.azure.com) currently returnstools/listwhere 12 of 17 tools carryand the SDK cannot list any of its tools on a 2025-11-25 session.
The 2026-07-28 surface already accepts this payload: its
InputSchema/OutputSchemahave no typedpropertiesfield (SEP-2106, #2792, made both free-form JSON Schema 2020-12). The 2025-11-25 strictness is an artefact of howschema.tsrendered{ [key: string]: object }to JSON, not something the 2025-11-25 spec text requires — that spec also saysoutputSchemais a JSON Schema object and defaults to the 2020-12 dialect.Expected:
validate_server_result("tools/list", "2025-11-25", ...)accepts boolean property sub-schemas (and the client'slist_tools()succeeds), matching 2026-07-28 behaviour and JSON Schema 2020-12.Proposed fix (happy to open the PR): extend the existing
SCHEMA_PATCHES["2025-11-25"]list inscripts/gen_surface_types.pyto widen$defs/Tool/properties/{inputSchema,outputSchema}/properties/properties/additionalPropertiestoanyOf: [<object>, {"type": "boolean"}], then regenerate. The generated diff is exactly two lines (dict[str, dict[str, Any]]→dict[str, dict[str, Any] | bool]) and the 2026-07-28 module is unchanged. Plus a regression test intests/types/test_methods.py.Example Code
Output (identical on the released
mcp==2.0.0wheel and onmain@ 57394b0):Python & MCP Python SDK