- Notifications
You must be signed in to change notification settings - Fork3.1k
feat: Add list-scopes command to show required OAuth scopes#1487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:SamMorrowDrums/oauth-scopes-phase2
Are you sure you want to change the base?
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,364 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package main | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "context" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "encoding/json" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "os" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "sort" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "strings" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/github-mcp-server/pkg/github" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/github-mcp-server/pkg/lockdown" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/github-mcp-server/pkg/raw" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/github-mcp-server/pkg/scopes" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/github-mcp-server/pkg/toolsets" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/github/github-mcp-server/pkg/translations" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gogithub "github.com/google/go-github/v79/github" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/shurcooL/githubv4" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/spf13/cobra" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "github.com/spf13/viper" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ToolScopeInfo contains scope information for a single tool. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type ToolScopeInfo struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Name string `json:"name"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Toolset string `json:"toolset"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ReadOnly bool `json:"read_only"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RequiredScopes []string `json:"required_scopes"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AcceptedScopes []string `json:"accepted_scopes,omitempty"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ScopesOutput is the full output structure for the list-scopes command. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type ScopesOutput struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Tools []ToolScopeInfo `json:"tools"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| UniqueScopes []string `json:"unique_scopes"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ScopesByTool map[string][]string `json:"scopes_by_tool"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ToolsByScope map[string][]string `json:"tools_by_scope"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EnabledToolsets []string `json:"enabled_toolsets"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ReadOnly bool `json:"read_only"` | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var listScopesCmd = &cobra.Command{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Use: "list-scopes", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Short: "List required OAuth scopes for enabled tools", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Long: `List the required OAuth scopes for all enabled tools. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| This command creates a toolset group based on the same flags as the stdio command | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| and outputs the required OAuth scopes for each enabled tool. This is useful for | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| determining what scopes a token needs to use specific tools. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| The output format can be controlled with the --output flag: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - text (default): Human-readable text output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - json: JSON output for programmatic use | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - summary: Just the unique scopes needed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Examples: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # List scopes for default toolsets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github-mcp-server list-scopes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # List scopes for specific toolsets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github-mcp-server list-scopes --toolsets=repos,issues,pull_requests | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # List scopes for all toolsets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github-mcp-server list-scopes --toolsets=all | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Output as JSON | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github-mcp-server list-scopes --output=json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Just show unique scopes needed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| github-mcp-server list-scopes --output=summary`, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| RunE: func(_ *cobra.Command, _ []string) error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return runListScopes() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func init() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| listScopesCmd.Flags().StringP("output", "o", "text", "Output format: text, json, or summary") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _ = viper.BindPFlag("list-scopes-output", listScopesCmd.Flags().Lookup("output")) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| rootCmd.AddCommand(listScopesCmd) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // mockScopesGetClient returns a mock GitHub client for scope listing. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func mockScopesGetClient(_ context.Context) (*gogithub.Client, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return gogithub.NewClient(nil), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // mockScopesGetGQLClient returns a mock GraphQL client for scope listing. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func mockScopesGetGQLClient(_ context.Context) (*githubv4.Client, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return githubv4.NewClient(nil), nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // mockScopesGetRawClient returns a mock raw client for scope listing. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func mockScopesGetRawClient(_ context.Context) (*raw.Client, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func runListScopes() error { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Get toolsets configuration (same logic as stdio command) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var enabledToolsets []string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err := viper.UnmarshalKey("toolsets", &enabledToolsets); err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("failed to unmarshal toolsets: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // No passed toolsets configuration means we enable the default toolset | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if len(enabledToolsets) == 0 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enabledToolsets = []string{github.ToolsetMetadataDefault.ID} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readOnly := viper.GetBool("read-only") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| outputFormat := viper.GetString("list-scopes-output") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create translation helper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| t, _ := translations.TranslationHelper() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create toolset group with mock clients (no actual API calls needed) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| repoAccessCache := lockdown.GetInstance(nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tsg := github.DefaultToolsetGroup(readOnly, mockScopesGetClient, mockScopesGetGQLClient, mockScopesGetRawClient, t, 5000, github.FeatureFlags{}, repoAccessCache) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Process enabled toolsets (same logic as server.go) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If "all" is present, override all other toolsets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if github.ContainsToolset(enabledToolsets, github.ToolsetMetadataAll.ID) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enabledToolsets = []string{github.ToolsetMetadataAll.ID} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // If "default" is present, expand to real toolset IDs | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if github.ContainsToolset(enabledToolsets, github.ToolsetMetadataDefault.ID) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| enabledToolsets = github.AddDefaultToolset(enabledToolsets) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines +120 to +128 CopilotAI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Enable the requested toolsets | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| err := tsg.EnableToolsets(enabledToolsets, nil) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return fmt.Errorf("failed to enable toolsets: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Collect all tools and their scopes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| output := collectToolScopes(tsg, enabledToolsets, readOnly) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Output based on format | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| switch outputFormat { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "json": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return outputJSON(output) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "summary": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return outputSummary(output) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return outputText(output) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func collectToolScopes(tsg *toolsets.ToolsetGroup, enabledToolsets []string, readOnly bool) ScopesOutput { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var tools []ToolScopeInfo | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scopeSet := make(map[string]bool) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| scopesByTool := make(map[string][]string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| toolsByScope := make(map[string][]string) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Get all toolset names and sort them for consistent output | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var toolsetNames []string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for name := range tsg.Toolsets { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if name != "dynamic" { // Skip dynamic toolset | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| toolsetNames = append(toolsetNames, name) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sort.Strings(toolsetNames) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, toolsetName := range toolsetNames { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| toolset := tsg.Toolsets[toolsetName] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !toolset.Enabled { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Get active tools (respects read-only setting) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| activeTools := toolset.GetActiveTools() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, serverTool := range activeTools { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tool := serverTool.Tool | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Extract scopes from tool metadata | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| requiredScopes := scopes.GetScopesFromMeta(tool.Meta) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| requiredScopeStrs := scopes.ScopeStrings(requiredScopes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Calculate accepted scopes (scopes that also satisfy the requirement due to hierarchy) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| acceptedScopeStrs := []string{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, reqScope := range requiredScopes { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| accepted := scopes.GetAcceptedScopes(reqScope) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, accScope := range accepted { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if accScope != reqScope { // Don't duplicate the required scope | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| accStr := accScope.String() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Avoid duplicates | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| found := false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, existing := range acceptedScopeStrs { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if existing == accStr { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| found = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !found { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| acceptedScopeStrs = append(acceptedScopeStrs, accStr) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines +182 to +201 CopilotAI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| acceptedScopeStrs:= []string{} | |
| for_,reqScope:=rangerequiredScopes { | |
| accepted:=scopes.GetAcceptedScopes(reqScope) | |
| for_,accScope:=rangeaccepted { | |
| ifaccScope!=reqScope {// Don't duplicate the required scope | |
| accStr:=accScope.String() | |
| // Avoid duplicates | |
| found:=false | |
| for_,existing:=rangeacceptedScopeStrs { | |
| ifexisting==accStr { | |
| found=true | |
| break | |
| } | |
| } | |
| if!found { | |
| acceptedScopeStrs=append(acceptedScopeStrs,accStr) | |
| } | |
| } | |
| } | |
| } | |
| // Calculate accepted scopes (scopes that also satisfy the requirement due to hierarchy) | |
| acceptedScopeMap:=make(map[string]bool) | |
| for_,reqScope:=rangerequiredScopes { | |
| accepted:=scopes.GetAcceptedScopes(reqScope) | |
| for_,accScope:=rangeaccepted { | |
| ifaccScope!=reqScope {// Don't duplicate the required scope | |
| acceptedScopeMap[accScope.String()]=true | |
| } | |
| } | |
| } | |
| acceptedScopeStrs:=make([]string,0,len(acceptedScopeMap)) | |
| forscope:=rangeacceptedScopeMap { | |
| acceptedScopeStrs=append(acceptedScopeStrs,scope) | |
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||||||||||||||||
| #!/bin/bash | ||||||||||||||||||||
| # | ||||||||||||||||||||
| # List required OAuth scopes for enabled tools. | ||||||||||||||||||||
| # | ||||||||||||||||||||
| # Usage: | ||||||||||||||||||||
| # script/list-scopes [--toolsets=...] [--output=text|json|summary] | ||||||||||||||||||||
| # | ||||||||||||||||||||
| # Examples: | ||||||||||||||||||||
| # script/list-scopes | ||||||||||||||||||||
| # script/list-scopes --toolsets=all --output=json | ||||||||||||||||||||
| # script/list-scopes --toolsets=repos,issues --output=summary | ||||||||||||||||||||
| # | ||||||||||||||||||||
| set -e | ||||||||||||||||||||
| cd "$(dirname "$0")/.." | ||||||||||||||||||||
| # Build the server if it doesn't exist or is outdated | ||||||||||||||||||||
| if [ ! -f github-mcp-server ] || [ cmd/github-mcp-server/list_scopes.go -nt github-mcp-server ]; then | ||||||||||||||||||||
| echo "Building github-mcp-server..." >&2 | ||||||||||||||||||||
| go build -o github-mcp-server ./cmd/github-mcp-server | ||||||||||||||||||||
| fi | ||||||||||||||||||||
| exec ./github-mcp-server list-scopes "$@" | ||||||||||||||||||||
Comment on lines +18 to +24 CopilotAI | ||||||||||||||||||||
| # Build the server if it doesn't exist or is outdated | |
| if [ ! -f github-mcp-server ] || [ cmd/github-mcp-server/list_scopes.go -nt github-mcp-server ]; then | |
| echo "Building github-mcp-server..." >&2 | |
| go build -o github-mcp-server ./cmd/github-mcp-server | |
| fi | |
| exec ./github-mcp-server list-scopes "$@" | |
| # Always run the latest code, consistent with other scripts | |
| exec go run ./cmd/github-mcp-server list-scopes "$@" |
Uh oh!
There was an error while loading.Please reload this page.