Skip to content

Commit 3b41caf

Browse files
committed
fix(server): skip output schema validation for tool errors
1 parent 73d458b commit 3b41caf

2 files changed

Lines changed: 15 additions & 1 deletion

File tree

src/mcp/server/fastmcp/utilities/func_metadata.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def convert_result(self, result: Any) -> Any:
112112
the structured output.
113113
"""
114114
if isinstance(result, CallToolResult):
115-
if self.output_schema is not None:
115+
if self.output_schema is not None and not result.isError:
116116
assert self.output_model is not None, "Output model must be set if output schema is defined"
117117
self.output_model.model_validate(result.structuredContent)
118118
return result

tests/server/fastmcp/test_func_metadata.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,20 @@ def func_returning_annotated_tool_call_result() -> Annotated[CallToolResult, Per
878878
meta.convert_result(func_returning_annotated_tool_call_result())
879879

880880

881+
def test_tool_call_result_annotated_error_skips_structured_validation():
882+
class PersonClass(BaseModel):
883+
name: str
884+
885+
def func_returning_annotated_tool_call_result_error() -> Annotated[CallToolResult, PersonClass]: # pragma: no cover
886+
return CallToolResult(content=[], isError=True)
887+
888+
meta = func_metadata(func_returning_annotated_tool_call_result_error)
889+
result = func_returning_annotated_tool_call_result_error()
890+
891+
assert meta.output_schema is not None
892+
assert meta.convert_result(result) is result
893+
894+
881895
def test_tool_call_result_in_optional_is_rejected():
882896
"""Test that Optional[CallToolResult] raises InvalidSignature"""
883897

0 commit comments

Comments
 (0)