Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 23, 2025

Summary

Added OAuth scope requirements to all 100+ MCP tools and automated scope documentation generation with conditional display logic.

Why

Enables users and systems to understand OAuth permission requirements for each tool. Prepares infrastructure for future scope validation logic.

What changed

  • Created pkg/scopes package with typed OAuth scope constants (Repo, Gist, Notifications, ReadOrg, WriteOrg, AdminOrg, ReadProject, Project, SecurityEvents, PublicRepo)
  • Extended ServerTool struct with RequiredScopes and AcceptedScopes string slices
  • Updated NewTool and NewToolFromHandler to include scope parameters (all tools use same constructor)
  • Updated all 100+ tool definitions across 16 files with explicit scope metadata
  • Enhanced generate-docs command to display scopes in tool documentation
  • Documentation only shows accepted scopes when they differ from required scopes
  • Tools with no scopes omit scope information entirely

Scope mapping examples:

  • get_me: no scopes required (public user data) - no scope info shown
  • get_teams: requires read:org, accepts read:org, write:org, admin:org - shows both
  • create_gist: requires gist, accepts gist - only shows required
  • star_repository: requires public_repo, accepts public_repo, repo - shows both
  • Most repo operations: require repo, accept repo - only shows required
  • Security tools: require security_events, accept security_events, repo - shows both

MCP impact

  • Tool schema or behavior changed
    • Added scope metadata fields to all tools; no functional behavior changes

Prompts tested (tool changes only)

  • N/A - metadata-only change, no behavior modifications

Security / limits

  • Auth / permissions considered
    • Documented existing OAuth requirements; no new permissions added

Tool renaming

  • I am not renaming tools as part of this PR

Lint & tests

  • Linted locally with ./script/lint
  • Tested locally with ./script/test

Docs

  • Updated (README / docs / examples)
    • README.md displays OAuth scopes for each tool with conditional accepted scope display
Original prompt

I added a bunch of PRs in order to enable oauth scopes to be documented and available for end users.

Can you add per tool scope information provided for the server tools, and added to documentation using the new arch where tools are self defining. It should be small changes with current arch even though it is going to touch every tool definition. Maybe the available scopes should also be a typed set of string constants with a scopes package that can be used on remote server also.

We need both required and accepted scopes due to hierarchy and scopes getting rolled up, but for now just edit tools and document. Later we'll add logic.

Here's the tool scope's mapping:

{
"get_me": {
"required_scopes": {},
"accepted_scopes": {}
},
"get_teams": {
"required_scopes": {"read:org": true},
"accepted_scopes": {"read:org": true, "write:org": true, "admin:org": true}
},
"get_team_members": {
"required_scopes": {"read:org": true},
"accepted_scopes": {"read:org": true, "write:org": true, "admin:org": true}
},
"list_issue_types": {
"required_scopes": {"read:org": true},
"accepted_scopes": {"read:org": true, "write:org": true, "admin:org": true}
},
"list_gists": {
"required_scopes": {},
"accepted_scopes": {}
},
"get_gist": {
"required_scopes": {},
"accepted_scopes": {}
},
"create_gist": {
"required_scopes": {"gist": true},
"accepted_scopes": {"gist": true}
},
"update_gist": {
"required_scopes": {"gist": true},
"accepted_scopes": {"gist": true}
},
"list_notifications": {
"required_scopes": {"notifications": true},
"accepted_scopes": {"notifications": true}
},
"dismiss_notification": {
"required_scopes": {"notifications": true},
"accepted_scopes": {"notifications": true}
},
"get_notification_details": {
"required_scopes": {"notifications": true},
"accepted_scopes": {"notifications": true}
},
"manage_notification_subscription": {
"required_scopes": {"notifications": true},
"accepted_scopes": {"notifications": true}
},
"manage_repository_notification_subscription": {
"required_scopes": {"notifications": true},
"accepted_scopes": {"notifications": true}
},
"mark_all_notifications_read": {
"required_scopes": {"notifications": true},
"accepted_scopes": {"notifications": true}
},
"star_repository": {
"required_scopes": {"public_repo": true},
"accepted_scopes": {"public_repo": true, "repo": true}
},
"unstar_repository": {
"required_scopes": {"public_repo": true},
"accepted_scopes": {"public_repo": true, "repo": true}
},
"get_project": {
"required_scopes": {"read:project": true},
"accepted_scopes": {"read:project": true, "project": true}
},
"get_project_field": {
"required_scopes": {"read:project": true},
"accepted_scopes": {"read:project": true, "project": true}
},
"get_project_item": {
"required_scopes": {"read:project": true},
"accepted_scopes": {"read:project": true, "project": true}
},
"list_project_fields": {
"required_scopes": {"read:project": true},
"accepted_scopes": {"read:project": true, "project": true}
},
"list_project_items": {
"required_scopes": {"read:project": true},
"accepted_scopes": {"read:project": true, "project": true}
},
"list_projects": {
"required_scopes": {"read:project": true},
"accepted_scopes": {"read:project": true, "project": true}
},
"add_project_item": {
"required_scopes": {"project": true},
"accepted_scopes": {"project": true}
},
"delete_project_item": {
"required_scopes": {"project": true},
"accepted_scopes": {"project": true}
},
"update_project_item": {
"required_scopes": {"project": true},
"accepted_scopes": {"project": true}
},
"get_code_scanning_alert": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"list_code_scanning_alerts": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"get_dependabot_alert": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"list_dependabot_alerts": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"get_secret_scanning_alert": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"list_secret_scanning_alerts": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"get_global_security_advisory": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "repo": true}
},
"list_global_security_advisories": {
"required_scopes": {"security_events": true},
"accepted_scopes": {"security_events": true, "r...


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add OAuth scopes documentation for server tools Add OAuth scope metadata to all MCP tools Dec 23, 2025
Copilot AI requested a review from SamMorrowDrums December 23, 2025 15:18
Copy link
Collaborator

@SamMorrowDrums SamMorrowDrums left a comment

Choose a reason for hiding this comment

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

@copilot this is pretty great, but let's only show accepted scopes where they differ, we generally want to omit those.

Also now all the changes are made you don't need NewToolWithScopes and can simply replace NewTool as all new tools should have explicitly require no scopes rather than having a different constructors.

Copy link
Contributor Author

Copilot AI commented Dec 23, 2025

@copilot this is pretty great, but let's only show accepted scopes where they differ, we generally want to omit those.

Also now all the changes are made you don't need NewToolWithScopes and can simpl...

Done in commit 29e9374.

Changes made:

  1. Unified constructor: Replaced NewToolWithScopes with an updated NewTool that includes scope parameters. All tools now use the same constructor with explicit scope requirements (including nil for no scopes).

  2. Conditional accepted scopes display: Documentation now only shows "Accepted OAuth Scopes" when they differ from "Required OAuth Scopes".

Examples from the generated documentation:

  • create_gist (same required/accepted): Only shows "Required OAuth Scopes: gist"
  • get_teams (different): Shows both "Required: read:org" and "Accepted: read:org, write:org, admin:org"
  • star_repository (different): Shows both "Required: public_repo" and "Accepted: public_repo, repo"
  • get_me (no scopes): Shows no scope information

Copilot AI requested a review from SamMorrowDrums December 23, 2025 15:29
@SamMorrowDrums SamMorrowDrums force-pushed the copilot/add-oauth-scopes-documentation branch from 29e9374 to c32646d Compare January 5, 2026 10:20
Copilot AI and others added 10 commits January 5, 2026 14:28
- Created pkg/scopes package with OAuth scope constants
- Added RequiredScopes and AcceptedScopes fields to ServerTool
- Added NewToolWithScopes helpers in dependencies.go
- Updated context tools (get_me, get_teams, get_team_members) with scopes

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
- Updated 60+ tools with required and accepted OAuth scopes
- Added scopes to: gists, git, notifications, projects, code scanning,
  dependabot, secret scanning, security advisories, actions, discussions,
  issues (partial), labels, pull requests (partial), repositories (partial), search (partial)
- Remaining: ~20 tools in issues, pullrequests, repositories, and search files

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
- Updated all remaining tools with OAuth scope information
- Added scope documentation generation to generate-docs command
- Documentation now shows Required and Accepted OAuth scopes for each tool
- All 100+ tools now have scope information defined
- Tests pass, linter passes, documentation generated successfully

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
- Replace NewToolWithScopes with updated NewTool that includes scope parameters
- All tools now use the same constructor with explicit scope requirements
- Documentation only shows accepted scopes when they differ from required
- Removed NewToolWithScopes and NewToolFromHandlerWithScopes helper functions

Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com>
- Add ScopeHierarchy map defining parent-child scope relationships
- Add ExpandScopes() function to derive accepted scopes from required scopes
- Update NewTool/NewToolFromHandler to take []scopes.Scope and auto-derive AcceptedScopes
- Add new scope constants: NoScope, User, ReadUser, UserEmail, ReadPackages, WritePackages
- Update all tool files to use new signature with typed scopes
- Add comprehensive tests for ExpandScopes

The scope hierarchy allows automatic derivation of accepted scopes:
- repo → public_repo, security_events
- admin:org → write:org → read:org
- project → read:project
- write:packages → read:packages
- user → read:user, user:email

This enables the remote server to consume scope info directly from OSS tools.
public_repo is implicit - the GitHub API handles the distinction between
public and private repos. Using repo as the required scope is more
consistent with our enforcement model:
- PATs: tools visible if token has repo scope
- OAuth: scope challenge requests repo scope
@SamMorrowDrums SamMorrowDrums force-pushed the copilot/add-oauth-scopes-documentation branch from c4c6491 to 742dfe3 Compare January 5, 2026 13:31
Map iteration in Go is non-deterministic, which causes doc generation
to produce different output on each run. Sort the scope slices in:
- ScopeSet.ToSlice()
- ScopeSet.ToStringSlice()
- ExpandScopes()
@SamMorrowDrums SamMorrowDrums marked this pull request as ready for review January 5, 2026 13:42
Copilot AI review requested due to automatic review settings January 5, 2026 13:42
@SamMorrowDrums SamMorrowDrums requested a review from a team as a code owner January 5, 2026 13:42
Copy link
Contributor

Copilot AI 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 OAuth scope metadata infrastructure to all 100+ MCP tools, enabling users and systems to understand permission requirements for each tool. The implementation creates a new typed scope system with automatic scope hierarchy expansion and conditional documentation display.

Key changes:

  • Created pkg/scopes package with typed OAuth scope constants and hierarchy-aware expansion logic
  • Extended tool infrastructure to include RequiredScopes and AcceptedScopes metadata fields
  • Updated all tool definitions with explicit scope requirements
  • Enhanced documentation generation to display scope information conditionally

Reviewed changes

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

Show a summary per file
File Description
pkg/scopes/scopes.go New package defining OAuth scope constants, hierarchy, and expansion logic that automatically derives accepted scopes from required scopes
pkg/scopes/scopes_test.go Comprehensive test coverage for scope expansion and hierarchy validation
pkg/inventory/server_tool.go Added RequiredScopes and AcceptedScopes fields to ServerTool struct for scope metadata storage
pkg/github/dependencies.go Updated NewTool and NewToolFromHandler constructors to accept scope parameters and populate scope fields automatically
pkg/github/actions.go Added scopes.Repo requirement to all GitHub Actions workflow tools
pkg/github/code_scanning.go Added scopes.SecurityEvents requirement to code scanning alert tools
pkg/github/context_tools.go Added nil scopes for get_me (public), scopes.ReadOrg for team tools
pkg/github/dependabot.go Added scopes.SecurityEvents requirement to Dependabot alert tools
pkg/github/discussions.go Added scopes.Repo requirement to all discussion tools
pkg/github/gists.go Added nil scopes for read operations, scopes.Gist for write operations
pkg/github/git.go Added scopes.Repo requirement to repository tree tool
pkg/github/issues.go Added scopes.Repo for most issue tools, scopes.ReadOrg for list_issue_types
pkg/github/labels.go Added scopes.Repo requirement to all label tools
pkg/github/notifications.go Added scopes.Notifications requirement to all notification tools
pkg/github/projects.go Added scopes.ReadProject for read tools, scopes.Project for write tools
pkg/github/pullrequests.go Added scopes.Repo requirement to all pull request tools
pkg/github/repositories.go Added scopes.Repo to most repository tools; incorrectly uses scopes.Repo instead of scopes.PublicRepo for star/unstar operations
pkg/github/search.go Added scopes.Repo for repository/code/user search, scopes.ReadOrg for org search
pkg/github/secret_scanning.go Added scopes.SecurityEvents requirement to secret scanning alert tools
pkg/github/security_advisories.go Added scopes.SecurityEvents requirement to all security advisory tools
cmd/github-mcp-server/generate_docs.go Enhanced to display OAuth scopes with conditional logic (shows accepted scopes only when they differ from required)
README.md Generated documentation now displays OAuth scope requirements for all tools with proper conditional formatting

Required: []string{"owner", "repo"},
},
},
[]scopes.Scope{scopes.Repo},
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

According to the PR description's scope mapping, star_repository should require the public_repo scope (not repo). The mapping shows:

  • required_scopes: public_repo
  • accepted_scopes: public_repo, repo

This should use []scopes.Scope{scopes.PublicRepo} instead of []scopes.Scope{scopes.Repo}.

Suggested change
[]scopes.Scope{scopes.Repo},
[]scopes.Scope{scopes.PublicRepo},

Copilot uses AI. Check for mistakes.
Required: []string{"owner", "repo"},
},
},
[]scopes.Scope{scopes.Repo},
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

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

According to the PR description's scope mapping, unstar_repository should require the public_repo scope (not repo). The mapping shows:

  • required_scopes: public_repo
  • accepted_scopes: public_repo, repo

This should use []scopes.Scope{scopes.PublicRepo} instead of []scopes.Scope{scopes.Repo}.

Suggested change
[]scopes.Scope{scopes.Repo},
[]scopes.Scope{scopes.PublicRepo},

Copilot uses AI. Check for mistakes.
@SamMorrowDrums SamMorrowDrums merged commit 48744ca into main Jan 5, 2026
22 checks passed
@SamMorrowDrums SamMorrowDrums deleted the copilot/add-oauth-scopes-documentation branch January 5, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants