Skip to content

Add isError support for non-text tool results (Fixes #348) - #3370

Closed
mukktinaadh wants to merge 2 commits into
modelcontextprotocol:mainfrom
mukktinaadh:main
Closed

Add isError support for non-text tool results (Fixes #348)#3370
mukktinaadh wants to merge 2 commits into
modelcontextprotocol:mainfrom
mukktinaadh:main

Conversation

@mukktinaadh

Copy link
Copy Markdown

Summary

This PR addresses issue #348 by adding support for returning tool errors with non-text content (images, audio, structured data) without raising exceptions.

Changes

Core Changes (src/mcp-types/mcp_types/_types.py and version-specific models)

  • Added CallToolResult.create_error() classmethod for creating error results with non-text content
  • Added model_validator to auto-convert SDK Image/Audio helpers to their wire content types (ImageContent, AudioContent)

Server Integration (src/mcp/server/mcpserver/utilities/func_metadata.py)

  • Updated convert_result to handle Image/Audio helpers when passed directly in CallToolResult.content

Tests (tests/server/mcpserver/tools/test_base.py)

  • Added tests for image, audio, and structured content error results

Usage Example

from mcp.server.mcpserver import MCPServer
from mcp.server.mcpserver.utilities.types import Image
from mcp.types import CallToolResult

mcp = MCPServer("test")

@mcp.tool()
async def my_tool() -> CallToolResult:
    # Return an image error directly!
    img = Image(data=b"...", format="png")
    return CallToolResult.create_error(content=[img])

@mcp.tool()
async def structured_error() -> CallToolResult:
    return CallToolResult.create_error(
        content=[TextContent(type="text", text="Invalid input")],
        structured_content={"error_code": "INVALID_INPUT", "details": {"field": "email"}},
    )

Backwards Compatibility

  • Existing code using CallToolResult with is_error=True continues to work
  • The auto-conversion only applies when helper objects are detected (no breaking changes)

Testing

All 5,747 existing tests pass + 3 new tests added for the new functionality.

…lback

- Add new  callback to ClientSession and Client
  for handling transport-level exceptions (timeouts, connection errors)
- Update  to use the new handler with fallback to
   for backwards compatibility
- Make default  log transport exceptions at ERROR level
- Add tests for the new callback and fallback behavior

Fixes modelcontextprotocol#1401
…ocol#348)

- Add CallToolResult.create_error() classmethod for convenient error results with non-text content
- Add model_validator to auto-convert SDK Image/Audio helpers to wire content types
- Allow Image/Audio helpers directly in CallToolResult.content
- Add tests for image, audio, and structured content error results
@github-actions github-actions Bot added the missing-issue-link Auto-closed: PR needs a linked issue assigned to its author (see CONTRIBUTING.md) label Aug 23, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Thanks for the contribution. This repository only keeps pull requests open when they're linked to an issue that a maintainer has assigned to the author — CONTRIBUTING.md explains why and how we work. This PR has been closed for now because its description doesn't yet link an open issue in this repository (with Fixes #123 or similar).

If there isn't an issue for this yet, please open one — a clear description of the problem is genuinely the most useful thing for us. Then add Fixes #<number> to this PR's description. If a maintainer would like the change as a PR from you, they'll assign you to the issue and this PR will reopen automatically.

There's no need to open a new PR — this one will be reopened. While it's closed, please push any updates as new commits rather than force-pushing, since GitHub can't reopen a PR whose branch has been rewritten.

Maintainers: reopening this PR, removing the missing-issue-link label, or adding bypass-issue-check bypasses the check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

missing-issue-link Auto-closed: PR needs a linked issue assigned to its author (see CONTRIBUTING.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant