Skip to content

Commit 444edf6

Browse files
Merge pull request #180 from modelcontextprotocol/jeremy/relax-pydantic
Relax pydantic, pydantic-settings, and uvicorn requirements
2 parents 5e19c7c + defd52b commit 444edf6

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

pyproject.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ dependencies = [
2525
"anyio>=4.5",
2626
"httpx>=0.27",
2727
"httpx-sse>=0.4",
28-
"pydantic>=2.10.1,<3.0.0",
28+
"pydantic>=2.7.2,<3.0.0",
2929
"starlette>=0.27",
3030
"sse-starlette>=1.6.1",
31-
"pydantic-settings>=2.6.1",
32-
"uvicorn>=0.30",
31+
"pydantic-settings>=2.5.2",
32+
"uvicorn>=0.23.1",
3333
]
3434

3535
[project.optional-dependencies]

tests/server/fastmcp/test_func_metadata.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,45 @@ async def check_call(args):
235235

236236

237237
def test_complex_function_json_schema():
238+
"""Test JSON schema generation for complex function arguments.
239+
240+
Note: Different versions of pydantic output slightly different
241+
JSON Schema formats for model fields with defaults. The format changed in 2.9.0:
242+
243+
1. Before 2.9.0:
244+
{
245+
"allOf": [{"$ref": "#/$defs/Model"}],
246+
"default": {}
247+
}
248+
249+
2. Since 2.9.0:
250+
{
251+
"$ref": "#/$defs/Model",
252+
"default": {}
253+
}
254+
255+
Both formats are valid and functionally equivalent. This test accepts either format
256+
to ensure compatibility across our supported pydantic versions.
257+
258+
This change in format does not affect runtime behavior since:
259+
1. Both schemas validate the same way
260+
2. The actual model classes and validation logic are unchanged
261+
3. func_metadata uses model_validate/model_dump, not the schema directly
262+
"""
238263
meta = func_metadata(complex_arguments_fn)
239-
assert meta.arg_model.model_json_schema() == {
264+
actual_schema = meta.arg_model.model_json_schema()
265+
266+
# Create a copy of the actual schema to normalize
267+
normalized_schema = actual_schema.copy()
268+
269+
# Normalize the my_model_a_with_default field to handle both pydantic formats
270+
if 'allOf' in actual_schema['properties']['my_model_a_with_default']:
271+
normalized_schema['properties']['my_model_a_with_default'] = {
272+
'$ref': '#/$defs/SomeInputModelA',
273+
'default': {}
274+
}
275+
276+
assert normalized_schema == {
240277
"$defs": {
241278
"InnerModel": {
242279
"properties": {"x": {"title": "X", "type": "integer"}},

0 commit comments

Comments
 (0)