diff --git a/src/mcp/server/fastmcp/utilities/func_metadata.py b/src/mcp/server/fastmcp/utilities/func_metadata.py index cf93049e..629580e1 100644 --- a/src/mcp/server/fastmcp/utilities/func_metadata.py +++ b/src/mcp/server/fastmcp/utilities/func_metadata.py @@ -88,7 +88,7 @@ def pre_parse_json(self, data: dict[str, Any]) -> dict[str, Any]: 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/server/fastmcp/test_func_metadata.py b/tests/server/fastmcp/test_func_metadata.py index 6461648e..b1828ffe 100644 --- a/tests/server/fastmcp/test_func_metadata.py +++ b/tests/server/fastmcp/test_func_metadata.py @@ -399,3 +399,18 @@ def test_complex_function_json_schema(): "title": "complex_arguments_fnArguments", "type": "object", } + + +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