Conversation
…criptions The existing ^mcp_[^_] → Mcp_X tool-name rewrite (diegosouzapw#2165) dodged Anthropic's MCP-connector billing gate but left every textual reference to those names unchanged in the system prompt and tool descriptions. Models then saw an inconsistent catalog : the prompt says "use mcp_call", the tool list only contains `Mcp_call`. Result : the model gave up on tool-calling and fell back to plain text — which Anthropic-SDK clients (Capy, claude-cli) render as a reasoning trace rather than a normal message. Apply the same regex transformation to all textual references in the top-level `system` blocks and `tools[*].description`. Skip message content blocks — those carry user-supplied text we shouldn't mutate. The text-replace regex is `\bmcp_(?=[^_\s])` so it only touches the same forms the tool-name rewrite touches : preserves `mcp__double_underscore`, `my_mcp_helper`, and other non-gate-triggering shapes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request introduces logic to ensure consistency between tool names and their textual references in system prompts and tool descriptions. It adds a regex-based transformation that converts 'mcp_' prefixes to 'Mcp_' within the system prompt and tool descriptions when MCP tools are being used, preventing potential tool-calling failures due to naming mismatches. Comprehensive unit tests were included to verify the transformation logic, handle various system prompt formats, and ensure that user-supplied message content is preserved. I have no feedback to provide as there were no review comments.
|
Closing after 2026-05-12 empirical bisect. This PR added two transformations to align model perception of
Bisect against live Anthropic via CPA cloak (Claude Opus 4.7, full Capy body with 24 tools incl.
Fork-side: NomenAK/OmniRoute@cleanup/remove-over-engineered-strips contains the name-only rewrite via commit 3166060 ("drop mcp_ prose rewrite, keep name-only rewrite"). If upstream wants the name-only rewrite as a clean standalone PR, happy to open one — let me know. |
Summary
Follow-up to #2165 (Anthropic-shape body routing and
^mcp_[^_]tool-name rewrite). The original rewrite renamed the tools but left every textual reference to those names unchanged in the system prompt and tool descriptions. The model then reads a prompt that says "use `mcp_call`" while the tool catalog only contains `Mcp_call` — it cannot match the name, gives up on tool-calling, and falls back to plain-text responses.Anthropic-SDK clients (Capy, claude-cli) render plain text outside of designated message tools as a reasoning trace, so the response visibly lands in the "Thought" panel rather than as a normal assistant message. The fix here closes that loop.
Related Issues
Motivation
Captured live artifact (Capy /v1/messages → OmniRoute → cliproxyapi → Anthropic, 2026-05-12) :
```
// providerRequest (post-#2165 rewrite)
tools: [
{ name: "Mcp_query", description: "Discover MCP tools via mcp_query. Use before mcp_call." },
{ name: "Mcp_call", description: "..." }
]
system: [{ text: "ALWAYS use mcp_query first to discover available tools, THEN use mcp_call." }]
```
```
// providerResponse — Claude does NOT use any tool, emits plain text
content: [{ type: "text", text: "Test received. What would you like me to do?" }]
stop_reason: "end_turn"
```
Same body shape with this PR applied :
```
// providerRequest (post-#2165 + this PR)
tools: [
{ name: "Mcp_query", description: "Discover MCP tools via Mcp_query. Use before Mcp_call." },
{ name: "Mcp_call", description: "..." }
]
system: [{ text: "ALWAYS use Mcp_query first... THEN use Mcp_call." }]
```
```
// providerResponse — Claude correctly uses the tool
content: [{ type: "tool_use", id: "...", name: "Mcp_query", input: {...} }]
stop_reason: "tool_use"
```
(Response-side tool name is restored to the client's original namespace by the existing reverse-map mechanism — Capy sees `mcp_query` back in `tool_use` blocks, no client-visible change.)
Changes
`open-sse/executors/cliproxyapi.ts` :
Regex shape — edge cases handled (covered by tests)
Validation
🤖 Generated with Claude Code