Skip to content

Commit 8f5e302

Browse files
simplify: remove lazy toolsByName map - not needed for actual use cases
FindToolByName() is only called once per request at most (to find toolset ID for dynamic enablement). The SDK handles tool dispatch after registration. A simple linear scan over ~90 tools is trivially fast and avoids: - sync.Once complexity - Map allocation - Premature optimization for non-existent 'repeated lookups' The pre-computed maps we keep (toolsetIDSet, etc.) are justified because they're used for filtering logic that runs on every request.
1 parent ab67ed6 commit 8f5e302

File tree

2 files changed

+4
-21
lines changed

2 files changed

+4
-21
lines changed

pkg/registry/builder.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,6 @@ func (b *Builder) Build() *Registry {
125125
featureChecker: b.featureChecker,
126126
}
127127

128-
// Note: toolsByName map is lazy-initialized on first use via getToolsByName()
129-
130128
// Process toolsets and pre-compute metadata in a single pass
131129
r.enabledToolsets, r.unrecognizedToolsets, r.toolsetIDs, r.toolsetIDSet, r.defaultToolsetIDs, r.toolsetDescriptions = b.processToolsets()
132130

pkg/registry/registry.go

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"os"
77
"slices"
88
"sort"
9-
"sync"
109

1110
"github.com/modelcontextprotocol/go-sdk/mcp"
1211
)
@@ -28,10 +27,6 @@ import (
2827
type Registry struct {
2928
// tools holds all tools in this group (ordered for iteration)
3029
tools []ServerTool
31-
// toolsByName provides O(1) lookup by tool name (lazy-initialized)
32-
// Used by FindToolByName for repeated lookups in long-lived servers
33-
toolsByName map[string]*ServerTool
34-
toolsByNameOnce sync.Once
3530
// resourceTemplates holds all resource templates in this group (ordered for iteration)
3631
resourceTemplates []ServerResourceTemplate
3732
// prompts holds all prompts in this group (ordered for iteration)
@@ -68,18 +63,6 @@ func (r *Registry) UnrecognizedToolsets() []string {
6863
return r.unrecognizedToolsets
6964
}
7065

71-
// getToolsByName returns the toolsByName map, initializing it lazily on first call.
72-
// Used by FindToolByName for O(1) lookups in long-lived servers with repeated lookups.
73-
func (r *Registry) getToolsByName() map[string]*ServerTool {
74-
r.toolsByNameOnce.Do(func() {
75-
r.toolsByName = make(map[string]*ServerTool, len(r.tools))
76-
for i := range r.tools {
77-
r.toolsByName[r.tools[i].Tool.Name] = &r.tools[i]
78-
}
79-
})
80-
return r.toolsByName
81-
}
82-
8366
// MCP method constants for use with ForMCPRequest.
8467
const (
8568
MCPMethodInitialize = "initialize"
@@ -237,8 +220,10 @@ func (r *Registry) ResolveToolAliases(toolNames []string) (resolved []string, al
237220
// Returns the tool, its toolset ID, and an error if not found.
238221
// This searches ALL tools regardless of filters.
239222
func (r *Registry) FindToolByName(toolName string) (*ServerTool, ToolsetID, error) {
240-
if tool, ok := r.getToolsByName()[toolName]; ok {
241-
return tool, tool.Toolset.ID, nil
223+
for i := range r.tools {
224+
if r.tools[i].Tool.Name == toolName {
225+
return &r.tools[i], r.tools[i].Toolset.ID, nil
226+
}
242227
}
243228
return nil, "", NewToolDoesNotExistError(toolName)
244229
}

0 commit comments

Comments
 (0)