-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathregistry.go
More file actions
53 lines (47 loc) · 1.57 KB
/
Copy pathregistry.go
File metadata and controls
53 lines (47 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package mcp
import "fmt"
// Registry collects MCP tools. Insertion order is preserved so
// `tools/list` returns tools in a deterministic order (matches the
// Java side where Spring iterates beans in registration order).
type Registry struct {
tools []Tool
seen map[string]struct{}
}
// NewRegistry returns an empty registry ready for Add calls.
func NewRegistry() *Registry {
return &Registry{seen: make(map[string]struct{})}
}
// Add registers a tool. Duplicate names, empty names, and nil handlers
// all return an error rather than panicking — RegisterAll wires many
// tools at server boot and one bad entry should not abort the rest.
func (r *Registry) Add(t Tool) error {
if t.Name == "" {
return fmt.Errorf("mcp: tool name is empty")
}
if t.Handler == nil {
return fmt.Errorf("mcp: tool %q has nil handler", t.Name)
}
if _, dup := r.seen[t.Name]; dup {
return fmt.Errorf("mcp: tool %q registered twice", t.Name)
}
r.seen[t.Name] = struct{}{}
r.tools = append(r.tools, t)
return nil
}
// All returns a defensive copy of the registered tools in registration
// order. Mutating the returned slice does not affect the registry.
func (r *Registry) All() []Tool {
out := make([]Tool, len(r.tools))
copy(out, r.tools)
return out
}
// Names returns the registered tool names in registration order. Used
// by `TestRegisterGraphRegistersAllTwentyTools` (and the topology/flow
// analogues) to assert the wiring without inspecting handlers.
func (r *Registry) Names() []string {
out := make([]string, len(r.tools))
for i, t := range r.tools {
out[i] = t.Name
}
return out
}