diff --git a/src/fastmcp/cli/generate.py b/src/fastmcp/cli/generate.py index 9629c28db..559847409 100644 --- a/src/fastmcp/cli/generate.py +++ b/src/fastmcp/cli/generate.py @@ -98,10 +98,10 @@ def _schema_to_python_type(schema: dict[str, Any]) -> tuple[str, bool]: def _format_schema_for_help(schema: dict[str, Any]) -> str: """Format a JSON schema for display in help text.""" - import json + import pydantic_core # Pretty print the schema, indented for help text - schema_str = json.dumps(schema, indent=2) + schema_str = pydantic_core.to_json(schema, indent=2).decode() # Indent each line for help text alignment lines = schema_str.split("\n") indented = "\n ".join(lines) @@ -202,9 +202,9 @@ def _tool_function_source(tool: mcp.types.Tool) -> str: if default is not None: # For complex types with defaults, serialize to JSON string if needs_json: - import json + import pydantic_core - default_str = json.dumps(default) + default_str = pydantic_core.to_json(default, fallback=str).decode() annotation = f'Annotated[{py_type}, cyclopts.Parameter(help="{help_escaped}")]' param_lines.append( f" {safe_name}: {annotation} = {default_str!r}," diff --git a/tests/cli/test_generate_cli.py b/tests/cli/test_generate_cli.py index c0f1aa43c..f513338d7 100644 --- a/tests/cli/test_generate_cli.py +++ b/tests/cli/test_generate_cli.py @@ -356,7 +356,8 @@ class TestToolFunctionSource: ) source = _tool_function_source(tool) # Default should be JSON string, not Python dict - assert '= \'{"timeout": 30, "retry": true}\'' in source + # pydantic_core.to_json produces compact JSON + assert '= \'{"timeout":30,"retry":true}\'' in source # Should parse safely even with default assert "isinstance(options, str)" in source compile(source, "", "exec")