Skip to content

fix(opencode): match MCP tool calls case- and hyphen-insensitively at dispatch#31514

Open
sqeeswy wants to merge 1 commit into
anomalyco:devfrom
sqeeswy:fix/mcp-tool-name-dispatch
Open

fix(opencode): match MCP tool calls case- and hyphen-insensitively at dispatch#31514
sqeeswy wants to merge 1 commit into
anomalyco:devfrom
sqeeswy:fix/mcp-tool-name-dispatch

Conversation

@sqeeswy

@sqeeswy sqeeswy commented Jun 9, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #31506
Closes #27396

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

MCP tools are registered with case- and hyphen-preserving names (mcp/index.ts: sanitize(client) + "_" + sanitize(tool)), e.g. Tool_get_prop or server_get-by-id. Models frequently emit a lowercased or all-underscore variant of the name. When that happens the AI SDK reports the call as unrecognized and hands it to experimental_repairToolCall in session/llm.ts. That repair only tried the lowercased form, so a capitalized-prefix tool (#31506) or a hyphenated tool called with underscores (#27396) never matched and every call routed to the invalid sentinel tool in a loop.

The fix adds repairToolName, which matches the failed name back to the registered key by normalizing both sides case-insensitively and treating - and _ as equivalent. If the normalization is ambiguous (more than one registered key collapses to the same form) it returns nothing, so the call still routes to invalid rather than guessing the wrong tool. This is the single client-side dispatch chokepoint, so it covers both issues without touching registration.

This is separate from #29156, which sanitizes genuinely malformed names (invalid characters) at the serialization boundary in message-v2.ts. This PR only normalizes well-formed names at dispatch; the two do not overlap.

How did you verify your code works?

From packages/opencode:

  • bun typecheck — clean
  • bun test test/session/llm.test.ts — 31 pass, 0 fail

Added unit tests for repairToolName covering both axes (case and hyphen/underscore), an exact match, an unknown name, and an ambiguous collision.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added the needs:compliance This means the issue will auto-close after 2 hours. label Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

One potentially related PR found:

PR #29156: fix(session): sanitize malformed tool names in pending parts

The other results are mostly unrelated tooling/schema fixes. The search for the specific issue numbers (#31506, #27396) that this PR fixes didn't return other open PRs.

Recommendation: Check if PR #29156 is still open and whether it addresses the same underlying problem or if they can be coordinated.

@github-actions github-actions Bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Jun 9, 2026
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

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

Labels

None yet

Projects

None yet

1 participant