Add PAT scope filtering for stdio server#1741
Merged
SamMorrowDrums merged 13 commits intomainfrom Jan 5, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds PAT (Personal Access Token) scope filtering for the stdio server, enabling the server to hide tools that require OAuth scopes not granted to the token. The implementation fetches token scopes via an HTTP HEAD request to GitHub's API and applies filtering at server startup.
Key changes:
- New
pkg/scopespackage with scope hierarchy-aware filtering and HTTP-based scope fetching - Integration with the inventory system to filter tools based on token scopes
- Opt-in
--enable-scope-filteringCLI flag (disabled by default for graceful degradation)
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pkg/scopes/filter.go | Package documentation for scope filtering utilities |
| pkg/scopes/scopes.go | Adds HasRequiredScopes function and internal expandScopeSet helper for hierarchy-aware scope checking |
| pkg/scopes/scopes_test.go | Comprehensive test coverage for scope expansion and filtering logic |
| pkg/scopes/fetcher.go | HTTP fetcher implementation that retrieves token scopes via HEAD request to GitHub API |
| pkg/scopes/fetcher_test.go | Unit tests for scope fetcher with mock HTTP servers |
| pkg/github/scope_filter.go | Creates CreateToolScopeFilter function that bridges scopes package with inventory system |
| pkg/github/scope_filter_test.go | Tests for scope filter integration with inventory builder |
| internal/ghmcp/server.go | Integrates scope filtering into server startup, adding TokenScopes config field and fetchTokenScopesForHost helper |
| cmd/github-mcp-server/main.go | Adds --enable-scope-filtering CLI flag with viper binding |
| README.md | Auto-generated documentation updates showing reordered accepted scopes (cosmetic) |
c4c6491 to
742dfe3
Compare
a496f06 to
7c31fda
Compare
Base automatically changed from
copilot/add-oauth-scopes-documentation
to
main
January 5, 2026 15:54
The base branch was changed.
Add the ability to filter tools based on token scopes for PAT users. This uses an HTTP HEAD request to GitHub's API to discover token scopes. New components: - pkg/scopes/filter.go: HasRequiredScopes checks if scopes satisfy tool requirements - pkg/scopes/fetcher.go: FetchTokenScopes gets scopes via HTTP HEAD to GitHub API - pkg/github/scope_filter.go: CreateScopeFilter creates inventory.ToolFilter Integration: - Add --filter-by-scope flag to stdio command (disabled by default) - When enabled, fetches token scopes on startup - Tools requiring unavailable scopes are hidden from tool list - Gracefully continues without filtering if scope fetch fails (logs warning) This allows the OSS server to have similar scope-based tool visibility as the remote server, and the filter logic can be reused by remote server.
Scope filtering is now a built-in feature rather than a configurable option. The server automatically fetches token scopes at startup and filters tools accordingly. If scope detection fails, it logs a warning and continues with all tools available.
- Scope filtering only applies to classic PATs which return X-OAuth-Scopes - Fine-grained PATs and other token types skip filtering (all tools shown) - Updated docs to clarify PAT filtering vs OAuth scope challenges
The README already has auto-generated tool documentation with scopes. Keep only the scope hierarchy explanation which is structural.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
e04a578 to
9bf0cf5
Compare
omgitsads
approved these changes
Jan 5, 2026
SamMorrowDrums
added a commit
that referenced
this pull request
Jan 19, 2026
Documents the new OAuth scope handling capabilities including: - OAuth scope challenges (MCP step-up auth) for remote server - PAT scope filtering for local/stdio server - Documented scopes for all MCP tools - New list-scopes CLI command Related PRs: - github-mcp-server: #1679, #1741, #1750, #1650 - github-mcp-server-remote: #503, #609, #618
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Automatically filter tools based on the user's PAT OAuth scopes. This ensures users only see tools their token has permission to use, reducing clutter and preventing errors from attempting operations without the required scopes.
How It Works
ghp_prefix)X-OAuth-ScopesheaderToken Type Behavior
ghp_)github_pat_)Changes
New Components in
pkg/scopes/filter.go:HasRequiredScopes()checks if user scopes satisfy tool requirements using the scope hierarchyfetcher.go:FetchTokenScopes()gets token scopes via HTTP HEAD request (readsX-OAuth-Scopesheader)New Components in
pkg/github/scope_filter.go:CreateScopeFilter()creates aninventory.ToolFilterfor scope-based filteringIntegration
docs/scope-filtering.mdLibrary Usage (for Remote Server)
The scope filtering logic is designed to be reusable:
Testing
HasRequiredScopesFetchTokenScopeswith mock HTTP serverCreateScopeFilterStacked On
This PR is stacked on #1740 (scope hierarchy PR) which provides the
ExpandScopesfunction and scope definitions used here.