Map stored agent tool aliases to canonical names

What does this MR do and why?

A catalog agent stores the tool names it selected. When an MCP tool is renamed and its old name kept as an alias, McpConfigService#mcp_tools_for_agent dropped the stored old name, because it intersects the stored names against the server's canonical tool list and aliases aren't in it. The agent then ran without the tool, silently. This maps the stored names through Manager#resolve_alias before the intersection, so an aliased name resolves to its canonical tool and is retained.

Part of #606029 (closed) (MR A). Independent of MR B (!249676 (merged)); verifiable against the two aliases that already ship (gitlab_search, gitlab_merge_request_search).

Implementation details
  • Manager#resolve_alias is promoted from private to the public API so the config service can call it. It was previously only used internally by Manager#get_tool.
  • mcp_tools_for_agent maps agent_mcp_tools through resolve_alias before & available. Built-in tool names are a separate namespace and are intentionally left unresolved — an MCP alias colliding with a built-in name must not rewrite the built-in.
  • Out of scope, tracked separately: ListTools#invoke does not alias-resolve allowed_tools (same bug class one layer up), and declaring an actual production alias belongs in the consolidation MR. tracked in #618876

References

Screenshots or screen recordings

No UI changes.

How to set up and validate locally

  1. In the Rails console, build a config for an agent whose stored tools reference a renamed tool by its old alias, and confirm the canonical tool is retained:
    mgr = Mcp::Tools::Manager.new
    mgr.resolve_alias("gitlab_search")   # => "search"
    mgr.alias_map                        # => includes "gitlab_search" => "search"
    A stored mcp_tools: ["gitlab_search"] now yields search in the agent's tool list instead of being dropped.

Manual testing

I manually tested this on master vs. my branch:

  1. create a catalog agent in a project, give it access to search tool
  2. change the name of the MCP server search tool to search-new-name and add an alias for search ( see diff )
  3. restart rails
  4. open duo chat, select the test agent, ask it to search for merge requests
Click to expand diff
diff --git a/app/services/mcp/tools/search/search_service.rb b/app/services/mcp/tools/search/search_service.rb
index 45e4db45eca3..d9ac83f1cedc 100644
--- a/app/services/mcp/tools/search/search_service.rb
+++ b/app/services/mcp/tools/search/search_service.rb
@@ -18,12 +18,12 @@ class SearchService < Base::AggregatedService
 
         override :tool_name
         def self.tool_name
-          'search'
+          'search-new-name'
         end
 
         override :tool_aliases
         def self.tool_aliases
-          ['gitlab_search']
+          ['gitlab_search', 'search']
         end
 
         override :description

On master

it silently refuses to run the tool

image

On my branch

tool runs and is attributed to the corrected tool name in UI

image

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Terri Chu

Merge request reports

Loading
Loading