Skip to content

feat: preserve CallToolResult.isError flag in MCPToolResult#1943

Open
Exploreunive wants to merge 1 commit intostrands-agents:mainfrom
Exploreunive:fix/preserve-mcp-tool-result-iserror
Open

feat: preserve CallToolResult.isError flag in MCPToolResult#1943
Exploreunive wants to merge 1 commit intostrands-agents:mainfrom
Exploreunive:fix/preserve-mcp-tool-result-iserror

Conversation

@Exploreunive
Copy link

What

The isError flag from MCP's CallToolResult is now preserved in the framework's MCPToolResult, enabling consumers to distinguish between:

  • Application errors (tool executed but reported failure via CallToolResult.isError=True)
  • Protocol/client errors (exception during execution)

Previously, both error types ended up as status="error" with no way to tell them apart.

Changes

  • Added isError: NotRequired[bool] to MCPToolResult TypedDict in mcp_types.py
  • _handle_tool_result() now propagates isError from the MCP CallToolResult
  • _handle_tool_execution_error() sets isError=True for execution exceptions

How to test

pytest tests/strands/tools/mcp/test_mcp_client.py -x -q

All 53 tests pass (including new assertions for isError in both success/error and exception scenarios).

Fixes

Fixes #1670

Addresses review feedback from strands-agents#1943:

1. **Clean split**: Only isError-related changes, no unrelated commits from
   AgentResult.text (PR strands-agents#1942) or other work.

2. **isError propagation**: MCPToolResult now exposes isError field:
   - True when MCP server reports CallToolResult.isError (application error)
   - True when a Python exception occurs during tool execution (protocol error)
   - False/absent on success
   Updated docstring clarifies both error sources.

3. **Exception propagation** (maintainer feedback from strands-agents#1670):
   MCPAgentTool.stream() now passes the original exception via
   ToolResultEvent(result, exception=e), matching the pattern used by
   decorated tools. Added _invoke_tool() helper that calls the MCP client
   internals directly to capture exceptions.

Files changed:
- mcp_types.py: Added isError: NotRequired[bool], updated docstring
- mcp_client.py: Propagated isError in _handle_tool_result and
  _handle_tool_execution_error
- mcp_agent_tool.py: Added _invoke_tool() for exception capture,
  stream() yields ToolResultEvent(result, exception=...)
- Tests: Added isError assertions, exception propagation tests
@Exploreunive Exploreunive force-pushed the fix/preserve-mcp-tool-result-iserror branch from e8d89a9 to afc5a74 Compare March 21, 2026 01:01
@github-actions github-actions bot added size/m and removed size/m labels Mar 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Preserve CallToolResult.isError flag in MCPToolResult to distinguish application errors from protocol errors

1 participant