@@ -192,19 +192,42 @@ func (t *Toolset) AddReadTools(tools ...ServerTool) *Toolset {
192192}
193193
194194type ToolsetGroup struct {
195- Toolsets map [string ]* Toolset
196- everythingOn bool
197- readOnly bool
195+ Toolsets map [string ]* Toolset
196+ deprecatedAliases map [string ]string // oldName → newName for renamed tools
197+ everythingOn bool
198+ readOnly bool
198199}
199200
200201func NewToolsetGroup (readOnly bool ) * ToolsetGroup {
201202 return & ToolsetGroup {
202- Toolsets : make (map [string ]* Toolset ),
203- everythingOn : false ,
204- readOnly : readOnly ,
203+ Toolsets : make (map [string ]* Toolset ),
204+ deprecatedAliases : make (map [string ]string ),
205+ everythingOn : false ,
206+ readOnly : readOnly ,
205207 }
206208}
207209
210+ // AddDeprecatedToolAlias registers an alias for a renamed tool.
211+ // When a user requests oldName, it will resolve to newName.
212+ // This allows tool renames without breaking existing user configurations.
213+ func (tg * ToolsetGroup ) AddDeprecatedToolAlias (oldName , newName string ) {
214+ tg .deprecatedAliases [oldName ] = newName
215+ }
216+
217+ // AddDeprecatedToolAliases registers multiple aliases for renamed tools.
218+ func (tg * ToolsetGroup ) AddDeprecatedToolAliases (aliases map [string ]string ) {
219+ for oldName , newName := range aliases {
220+ tg .deprecatedAliases [oldName ] = newName
221+ }
222+ }
223+
224+ // IsDeprecatedToolAlias checks if a tool name is a deprecated alias.
225+ // Returns the canonical name and true if it's an alias, or empty string and false otherwise.
226+ func (tg * ToolsetGroup ) IsDeprecatedToolAlias (toolName string ) (canonicalName string , isAlias bool ) {
227+ canonicalName , isAlias = tg .deprecatedAliases [toolName ]
228+ return canonicalName , isAlias
229+ }
230+
208231func (tg * ToolsetGroup ) AddToolset (ts * Toolset ) {
209232 if tg .readOnly {
210233 ts .SetReadOnly ()
@@ -307,9 +330,23 @@ func NewToolDoesNotExistError(name string) *ToolDoesNotExistError {
307330 return & ToolDoesNotExistError {Name : name }
308331}
309332
333+ // ToolLookupResult contains the result of a tool lookup operation.
334+ type ToolLookupResult struct {
335+ Tool * ServerTool
336+ ToolsetName string
337+ RequestedName string // The name that was requested (may differ from Tool.Name if alias was used)
338+ AliasUsed bool // True if the requested name was a deprecated alias
339+ }
340+
310341// FindToolByName searches all toolsets (enabled or disabled) for a tool by name.
342+ // It resolves deprecated aliases automatically.
311343// Returns the tool, its parent toolset name, and an error if not found.
312344func (tg * ToolsetGroup ) FindToolByName (toolName string ) (* ServerTool , string , error ) {
345+ // Resolve deprecated alias if applicable
346+ if canonicalName , isAlias := tg .deprecatedAliases [toolName ]; isAlias {
347+ toolName = canonicalName
348+ }
349+
313350 for toolsetName , toolset := range tg .Toolsets {
314351 // Check read tools
315352 for _ , tool := range toolset .readTools {
@@ -327,9 +364,36 @@ func (tg *ToolsetGroup) FindToolByName(toolName string) (*ServerTool, string, er
327364 return nil , "" , NewToolDoesNotExistError (toolName )
328365}
329366
367+ // FindToolWithAliasInfo searches all toolsets for a tool by name and returns
368+ // additional metadata about whether a deprecated alias was used.
369+ // Use this when you need to track/log deprecated alias usage (e.g., for telemetry).
370+ func (tg * ToolsetGroup ) FindToolWithAliasInfo (toolName string ) (* ToolLookupResult , error ) {
371+ requestedName := toolName
372+ aliasUsed := false
373+
374+ // Check if this is a deprecated alias and resolve to canonical name
375+ if canonicalName , isAlias := tg .deprecatedAliases [toolName ]; isAlias {
376+ toolName = canonicalName
377+ aliasUsed = true
378+ }
379+
380+ tool , toolsetName , err := tg .FindToolByName (toolName )
381+ if err != nil {
382+ return nil , NewToolDoesNotExistError (requestedName )
383+ }
384+
385+ return & ToolLookupResult {
386+ Tool : tool ,
387+ ToolsetName : toolsetName ,
388+ RequestedName : requestedName ,
389+ AliasUsed : aliasUsed ,
390+ }, nil
391+ }
392+
330393// RegisterSpecificTools registers only the specified tools.
331394// Respects read-only mode (skips write tools if readOnly=true).
332395// Returns error if any tool is not found.
396+ // Deprecated tool aliases are resolved automatically.
333397func (tg * ToolsetGroup ) RegisterSpecificTools (s * mcp.Server , toolNames []string , readOnly bool ) error {
334398 var skippedTools []string
335399 for _ , toolName := range toolNames {
0 commit comments