Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 34 additions & 23 deletions pkg/github/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package github

import (
"context"
"fmt"
"strings"

"github.com/github/github-mcp-server/pkg/registry"
Expand Down Expand Up @@ -266,17 +265,19 @@ func GenerateToolsetsHelp() string {
// Get toolset group to derive defaults and available toolsets
r := NewRegistry(stubTranslator).Build()

// Format default tools from metadata
// Format default tools from metadata using strings.Builder
var defaultBuf strings.Builder
defaultIDs := r.DefaultToolsetIDs()
defaultStrings := make([]string, len(defaultIDs))
for i, id := range defaultIDs {
defaultStrings[i] = string(id)
if i > 0 {
defaultBuf.WriteString(", ")
}
defaultBuf.WriteString(string(id))
}
defaultTools := strings.Join(defaultStrings, ", ")

// Get all available toolsets (excludes context and dynamic for display)
allToolsets := r.AvailableToolsets("context", "dynamic")
var availableToolsLines []string
var availableBuf strings.Builder
const maxLineLength = 70
currentLine := ""

Expand All @@ -288,27 +289,37 @@ func GenerateToolsetsHelp() string {
case len(currentLine)+len(id)+2 <= maxLineLength:
currentLine += ", " + id
Copy link

Copilot AI Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line 290 still uses string concatenation (+=) to build the currentLine. For consistency with the strings.Builder refactoring pattern, consider using a strings.Builder for building currentLine as well, or document why the current approach is preferred for this specific case.

Copilot uses AI. Check for mistakes.
default:
availableToolsLines = append(availableToolsLines, currentLine)
if availableBuf.Len() > 0 {
availableBuf.WriteString(",\n\t ")
}
availableBuf.WriteString(currentLine)
currentLine = id
}
}
if currentLine != "" {
availableToolsLines = append(availableToolsLines, currentLine)
}

availableTools := strings.Join(availableToolsLines, ",\n\t ")

toolsetsHelp := fmt.Sprintf("Comma-separated list of tool groups to enable (no spaces).\n"+
"Available: %s\n", availableTools) +
"Special toolset keywords:\n" +
" - all: Enables all available toolsets\n" +
fmt.Sprintf(" - default: Enables the default toolset configuration of:\n\t %s\n", defaultTools) +
"Examples:\n" +
" - --toolsets=actions,gists,notifications\n" +
" - Default + additional: --toolsets=default,actions,gists\n" +
" - All tools: --toolsets=all"

return toolsetsHelp
if availableBuf.Len() > 0 {
availableBuf.WriteString(",\n\t ")
}
availableBuf.WriteString(currentLine)
}

// Build the complete help text using strings.Builder
var buf strings.Builder
buf.WriteString("Comma-separated list of tool groups to enable (no spaces).\n")
buf.WriteString("Available: ")
buf.WriteString(availableBuf.String())
buf.WriteString("\n")
buf.WriteString("Special toolset keywords:\n")
buf.WriteString(" - all: Enables all available toolsets\n")
buf.WriteString(" - default: Enables the default toolset configuration of:\n\t ")
buf.WriteString(defaultBuf.String())
buf.WriteString("\n")
buf.WriteString("Examples:\n")
buf.WriteString(" - --toolsets=actions,gists,notifications\n")
buf.WriteString(" - Default + additional: --toolsets=default,actions,gists\n")
buf.WriteString(" - All tools: --toolsets=all")

return buf.String()
}

// stubTranslator is a passthrough translator for cases where we need a Registry
Expand Down
31 changes: 31 additions & 0 deletions pkg/github/tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,34 @@ func TestContainsToolset(t *testing.T) {
})
}
}

func TestGenerateToolsetsHelp(t *testing.T) {
// Generate the help text
helpText := GenerateToolsetsHelp()

// Verify help text is not empty
require.NotEmpty(t, helpText)

// Verify it contains expected sections
assert.Contains(t, helpText, "Comma-separated list of tool groups to enable")
assert.Contains(t, helpText, "Available:")
assert.Contains(t, helpText, "Special toolset keywords:")
assert.Contains(t, helpText, "all: Enables all available toolsets")
assert.Contains(t, helpText, "default: Enables the default toolset configuration")
assert.Contains(t, helpText, "Examples:")
assert.Contains(t, helpText, "--toolsets=actions,gists,notifications")
assert.Contains(t, helpText, "--toolsets=default,actions,gists")
assert.Contains(t, helpText, "--toolsets=all")

// Verify it contains some expected default toolsets
assert.Contains(t, helpText, "context")
assert.Contains(t, helpText, "repos")
assert.Contains(t, helpText, "issues")
assert.Contains(t, helpText, "pull_requests")
assert.Contains(t, helpText, "users")

// Verify it contains some expected available toolsets
assert.Contains(t, helpText, "actions")
assert.Contains(t, helpText, "gists")
assert.Contains(t, helpText, "notifications")
}
Loading