Skip to content

Anthropic MCP PascalCase tool responses do not normalize to registered tool names #16817

@irispillars

Description

@irispillars

Bug Description

Anthropic tool responses that use Claude Code-shaped MCP tool names can fail Hermes tool dispatch when strip_tool_prefix=True.

A Claude Code / OAuth-shaped Anthropic route may return tool names like mcp_Terminal after outgoing Hermes tools are rewritten from lowercase MCP names such as mcp_terminal to PascalCase names such as mcp_Terminal.

Hermes currently strips the mcp_ prefix, but leaves the rest unchanged. That turns mcp_Terminal into Terminal, which does not match the registered Hermes tool name terminal.

Steps to Reproduce

Using AnthropicTransport.normalize_response(..., strip_tool_prefix=True) with a tool-use block named mcp_Terminal:

from types import SimpleNamespace
from agent.transports.anthropic import AnthropicTransport

block = SimpleNamespace(
    type="tool_use",
    id="toolu_terminal",
    name="mcp_Terminal",
    input={"command": "printf OPUS_TOOL_OK"},
)
response = SimpleNamespace(content=[block], stop_reason="tool_use")

normalized = AnthropicTransport().normalize_response(response, strip_tool_prefix=True)
assert normalized.tool_calls[0].name == "terminal"

Expected Behavior

mcp_Terminal should normalize to the registered Hermes tool name:

terminal

Likewise, PascalCase Claude Code-shaped MCP names should map back to the corresponding Hermes registered tool names after stripping the mcp_ prefix.

Actual Behavior

Before the local fix, mcp_Terminal normalized to:

Terminal

That misses the registered terminal tool and can break dispatch.

Proposed Fix

After stripping the mcp_ prefix in AnthropicTransport.normalize_response(..., strip_tool_prefix=True), lowercase the first remaining character if it is uppercase.

Example:

mcp_Terminal -> Terminal -> terminal

This preserves existing lowercase behavior while supporting Claude Code-shaped PascalCase tool names.

Local Verification

Local patch/regression was verified in Hermes:

  • Regression: mcp_Terminal normalizes to terminal.
  • Tool-shape matrix: 11/11 PascalCase mcp_ response names normalized back to registered Hermes tools.
  • Focused tests: 22 passed locally.

Related Note

This does not promote or install any admin/OAuth route. It only hardens Anthropic response normalization for Claude Code-shaped mcp_ tool names.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/acpAgent Communication Protocol adaptercomp/agentCore agent loop, run_agent.py, prompt builderprovider/anthropicAnthropic native Messages APItool/mcpMCP client and OAuthtype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions