Merge pull request #379 from strawgate/fix-tool-serializer

Fix tool result serialization when the tool returns a list
This commit is contained in:
Jeremiah Lowin 2025-05-08 22:30:15 -04:00 committed by GitHub
commit 748d6bd02f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 1 deletions

View file

@ -192,7 +192,7 @@ def _convert_to_content(
other_content.append(item)
if other_content:
other_content = _convert_to_content(
other_content, _process_as_single_item=True
other_content, serializer=serializer, _process_as_single_item=True
)
return other_content + mcp_types

View file

@ -443,6 +443,34 @@ class TestCallTools:
assert isinstance(result[0], TextContent)
assert result[0].text == 'CUSTOM:{"key": "value", "number": 123}'
async def test_call_tool_with_list_result_custom_serializer(self):
"""Test that a custom serializer provided to FastMCP is used by tools that return lists."""
def custom_serializer(data: Any) -> str:
if isinstance(data, list):
return f"CUSTOM:{json.dumps(data)}"
return json.dumps(data)
mcp = FastMCP(tool_serializer=custom_serializer)
manager = mcp._tool_manager
def get_data() -> list[dict]:
return [
{"key": "value", "number": 123},
{"key": "value2", "number": 456},
]
manager.add_tool_from_fn(get_data)
result = await manager.call_tool("get_data", {})
assert isinstance(result, list)
assert len(result) == 1
assert isinstance(result[0], TextContent)
assert (
result[0].text
== 'CUSTOM:[{"key": "value", "number": 123}, {"key": "value2", "number": 456}]'
)
async def test_custom_serializer_fallback_on_error(self):
"""Test that a broken custom serializer gracefully falls back."""