diff --git a/src/fastmcp/utilities/func_metadata.py b/src/fastmcp/utilities/func_metadata.py index 9bd49214d..8bced29fa 100644 --- a/src/fastmcp/utilities/func_metadata.py +++ b/src/fastmcp/utilities/func_metadata.py @@ -91,7 +91,7 @@ class FuncMetadata(BaseModel): pre_parsed = json.loads(data[field_name]) except json.JSONDecodeError: continue # Not JSON - skip - if isinstance(pre_parsed, str): + if isinstance(pre_parsed, (str, int, float)): # This is likely that the raw value is e.g. `"hello"` which we # Should really be parsed as '"hello"' in Python - but if we parse # it as JSON it'll turn into just 'hello'. So we skip it. diff --git a/tests/test_func_metadata.py b/tests/test_func_metadata.py index d0429a12c..eebcb0401 100644 --- a/tests/test_func_metadata.py +++ b/tests/test_func_metadata.py @@ -174,6 +174,21 @@ def test_str_vs_list_str(): assert result["str_or_list"] == ["hello", "world"] +def test_str_vs_int(): + """ + Test that string values are kept as strings even when they contain numbers, + while numbers are parsed correctly. + """ + + def func_with_str_and_int(a: str, b: int): + return a + + meta = func_metadata(func_with_str_and_int) + result = meta.pre_parse_json({"a": "123", "b": 123}) + assert result["a"] == "123" + assert result["b"] == 123 + + def test_skip_names(): """Test that skipped parameters are not included in the model"""