@@ -16,102 +16,172 @@ type GetGQLClientFn func(context.Context) (*githubv4.Client, error)
1616
1717// Toolset metadata constants - these define all available toolsets and their descriptions.
1818// Tools use these constants to declare which toolset they belong to.
19+ // Icons are Octicon names from https://primer.style/foundations/icons
1920var (
2021 ToolsetMetadataAll = toolsets.ToolsetMetadata {
2122 ID : "all" ,
2223 Description : "Special toolset that enables all available toolsets" ,
24+ Icon : "apps" ,
2325 }
2426 ToolsetMetadataDefault = toolsets.ToolsetMetadata {
2527 ID : "default" ,
2628 Description : "Special toolset that enables the default toolset configuration. When no toolsets are specified, this is the set that is enabled" ,
29+ Icon : "check-circle" ,
2730 }
2831 ToolsetMetadataContext = toolsets.ToolsetMetadata {
2932 ID : "context" ,
3033 Description : "Tools that provide context about the current user and GitHub context you are operating in" ,
3134 Default : true ,
35+ Icon : "person" ,
3236 }
3337 ToolsetMetadataRepos = toolsets.ToolsetMetadata {
3438 ID : "repos" ,
3539 Description : "GitHub Repository related tools" ,
3640 Default : true ,
41+ Icon : "repo" ,
3742 }
3843 ToolsetMetadataGit = toolsets.ToolsetMetadata {
3944 ID : "git" ,
4045 Description : "GitHub Git API related tools for low-level Git operations" ,
46+ Icon : "git-branch" ,
4147 }
4248 ToolsetMetadataIssues = toolsets.ToolsetMetadata {
4349 ID : "issues" ,
4450 Description : "GitHub Issues related tools" ,
4551 Default : true ,
52+ Icon : "issue-opened" ,
4653 }
4754 ToolsetMetadataPullRequests = toolsets.ToolsetMetadata {
4855 ID : "pull_requests" ,
4956 Description : "GitHub Pull Request related tools" ,
5057 Default : true ,
58+ Icon : "git-pull-request" ,
5159 }
5260 ToolsetMetadataUsers = toolsets.ToolsetMetadata {
5361 ID : "users" ,
5462 Description : "GitHub User related tools" ,
5563 Default : true ,
64+ Icon : "people" ,
5665 }
5766 ToolsetMetadataOrgs = toolsets.ToolsetMetadata {
5867 ID : "orgs" ,
5968 Description : "GitHub Organization related tools" ,
69+ Icon : "organization" ,
6070 }
6171 ToolsetMetadataActions = toolsets.ToolsetMetadata {
6272 ID : "actions" ,
6373 Description : "GitHub Actions workflows and CI/CD operations" ,
74+ Icon : "workflow" ,
6475 }
6576 ToolsetMetadataCodeSecurity = toolsets.ToolsetMetadata {
6677 ID : "code_security" ,
6778 Description : "Code security related tools, such as GitHub Code Scanning" ,
79+ Icon : "codescan" ,
6880 }
6981 ToolsetMetadataSecretProtection = toolsets.ToolsetMetadata {
7082 ID : "secret_protection" ,
7183 Description : "Secret protection related tools, such as GitHub Secret Scanning" ,
84+ Icon : "shield-lock" ,
7285 }
7386 ToolsetMetadataDependabot = toolsets.ToolsetMetadata {
7487 ID : "dependabot" ,
7588 Description : "Dependabot tools" ,
89+ Icon : "dependabot" ,
7690 }
7791 ToolsetMetadataNotifications = toolsets.ToolsetMetadata {
7892 ID : "notifications" ,
7993 Description : "GitHub Notifications related tools" ,
94+ Icon : "bell" ,
8095 }
8196 ToolsetMetadataExperiments = toolsets.ToolsetMetadata {
8297 ID : "experiments" ,
8398 Description : "Experimental features that are not considered stable yet" ,
99+ Icon : "beaker" ,
84100 }
85101 ToolsetMetadataDiscussions = toolsets.ToolsetMetadata {
86102 ID : "discussions" ,
87103 Description : "GitHub Discussions related tools" ,
104+ Icon : "comment-discussion" ,
88105 }
89106 ToolsetMetadataGists = toolsets.ToolsetMetadata {
90107 ID : "gists" ,
91108 Description : "GitHub Gist related tools" ,
109+ Icon : "logo-gist" ,
92110 }
93111 ToolsetMetadataSecurityAdvisories = toolsets.ToolsetMetadata {
94112 ID : "security_advisories" ,
95113 Description : "Security advisories related tools" ,
114+ Icon : "shield" ,
96115 }
97116 ToolsetMetadataProjects = toolsets.ToolsetMetadata {
98117 ID : "projects" ,
99118 Description : "GitHub Projects related tools" ,
119+ Icon : "project" ,
100120 }
101121 ToolsetMetadataStargazers = toolsets.ToolsetMetadata {
102122 ID : "stargazers" ,
103123 Description : "GitHub Stargazers related tools" ,
124+ Icon : "star" ,
104125 }
105126 ToolsetMetadataDynamic = toolsets.ToolsetMetadata {
106127 ID : "dynamic" ,
107128 Description : "Discover GitHub MCP tools that can help achieve tasks by enabling additional sets of tools, you can control the enablement of any toolset to access its tools when this toolset is enabled." ,
129+ Icon : "tools" ,
108130 }
109131 ToolsetLabels = toolsets.ToolsetMetadata {
110132 ID : "labels" ,
111133 Description : "GitHub Labels related tools" ,
134+ Icon : "tag" ,
112135 }
113136)
114137
138+ func AvailableToolsets () []toolsets.ToolsetMetadata {
139+ return []toolsets.ToolsetMetadata {
140+ ToolsetMetadataContext ,
141+ ToolsetMetadataRepos ,
142+ ToolsetMetadataGit ,
143+ ToolsetMetadataIssues ,
144+ ToolsetMetadataPullRequests ,
145+ ToolsetMetadataUsers ,
146+ ToolsetMetadataOrgs ,
147+ ToolsetMetadataActions ,
148+ ToolsetMetadataCodeSecurity ,
149+ ToolsetMetadataSecretProtection ,
150+ ToolsetMetadataDependabot ,
151+ ToolsetMetadataNotifications ,
152+ ToolsetMetadataExperiments ,
153+ ToolsetMetadataDiscussions ,
154+ ToolsetMetadataGists ,
155+ ToolsetMetadataSecurityAdvisories ,
156+ ToolsetMetadataProjects ,
157+ ToolsetMetadataStargazers ,
158+ ToolsetMetadataDynamic ,
159+ ToolsetLabels ,
160+ }
161+ }
162+
163+ // GetValidToolsetIDs returns a map of all valid toolset IDs for quick lookup
164+ func GetValidToolsetIDs () map [toolsets.ToolsetID ]bool {
165+ validIDs := make (map [toolsets.ToolsetID ]bool )
166+ for _ , toolset := range AvailableToolsets () {
167+ validIDs [toolset .ID ] = true
168+ }
169+ // Add special keywords
170+ validIDs [ToolsetMetadataAll .ID ] = true
171+ validIDs [ToolsetMetadataDefault .ID ] = true
172+ return validIDs
173+ }
174+
175+ func GetDefaultToolsetIDs () []toolsets.ToolsetID {
176+ return []toolsets.ToolsetID {
177+ ToolsetMetadataContext .ID ,
178+ ToolsetMetadataRepos .ID ,
179+ ToolsetMetadataIssues .ID ,
180+ ToolsetMetadataPullRequests .ID ,
181+ ToolsetMetadataUsers .ID ,
182+ }
183+ }
184+
115185// AllTools returns all tools with their embedded toolset metadata.
116186// Tool functions return ServerTool directly with toolset info.
117187func AllTools (t translations.TranslationHelperFunc ) []toolsets.ServerTool {
@@ -262,19 +332,16 @@ func ToStringPtr(s string) *string {
262332
263333// GenerateToolsetsHelp generates the help text for the toolsets flag
264334func GenerateToolsetsHelp () string {
265- // Get toolset group to derive defaults and available toolsets
266- r := NewRegistry (stubTranslator )
267-
268- // Format default tools from metadata
269- defaultIDs := r .DefaultToolsetIDs ()
335+ // Format default tools
336+ defaultIDs := GetDefaultToolsetIDs ()
270337 defaultStrings := make ([]string , len (defaultIDs ))
271338 for i , id := range defaultIDs {
272339 defaultStrings [i ] = string (id )
273340 }
274341 defaultTools := strings .Join (defaultStrings , ", " )
275342
276- // Get all available toolsets (excludes context and dynamic for display)
277- allToolsets := r . AvailableToolsets ("context" , "dynamic" )
343+ // Format available tools with line breaks for better readability
344+ allToolsets := AvailableToolsets ()
278345 var availableToolsLines []string
279346 const maxLineLength = 70
280347 currentLine := ""
@@ -310,10 +377,6 @@ func GenerateToolsetsHelp() string {
310377 return toolsetsHelp
311378}
312379
313- // stubTranslator is a passthrough translator for cases where we need a Registry
314- // but don't need actual translations (e.g., getting toolset IDs for CLI help).
315- func stubTranslator (_ , fallback string ) string { return fallback }
316-
317380// AddDefaultToolset removes the default toolset and expands it to the actual default toolset IDs
318381func AddDefaultToolset (result []string ) []string {
319382 hasDefault := false
@@ -332,16 +395,43 @@ func AddDefaultToolset(result []string) []string {
332395
333396 result = RemoveToolset (result , string (ToolsetMetadataDefault .ID ))
334397
335- // Get default toolset IDs from the Registry
336- r := NewRegistry (stubTranslator )
337- for _ , id := range r .DefaultToolsetIDs () {
338- if ! seen [string (id )] {
339- result = append (result , string (id ))
398+ for _ , defaultToolset := range GetDefaultToolsetIDs () {
399+ if ! seen [string (defaultToolset )] {
400+ result = append (result , string (defaultToolset ))
340401 }
341402 }
342403 return result
343404}
344405
406+ // cleanToolsets cleans and handles special toolset keywords:
407+ // - Duplicates are removed from the result
408+ // - Removes whitespaces
409+ // - Validates toolset names and returns invalid ones separately - for warning reporting
410+ // Returns: (toolsets, invalidToolsets)
411+ func CleanToolsets (enabledToolsets []string ) ([]string , []string ) {
412+ seen := make (map [string ]bool )
413+ result := make ([]string , 0 , len (enabledToolsets ))
414+ invalid := make ([]string , 0 )
415+ validIDs := GetValidToolsetIDs ()
416+
417+ // Add non-default toolsets, removing duplicates and trimming whitespace
418+ for _ , toolset := range enabledToolsets {
419+ trimmed := strings .TrimSpace (toolset )
420+ if trimmed == "" {
421+ continue
422+ }
423+ if ! seen [trimmed ] {
424+ seen [trimmed ] = true
425+ result = append (result , trimmed )
426+ if ! validIDs [toolsets .ToolsetID (trimmed )] {
427+ invalid = append (invalid , trimmed )
428+ }
429+ }
430+ }
431+
432+ return result , invalid
433+ }
434+
345435func RemoveToolset (tools []string , toRemove string ) []string {
346436 result := make ([]string , 0 , len (tools ))
347437 for _ , tool := range tools {
0 commit comments