Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Open
SamMorrowDrums wants to merge1 commit intoSamMorrowDrums/oauth-scopes-phase2
base:SamMorrowDrums/oauth-scopes-phase2
Choose a base branch
Loading
fromSamMorrowDrums/oauth-scopes-phase3

Conversation

@SamMorrowDrums
Copy link
Collaborator

Summary

Adds a newlist-scopes subcommand that outputs the required OAuth scopes for all enabled tools. This helps users determine what scopes their token needs to use specific tools.

Part 3 of the OAuth scopes work:

Changes

  • Addcmd/github-mcp-server/list_scopes.go - new subcommand
  • Addscript/list-scopes - convenience wrapper script

Features

  • Respects all toolset configuration flags (--toolsets,--read-only)
  • Three output formats:text (default),json,summary
  • JSON output includes: tools, unique_scopes, scopes_by_tool, tools_by_scope
  • Calculates accepted scopes (parent scopes that satisfy requirements)

Usage Examples

# List scopes for default toolsetsgithub-mcp-server list-scopes# List scopes for specific toolsetsgithub-mcp-server list-scopes --toolsets=repos,issues,pull_requests# List scopes for all toolsetsgithub-mcp-server list-scopes --toolsets=all# Output as JSON (for programmatic use)github-mcp-server list-scopes --output=json# Just show unique scopes neededgithub-mcp-server list-scopes --output=summary# Read-only mode (excludes write tools)github-mcp-server list-scopes --read-only --output=summary

Example Output

$ github-mcp-server list-scopes --output=summaryRequired OAuth scopes for enabled tools:  (no scope required for public read access)  read:org  repoTotal: 3 unique scope(s)

Testing

  • script/lint - 0 issues
  • script/test - All tests pass

Adds a new 'list-scopes' subcommand that outputs the required OAuthscopes for all enabled tools. This helps users determine what scopestheir token needs to use specific tools.Features:- Respects all toolset configuration flags (--toolsets, --read-only)- Three output formats: text (default), json, summary- JSON output includes tools, unique_scopes, scopes_by_tool, tools_by_scope- Calculates accepted scopes (parent scopes that satisfy requirements)- Includes convenience wrapper script at script/list-scopesUsage examples:  github-mcp-server list-scopes  github-mcp-server list-scopes --toolsets=all --output=json  github-mcp-server list-scopes --read-only --output=summary
CopilotAI review requested due to automatic review settingsNovember 25, 2025 13:27
@SamMorrowDrumsSamMorrowDrums requested a review froma team as acode ownerNovember 25, 2025 13:27
Copilot finished reviewing on behalf ofSamMorrowDrumsNovember 25, 2025 13:32
Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a newlist-scopes subcommand to help users determine which OAuth scopes their GitHub token needs to use specific tools. The command respects all toolset configuration flags and supports multiple output formats (text, json, summary).

Key changes:

  • New CLI command that analyzes enabled toolsets and reports required OAuth scopes
  • Calculates both required scopes and accepted parent scopes that satisfy requirements
  • Three output formats for different use cases (human-readable, programmatic, and concise)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

FileDescription
script/list-scopesShell wrapper script that builds and executes the list-scopes command with argument forwarding
cmd/github-mcp-server/list_scopes.goMain implementation of the list-scopes subcommand including command definition, scope collection logic, and output formatting functions

Comment on lines +120 to +128
// 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)
}

Choose a reason for hiding this comment

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

The toolset processing logic is missing a call togithub.CleanToolsets() that exists in the stdio command (seeinternal/ghmcp/server.go line 102). This function:

  1. Removes whitespace from toolset names
  2. Removes duplicates
  3. Validates toolset names and identifies invalid ones

Without this, the command may behave inconsistently with the stdio command when users provide invalid or malformed toolset names. Add the CleanToolsets call before processing special keywords:

// Clean up the passed toolsetsenabledToolsets,invalidToolsets:=github.CleanToolsets(enabledToolsets)// Optionally warn about invalid toolsets (like server.go does)iflen(invalidToolsets)>0 {fmt.Fprintf(os.Stderr,"Invalid toolsets ignored: %s\n",strings.Join(invalidToolsets,", "))}// If "all" is present, override all other toolsetsifgithub.ContainsToolset(enabledToolsets,github.ToolsetMetadataAll.ID) {enabledToolsets= []string{github.ToolsetMetadataAll.ID}}// ...

Copilot uses AI. Check for mistakes.
Comment on lines +182 to +201
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)
}
}
}
}

Choose a reason for hiding this comment

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

The manual deduplication ofacceptedScopeStrs using nested loops is O(n²) and could be simplified for better maintainability and performance. Consider using a map for deduplication:

// 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 scopeacceptedScopeMap[accScope.String()]=true        }    }}acceptedScopeStrs:=make([]string,0,len(acceptedScopeMap))forscope:=rangeacceptedScopeMap {acceptedScopeStrs=append(acceptedScopeStrs,scope)}sort.Strings(acceptedScopeStrs)

This approach is more efficient and clearer in intent.

Suggested change
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)
}

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +24
# 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 "$@"

Choose a reason for hiding this comment

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

[nitpick] The conditional build check may not detect all necessary rebuilds (e.g., when dependencies in other packages change). For consistency with other scripts likescript/generate-docs, consider usinggo run instead:

exec go run ./cmd/github-mcp-server list-scopes"$@"

This approach is simpler, always ensures up-to-date code execution, and aligns with the project's script patterns. The build time overhead is minimal (~1s according to the guidelines).

Suggested change
# 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 "$@"

Copilot uses AI. Check for mistakes.
@SamMorrowDrums
Copy link
CollaboratorAuthor

Note: By default (without--toolsets), the command shows scopes for thedefault toolset (context,repos,issues,pull_requests,users):

$ ./github-mcp-server list-scopes --output=summaryRequired OAuth scopesfor enabled tools:  (no scope requiredfor publicread access)  read:org  repoTotal: 3 unique scope(s)

Compare this to all toolsets:

$ ./github-mcp-server list-scopes --toolsets=all --output=summaryRequired OAuth scopesfor enabled tools:  (no scope requiredfor publicread access)  gist  notifications  project  public_repo  read:org  read:project  repo  security_eventsTotal: 9 unique scope(s)

This matches the same default behavior as thestdio command.

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@SamMorrowDrums

[8]ページ先頭

©2009-2025 Movatter.jp