Spaces:
Running
Running
Merge pull request #379 from strawgate/fix-tool-serializer
Browse files
src/fastmcp/tools/tool.py
CHANGED
|
@@ -192,7 +192,7 @@ def _convert_to_content(
|
|
| 192 |
other_content.append(item)
|
| 193 |
if other_content:
|
| 194 |
other_content = _convert_to_content(
|
| 195 |
-
other_content, _process_as_single_item=True
|
| 196 |
)
|
| 197 |
|
| 198 |
return other_content + mcp_types
|
|
|
|
| 192 |
other_content.append(item)
|
| 193 |
if other_content:
|
| 194 |
other_content = _convert_to_content(
|
| 195 |
+
other_content, serializer=serializer, _process_as_single_item=True
|
| 196 |
)
|
| 197 |
|
| 198 |
return other_content + mcp_types
|
tests/tools/test_tool_manager.py
CHANGED
|
@@ -443,6 +443,34 @@ class TestCallTools:
|
|
| 443 |
assert isinstance(result[0], TextContent)
|
| 444 |
assert result[0].text == 'CUSTOM:{"key": "value", "number": 123}'
|
| 445 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 446 |
async def test_custom_serializer_fallback_on_error(self):
|
| 447 |
"""Test that a broken custom serializer gracefully falls back."""
|
| 448 |
|
|
|
|
| 443 |
assert isinstance(result[0], TextContent)
|
| 444 |
assert result[0].text == 'CUSTOM:{"key": "value", "number": 123}'
|
| 445 |
|
| 446 |
+
async def test_call_tool_with_list_result_custom_serializer(self):
|
| 447 |
+
"""Test that a custom serializer provided to FastMCP is used by tools that return lists."""
|
| 448 |
+
|
| 449 |
+
def custom_serializer(data: Any) -> str:
|
| 450 |
+
if isinstance(data, list):
|
| 451 |
+
return f"CUSTOM:{json.dumps(data)}"
|
| 452 |
+
return json.dumps(data)
|
| 453 |
+
|
| 454 |
+
mcp = FastMCP(tool_serializer=custom_serializer)
|
| 455 |
+
manager = mcp._tool_manager
|
| 456 |
+
|
| 457 |
+
def get_data() -> list[dict]:
|
| 458 |
+
return [
|
| 459 |
+
{"key": "value", "number": 123},
|
| 460 |
+
{"key": "value2", "number": 456},
|
| 461 |
+
]
|
| 462 |
+
|
| 463 |
+
manager.add_tool_from_fn(get_data)
|
| 464 |
+
|
| 465 |
+
result = await manager.call_tool("get_data", {})
|
| 466 |
+
assert isinstance(result, list)
|
| 467 |
+
assert len(result) == 1
|
| 468 |
+
assert isinstance(result[0], TextContent)
|
| 469 |
+
assert (
|
| 470 |
+
result[0].text
|
| 471 |
+
== 'CUSTOM:[{"key": "value", "number": 123}, {"key": "value2", "number": 456}]'
|
| 472 |
+
)
|
| 473 |
+
|
| 474 |
async def test_custom_serializer_fallback_on_error(self):
|
| 475 |
"""Test that a broken custom serializer gracefully falls back."""
|
| 476 |
|