From cc2e919e6da17539f810e6aca66c0447165d1c9b Mon Sep 17 00:00:00 2001 From: Yufeng He <40085740+he-yufeng@users.noreply.github.com> Date: Thu, 14 May 2026 22:42:08 +0800 Subject: [PATCH] fix: wrap structured union outputs explicitly --- .../mcpserver/utilities/func_metadata.py | 2 +- tests/server/mcpserver/test_func_metadata.py | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) 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..0743dbf3f 100644 --- a/tests/server/mcpserver/test_func_metadata.py +++ b/tests/server/mcpserver/test_func_metadata.py @@ -680,6 +680,9 @@ def func_union() -> str | int: # pragma: no cover def func_optional() -> str | None: # pragma: no cover return None + def func_builtin_union() -> dict[str, str] | list[str] | str: # pragma: no cover + return {"hello": "world"} + # Test list meta = func_metadata(func_list_str) assert meta.output_schema == { @@ -715,6 +718,23 @@ def func_optional() -> str | None: # pragma: no cover "title": "func_optionalOutput", } + meta = func_metadata(func_builtin_union) + assert meta.output_schema == { + "type": "object", + "properties": { + "result": { + "title": "Result", + "anyOf": [ + {"type": "object", "additionalProperties": {"type": "string"}}, + {"type": "array", "items": {"type": "string"}}, + {"type": "string"}, + ], + } + }, + "required": ["result"], + "title": "func_builtin_unionOutput", + } + def test_structured_output_dataclass(): """Test structured output with dataclass return types"""