Skip to content

Preserve MCP tool error outcomes#2138

Open
xeophon wants to merge 2 commits into
agent/fix-mcp-session-lifecyclefrom
agent/preserve-mcp-tool-errors
Open

Preserve MCP tool error outcomes#2138
xeophon wants to merge 2 commits into
agent/fix-mcp-session-lifecyclefrom
agent/preserve-mcp-tool-errors

Conversation

@xeophon

@xeophon xeophon commented Jul 26, 2026

Copy link
Copy Markdown
Member

Overview

Preserves MCP tool-declared outcome semantics across harness execution, typed messages, traces, replay, and provider conversion.

This PR follows #2134 in a native GitHub pull request stack. #2134 owns the shared null/bash MCP client and its session lifecycle and replay-safety behavior.

Details

MCP CallToolResult contains both model-visible content and an isError outcome. The shared MCP client now returns both values, and the harness program carries the outcome into ToolMessage.is_error.

The typed outcome participates in graph identity and trace serialization, so success and failure results with identical content remain distinguishable after persistence and resume.

For chat-compatible providers, the localhost harness handoff uses a private marker that is removed before the provider request while adding a readable failure label to the model-visible content. Anthropic-native tool_result.is_error maps directly into the same typed representation.


Note

Medium Risk
Touches message serialization, eval apply_overrides, and graph identity; behavior changes for tool failures on chat providers (prefixed content) but is scoped to error semantics rather than core auth or data paths.

Overview
Adds ToolMessage.is_error so MCP and harness tool failures are typed end-to-end, not only as text in content.

MCP → harness: call_mcp now returns (content, isError) from CallToolResult; the bash/null program sets a private _vf_is_error marker on tool wire messages and passes messages through extra_body so interception keeps that field.

Chat providers: message_to_wire strips the private marker before upstream requests and prefixes model-visible content with Tool execution failed:\n on errors; internal handoff (initial-messages JSON) uses include_internal=True to round-trip the flag. apply_overrides re-serializes messages that still carry the marker so eval overrides don’t leak private fields to the API.

Anthropic: tool_result.is_error maps into the same is_error field on parse.

Traces / replay: message_hash includes error vs success so identical tool bodies dedupe differently after persist/resume.

Reviewed by Cursor Bugbot for commit 47ea576. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Preserve MCP tool error outcomes across the message pipeline

  • Adds is_error: bool = False to ToolMessage in types.py to carry tool failure status through the message model.
  • Updates mcp_client.py so call_mcp returns a (content, is_error) tuple, and program.py propagates that flag via the internal _vf_is_error key on tool messages.
  • Updates chat.py to parse, serialize, and rewrite tool error markers: message_to_wire prefixes errored content with a human-visible banner unless include_internal=True, and ChatDialect.apply_overrides strips internal markers before forwarding requests upstream.
  • Updates anthropic.py to set is_error when parsing Anthropic tool_result blocks.
  • Behavioral Change: tool messages with identical content but different error status now produce different hashes in message_hash.

Macroscope summarized 47ea576.

@macroscopeapp

macroscopeapp Bot commented Jul 26, 2026

Copy link
Copy Markdown

Approvability

Verdict: Needs human review

This PR propagates MCP tool error state through the message pipeline, changing function signatures, message formatting (adding 'Tool execution failed:' prefix), and message hash computation. These runtime behavior changes, particularly the hash modification that could affect caching/deduplication, warrant human review.

You can customize Macroscope's approvability policy. Learn more.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1e47ec2. Configure here.

Comment thread verifiers/v1/harnesses/bash/program.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant