Skip to content

MCP: add transitional aliases for the gateway_ rename, and document the silent deny-rule failure #369

Description

@leggetter

Context

v3.0.0 renames every Gateway product tool from hookdeck_* to gateway_* (#352, epic #354).

The v3.0.0-beta.1 release notes already handle the out-of-band half of this well: a full old → new rename table, an explicit warning that per-tool permission grants and allowedTools entries do not survive a rename, and a recommendation to prefer server-scoped patterns like mcp__hookdeck__*.

What we do not have is any in-band handling. This issue covers the two gaps.

Gap 1: no transitional alias on tools/call

An agent that calls hookdeck_events after upgrading gets a JSON-RPC -32602 Unknown tool. The MCP spec draws a deliberate distinction here:

Clients MAY provide protocol errors to language models, though these are less likely to result in successful recovery.
Clients SHOULD provide tool execution errors to language models to enable self-correction.

So the one channel that can reach the model and get it to retry correctly is the one we are not using. Whatever is cached, hardcoded in a prompt, or written into an AGENTS.md hits a dead end with no pointer to the replacement.

Two options, either acceptable:

  1. Alias middleware on tools/call that maps hookdeck_* to the gateway_* equivalent, forwards the call, and appends a deprecation notice to the result. Keep aliases out of tools/list so we do not double the tool count or bloat context.
  2. Fail loudly but usefully: return a tool execution error (isError: true) naming the replacement rather than a protocol Unknown tool. Forces migration, but the agent is told where to go.

Worth noting we already do exactly this pattern on the CLI surface: cobra commands carry Aliases (pkg/cmd/event.go, destination.go, request.go and others) and connectionDeprecationNotice in pkg/cmd/connection.go prints a migration message on the deprecated path. The MCP tool surface never got the equivalent.

Note that a CLI-distributed MCP server has no URL to version, so there is no side-by-side v2/v3 migration path the way a remote server would have. An upgrade swaps the tool surface underneath the user with no seam, which is what makes the in-band alias worth more here than it would be elsewhere.

Gap 2: the release notes describe the annoying failure, not the dangerous one

The notes say grants will need re-approving. That is the allow case, and it fails closed: the user is prompted again and re-approves.

The deny case fails open and is worth calling out separately. From the Claude Code permissions docs:

A deny or ask rule whose tool name matches no known tool produces a startup warning to catch typos. Tool names containing _ or * are exempt from the check.

Every MCP tool name contains __ by construction (mcp__<server>__<tool>), so every MCP permission rule is exempt from that warning. A user who wrote mcp__hookdeck__hookdeck_events into a deny rule to block something has that guardrail silently stop matching after the rename, with no startup warning and nothing in the UI. That is a security note, not an ergonomics one, and it should be explicit in the release notes.

Suggested scope

  • Alias map for the hookdeck_*gateway_* renames, resolved at tools/call, absent from tools/list, with a deprecation notice on the result
  • Decide a removal version for the aliases and state it in the notice
  • Add the stale-deny-rule warning to the v3 release notes and upgrade docs
  • Audit for hardcoded old tool names in docs, READMEs, tests, and in the descriptions of other tools that reference their siblings
  • Check whether any analytics or dashboards key on MCP tool name, since a rename silently re-keys those without erroring

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions