diff --git a/src/mcp/server/mcpserver/utilities/func_metadata.py b/src/mcp/server/mcpserver/utilities/func_metadata.py index be4afb4e9..722b48f9f 100644 --- a/src/mcp/server/mcpserver/utilities/func_metadata.py +++ b/src/mcp/server/mcpserver/utilities/func_metadata.py @@ -397,9 +397,7 @@ def _try_create_model_and_schema( if origin is dict: args = get_args(type_expr) if len(args) == 2 and args[0] is str: - # TODO: should we use the original annotation? We are losing any potential `Annotated` - # metadata for Pydantic here: - model = _create_dict_model(func_name, type_expr) + model = _create_dict_model(func_name, original_annotation) else: # dict with non-str keys needs wrapping model = _create_wrapped_model(func_name, original_annotation) diff --git a/tests/server/mcpserver/test_func_metadata.py b/tests/server/mcpserver/test_func_metadata.py index 62a9612b9..c443af688 100644 --- a/tests/server/mcpserver/test_func_metadata.py +++ b/tests/server/mcpserver/test_func_metadata.py @@ -258,6 +258,19 @@ def func_dict_list() -> dict[str, list[int]]: # pragma: no cover "title": "func_dict_listDictOutput", } + def func_dict_with_description() -> Annotated[ + dict[str, int], Field(description="Configuration values") + ]: # pragma: no cover + return {"timeout": 30} + + meta = func_metadata(func_dict_with_description) + assert meta.output_schema == { + "type": "object", + "additionalProperties": {"type": "integer"}, + "title": "func_dict_with_descriptionDictOutput", + "description": "Configuration values", + } + # Test dict[int, str] - should be wrapped since key is not str def func_dict_int_key() -> dict[int, str]: # pragma: no cover return {1: "a", 2: "b"}