Skip to content

fix(v1): bump mcp to 2.2.0 and keep tool exception text for the model - #2982

Merged
hallerite merged 3 commits into
mainfrom
fix/mcp-tool-error-text
Oct 26, 2026
Merged

hallerite merged 3 commits into
mainfrom
fix/mcp-tool-error-text

Conversation

@hallerite

@hallerite hallerite commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Summary

Bumps mcp 2.0.0 → 2.2.0 (dependabot's commit from #2878, unchanged) and fixes the one behavior change in that range that silently affects our tasksets.

Since mcp 2.1.0 (modelcontextprotocol/python-sdk#3314), MCPServer treats any exception a tool raises, other than ToolError/MCPError, as a crash. The client then gets only Error executing tool <name>, without the exception text. Our tools raise to tell the model what went wrong (an unknown id, an invalid argument), so on 2.2.0 the model would lose that feedback:

tool raises ValueError("Order A-17 not found") tool result the model sees
mcp 2.0.0 Error executing tool lookup: Order A-17 not found
mcp 2.2.0 Error executing tool lookup
mcp 2.2.0 + this PR Error executing tool lookup: Order A-17 not found

ServerBase._with_state now re-raises a tool's own exception as ToolError, the channel upstream keeps for messages meant for the model. That keeps the 2.0 text byte-for-byte, and the server logs one INFO line instead of a traceback. This covers every @vf.tool and every add_tool(self._with_state(...)) registration. Toolsets that replace MCPServer.call_tool directly (Harbor, NeMo Gym) already kept their messages.

Nothing else in 2.1/2.2 affects us:

  • Idle-session expiry and the session cap apply only to stateful servers; ours run stateless_http=True.
  • The new same-origin redirect policy doesn't matter here: our server URLs are http://host:port/mcp and don't redirect.
  • The PEP 723 chat programs keep their own mcp==2.0.0 pin, so they are unchanged here.

Supersedes #2878.

Testing

  • New integration cell test_tool_error in tests/integration/test_multi_turn_tool.py (tool-error fixture, runs in the Multi-Turn Tool job): the tool always raises a stamped message, and the reward is 1.0 only if the stamp reaches the trace. It fails on the bump alone (the tool message is Error executing tool lookup) and passes with the fix.
  • Ran locally on 2.2.0 with the fix:
    • echo-tool cells (test_tool null-in-prime, plus test_tool_placement with the tool colocated, in a Compose service, as a subprocess, and on its own Prime VM)
    • test_stateful_tool
    • test_shared_tool
    • tests/unit, ruff, ty

🤖 Generated with Claude Code


Note

Medium Risk
Touches MCP tool error handling on every state-wrapped tool path; behavior is intentional but changes what clients see for unexpected exceptions versus true server crashes.

Overview
Upgrades mcp from 2.0.0 to 2.2.0 and restores behavior where tool exception messages reach the model. On MCP 2.1+, non-ToolError/MCPError failures are surfaced to clients as a generic “Error executing tool …” without the original message; task tools often raise ValueError (etc.) so the model can recover.

ServerBase._with_state in verifiers/v1/mcp/server.py now catches exceptions from wrapped tool calls and re-raises them as ToolError(str(e)), while leaving existing ToolError/MCPError unchanged—so @vf.tool and state-wrapped registrations keep the prior error text.

Adds integration coverage: tool-error fixture (tests/integration/fixtures/tool_error.py) with a reward that checks a secret token appears in tool messages, plus test_tool_error in test_multi_turn_tool.py.

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

Note

Keep tool exception text for the model in ServerBase tool calls and bump MCP to 2.2.0

  • Bumps the pinned MCP dependency in pyproject.toml from 2.0.0 to 2.2.0 and updates uv.lock.
  • Wraps tool execution in server.py so unexpected exceptions become ToolError results carrying the exception text; existing ToolError and MCPError are re-raised unchanged.
  • Adds a tool_error integration fixture and test in test_multi_turn_tool.py that gives full reward when the exception text reaches the recorded tool messages.
  • Behavioral Change: tools that previously raised an unhandled exception now surface as ToolError results instead; state sync only runs after successful execution.

Macroscope summarized ef809b5.

dependabot Bot and others added 3 commits October 26, 2026 09:19
Bumps [mcp](https://github.com/modelcontextprotocol/python-sdk) from 2.0.0 to 2.2.0.
- [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases)
- [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md)
- [Commits](modelcontextprotocol/python-sdk@v2.0.0...v2.2.0)

---
updated-dependencies:
- dependency-name: mcp
  dependency-version: 2.2.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
mcp 2.1 (modelcontextprotocol/python-sdk#3314) treats any exception from a
tool other than ToolError/MCPError as a crash and sends the client only
"Error executing tool <name>". Our tools raise to tell the model what went
wrong (e.g. general-agent's "Order X not found"), so re-raise those as
ToolError in the toolset wrapper, which keeps the 2.0 text exactly.

Adds a tool-error integration cell: a tool that raises a stamped message,
rewarded only if the stamp reaches the trace.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The integration matrix lists its files, so a new file would not run in CI.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@macroscopeapp

macroscopeapp Bot commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at ef809b5

Macroscope's review found this PR approvable — This is a focused MCP error-propagation fix with a pinned dependency update and an integration regression test. Runtime behavior changes only to preserve unexpected tool exception text for the model, with no broader workflow or schema impact.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

You can add or adjust custom eligibility rules. Learn more.

@mikasenghaas mikasenghaas left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

separate integration seems like quite a lot but sure

@hallerite
hallerite merged commit 6b0356e into main Oct 26, 2026
61 of 63 checks passed
@hallerite
hallerite deleted the fix/mcp-tool-error-text branch October 26, 2026 10:14
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.

2 participants