Skip to content

Commit db6cb9d

Browse files
feat: support standalone toolset metadata in inventory builder
- Added `toolsetMetadata` field to Builder for registering standalone toolset metadata - Added `SetToolsetMetadata()` method to Builder for setting standalone metadata - Updated `processToolsets()` to include standalone metadata in default toolsets - Updated `NewInventory()` to register remote-only toolset metadata - Updated test expectations to include `copilot` in defaults This change enables toolset metadata with `Default: true` to control whether tools in that toolset are included by default, even if no tools in the OSS repo use that toolset. The remote server can now register tools in the `copilot` toolset and they will automatically be included in defaults. Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
1 parent a372e28 commit db6cb9d

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

internal/ghmcp/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ func NewMCPServer(cfg MCPServerConfig) (*mcp.Server, error) {
215215
cfg.Translator,
216216
github.FeatureFlags{
217217
LockdownMode: cfg.LockdownMode,
218-
InsiderMode: cfg.InsiderMode,
218+
InsiderMode: cfg.InsiderMode,
219219
},
220220
cfg.ContentWindowSize,
221221
featureChecker,
@@ -235,7 +235,7 @@ func NewMCPServer(cfg MCPServerConfig) (*mcp.Server, error) {
235235
WithToolsets(enabledToolsets).
236236
WithTools(cfg.EnabledTools).
237237
WithFeatureChecker(featureChecker)
238-
238+
239239
// Apply token scope filtering if scopes are known (for PAT filtering)
240240
if cfg.TokenScopes != nil {
241241
inventoryBuilder = inventoryBuilder.WithFilter(github.CreateToolScopeFilter(cfg.TokenScopes))

pkg/github/inventory.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ func NewInventory(t translations.TranslationHelperFunc) *inventory.Builder {
1414
return inventory.NewBuilder().
1515
SetTools(AllTools(t)).
1616
SetResources(AllResources(t)).
17-
SetPrompts(AllPrompts(t))
17+
SetPrompts(AllPrompts(t)).
18+
SetToolsetMetadata(RemoteOnlyToolsets())
1819
}

pkg/github/tools_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func TestAddDefaultToolset(t *testing.T) {
2323
input: []string{"default"},
2424
expected: []string{
2525
"context",
26+
"copilot",
2627
"repos",
2728
"issues",
2829
"pull_requests",
@@ -36,6 +37,7 @@ func TestAddDefaultToolset(t *testing.T) {
3637
"actions",
3738
"gists",
3839
"context",
40+
"copilot",
3941
"repos",
4042
"issues",
4143
"pull_requests",
@@ -47,6 +49,7 @@ func TestAddDefaultToolset(t *testing.T) {
4749
input: []string{"default", "context", "repos"},
4850
expected: []string{
4951
"context",
52+
"copilot",
5053
"repos",
5154
"issues",
5255
"pull_requests",

pkg/inventory/builder.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type Builder struct {
3232
resourceTemplates []ServerResourceTemplate
3333
prompts []ServerPrompt
3434
deprecatedAliases map[string]string
35+
toolsetMetadata []ToolsetMetadata // standalone toolset metadata
3536

3637
// Configuration options (processed at Build time)
3738
readOnly bool
@@ -68,6 +69,16 @@ func (b *Builder) SetPrompts(prompts []ServerPrompt) *Builder {
6869
return b
6970
}
7071

72+
// SetToolsetMetadata sets standalone toolset metadata for the inventory.
73+
// This is used for toolsets that may not have tools registered in this build
74+
// but should still be recognized (e.g., remote-only toolsets).
75+
// Toolsets with Default: true will be included in default toolsets even if
76+
// no tools use them. Returns self for chaining.
77+
func (b *Builder) SetToolsetMetadata(metadata []ToolsetMetadata) *Builder {
78+
b.toolsetMetadata = metadata
79+
return b
80+
}
81+
7182
// WithDeprecatedAliases adds deprecated tool name aliases that map to canonical names.
7283
// Returns self for chaining.
7384
func (b *Builder) WithDeprecatedAliases(aliases map[string]string) *Builder {
@@ -248,6 +259,17 @@ func (b *Builder) processToolsets() (map[ToolsetID]bool, []string, []ToolsetID,
248259
descriptions[p.Toolset.ID] = p.Toolset.Description
249260
}
250261
}
262+
// Process standalone toolset metadata
263+
for i := range b.toolsetMetadata {
264+
m := &b.toolsetMetadata[i]
265+
validIDs[m.ID] = true
266+
if m.Default {
267+
defaultIDs[m.ID] = true
268+
}
269+
if m.Description != "" {
270+
descriptions[m.ID] = m.Description
271+
}
272+
}
251273

252274
// Build sorted slices from the collected maps
253275
allToolsetIDs := make([]ToolsetID, 0, len(validIDs))

0 commit comments

Comments
 (0)