Add optional content parameter to ToolError for rich error responses
Closed
SU
2mo ago+132+132+012345678901234567890123456789-10-10-01234567890123456789
Summary
Fixes #348.
Adds an optional content keyword argument to ToolError, allowing tool implementations to return rich error responses (images, structured data) alongside error messages — matching what the MCP protocol already supports in CallToolResult.
Changes
src/mcp/server/mcpserver/exceptions.py
- Added
content: list[ContentBlock] | Noneattribute toToolError - Added
__init__with optionalcontentkwarg (defaults toNone)
src/mcp/server/mcpserver/server.py
- In
_handle_call_tool: when a caughtToolErrorhascontent, uses it directly inCallToolResultinstead of wrappingstr(exc)as text - Falls back to existing behavior when
contentisNone
src/mcp/server/mcpserver/tools/base.py
- Preserves
contentattribute through the re-raise inTool.run()(was lost when wrapping the error message with tool name)
tests/server/mcpserver/test_server.py
- 4 new tests: rich content round-trip, backward compatibility with plain string, content preservation through
call_tool(), logging behavior unchanged
Backward compatibility
Zero breaking changes. raise ToolError("msg") works exactly as before — content defaults to None and the existing text-wrapping path runs.
Usage
raise ToolError(
"rendering failed",
content=[
TextContent(type="text", text="partial render completed"),
ImageContent(type="image", data=b64_png, mimeType="image/png"),
],
)
Test plan
- All 170 existing tests pass
- 4 new tests cover the feature, backward compatibility, propagation, and logging
- Ruff and pyright clean