Skip to content

fix(cursor): client tool calls from Claude Code 2.1.30x never reach the client — model narrates failures instead #7609

Closed as not planned

Description

@danieltao118

Follow-up to #6640. With Claude Code 2.1.30x (tested 2.1.304) on a Cursor-backed model (cursor/claude-opus-5-5) via /v1/messages, no tool call ever reaches the client: the CC transcript contains zero tool_use blocks while the model narrates tool failures in text. All other providers on the same gateway (OpenAI, GLM, xAI) work fine from the same client.

Summary

Claude Code 2.1.30x advertises a new-generation toolset — Agent, TodoWrite, ToolSearch, AskUserQuestion, EnterPlanMode, ExitPlanMode, SendMessage, Skill, ListAgents. The bare-name preservation added in #6640 (CLAUDE_CLIENT_BARE_TOOL_NAMES, src/adapters/cursor/tool-naming.ts) still lists only the pre-2.x names (Task, Todo, EnterMode, ExitMode, GetDynamicTools, …). The new names are therefore absent from the list, so isCursorBareClientToolWireAliased → cursorToolWireName prefixes them with ocx_client_ (CURSOR_CLIENT_TOOL_WIRE_PREFIX, same file) while the old names stay bare.

The result is a self-contradictory catalog on the Cursor wire: the model's system prompt describes one tool list while its function definitions use mixed naming. Per the mechanism #6640 established, the model falls back to Cursor-native execution frames; the proxy answers with the cursorNativeExecRedirectHint denial ("re-issue through ocx_client_* … do not narrate"), which frontier Claude models treat as a prompt-injection directive: they refuse to execute and narrate the refusal instead. The client then receives a text-only turn with no tool_use at all.

The root cause is on the proxy side: the same request shape sent directly to the gateway with classic full tool definitions returns tool_use correctly, so the break is in the cursor adapter's tool-naming step, not in the Cursor upstream and not in the gateway generally.

Evidence

  • Real CC session (2026-10-22): 10 assistant events, 0 tool_use blocks. The model's thinking states verbatim: "There's a mismatch between the tools listed and what's actually available in my function definitions, so I can't call things like Bash, Edit, or ocx_client" — naming the proxy's own wire prefix.
  • After the failed attempts the model reports being redirected toward ocx_client_PowerShell / ocx_client_Agent — i.e. the renamed/prefixed namespace, denied because nativeLocalExec is off.
  • Isolation experiment: replaying the same conversation history via direct curl to /v1/messages with classic full tool definitions (including the new names) returns tool_use correctly. Seven request-shape variants all pass through the same path — streaming, thinking, {"type":"adaptive"} thinking, the full beta list, 128k max_tokens, poisoned history, CLAUDE_CODE_INLINE_TOOLS=1 — so the failure is specific to what the real CC client sends, most likely (unverified) how its deferred/ToolSearch-era tool declaration interacts with the adapter.

Repro

claude -p "Use the Read tool to read <any file>, then quote its first line." \
  --model cursor/claude-opus-5-5 --allowedTools "Read"

CC points at the gateway via ANTHROPIC_BASE_URL=http://127.0.0.1:10100 with the cursor provider enabled (PKCE login). Expected: tool_use blocks surface to the client and Read executes client-side. Actual: a text-only turn narrating that native Read/Shell are unavailable and suggesting ocx_client_* tools; the transcript contains no tool_use.

  • Windows 11 build 26200, Claude Code 2.1.304, opencodex 2.90.0 and 2.91.0 (latest at time of writing — both reproduce); first observed on 2.86.0.

Suggested fix

  • Extend the bare-name preservation to the current Claude Code toolset — ideally version-adaptive rather than a hardcoded list; and/or
  • Register deferred client tools declared via ToolSearch/advanced-tool-use so cursorToolAllowedByChoice and the catalog budget see them on the cursor wire.

Related: #7452, #7453 (tool discovery). Happy to provide full session jsonl excerpts and curl payloads.

Activity

  1. github-actions commented on Oct 23, 2026

    @github-actions
    Contributor

    Issue closed: use an issue template

    Thanks for taking the time to submit this issue. It was closed automatically because it was not opened with a recognized issue template (Bug report, Feature request, Documentation, or Provider compatibility). Freeform and API-opened issues cannot skip this check.

    • This issue does not use a recognized issue template.

    Please edit the issue to add:

    • Open a new issue with the Bug report, Feature request, Documentation, or Provider compatibility template.
    • Or edit this issue so the body uses the template section headings for the kind of report you are filing.

    See the Contributing guide for details.

    Once the report passes the automated checks, it will be reopened automatically unless a maintainer has changed its state.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    toolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions