diff --git a/src/mcp/server/mcpserver/utilities/func_metadata.py b/src/mcp/server/mcpserver/utilities/func_metadata.py index 4a7610637..3ea9bf7ce 100644 --- a/src/mcp/server/mcpserver/utilities/func_metadata.py +++ b/src/mcp/server/mcpserver/utilities/func_metadata.py @@ -478,7 +478,7 @@ def _create_wrapped_model(func_name: str, annotation: Any) -> type[BaseModel]: """ model_name = f"{func_name}Output" - return create_model(model_name, result=annotation) + return create_model(model_name, result=(annotation, ...)) def _create_dict_model(func_name: str, dict_annotation: Any) -> type[BaseModel]: diff --git a/tests/server/mcpserver/test_func_metadata.py b/tests/server/mcpserver/test_func_metadata.py index c57d1ee9f..5ef6cd686 100644 --- a/tests/server/mcpserver/test_func_metadata.py +++ b/tests/server/mcpserver/test_func_metadata.py @@ -716,6 +716,30 @@ def func_optional() -> str | None: # pragma: no cover } +def test_structured_output_pep604_union_of_container_and_primitives(): + """Test structured output with PEP 604 unions that combine containers and primitives.""" + + def func_container_union() -> dict | list | str: # pragma: no cover + return {"hello": "world"} + + meta = func_metadata(func_container_union) + assert meta.output_schema == { + "type": "object", + "properties": { + "result": { + "title": "Result", + "anyOf": [ + {"additionalProperties": True, "type": "object"}, + {"items": {}, "type": "array"}, + {"type": "string"}, + ], + } + }, + "required": ["result"], + "title": "func_container_unionOutput", + } + + def test_structured_output_dataclass(): """Test structured output with dataclass return types"""