Skip to content

Commit c17ebfe

Browse files
chore: separate toolset creation from init and use typed error (#487)
1 parent 9dd6fc5 commit c17ebfe

File tree

4 files changed

+68
-20
lines changed

4 files changed

+68
-20
lines changed

internal/ghmcp/server.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -113,26 +113,22 @@ func NewMCPServer(cfg MCPServerConfig) (*server.MCPServer, error) {
113113
}
114114

115115
// Create default toolsets
116-
toolsets, err := github.InitToolsets(
117-
enabledToolsets,
118-
cfg.ReadOnly,
119-
getClient,
120-
getGQLClient,
121-
cfg.Translator,
122-
)
116+
tsg := github.DefaultToolsetGroup(cfg.ReadOnly, getClient, getGQLClient, cfg.Translator)
117+
err = tsg.EnableToolsets(enabledToolsets)
118+
123119
if err != nil {
124-
return nil, fmt.Errorf("failed to initialize toolsets: %w", err)
120+
return nil, fmt.Errorf("failed to enable toolsets: %w", err)
125121
}
126122

127123
context := github.InitContextToolset(getClient, cfg.Translator)
128124
github.RegisterResources(ghServer, getClient, cfg.Translator)
129125

130126
// Register the tools with the server
131-
toolsets.RegisterTools(ghServer)
127+
tsg.RegisterTools(ghServer)
132128
context.RegisterTools(ghServer)
133129

134130
if cfg.DynamicToolsets {
135-
dynamic := github.InitDynamicToolset(ghServer, toolsets, cfg.Translator)
131+
dynamic := github.InitDynamicToolset(ghServer, tsg, cfg.Translator)
136132
dynamic.RegisterTools(ghServer)
137133
}
138134

pkg/github/tools.go

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ type GetGQLClientFn func(context.Context) (*githubv4.Client, error)
1515

1616
var DefaultTools = []string{"all"}
1717

18-
func InitToolsets(passedToolsets []string, readOnly bool, getClient GetClientFn, getGQLClient GetGQLClientFn, t translations.TranslationHelperFunc) (*toolsets.ToolsetGroup, error) {
19-
// Create a new toolset group
18+
func DefaultToolsetGroup(readOnly bool, getClient GetClientFn, getGQLClient GetGQLClientFn, t translations.TranslationHelperFunc) *toolsets.ToolsetGroup {
2019
tsg := toolsets.NewToolsetGroup(readOnly)
2120

2221
// Define all available features with their default state (disabled)
@@ -116,13 +115,8 @@ func InitToolsets(passedToolsets []string, readOnly bool, getClient GetClientFn,
116115
tsg.AddToolset(secretProtection)
117116
tsg.AddToolset(notifications)
118117
tsg.AddToolset(experiments)
119-
// Enable the requested features
120118

121-
if err := tsg.EnableToolsets(passedToolsets); err != nil {
122-
return nil, err
123-
}
124-
125-
return tsg, nil
119+
return tsg
126120
}
127121

128122
func InitContextToolset(getClient GetClientFn, t translations.TranslationHelperFunc) *toolsets.Toolset {

pkg/toolsets/toolsets.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,28 @@ import (
77
"github.com/mark3labs/mcp-go/server"
88
)
99

10+
type ToolsetDoesNotExistError struct {
11+
Name string
12+
}
13+
14+
func (e *ToolsetDoesNotExistError) Error() string {
15+
return fmt.Sprintf("toolset %s does not exist", e.Name)
16+
}
17+
18+
func (e *ToolsetDoesNotExistError) Is(target error) bool {
19+
if target == nil {
20+
return false
21+
}
22+
if _, ok := target.(*ToolsetDoesNotExistError); ok {
23+
return true
24+
}
25+
return false
26+
}
27+
28+
func NewToolsetDoesNotExistError(name string) *ToolsetDoesNotExistError {
29+
return &ToolsetDoesNotExistError{Name: name}
30+
}
31+
1032
func NewServerTool(tool mcp.Tool, handler server.ToolHandlerFunc) server.ServerTool {
1133
return server.ServerTool{Tool: tool, Handler: handler}
1234
}
@@ -150,7 +172,7 @@ func (tg *ToolsetGroup) EnableToolsets(names []string) error {
150172
func (tg *ToolsetGroup) EnableToolset(name string) error {
151173
toolset, exists := tg.Toolsets[name]
152174
if !exists {
153-
return fmt.Errorf("toolset %s does not exist", name)
175+
return NewToolsetDoesNotExistError(name)
154176
}
155177
toolset.Enabled = true
156178
tg.Toolsets[name] = toolset
@@ -162,3 +184,11 @@ func (tg *ToolsetGroup) RegisterTools(s *server.MCPServer) {
162184
toolset.RegisterTools(s)
163185
}
164186
}
187+
188+
func (tg *ToolsetGroup) GetToolset(name string) (*Toolset, error) {
189+
toolset, exists := tg.Toolsets[name]
190+
if !exists {
191+
return nil, NewToolsetDoesNotExistError(name)
192+
}
193+
return toolset, nil
194+
}

pkg/toolsets/toolsets_test.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package toolsets
22

33
import (
4+
"errors"
45
"testing"
56
)
67

@@ -151,6 +152,9 @@ func TestEnableToolsets(t *testing.T) {
151152
if err == nil {
152153
t.Error("Expected error when enabling list with non-existent toolset")
153154
}
155+
if !errors.Is(err, NewToolsetDoesNotExistError("non-existent")) {
156+
t.Errorf("Expected ToolsetDoesNotExistError when enabling non-existent toolset, got: %v", err)
157+
}
154158

155159
// Test with empty list
156160
err = tsg.EnableToolsets([]string{})
@@ -207,7 +211,7 @@ func TestEnableEverything(t *testing.T) {
207211
func TestIsEnabledWithEverythingOn(t *testing.T) {
208212
tsg := NewToolsetGroup(false)
209213

210-
// Enable "everything"
214+
// Enable "all"
211215
err := tsg.EnableToolsets([]string{"all"})
212216
if err != nil {
213217
t.Errorf("Expected no error when enabling 'all', got: %v", err)
@@ -222,3 +226,27 @@ func TestIsEnabledWithEverythingOn(t *testing.T) {
222226
t.Error("Expected IsEnabled to return true for any toolset when everythingOn is true")
223227
}
224228
}
229+
230+
func TestToolsetGroup_GetToolset(t *testing.T) {
231+
tsg := NewToolsetGroup(false)
232+
toolset := NewToolset("my-toolset", "desc")
233+
tsg.AddToolset(toolset)
234+
235+
// Should find the toolset
236+
got, err := tsg.GetToolset("my-toolset")
237+
if err != nil {
238+
t.Fatalf("expected no error, got %v", err)
239+
}
240+
if got != toolset {
241+
t.Errorf("expected to get the same toolset instance")
242+
}
243+
244+
// Should not find a non-existent toolset
245+
_, err = tsg.GetToolset("does-not-exist")
246+
if err == nil {
247+
t.Error("expected error for missing toolset, got nil")
248+
}
249+
if !errors.Is(err, NewToolsetDoesNotExistError("does-not-exist")) {
250+
t.Errorf("expected error to be ToolsetDoesNotExistError, got %v", err)
251+
}
252+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy