MCP tool call log does not mark alias calls
Background
Handlers::CallTool logs tool_name as the caller sent it
(tool_name = params[:name], before Manager#resolve_alias runs), so mcp.log already
carries alias usage. What it does not carry is any indication that a name was an alias, or
what it resolved to. Reading the logs requires knowing the alias map from memory.
#629245 is the concrete cost:
that analysis had to know semantic_code_search is an alias of semantic_search in order to
see that both rows were the same defect. Came up while reviewing
!255111 (merged), which makes
tools/list resolve aliases the same way tools/call already did.
Current behavior
event_name: tool_call records tool_name: "semantic_code_search" with nothing to
distinguish it from a canonical tool name. Finding all legacy-name traffic means querying
each alias individually, from a list held outside the logs.
Expected behavior
When the name the caller sent resolves to a different tool, the log line also carries the
canonical name. The field is absent for canonical calls, so its presence alone identifies
alias traffic and _exists_: json.canonical_tool_name becomes the "all legacy alias calls"
filter.
Implementation plan
-
In
CallTool#log_tool_call, resolve the name and add the field only when it differs:canonical_name = manager.resolve_alias(tool_name) logger.conditional_info( current_user, ... tool_name: tool_name, **(canonical_name == tool_name ? {} : { canonical_tool_name: canonical_name }), ... )alias_mapis memoized on the manager andtoolsis already built by the time we log, on both the success and theToolNotFoundErrorpath, so this is a hash lookup. Canonical calls get no extra field, so log volume is unchanged for almost all traffic. -
Do not repurpose
tool_nameto hold the canonical name instead. It is an indexed field with existing queries against it (including #629245's tables), and changing its meaning would silently empty them. A new field breaks nothing. -
Specs for both cases: an alias call logs
canonical_tool_name, a canonical call does not.
Out of scope: the EE internal events (track_start_event / track_finish_event) if we also
want this dimension in Snowflake, and the tools/list header side, where alias names arrive
by design from preapproved_tools_from_annotations and are not logged at all.
Relevant code
lib/api/mcp/handlers/call_tool.rb—tool_namecapture (line 24) andlog_tool_callapp/services/mcp/tools/manager.rb—resolve_alias,alias_maplib/gitlab/mcp/logger.rb—conditional_info, which fields are always indexed