Skip to content

fix(models): mark failed MCP tool results as errors for Claude - #7665

Closed
AkshayShah03 wants to merge 1 commit into
google:mainfrom
AkshayShah03:fix/anthropic-tool-result-content
Closed

AkshayShah03 wants to merge 1 commit into
google:mainfrom
AkshayShah03:fix/anthropic-tool-result-content

Conversation

@AkshayShah03

Copy link
Copy Markdown
Contributor

Link to Issue or Description of Change

1. Link to an existing issue (if applicable):

Problem:
_part_to_message_block in anthropic_llm.py builds every tool_result block with is_error=False. When an MCP server reports a failed call (CallToolResult.isError), McpTool passes that result on, and Claude receives the error text as a successful result.

Solution:
Set is_error from the function response's isError flag, also accepting is_error (the MCP SDK 2.x field name), the same two spellings McpTool._detect_error_in_response reads. Everything else in the block is unchanged.

The question in #7664 about content responses dropping sibling keys is left out of this PR.

Testing Plan

Unit Tests:

  • I have added or updated unit tests for my change.
  • All unit tests pass locally.

Added test_part_to_message_block_marks_mcp_error_result_as_error (parametrized for isError and is_error) to tests/unittests/models/test_anthropic_llm.py. Both cases fail on main (is_error is False) and pass with this change. The existing tests that assert not result["is_error"] for successful results still pass.

$ pytest tests/unittests/models/test_anthropic_llm.py
186 passed

$ pytest -n auto tests/unittests/models tests/unittests/tools/mcp_tool tests/unittests/flows
3250 passed, 4 failed

The 4 failures are test_google_llm.py::test_generate_content_async_leaves_continuation_to_sdk, which also fail on main in my environment (google-genai 2.29; that feature needs a newer SDK).

pyink and isort report no changes.

Manual End-to-End (E2E) Tests:

Ran the snippet from #7664 (an MCP CallToolResult dump with isError: true through part_to_message_block):

  • on main: 'file not found: notes.txt' is_error = False
  • with this change: 'file not found: notes.txt' is_error = True

Checklist

  • I have read the CONTRIBUTING.md document.
  • I have performed a self-review of my own code.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes.
  • I have manually tested my changes end-to-end.
  • Any dependent changes have been merged and published in downstream modules.

AnthropicLlm hardcoded is_error=False on every tool_result block, so a
CallToolResult with isError reached Claude as a successful result. Read
the flag (isError, or is_error in MCP SDK 2.x dumps) instead.

Fixes google#7664
copybara-service Bot pushed a commit that referenced this pull request Oct 22, 2026
Merge #7665

AnthropicLlm now sends a tool_result with is_error set when the function
response carries a truthy isError or is_error key, as a failed MCP
CallToolResult does; it previously always sent it as false.

Fixes #7664

PiperOrigin-RevId: 1005107381
@adk-bot

adk-bot commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

Thank you @AkshayShah03 for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit 37b1ab3.

Closing this PR as the changes are now in the main branch.

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

Labels

merged [Status] This PR is merged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AnthropicLlm sends failed MCP tool results to Claude with is_error=False

3 participants