Skip to content

fix(models): mark failed MCP tool results as errors on the interactions API - #7825

Closed
adityasingh2400 wants to merge 1 commit into
google:mainfrom
adityasingh2400:fix/interactions-mcp-tool-errors
Closed

adityasingh2400 wants to merge 1 commit into
google:mainfrom
adityasingh2400:fix/interactions-mcp-tool-errors

Conversation

@adityasingh2400

Copy link
Copy Markdown
Contributor

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

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

Problem:
_convert_part_to_interaction_content set is_error on a function_result step only when the function response had an error key. A failed MCP CallToolResult reports the failure with isError (is_error in MCP SDK 2.x dumps) and has no error key, so on the Interactions API Gemini was told that a failed MCP tool call succeeded.

Solution:
Also treat a truthy isError or is_error in the response dict as an error. This matches what AnthropicLlm does since #7665. Responses with an error key behave as before, and the result payload is still passed through unchanged.

Testing Plan

Unit Tests:

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

Added to tests/unittests/models/test_interactions_utils.py, each parametrized over isError and is_error:

  • test_function_response_failed_mcp_result_is_error
  • test_function_response_successful_mcp_result_is_not_error
# On main (before the fix)
test_function_response_failed_mcp_result_is_error[isError]   assert False is True
test_function_response_failed_mcp_result_is_error[is_error]  assert False is True

# With the fix
$ pytest tests/unittests/models/test_interactions_utils.py tests/unittests/models/test_google_llm.py
335 passed

pre-commit run passes on the changed files. mypy reports one error in interactions_utils.py (FunctionResultDelta has no attribute call_id), which is already on main and outside this change.

Manual End-to-End (E2E) Tests:

The test server is a real streamable-HTTP MCP server whose read_file tool raises, so it returns an isError: true result. A Runner drives an LlmAgent(model=Gemini("gemini-2.5-flash", use_interactions_api=True), tools=[McpToolset(StreamableHTTPConnectionParams(...))]). Only interactions_utils._create_interactions (the network call) is stubbed: it records create_kwargs["input"], asks for read_file on the first request, and answers on the second. The output below is the function_result step from the second request:

=== BEFORE (main) ===
function_result sent to Gemini: name=read_file is_error=False result='Error executing tool read_file'
=== AFTER (this PR) ===
function_result sent to Gemini: name=read_file is_error=True result='Error executing tool read_file'

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.

Additional context

None.

…ns API

_convert_part_to_interaction_content set is_error on a function_result
step only when the response had an error key. A failed MCP CallToolResult
reports the failure with isError (is_error in MCP SDK 2.x dumps), so Gemini
was told the failed call succeeded. Treat a truthy isError or is_error as
an error too, as AnthropicLlm already does.

Fixes google#7824
copybara-service Bot pushed a commit that referenced this pull request Oct 30, 2026
Merge #7825

A function response dict with a truthy `isError` or `is_error` and no `error` key, as a failed MCP CallToolResult produces, is now sent to the Interactions API with `is_error=True` instead of `False`, matching AnthropicLlm.

Part of #7824

PiperOrigin-RevId: 1010827537
@adk-bot

adk-bot commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator

Thank you @adityasingh2400 for your contribution! 🎉

Your changes have been successfully imported and merged via Copybara in commit 72205cd.

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.

Failed MCP tool results are sent to the Interactions API with is_error=False

3 participants