chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
# Error Handling
|
||||
|
||||
This document describes the error handling patterns used in the GitHub MCP Server, specifically how we handle GitHub API errors and avoid direct use of mcp-go error types.
|
||||
|
||||
## Overview
|
||||
|
||||
The GitHub MCP Server implements a custom error handling approach that serves two primary purposes:
|
||||
|
||||
1. **Tool Response Generation**: Return appropriate MCP tool error responses to clients
|
||||
2. **Middleware Inspection**: Store detailed error information in the request context for middleware analysis
|
||||
|
||||
This dual approach enables better observability and debugging capabilities, particularly for remote server deployments where understanding the nature of failures (rate limiting, authentication, 404s, 500s, etc.) is crucial for validation and monitoring.
|
||||
|
||||
## Error Types
|
||||
|
||||
### GitHubAPIError
|
||||
|
||||
Used for REST API errors from the GitHub API:
|
||||
|
||||
```go
|
||||
type GitHubAPIError struct {
|
||||
Message string `json:"message"`
|
||||
Response *github.Response `json:"-"`
|
||||
Err error `json:"-"`
|
||||
}
|
||||
```
|
||||
|
||||
### GitHubGraphQLError
|
||||
|
||||
Used for GraphQL API errors from the GitHub API:
|
||||
|
||||
```go
|
||||
type GitHubGraphQLError struct {
|
||||
Message string `json:"message"`
|
||||
Err error `json:"-"`
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Patterns
|
||||
|
||||
### For GitHub REST API Errors
|
||||
|
||||
Instead of directly returning `mcp.NewToolResultError()`, use:
|
||||
|
||||
```go
|
||||
return ghErrors.NewGitHubAPIErrorResponse(ctx, message, response, err), nil
|
||||
```
|
||||
|
||||
This function:
|
||||
- Creates a `GitHubAPIError` with the provided message, response, and error
|
||||
- Stores the error in the context for middleware inspection
|
||||
- Returns an appropriate MCP tool error response
|
||||
|
||||
### For GitHub GraphQL API Errors
|
||||
|
||||
```go
|
||||
return ghErrors.NewGitHubGraphQLErrorResponse(ctx, message, err), nil
|
||||
```
|
||||
|
||||
### Context Management
|
||||
|
||||
The error handling system uses context to store errors for later inspection:
|
||||
|
||||
```go
|
||||
// Initialize context with error tracking
|
||||
ctx = errors.ContextWithGitHubErrors(ctx)
|
||||
|
||||
// Retrieve errors for inspection (typically in middleware)
|
||||
apiErrors, err := errors.GetGitHubAPIErrors(ctx)
|
||||
graphqlErrors, err := errors.GetGitHubGraphQLErrors(ctx)
|
||||
```
|
||||
|
||||
## Design Principles
|
||||
|
||||
### User-Actionable vs. Developer Errors
|
||||
|
||||
- **User-actionable errors** (authentication failures, rate limits, 404s) should be returned as failed tool calls using the error response functions
|
||||
- **Developer errors** (JSON marshaling failures, internal logic errors) should be returned as actual Go errors that bubble up through the MCP framework
|
||||
|
||||
### Context Limitations
|
||||
|
||||
This approach was designed to work around current limitations in mcp-go where context is not propagated through each step of request processing. By storing errors in context values, middleware can inspect them without requiring context propagation.
|
||||
|
||||
### Graceful Error Handling
|
||||
|
||||
Error storage operations in context are designed to fail gracefully - if context storage fails, the tool will still return an appropriate error response to the client.
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Observability**: Middleware can inspect the specific types of GitHub API errors occurring
|
||||
2. **Debugging**: Detailed error information is preserved without exposing potentially sensitive data in logs
|
||||
3. **Validation**: Remote servers can use error types and HTTP status codes to validate that changes don't break functionality
|
||||
4. **Privacy**: Error inspection can be done programmatically using `errors.Is` checks without logging PII
|
||||
|
||||
## Example Implementation
|
||||
|
||||
```go
|
||||
func GetIssue(getClient GetClientFn, t translations.TranslationHelperFunc) (tool mcp.Tool, handler server.ToolHandlerFunc) {
|
||||
return mcp.NewTool("get_issue", /* ... */),
|
||||
func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||
owner, err := RequiredParam[string](request, "owner")
|
||||
if err != nil {
|
||||
return mcp.NewToolResultError(err.Error()), nil
|
||||
}
|
||||
|
||||
client, err := getClient(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get GitHub client: %w", err)
|
||||
}
|
||||
|
||||
issue, resp, err := client.Issues.Get(ctx, owner, repo, issueNumber)
|
||||
if err != nil {
|
||||
return ghErrors.NewGitHubAPIErrorResponse(ctx,
|
||||
"failed to get issue",
|
||||
resp,
|
||||
err,
|
||||
), nil
|
||||
}
|
||||
|
||||
return MarshalledTextResult(issue), nil
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This approach ensures that both the client receives an appropriate error response and any middleware can inspect the underlying GitHub API error for monitoring and debugging purposes.
|
||||
@@ -0,0 +1,431 @@
|
||||
# Feature Flags
|
||||
|
||||
Feature flags let you opt into experimental tool behavior on top of the default
|
||||
GitHub MCP Server surface. Insiders Mode turns on a curated subset of these
|
||||
flags automatically — see [Insiders Features](./insiders-features.md) for that
|
||||
specific set.
|
||||
|
||||
For background on how flags resolve at request time, see the [resolution
|
||||
section in the Insiders docs](./insiders-features.md#how-feature-flags-are-resolved).
|
||||
|
||||
## Enabling a flag
|
||||
|
||||
| Method | Remote Server | Local Server |
|
||||
|--------|---------------|--------------|
|
||||
| Header | `X-MCP-Features: <flag>,<flag>` | N/A |
|
||||
| CLI flag | N/A | `--features=<flag>,<flag>` |
|
||||
| Environment variable | N/A | `GITHUB_FEATURES=<flag>,<flag>` |
|
||||
|
||||
Only flags listed in
|
||||
[`AllowedFeatureFlags`](../pkg/github/feature_flags.go) can be enabled by
|
||||
end users. Insiders-only flags are not user-toggleable.
|
||||
|
||||
---
|
||||
|
||||
## Tools affected by each flag
|
||||
|
||||
The list below is regenerated from the Go source. For each user-controllable
|
||||
feature flag, it lists every tool whose **inventory or input schema** differs
|
||||
from the default — either because the flag introduces a new tool, or because
|
||||
it selects a flag-aware variant of an existing tool. Flags that only affect
|
||||
runtime behavior (such as output formatting) won't appear here.
|
||||
|
||||
<!-- START AUTOMATED FEATURE FLAG TOOLS -->
|
||||
|
||||
### `remote_mcp_ui_apps`
|
||||
|
||||
- **create_pull_request** - Open new pull request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- **MCP App UI**: `ui://github-mcp-server/pr-write`
|
||||
- `base`: Branch to merge into (string, required)
|
||||
- `body`: PR description (string, optional)
|
||||
- `draft`: Create as draft PR (boolean, optional)
|
||||
- `head`: Branch containing changes (string, required)
|
||||
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
|
||||
- `title`: PR title (string, required)
|
||||
|
||||
- **get_me** - Get my user profile
|
||||
- **MCP App UI**: `ui://github-mcp-server/get-me`
|
||||
- No parameters required
|
||||
|
||||
- **issue_write** - Create or update issue/pull request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- **MCP App UI**: `ui://github-mcp-server/issue-write`
|
||||
- `assignees`: Usernames to assign to this issue (string[], optional)
|
||||
- `body`: Issue body content (string, optional)
|
||||
- `duplicate_of`: Issue number that this issue is a duplicate of. Only used when state_reason is 'duplicate'. (number, optional)
|
||||
- `issue_fields`: Issue field values to set or clear. Each item requires 'field_name' and exactly one of 'value', 'field_option_name', or 'delete: true'. (object[], optional)
|
||||
- `issue_number`: Issue number to update (number, optional)
|
||||
- `labels`: Labels to apply to this issue (string[], optional)
|
||||
- `method`: Write operation to perform on a single issue.
|
||||
Options are:
|
||||
- 'create' - creates a new issue.
|
||||
- 'update' - updates an existing issue.
|
||||
(string, required)
|
||||
- `milestone`: Milestone number (number, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `state`: New state (string, optional)
|
||||
- `state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
|
||||
- `title`: Issue title (string, optional)
|
||||
- `type`: Type of this issue. Only use if issue types are enabled for this repository. Use list_issue_types tool to get valid type values for this repository or its owner organization. If the repository doesn't support issue types, omit this parameter. (string, optional)
|
||||
|
||||
- **ui_get** - Get UI data
|
||||
- **Required OAuth Scopes (any of)**: `repo`, `read:org`
|
||||
- **Accepted OAuth Scopes**: `admin:org`, `read:org`, `repo`, `write:org`
|
||||
- `method`: The type of data to fetch (string, required)
|
||||
- `owner`: Repository owner (required for all methods) (string, required)
|
||||
- `repo`: Repository name (required for labels, assignees, milestones, branches, issue fields, reviewers) (string, optional)
|
||||
|
||||
- **update_pull_request** - Edit pull request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- **MCP App UI**: `ui://github-mcp-server/pr-edit`
|
||||
- `base`: New base branch name (string, optional)
|
||||
- `body`: New description (string, optional)
|
||||
- `draft`: Mark pull request as draft (true) or ready for review (false) (boolean, optional)
|
||||
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `pullNumber`: Pull request number to update (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
|
||||
- `state`: New state (string, optional)
|
||||
- `title`: New title (string, optional)
|
||||
|
||||
### `issues_granular`
|
||||
|
||||
- **add_issue_comment_reaction** - Add Reaction to Issue or Pull Request Comment
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `comment_id`: The issue or pull request comment ID (number, required)
|
||||
- `content`: The emoji reaction type (string, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **add_issue_reaction** - Add Reaction to Issue or Pull Request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `content`: The emoji reaction type (string, required)
|
||||
- `issue_number`: The issue number (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **add_sub_issue** - Add Sub-Issue
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The parent issue number (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `replace_parent`: If true, reparent the sub-issue if it already has a parent (boolean, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `sub_issue_id`: The ID of the sub-issue to add. ID is not the same as issue number (number, required)
|
||||
|
||||
- **create_issue** - Create Issue
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `body`: Issue body content (optional) (string, optional)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `title`: Issue title (string, required)
|
||||
|
||||
- **remove_sub_issue** - Remove Sub-Issue
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The parent issue number (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `sub_issue_id`: The ID of the sub-issue to remove. ID is not the same as issue number (number, required)
|
||||
|
||||
- **reprioritize_sub_issue** - Reprioritize Sub-Issue
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `after_id`: The ID of the sub-issue to place this after (either after_id OR before_id should be specified) (number, optional)
|
||||
- `before_id`: The ID of the sub-issue to place this before (either after_id OR before_id should be specified) (number, optional)
|
||||
- `issue_number`: The parent issue number (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `sub_issue_id`: The ID of the sub-issue to reorder. ID is not the same as issue number (number, required)
|
||||
|
||||
- **set_issue_fields** - Set Issue Fields
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `fields`: Array of issue field values to set. Each element must have a 'field_id' (string, the GraphQL node ID of the field) and exactly one value field: 'text_value' for text fields, 'number_value' for number fields, 'date_value' (ISO 8601 date string) for date fields, or 'single_select_option_id' (the GraphQL node ID of the option) for single select fields. Set 'delete' to true to remove a field value. (object[], required)
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_issue_assignees** - Update Issue Assignees
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `assignees`: GitHub usernames to assign to this issue. ([], required)
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_issue_body** - Update Issue Body
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `body`: The new body content for the issue (string, required)
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_issue_labels** - Update Issue Labels
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `labels`: Labels to apply to this issue. ([], required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_issue_milestone** - Update Issue Milestone
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `milestone`: The milestone number to set on the issue (integer, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_issue_state** - Update Issue State
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `confidence`: How confident you are in this choice. Use 'HIGH' for clear signal or explicit user request, 'MEDIUM' for reasonable inference with some ambiguity, 'LOW' for best guess with limited signal. (string, optional)
|
||||
- `duplicate_of`: The issue number of the canonical issue this issue duplicates. Only valid when state_reason is 'duplicate'. Required when is_suggestion is true and state_reason is 'duplicate'. The issue number is resolved to a database ID before being sent to the API. (number, optional)
|
||||
- `is_suggestion`: If true, this state change is sent to the API as a suggestion (suggest:true) rather than an applied change. Whether the change is applied or recorded as a proposal is determined by the API. (boolean, optional)
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `rationale`: One concise sentence explaining what specifically about the issue led you to choose this state. State the concrete signal (e.g. 'The reported crash is fixed in v2.1' → completed). (string, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `state`: The new state for the issue (string, required)
|
||||
- `state_reason`: The reason for the state change (only for closed state) (string, optional)
|
||||
|
||||
- **update_issue_title** - Update Issue Title
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `title`: The new title for the issue (string, required)
|
||||
|
||||
- **update_issue_type** - Update Issue Type
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `confidence`: How confident you are in this choice. Use 'HIGH' for clear signal or explicit user request, 'MEDIUM' for reasonable inference with some ambiguity, 'LOW' for best guess with limited signal. (string, optional)
|
||||
- `is_suggestion`: If true, this issue type change is sent to the API as a suggestion (suggest:true) rather than an applied value. Whether the type is applied or recorded as a proposal is determined by the API. (boolean, optional)
|
||||
- `issue_number`: The issue number to update (number, required)
|
||||
- `issue_type`: The issue type to set (string, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `rationale`: One concise sentence explaining what specifically about the issue led you to choose this type. State the concrete signal (e.g. 'Reports a crash when saving' → bug, 'Asks for dark mode support' → feature). (string, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
### `pull_requests_granular`
|
||||
|
||||
- **add_pull_request_review_comment** - Add Pull Request Review Comment
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `body`: The comment body (string, required)
|
||||
- `line`: The line number in the diff to comment on (optional) (number, optional)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `path`: The relative path of the file to comment on (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `side`: The side of the diff to comment on (optional) (string, optional)
|
||||
- `startLine`: The start line of a multi-line comment (optional) (number, optional)
|
||||
- `startSide`: The start side of a multi-line comment (optional) (string, optional)
|
||||
- `subjectType`: The subject type of the comment (string, required)
|
||||
|
||||
- **add_pull_request_review_comment_reaction** - Add Pull Request Review Comment Reaction
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `comment_id`: The numeric pull request review comment ID. Use the number from a #discussion_r... anchor, not the GraphQL thread node ID (PRRT_...). (number, required)
|
||||
- `content`: The emoji reaction type (string, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **create_pull_request_review** - Create Pull Request Review
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `body`: The review body text (optional) (string, optional)
|
||||
- `commitID`: The SHA of the commit to review (optional, defaults to latest) (string, optional)
|
||||
- `event`: The review action to perform. If omitted, creates a pending review. (string, optional)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **delete_pending_pull_request_review** - Delete Pending Pull Request Review
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **request_pull_request_reviewers** - Request Pull Request Reviewers
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], required)
|
||||
|
||||
- **resolve_review_thread** - Resolve Review Thread
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `threadID`: The node ID of the review thread to resolve (e.g., PRRT_kwDOxxx) (string, required)
|
||||
|
||||
- **submit_pending_pull_request_review** - Submit Pending Pull Request Review
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `body`: The review body text (optional) (string, optional)
|
||||
- `event`: The review action to perform (string, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **unresolve_review_thread** - Unresolve Review Thread
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `threadID`: The node ID of the review thread to unresolve (e.g., PRRT_kwDOxxx) (string, required)
|
||||
|
||||
- **update_pull_request_body** - Update Pull Request Body
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `body`: The new body content for the pull request (string, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_pull_request_draft_state** - Update Pull Request Draft State
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `draft`: Set to true to convert to draft, false to mark as ready for review (boolean, required)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **update_pull_request_state** - Update Pull Request State
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `state`: The new state for the pull request (string, required)
|
||||
|
||||
- **update_pull_request_title** - Update Pull Request Title
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `pullNumber`: The pull request number (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `title`: The new title for the pull request (string, required)
|
||||
|
||||
### `file_blame`
|
||||
|
||||
- **get_file_blame** - Get file blame information
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `after`: Cursor for pagination. Use the cursor from the previous response. (string, optional)
|
||||
- `end_line`: Optional 1-based ending line of the window of interest. Must be >= start_line when both are provided. (number, optional)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `path`: Path to the file in the repository, relative to the repository root (string, required)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `ref`: Git reference (branch, tag, or commit SHA). Defaults to the repository's default branch (HEAD). (string, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `start_line`: Optional 1-based starting line of the window of interest. Only ranges overlapping [start_line, end_line] are returned, clamped to the window. (number, optional)
|
||||
|
||||
### `issue_dependencies`
|
||||
|
||||
- **issue_dependency_read** - Read issue dependencies
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The number of the issue (number, required)
|
||||
- `method`: The read operation to perform on a single issue's dependencies.
|
||||
Options are:
|
||||
1. get_blocked_by - List the issues that block this issue (this issue is blocked by them).
|
||||
2. get_blocking - List the issues that this issue blocks.
|
||||
(string, required)
|
||||
- `owner`: The owner of the repository (string, required)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `repo`: The name of the repository (string, required)
|
||||
|
||||
- **issue_dependency_write** - Change issue dependency
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The number of the subject issue (number, required)
|
||||
- `method`: The action to perform.
|
||||
Options are:
|
||||
- 'add' - create the dependency relationship.
|
||||
- 'remove' - delete the dependency relationship. (string, required)
|
||||
- `owner`: The owner of the subject issue's repository (string, required)
|
||||
- `related_issue_number`: The number of the related issue to link or unlink (number, required)
|
||||
- `related_owner`: The owner of the related issue's repository. Defaults to 'owner' when omitted. (string, optional)
|
||||
- `related_repo`: The name of the related issue's repository. Defaults to 'repo' when omitted. (string, optional)
|
||||
- `repo`: The name of the subject issue's repository (string, required)
|
||||
- `type`: The relationship direction relative to the subject issue.
|
||||
Options are:
|
||||
- 'blocked_by' - the subject issue is blocked by the related issue.
|
||||
- 'blocking' - the subject issue blocks the related issue. (string, required)
|
||||
|
||||
### `fields_param`
|
||||
|
||||
- **get_file_contents** - Get file or directory contents
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `fields`: Subset of fields to return for each entry when the path is a directory. If omitted, all fields are returned. Ignored when the path is a single file. Use this to reduce response size when listing directories and you only need specific fields, e.g. just 'name' and 'type'. (string[], optional)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `path`: Path to file/directory (string, optional)
|
||||
- `ref`: Accepts optional git refs such as `refs/tags/{tag}`, `refs/heads/{branch}` or `refs/pull/{pr_number}/head` (string, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `sha`: Accepts optional commit SHA. If specified, it will be used instead of ref (string, optional)
|
||||
|
||||
- **list_commits** - List commits
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `author`: Author username or email address to filter commits by (string, optional)
|
||||
- `fields`: Subset of fields to return for each commit. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields, e.g. just 'sha' and 'html_url'. (string[], optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `path`: Only commits containing this file path will be returned (string, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `sha`: Commit SHA, branch or tag name to list commits of. If not provided, uses the default branch of the repository. If a commit SHA is provided, will list commits up to that SHA. (string, optional)
|
||||
- `since`: Only commits after this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD) (string, optional)
|
||||
- `until`: Only commits before this date will be returned (ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ or YYYY-MM-DD) (string, optional)
|
||||
|
||||
- **list_issues** - List issues
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `after`: Cursor for pagination. Use the cursor from the previous response. (string, optional)
|
||||
- `direction`: Order direction. If provided, the 'orderBy' also needs to be provided. (string, optional)
|
||||
- `field_filters`: Filter by custom issue field values. Each entry takes a field_name and a value; the server looks up the field and coerces the value to its type (single-select option name, text, number, or YYYY-MM-DD date). (object[], optional)
|
||||
- `fields`: Subset of fields to return for each issue. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' and 'field_values' in particular drops the largest per-result data. (string[], optional)
|
||||
- `labels`: Filter by labels (string[], optional)
|
||||
- `orderBy`: Order issues by field. If provided, the 'direction' also needs to be provided. (string, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `since`: Filter by date (ISO 8601 timestamp) (string, optional)
|
||||
- `state`: Filter by state, by default both open and closed issues are returned when not provided (string, optional)
|
||||
|
||||
- **list_pull_requests** - List pull requests
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `base`: Filter by base branch (string, optional)
|
||||
- `direction`: Sort direction (string, optional)
|
||||
- `fields`: Subset of fields to return for each pull request. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-result data. (string[], optional)
|
||||
- `head`: Filter by head user/org and branch (string, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `sort`: Sort by (string, optional)
|
||||
- `state`: Filter by state (string, optional)
|
||||
|
||||
- **list_releases** - List releases
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `fields`: Subset of fields to return for each release. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body' in particular drops the largest per-release data. (string[], optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
|
||||
- **search_code** - Search code
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `fields`: Subset of fields to return for each code search result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'repository' and 'text_matches' in particular drops the largest per-result data. (string[], optional)
|
||||
- `order`: Sort order for results (string, optional)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `query`: Search query (GitHub code search REST). Implicit AND between terms; supports `OR`, `NOT`, and `"quoted phrase"` for exact match. Qualifiers: `repo:owner/repo`, `org:`, `user:`, `language:`, `path:dir` (prefix match), `filename:exact.ext`, `extension:`, `in:file`, `in:path`, `size:`, `is:archived`, `is:fork`. Max 256 chars. Examples: `WithContext language:go org:github`; `"package main" repo:o/r`; `func extension:go path:cmd repo:o/r`; `NOT TODO language:go repo:o/r`. (string, required)
|
||||
- `sort`: Sort field ('indexed' only) (string, optional)
|
||||
|
||||
- **search_issues** - Search issues
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `fields`: Subset of fields to return for each issue result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data. (string[], optional)
|
||||
- `order`: Sort order (string, optional)
|
||||
- `owner`: Optional repository owner. If provided with repo, only issues for this repository are listed. (string, optional)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `query`: Search query using GitHub issues search syntax (string, required)
|
||||
- `repo`: Optional repository name. If provided with owner, only issues for this repository are listed. (string, optional)
|
||||
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
|
||||
|
||||
- **search_pull_requests** - Search pull requests
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `fields`: Subset of fields to return for each pull request result. If omitted, all fields are returned. Use this to reduce response size when you only need specific fields; omitting 'body', 'reactions', and 'labels' in particular drops the largest per-result data. (string[], optional)
|
||||
- `order`: Sort order (string, optional)
|
||||
- `owner`: Optional repository owner. If provided with repo, only pull requests for this repository are listed. (string, optional)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `query`: Search query using GitHub pull request search syntax (string, required)
|
||||
- `repo`: Optional repository name. If provided with owner, only pull requests for this repository are listed. (string, optional)
|
||||
- `sort`: Sort field by number of matches of categories, defaults to best match (string, optional)
|
||||
|
||||
<!-- END AUTOMATED FEATURE FLAG TOOLS -->
|
||||
@@ -0,0 +1,193 @@
|
||||
# GitHub Remote MCP Integration Guide for MCP Host Authors
|
||||
|
||||
This guide outlines high-level considerations for MCP Host authors who want to allow installation of the Remote GitHub MCP server.
|
||||
|
||||
The goal is to explain the architecture at a high-level, define key requirements, and provide guidance to get you started, while pointing to official documentation for deeper implementation details.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Understanding MCP Architecture](#understanding-mcp-architecture)
|
||||
- [Connecting to the Remote GitHub MCP Server](#connecting-to-the-remote-github-mcp-server)
|
||||
- [Authentication and Authorization](#authentication-and-authorization)
|
||||
- [OAuth Support on GitHub](#oauth-support-on-github)
|
||||
- [Create an OAuth-enabled App Using the GitHub UI](#create-an-oauth-enabled-app-using-the-github-ui)
|
||||
- [Things to Consider](#things-to-consider)
|
||||
- [Initiating the OAuth Flow from your Client Application](#initiating-the-oauth-flow-from-your-client-application)
|
||||
- [Handling Organization Access Restrictions](#handling-organization-access-restrictions)
|
||||
- [Essential Security Considerations](#essential-security-considerations)
|
||||
- [Additional Resources](#additional-resources)
|
||||
|
||||
---
|
||||
|
||||
## Understanding MCP Architecture
|
||||
|
||||
The Model Context Protocol (MCP) enables seamless communication between your application and various external tools through an architecture defined by the [MCP Standard](https://modelcontextprotocol.io/).
|
||||
|
||||
### High-level Architecture
|
||||
|
||||
The diagram below illustrates how a single client application can connect to multiple MCP Servers, each providing access to a unique set of resources. Notice that some MCP Servers are running locally (side-by-side with the client application) while others are hosted remotely. GitHub's MCP offerings are available to run either locally or remotely.
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph "Local Runtime Environment"
|
||||
subgraph "Client Application (e.g., IDE)"
|
||||
CLIENTAPP[Application Runtime]
|
||||
CX["MCP Client (FileSystem)"]
|
||||
CY["MCP Client (GitHub)"]
|
||||
CZ["MCP Client (Other)"]
|
||||
end
|
||||
|
||||
LOCALMCP[File System MCP Server]
|
||||
end
|
||||
|
||||
subgraph "Internet"
|
||||
GITHUBMCP[GitHub Remote MCP Server]
|
||||
OTHERMCP[Other Remote MCP Server]
|
||||
end
|
||||
|
||||
CLIENTAPP --> CX
|
||||
CLIENTAPP --> CY
|
||||
CLIENTAPP --> CZ
|
||||
|
||||
CX <-->|"stdio"| LOCALMCP
|
||||
CY <-->|"OAuth 2.0 + HTTP/SSE"| GITHUBMCP
|
||||
CZ <-->|"OAuth 2.0 + HTTP/SSE"| OTHERMCP
|
||||
```
|
||||
|
||||
### Runtime Environment
|
||||
|
||||
- **Application**: The user-facing application you are building. It instantiates one or more MCP clients and orchestrates tool calls.
|
||||
- **MCP Client**: A component within your client application that maintains a 1:1 connection with a single MCP server.
|
||||
- **MCP Server**: A service that provides access to a specific set of tools.
|
||||
- **Local MCP Server**: An MCP Server running locally, side-by-side with the Application.
|
||||
- **Remote MCP Server**: An MCP Server running remotely, accessed via the internet. Most Remote MCP Servers require authentication via OAuth.
|
||||
|
||||
For more detail, see the [official MCP specification](https://modelcontextprotocol.io/specification/2025-06-18).
|
||||
|
||||
> [!NOTE]
|
||||
> GitHub offers both a Local MCP Server and a Remote MCP Server.
|
||||
|
||||
---
|
||||
|
||||
## Connecting to the Remote GitHub MCP Server
|
||||
|
||||
### Authentication and Authorization
|
||||
|
||||
GitHub MCP Servers require a valid access token in the `Authorization` header. This is true for both the Local GitHub MCP Server and the Remote GitHub MCP Server.
|
||||
|
||||
For the Remote GitHub MCP Server, the recommended way to obtain a valid access token is to ensure your client application supports [OAuth 2.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13). It should be noted, however, that you may also supply any valid access token. For example, you may supply a pre-generated Personal Access Token (PAT).
|
||||
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The Remote GitHub MCP Server itself does not provide Authentication services.
|
||||
> Your client application must obtain valid GitHub access tokens through one of the supported methods.
|
||||
|
||||
The expected flow for obtaining a valid access token via OAuth is depicted in the [MCP Specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization#authorization-flow-steps). For convenience, we've embedded a copy of the authorization flow below. Please study it carefully as the remainder of this document is written with this flow in mind.
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant B as User-Agent (Browser)
|
||||
participant C as Client
|
||||
participant M as MCP Server (Resource Server)
|
||||
participant A as Authorization Server
|
||||
|
||||
C->>M: MCP request without token
|
||||
M->>C: HTTP 401 Unauthorized with WWW-Authenticate header
|
||||
Note over C: Extract resource_metadata URL from WWW-Authenticate
|
||||
|
||||
C->>M: Request Protected Resource Metadata
|
||||
M->>C: Return metadata
|
||||
|
||||
Note over C: Parse metadata and extract authorization server(s)<br/>Client determines AS to use
|
||||
|
||||
C->>A: GET /.well-known/oauth-authorization-server
|
||||
A->>C: Authorization server metadata response
|
||||
|
||||
alt Dynamic client registration
|
||||
C->>A: POST /register
|
||||
A->>C: Client Credentials
|
||||
end
|
||||
|
||||
Note over C: Generate PKCE parameters
|
||||
C->>B: Open browser with authorization URL + code_challenge
|
||||
B->>A: Authorization request
|
||||
Note over A: User authorizes
|
||||
A->>B: Redirect to callback with authorization code
|
||||
B->>C: Authorization code callback
|
||||
C->>A: Token request + code_verifier
|
||||
A->>C: Access token (+ refresh token)
|
||||
C->>M: MCP request with access token
|
||||
M-->>C: MCP response
|
||||
Note over C,M: MCP communication continues with valid token
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Dynamic Client Registration is NOT supported by Remote GitHub MCP Server at this time.
|
||||
|
||||
|
||||
#### OAuth Support on GitHub
|
||||
|
||||
GitHub offers two solutions for obtaining access tokens via OAuth: [**GitHub Apps**](https://docs.github.com/en/apps/using-github-apps/about-using-github-apps#about-github-apps) and [**OAuth Apps**](https://docs.github.com/en/apps/oauth-apps). These solutions are typically created, administered, and maintained by GitHub Organization administrators. Collaborate with a GitHub Organization administrator to configure either a **GitHub App** or an **OAuth App** to allow your client application to utilize GitHub OAuth support. Furthermore, be aware that it may be necessary for users of your client application to register your **GitHub App** or **OAuth App** within their own GitHub Organization in order to generate authorization tokens capable of accessing Organization's GitHub resources.
|
||||
|
||||
> [!TIP]
|
||||
> Before proceeding, check whether your organization already supports one of these solutions. Administrators of your GitHub Organization can help you determine what **GitHub Apps** or **OAuth Apps** are already registered. If there's an existing **GitHub App** or **OAuth App** that fits your use case, consider reusing it for Remote MCP Authorization. That said, be sure to take heed of the following warning.
|
||||
|
||||
> [!WARNING]
|
||||
> Both **GitHub Apps** and **OAuth Apps** require the client application to pass a "client secret" in order to initiate the OAuth flow. If your client application is designed to run in an uncontrolled environment (i.e. customer-provided hardware), end users will be able to discover your "client secret" and potentially exploit it for other purposes. In such cases, our recommendation is to register a new **GitHub App** (or **OAuth App**) exclusively dedicated to servicing OAuth requests from your client application.
|
||||
|
||||
#### Create an OAuth-enabled App Using the GitHub UI
|
||||
|
||||
Detailed instructions for creating a **GitHub App** can be found at ["Creating GitHub Apps"](https://docs.github.com/en/apps/creating-github-apps/about-creating-github-apps/about-creating-github-apps#building-a-github-app). (RECOMMENDED)<br/>
|
||||
Detailed instructions for creating an **OAuth App** can be found ["Creating an OAuth App"](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app).
|
||||
|
||||
For guidance on which type of app to choose, see ["Differences Between GitHub Apps and OAuth Apps"](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps).
|
||||
|
||||
#### Things to Consider:
|
||||
- Tokens provided by **GitHub Apps** are generally more secure because they:
|
||||
- include an expiration
|
||||
- include support for fine-grained permissions
|
||||
- **GitHub Apps** must be installed on a GitHub Organization before they can be used.<br/>In general, installation must be approved by someone in the Organization with administrator permissions. For more details, see [this explanation](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/differences-between-github-apps-and-oauth-apps#who-can-install-github-apps-and-authorize-oauth-apps).<br/>By contrast, **OAuth Apps** don't require installation and, typically, can be used immediately.
|
||||
- Members of an Organization may use the GitHub UI to [request that a GitHub App be installed](https://docs.github.com/en/apps/using-github-apps/requesting-a-github-app-from-your-organization-owner) organization-wide.
|
||||
- While not strictly necessary, if you expect that a wide range of users will use your MCP Server, consider publishing its corresponding **GitHub App** or **OAuth App** on the [GitHub App Marketplace](https://github.com/marketplace?type=apps) to ensure that it's discoverable by your audience.
|
||||
|
||||
|
||||
#### Initiating the OAuth Flow from your Client Application
|
||||
|
||||
For **GitHub Apps**, details on initiating the OAuth flow from a client application are described in detail [here](https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-user-access-token-for-a-github-app#using-the-web-application-flow-to-generate-a-user-access-token).
|
||||
|
||||
For **OAuth Apps**, details on initiating the OAuth flow from a client application are described in detail [here](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#web-application-flow).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> For endpoint discovery, be sure to honor the [`WWW-Authenticate` information provided](https://modelcontextprotocol.io/specification/draft/basic/authorization#authorization-server-location) by the Remote GitHub MCP Server rather than relying on hard-coded endpoints like `https://github.com/login/oauth/authorize`.
|
||||
|
||||
|
||||
### Handling Organization Access Restrictions
|
||||
Organizations may block **GitHub Apps** and **OAuth Apps** until explicitly approved. Within your client application code, you can provide actionable next steps for a smooth user experience in the event that OAuth-related calls fail due to your **GitHub App** or **OAuth App** being unavailable (i.e. not registered within the user's organization).
|
||||
|
||||
1. Detect the specific error.
|
||||
2. Notify the user clearly.
|
||||
3. Depending on their GitHub organization privileges:
|
||||
- Org Members: Prompt them to request approval from a GitHub organization admin, within the organization where access has not been approved.
|
||||
- Org Admins: Link them to the corresponding GitHub organization’s App approval settings at `https://github.com/organizations/[ORG_NAME]/settings/oauth_application_policy`
|
||||
|
||||
|
||||
## Essential Security Considerations
|
||||
- **Token Storage**: Use secure platform APIs (e.g. keytar for Node.js).
|
||||
- **Input Validation**: Sanitize all tool arguments.
|
||||
- **HTTPS Only**: Never send requests over plaintext HTTP. Always use HTTPS in production.
|
||||
- **PKCE:** We strongly recommend implementing [PKCE](https://datatracker.ietf.org/doc/html/rfc7636) for all OAuth flows to prevent code interception, to prepare for upcoming PKCE support.
|
||||
|
||||
## Additional Resources
|
||||
- [MCP Official Spec](https://modelcontextprotocol.io/specification/draft)
|
||||
- [MCP SDKs](https://modelcontextprotocol.io/sdk/java/mcp-overview)
|
||||
- [GitHub Docs on Creating GitHub Apps](https://docs.github.com/en/apps/creating-github-apps)
|
||||
- [GitHub Docs on Using GitHub Apps](https://docs.github.com/en/apps/using-github-apps/about-using-github-apps)
|
||||
- [GitHub Docs on Creating OAuth Apps](https://docs.github.com/en/apps/oauth-apps)
|
||||
- GitHub Docs on Installing OAuth Apps into a [Personal Account](https://docs.github.com/en/apps/oauth-apps/using-oauth-apps/installing-an-oauth-app-in-your-personal-account) and [Organization](https://docs.github.com/en/apps/oauth-apps/using-oauth-apps/installing-an-oauth-app-in-your-organization)
|
||||
- [Managing OAuth Apps at the Organization Level](https://docs.github.com/en/organizations/managing-oauth-access-to-your-organizations-data)
|
||||
- [Managing Programmatic Access at the GitHub Organization Level](https://docs.github.com/en/organizations/managing-programmatic-access-to-your-organization)
|
||||
- [Building Copilot Extensions](https://docs.github.com/en/copilot/building-copilot-extensions)
|
||||
- [Managing App/Extension Visibility](https://docs.github.com/en/copilot/building-copilot-extensions/managing-the-availability-of-your-copilot-extension) (including GitHub Marketplace information)
|
||||
- [Example Implementation in VS Code Repository](https://github.com/microsoft/vscode/blob/main/src/vs/workbench/api/common/extHostMcp.ts#L313)
|
||||
@@ -0,0 +1,218 @@
|
||||
# Insiders Features
|
||||
|
||||
Insiders Mode gives you access to experimental features in the GitHub MCP Server. These features may change, evolve, or be removed based on community feedback.
|
||||
|
||||
We created this mode to have a way to roll out experimental features and collect feedback. So if you are using Insiders, please don't hesitate to share your feedback with us!
|
||||
|
||||
> [!NOTE]
|
||||
> Features in Insiders Mode are experimental.
|
||||
|
||||
## Enabling Insiders Mode
|
||||
|
||||
| Method | Remote Server | Local Server |
|
||||
|--------|---------------|--------------|
|
||||
| URL path | Append `/insiders` to the URL | N/A |
|
||||
| Header | `X-MCP-Insiders: true` | N/A |
|
||||
| CLI flag | N/A | `--insiders` |
|
||||
| Environment variable | N/A | `GITHUB_INSIDERS=true` |
|
||||
|
||||
For configuration examples, see the [Server Configuration Guide](./server-configuration.md#insiders-mode).
|
||||
|
||||
---
|
||||
|
||||
## Tools added or changed by Insiders Mode
|
||||
|
||||
The list below is generated from the Go source. It covers tool **inventory and schema deltas** introduced by each Insiders feature flag — newly registered tools, or existing tools whose input schema or MCP metadata changes when the flag is on. Flags that only affect runtime behavior (e.g. output formatting or extra field lookups behind an existing schema) won't appear here; those are documented in the prose sections of this file.
|
||||
|
||||
<!-- START AUTOMATED INSIDERS TOOLS -->
|
||||
|
||||
### `remote_mcp_ui_apps`
|
||||
|
||||
- **create_pull_request** - Open new pull request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- **MCP App UI**: `ui://github-mcp-server/pr-write`
|
||||
- `base`: Branch to merge into (string, required)
|
||||
- `body`: PR description (string, optional)
|
||||
- `draft`: Create as draft PR (boolean, optional)
|
||||
- `head`: Branch containing changes (string, required)
|
||||
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
|
||||
- `title`: PR title (string, required)
|
||||
|
||||
- **get_me** - Get my user profile
|
||||
- **MCP App UI**: `ui://github-mcp-server/get-me`
|
||||
- No parameters required
|
||||
|
||||
- **issue_write** - Create or update issue/pull request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- **MCP App UI**: `ui://github-mcp-server/issue-write`
|
||||
- `assignees`: Usernames to assign to this issue (string[], optional)
|
||||
- `body`: Issue body content (string, optional)
|
||||
- `duplicate_of`: Issue number that this issue is a duplicate of. Only used when state_reason is 'duplicate'. (number, optional)
|
||||
- `issue_fields`: Issue field values to set or clear. Each item requires 'field_name' and exactly one of 'value', 'field_option_name', or 'delete: true'. (object[], optional)
|
||||
- `issue_number`: Issue number to update (number, optional)
|
||||
- `labels`: Labels to apply to this issue (string[], optional)
|
||||
- `method`: Write operation to perform on a single issue.
|
||||
Options are:
|
||||
- 'create' - creates a new issue.
|
||||
- 'update' - updates an existing issue.
|
||||
(string, required)
|
||||
- `milestone`: Milestone number (number, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `state`: New state (string, optional)
|
||||
- `state_reason`: Reason for the state change. Ignored unless state is changed. (string, optional)
|
||||
- `title`: Issue title (string, optional)
|
||||
- `type`: Type of this issue. Only use if issue types are enabled for this repository. Use list_issue_types tool to get valid type values for this repository or its owner organization. If the repository doesn't support issue types, omit this parameter. (string, optional)
|
||||
|
||||
- **ui_get** - Get UI data
|
||||
- **Required OAuth Scopes (any of)**: `repo`, `read:org`
|
||||
- **Accepted OAuth Scopes**: `admin:org`, `read:org`, `repo`, `write:org`
|
||||
- `method`: The type of data to fetch (string, required)
|
||||
- `owner`: Repository owner (required for all methods) (string, required)
|
||||
- `repo`: Repository name (required for labels, assignees, milestones, branches, issue fields, reviewers) (string, optional)
|
||||
|
||||
- **update_pull_request** - Edit pull request
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- **MCP App UI**: `ui://github-mcp-server/pr-edit`
|
||||
- `base`: New base branch name (string, optional)
|
||||
- `body`: New description (string, optional)
|
||||
- `draft`: Mark pull request as draft (true) or ready for review (false) (boolean, optional)
|
||||
- `maintainer_can_modify`: Allow maintainer edits (boolean, optional)
|
||||
- `owner`: Repository owner (string, required)
|
||||
- `pullNumber`: Pull request number to update (number, required)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `reviewers`: GitHub usernames or ORG/team-slug team reviewers to request reviews from (string[], optional)
|
||||
- `state`: New state (string, optional)
|
||||
- `title`: New title (string, optional)
|
||||
|
||||
### `file_blame`
|
||||
|
||||
- **get_file_blame** - Get file blame information
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `after`: Cursor for pagination. Use the cursor from the previous response. (string, optional)
|
||||
- `end_line`: Optional 1-based ending line of the window of interest. Must be >= start_line when both are provided. (number, optional)
|
||||
- `owner`: Repository owner (username or organization) (string, required)
|
||||
- `path`: Path to the file in the repository, relative to the repository root (string, required)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `ref`: Git reference (branch, tag, or commit SHA). Defaults to the repository's default branch (HEAD). (string, optional)
|
||||
- `repo`: Repository name (string, required)
|
||||
- `start_line`: Optional 1-based starting line of the window of interest. Only ranges overlapping [start_line, end_line] are returned, clamped to the window. (number, optional)
|
||||
|
||||
### `issue_dependencies`
|
||||
|
||||
- **issue_dependency_read** - Read issue dependencies
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The number of the issue (number, required)
|
||||
- `method`: The read operation to perform on a single issue's dependencies.
|
||||
Options are:
|
||||
1. get_blocked_by - List the issues that block this issue (this issue is blocked by them).
|
||||
2. get_blocking - List the issues that this issue blocks.
|
||||
(string, required)
|
||||
- `owner`: The owner of the repository (string, required)
|
||||
- `page`: Page number for pagination (min 1) (number, optional)
|
||||
- `perPage`: Results per page for pagination (min 1, max 100) (number, optional)
|
||||
- `repo`: The name of the repository (string, required)
|
||||
|
||||
- **issue_dependency_write** - Change issue dependency
|
||||
- **Required OAuth Scopes**: `repo`
|
||||
- `issue_number`: The number of the subject issue (number, required)
|
||||
- `method`: The action to perform.
|
||||
Options are:
|
||||
- 'add' - create the dependency relationship.
|
||||
- 'remove' - delete the dependency relationship. (string, required)
|
||||
- `owner`: The owner of the subject issue's repository (string, required)
|
||||
- `related_issue_number`: The number of the related issue to link or unlink (number, required)
|
||||
- `related_owner`: The owner of the related issue's repository. Defaults to 'owner' when omitted. (string, optional)
|
||||
- `related_repo`: The name of the related issue's repository. Defaults to 'repo' when omitted. (string, optional)
|
||||
- `repo`: The name of the subject issue's repository (string, required)
|
||||
- `type`: The relationship direction relative to the subject issue.
|
||||
Options are:
|
||||
- 'blocked_by' - the subject issue is blocked by the related issue.
|
||||
- 'blocking' - the subject issue blocks the related issue. (string, required)
|
||||
|
||||
<!-- END AUTOMATED INSIDERS TOOLS -->
|
||||
|
||||
---
|
||||
|
||||
## MCP Apps
|
||||
|
||||
[MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) is an extension to the Model Context Protocol that enables servers to deliver interactive user interfaces to end users. Instead of returning plain text that the LLM must interpret and relay, tools can render forms, profiles, and dashboards right in the chat using MCP Apps.
|
||||
|
||||
This means you can interact with GitHub visually: fill out forms to create issues, see user profiles with avatars, open pull requests — all without leaving your agent chat.
|
||||
|
||||
### Supported tools
|
||||
|
||||
The following tools have MCP Apps UIs:
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `get_me` | Displays your GitHub user profile with avatar, bio, and stats in a rich card |
|
||||
| `issue_write` | Opens an interactive form to create or update issues |
|
||||
| `create_pull_request` | Provides a full PR creation form to create a pull request (or a draft pull request) |
|
||||
|
||||
### Client requirements
|
||||
|
||||
MCP Apps requires a host that supports the [MCP Apps extension](https://modelcontextprotocol.io/docs/extensions/apps). Currently tested and working with:
|
||||
|
||||
- **VS Code Insiders** — enable via the `chat.mcp.apps.enabled` setting
|
||||
- **Visual Studio Code** — enable via the `chat.mcp.apps.enabled` setting
|
||||
|
||||
---
|
||||
|
||||
## CSV output for list tools
|
||||
|
||||
CSV output mode returns supported list tool responses as CSV instead of JSON. This is intended to reduce response context for agents when scanning or summarising lists of GitHub data.
|
||||
|
||||
CSV output applies only to tools in default toolsets whose names start with `list_`, such as `list_issues`, `list_pull_requests`, `list_commits`, and `list_branches`. It does not add new tools or expose a tool argument for selecting the format; the server controls the response format through the Insiders feature flag.
|
||||
|
||||
### Format
|
||||
|
||||
- Nested objects are flattened into dot-notation columns, for example `user.login`, `category.name`, or `head.ref`.
|
||||
- Arrays are represented as compact single-cell values joined with `;`.
|
||||
- `body` fields are whitespace-normalized so multiline Markdown does not expand a list response into many output lines.
|
||||
- Response metadata present in wrapped responses, such as `pageInfo.*` and `totalCount`, is emitted as `#`-prefixed lines before the CSV rows, followed by a blank line. Tools that return a root JSON array do not include metadata preamble lines.
|
||||
|
||||
### Enabling CSV output
|
||||
|
||||
CSV output is enabled by Insiders Mode. For local development, it can also be enabled explicitly with the `csv_output` feature flag:
|
||||
|
||||
```bash
|
||||
github-mcp-server stdio --features csv_output
|
||||
```
|
||||
|
||||
Because this changes list tool response shape, clients that require JSON list responses should avoid enabling this feature.
|
||||
|
||||
---
|
||||
|
||||
## How feature flags are resolved
|
||||
|
||||
> [!NOTE]
|
||||
> This section is for contributors. End users only need the table at the top of this page.
|
||||
|
||||
Insiders is a **meta feature flag** — the same shape as `default` or `all` for toolsets. It expands once at startup into a curated set of individual feature flags, and from that point on every code path keys off concrete flags, never `InsidersMode` directly. New experimental work should always get its own flag and then be added to the insiders expansion list, never folded into `insiders` as a catch-all.
|
||||
|
||||
### Resolution order
|
||||
|
||||
1. **User input.** Users may opt into specific features:
|
||||
- Local server: `--features=<flag>,<flag>` CLI flag (or `GITHUB_FEATURES` env var).
|
||||
- Self-hosted HTTP server: `X-MCP-Features: <flag>,<flag>` request header.
|
||||
2. **Allowlist filter.** User-supplied flags are filtered against [`AllowedFeatureFlags`](../pkg/github/feature_flags.go). Anything not on the allowlist is silently dropped — flags missing from the allowlist can only be turned on by remote-server feature management, not by end users.
|
||||
3. **Insiders expansion.** If insiders mode is on (`--insiders`, `/insiders` route, or `X-MCP-Insiders: true`), every flag in [`InsidersFeatureFlags`](../pkg/github/feature_flags.go) is unioned in. The insiders expansion is **not** re-validated against the allowlist — insiders is a server-controlled switch that can reach internal-only flags.
|
||||
4. **Server-side fallback (remote server only).** Any flag not yet decided falls back to the remote server's feature manager, which can roll a feature out independently of user input or insiders membership.
|
||||
|
||||
`AllowedFeatureFlags` and `InsidersFeatureFlags` are deliberately independent sets:
|
||||
|
||||
- A flag in **`AllowedFeatureFlags` only** is a regular opt-in: users can turn it on, but insiders does not auto-enable it. Granular issues/PRs flags work this way.
|
||||
- A flag in **`InsidersFeatureFlags` only** is reachable through insiders (and remote-server rollouts), but cannot be enabled by user input. Internal-only experiments work this way.
|
||||
- A flag in **both** is opt-in for end users *and* automatically on under insiders.
|
||||
|
||||
### Adding a new feature flag
|
||||
|
||||
1. Add a constant in `pkg/github/feature_flags.go`.
|
||||
2. Add it to `AllowedFeatureFlags` if end users should be able to opt in via `--features` / `X-MCP-Features`.
|
||||
3. Add it to `InsidersFeatureFlags` if insiders mode should turn it on automatically.
|
||||
4. Gate the behavior on the concrete flag (`deps.IsFeatureEnabled(ctx, FeatureFlagX)`), never on `cfg.InsidersMode`. There is a `TestGitHubPackageDoesNotReadInsidersMode` guard test that fails if `pkg/github` reads `InsidersMode` directly.
|
||||
5. The MCP-diff CI workflow picks up new entries in `AllowedFeatureFlags` automatically — see `.github/workflows/mcp-diff.yml`.
|
||||
@@ -0,0 +1,112 @@
|
||||
# GitHub MCP Server Installation Guides
|
||||
|
||||
This directory contains detailed installation instructions for the GitHub MCP Server across different host applications and IDEs. Choose the guide that matches your development environment.
|
||||
|
||||
## Installation Guides by Host Application
|
||||
- **[Copilot CLI](install-copilot-cli.md)** - Installation guide for GitHub Copilot CLI
|
||||
- **[GitHub Copilot in other IDEs](install-other-copilot-ides.md)** - Installation for JetBrains, Visual Studio, Eclipse, and Xcode with GitHub Copilot
|
||||
- **[Antigravity](install-antigravity.md)** - Installation for Google Antigravity IDE
|
||||
- **[Claude Applications](install-claude.md)** - Installation guide for Claude Desktop and Claude Code CLI
|
||||
- **[Cline](install-cline.md)** - Installation guide for Cline
|
||||
- **[Cursor](install-cursor.md)** - Installation guide for Cursor IDE
|
||||
- **[Google Gemini CLI](install-gemini-cli.md)** - Installation guide for Google Gemini CLI
|
||||
- **[OpenAI Codex](install-codex.md)** - Installation guide for OpenAI Codex
|
||||
- **[OpenCode](install-opencode.md)** - Installation guide for the OpenCode terminal agent
|
||||
- **[Roo Code](install-roo-code.md)** - Installation guide for Roo Code
|
||||
- **[Windsurf](install-windsurf.md)** - Installation guide for Windsurf IDE
|
||||
- **[Xcode (Codex & Claude Agent)](install-xcode.md)** - Installation guide for Codex and Claude Agent within Xcode
|
||||
- **[Zed](install-zed.md)** - Installation guide for Zed editor
|
||||
|
||||
## Support by Host Application
|
||||
|
||||
| Host Application | Local GitHub MCP Support | Remote GitHub MCP Support | Prerequisites | Difficulty |
|
||||
|-----------------|---------------|----------------|---------------|------------|
|
||||
| Copilot CLI | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Copilot in VS Code | ✅ | ✅ Full (OAuth + PAT) | Local: Docker or Go build, GitHub PAT<br>Remote: VS Code 1.101+ | Easy |
|
||||
| Copilot Coding Agent | ✅ | ✅ Full (on by default; no auth needed) | Any _paid_ copilot license | Default on |
|
||||
| Copilot in Visual Studio | ✅ | ✅ Full (OAuth + PAT) | Local: Docker or Go build, GitHub PAT<br>Remote: Visual Studio 17.14+ | Easy |
|
||||
| Copilot in JetBrains | ✅ | ✅ Full (OAuth + PAT) | Local: Docker or Go build, GitHub PAT<br>Remote: JetBrains Copilot Extension v1.5.53+ | Easy |
|
||||
| Claude Code | ✅ | ✅ PAT + ❌ No OAuth| GitHub MCP Server binary or remote URL, GitHub PAT | Easy |
|
||||
| Claude Desktop | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Moderate |
|
||||
| Cline | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Cursor | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Google Gemini CLI | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| OpenCode | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Roo Code | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Windsurf | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Zed | ✅ | ✅ PAT + ❌ No OAuth | Docker or Go build, GitHub PAT | Easy |
|
||||
| Copilot in Xcode | ✅ | ✅ Full (OAuth + PAT) | Local: Docker or Go build, GitHub PAT<br>Remote: Copilot for Xcode 0.41.0+ | Easy |
|
||||
| Copilot in Eclipse | ✅ | ✅ Full (OAuth + PAT) | Local: Docker or Go build, GitHub PAT<br>Remote: Eclipse Plug-in for Copilot 0.10.0+ | Easy |
|
||||
| Xcode (Codex) | ✅ | ✅ PAT + ❌ No OAuth | Local: Docker (full path required), GitHub PAT<br>Remote: GitHub PAT via `GITHUB_PAT_TOKEN` env var (`bearer_token_env_var`) | Easy |
|
||||
| Xcode (Claude Agent) | ✅ | ✅ PAT + ❌ No OAuth | Local: Docker (full path required), GitHub PAT<br>Remote: GitHub PAT | Easy |
|
||||
|
||||
**Legend:**
|
||||
- ✅ = Fully supported
|
||||
- ❌ = Not yet supported
|
||||
|
||||
**Note:** Remote MCP support requires host applications to register a GitHub App or OAuth app for OAuth flow support – even if the new OAuth spec is supported by that host app. Currently, only VS Code has full remote GitHub server support.
|
||||
|
||||
## Installation Methods
|
||||
|
||||
The GitHub MCP Server can be installed using several methods. **Docker is the most popular and recommended approach** for most users, but alternatives are available depending on your needs:
|
||||
|
||||
### 🐳 Docker (Most Common & Recommended)
|
||||
- **Pros**: No local build required, consistent environment, easy updates, works across all platforms
|
||||
- **Cons**: Requires Docker installed and running
|
||||
- **Best for**: Most users, especially those already using Docker or wanting the simplest setup
|
||||
- **Used by**: Claude Desktop, Copilot in VS Code, Cursor, Windsurf, etc.
|
||||
|
||||
### 📦 Pre-built Binary (Lightweight Alternative)
|
||||
- **Pros**: No Docker required, direct execution via stdio, minimal setup
|
||||
- **Cons**: Need to manually download and manage updates, platform-specific binaries
|
||||
- **Best for**: Minimal environments, users who prefer not to use Docker
|
||||
- **Used by**: Claude Code CLI, lightweight setups
|
||||
|
||||
### 🔨 Build from Source (Advanced Users)
|
||||
- **Pros**: Latest features, full customization, no external dependencies
|
||||
- **Cons**: Requires Go development environment, more complex setup
|
||||
- **Prerequisites**: [Go 1.24+](https://go.dev/doc/install)
|
||||
- **Build command**: `go build -o github-mcp-server cmd/github-mcp-server/main.go`
|
||||
- **Best for**: Developers who want the latest features or need custom modifications
|
||||
|
||||
### Important Notes on the GitHub MCP Server
|
||||
|
||||
- **Docker Image**: The official Docker image is now `ghcr.io/github/github-mcp-server`
|
||||
- **npm Package**: The npm package @modelcontextprotocol/server-github is no longer supported as of April 2025
|
||||
- **Remote Server**: The remote server URL is `https://api.githubcopilot.com/mcp/`
|
||||
|
||||
## General Prerequisites
|
||||
|
||||
All installations with Personal Access Tokens (PAT) require:
|
||||
- **GitHub Personal Access Token (PAT)**: [Create one here](https://github.com/settings/personal-access-tokens/new)
|
||||
|
||||
Optional (depending on installation method):
|
||||
- **Docker** (for Docker-based installations): [Download Docker](https://www.docker.com/)
|
||||
- **Go 1.24+** (for building from source): [Install Go](https://go.dev/doc/install)
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
Regardless of which installation method you choose, follow these security guidelines:
|
||||
|
||||
1. **Secure Token Storage**: Never commit your GitHub PAT to version control
|
||||
2. **Limit Token Scope**: Only grant necessary permissions to your GitHub PAT
|
||||
3. **File Permissions**: Restrict access to configuration files containing tokens
|
||||
4. **Regular Rotation**: Periodically rotate your GitHub Personal Access Tokens
|
||||
5. **Environment Variables**: Use environment variables when supported by your host
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you encounter issues:
|
||||
1. Check the troubleshooting section in your specific installation guide
|
||||
2. Verify your GitHub PAT has the required permissions
|
||||
3. Ensure Docker is running (for local installations)
|
||||
4. Review your host application's logs for error messages
|
||||
5. Consult the main [README.md](README.md) for additional configuration options
|
||||
|
||||
## Configuration Options
|
||||
|
||||
After installation, you may want to explore:
|
||||
- **Toolsets**: Enable/disable specific GitHub API capabilities
|
||||
- **Read-Only Mode**: Restrict to read-only operations
|
||||
- **Lockdown Mode**: Hide public issue details created by users without push access
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
# Installing GitHub MCP Server in Antigravity
|
||||
|
||||
This guide covers setting up the GitHub MCP Server in Google's Antigravity IDE.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Antigravity IDE installed (latest version)
|
||||
- GitHub Personal Access Token with appropriate scopes
|
||||
|
||||
## Installation Methods
|
||||
|
||||
### Option 1: Remote Server (Recommended)
|
||||
|
||||
Uses GitHub's hosted server at `https://api.githubcopilot.com/mcp/`.
|
||||
|
||||
> [!NOTE]
|
||||
> We recommend this manual configuration method because the "official" installation via the Antigravity MCP Store currently has known issues (often resulting in Docker errors). This direct remote connection is more reliable.
|
||||
|
||||
#### Step 1: Access MCP Configuration
|
||||
|
||||
1. Open Antigravity
|
||||
2. Click the "..." (Additional Options) menu in the Agent panel
|
||||
3. Select "MCP Servers"
|
||||
4. Click "Manage MCP Servers"
|
||||
5. Click "View raw config"
|
||||
|
||||
This will open your `mcp_config.json` file at:
|
||||
- **Windows**: `C:\Users\<USERNAME>\.gemini\antigravity\mcp_config.json`
|
||||
- **macOS/Linux**: `~/.gemini/antigravity/mcp_config.json`
|
||||
|
||||
#### Step 2: Add Configuration
|
||||
|
||||
Add the following to your `mcp_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"serverUrl": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Important**: Note that Antigravity uses `serverUrl` instead of `url` for HTTP-based MCP servers.
|
||||
|
||||
#### Step 3: Configure Your Token
|
||||
|
||||
Replace `YOUR_GITHUB_PAT` with your actual GitHub Personal Access Token.
|
||||
|
||||
Create a token here: https://github.com/settings/tokens
|
||||
|
||||
Recommended scopes:
|
||||
- `repo` - Full control of private repositories
|
||||
- `read:org` - Read org and team membership
|
||||
- `read:user` - Read user profile data
|
||||
|
||||
#### Step 4: Restart Antigravity
|
||||
|
||||
Close and reopen Antigravity for the changes to take effect.
|
||||
|
||||
#### Step 5: Verify Installation
|
||||
|
||||
1. Open the MCP Servers panel (... menu → MCP Servers)
|
||||
2. You should see "github" with a list of available tools
|
||||
3. You can now use GitHub tools in your conversations
|
||||
|
||||
> [!NOTE]
|
||||
> The status indicator in the MCP Servers panel might not immediately turn green in some versions, but the tools will still function if configured correctly.
|
||||
|
||||
### Option 2: Local Docker Server
|
||||
|
||||
If you prefer running the server locally with Docker:
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Requirements**:
|
||||
- Docker Desktop installed and running
|
||||
- Docker must be in your system PATH
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Error: serverUrl or command must be specified"
|
||||
|
||||
Make sure you're using `serverUrl` (not `url`) for the remote server configuration. Antigravity requires `serverUrl` for HTTP-based MCP servers.
|
||||
|
||||
### Server not appearing in MCP list
|
||||
|
||||
- Verify JSON syntax in your config file
|
||||
- Check that your PAT hasn't expired
|
||||
- Restart Antigravity completely
|
||||
|
||||
### Tools not working
|
||||
|
||||
- Ensure your PAT has the correct scopes
|
||||
- Check the MCP Servers panel for error messages
|
||||
- Verify internet connection for remote server
|
||||
|
||||
## Available Tools
|
||||
|
||||
Once installed, you'll have access to tools like:
|
||||
- `create_repository` - Create new GitHub repositories
|
||||
- `push_files` - Push files to repositories
|
||||
- `search_repositories` - Search for repositories
|
||||
- `create_or_update_file` - Manage file content
|
||||
- `get_file_contents` - Read file content
|
||||
- And many more...
|
||||
|
||||
For a complete list of available tools and features, see the [main README](../../README.md).
|
||||
|
||||
## Differences from Other IDEs
|
||||
|
||||
- **Configuration key**: Antigravity uses `serverUrl` instead of `url` for HTTP servers
|
||||
- **Config location**: `.gemini/antigravity/mcp_config.json` instead of `.cursor/mcp.json`
|
||||
- **Tool limits**: Antigravity recommends keeping total enabled tools under 50 for optimal performance
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Explore the [Server Configuration Guide](../server-configuration.md) for advanced options
|
||||
- Check out [toolsets documentation](../../README.md#available-toolsets) to customize available tools
|
||||
- See the [Remote Server Documentation](../remote-server.md) for more details
|
||||
@@ -0,0 +1,342 @@
|
||||
# Install GitHub MCP Server in Claude Applications
|
||||
|
||||
## Claude Code CLI
|
||||
|
||||
### Prerequisites
|
||||
- Claude Code CLI installed
|
||||
- [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new)
|
||||
- For local setup: [Docker](https://www.docker.com/) installed and running
|
||||
- Open Claude Code inside the directory for your project (recommended for best experience and clear scope of configuration)
|
||||
|
||||
<details>
|
||||
<summary><b>Storing Your PAT Securely</b></summary>
|
||||
<br>
|
||||
|
||||
For security, avoid hardcoding your token. One common approach:
|
||||
|
||||
1. Store your token in `.env` file
|
||||
```
|
||||
GITHUB_PAT=your_token_here
|
||||
```
|
||||
|
||||
2. Add to .gitignore
|
||||
```bash
|
||||
echo -e ".env\n.mcp.json" >> .gitignore
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Remote Server Setup (Streamable HTTP)
|
||||
|
||||
> **Note**: For Claude Code versions **2.1.1 and newer**, use the `add-json` command format below. For older versions, see the [legacy command format](#for-older-versions-of-claude-code).
|
||||
>
|
||||
> **Windows / CLI note**: `claude mcp add-json` may return `Invalid input` when adding an HTTP server. If that happens, use the legacy `claude mcp add --transport http ...` command format below.
|
||||
|
||||
1. Run the following command in the terminal (not in Claude Code CLI):
|
||||
```bash
|
||||
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer YOUR_GITHUB_PAT"}}'
|
||||
```
|
||||
|
||||
With an environment variable (Linux/macOS):
|
||||
```bash
|
||||
export GITHUB_PAT="$(grep '^GITHUB_PAT=' .env | cut -d '=' -f2-)"
|
||||
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp","headers":{"Authorization":"Bearer '"$GITHUB_PAT"'"}}'
|
||||
```
|
||||
|
||||
With an environment variable (Windows PowerShell):
|
||||
```powershell
|
||||
$githubPatLine = Get-Content .env | Select-String "^\s*GITHUB_PAT\s*=" | Select-Object -First 1
|
||||
$env:GITHUB_PAT = ($githubPatLine.Line -split "=", 2)[1].Trim().Trim('"').Trim("'")
|
||||
claude mcp add-json github "{`"type`":`"http`",`"url`":`"https://api.githubcopilot.com/mcp`",`"headers`":{`"Authorization`":`"Bearer $env:GITHUB_PAT`"}}"
|
||||
```
|
||||
|
||||
> **About the `--scope` flag** (optional): Use this to specify where the configuration is stored:
|
||||
> - `local` (default): Available only to you in the current project (was called `project` in older versions)
|
||||
> - `project`: Shared with everyone in the project via `.mcp.json` file
|
||||
> - `user`: Available to you across all projects (was called `global` in older versions)
|
||||
>
|
||||
> Example: Add `--scope user` to the end of the command to make it available across all projects.
|
||||
|
||||
2. Restart Claude Code
|
||||
3. Run `claude mcp list` to see if the GitHub server is configured
|
||||
|
||||
### Local Server Setup (Docker required)
|
||||
|
||||
### With Docker
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback. Run the following command in the terminal (not in Claude Code CLI):
|
||||
|
||||
```bash
|
||||
claude mcp add github -e GITHUB_OAUTH_CALLBACK_PORT=8085 -- docker run -i --rm -p 127.0.0.1:8085:8085 -e GITHUB_OAUTH_CALLBACK_PORT ghcr.io/github/github-mcp-server
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
1. Run the following command in the terminal (not in Claude Code CLI):
|
||||
```bash
|
||||
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_GITHUB_PAT -- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
|
||||
```
|
||||
|
||||
With an environment variable:
|
||||
```bash
|
||||
claude mcp add github -e GITHUB_PERSONAL_ACCESS_TOKEN=$(grep GITHUB_PAT .env | cut -d '=' -f2) -- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
|
||||
```
|
||||
2. Restart Claude Code
|
||||
3. Run `claude mcp list` to see if the GitHub server is configured
|
||||
|
||||
### With a Binary (no Docker)
|
||||
|
||||
1. Download [release binary](https://github.com/github/github-mcp-server/releases)
|
||||
2. Add to your `PATH`
|
||||
3. Run:
|
||||
```bash
|
||||
claude mcp add-json github '{"command": "github-mcp-server", "args": ["stdio"], "env": {"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"}}'
|
||||
```
|
||||
2. Restart Claude Code
|
||||
3. Run `claude mcp list` to see if the GitHub server is configured
|
||||
|
||||
### Verification
|
||||
```bash
|
||||
claude mcp list
|
||||
claude mcp get github
|
||||
```
|
||||
|
||||
### For Older Versions of Claude Code
|
||||
|
||||
If you're using Claude Code version **2.1.0 or earlier**, use this legacy command format:
|
||||
|
||||
```bash
|
||||
claude mcp add --transport http github https://api.githubcopilot.com/mcp -H "Authorization: Bearer YOUR_GITHUB_PAT"
|
||||
```
|
||||
|
||||
With an environment variable:
|
||||
```bash
|
||||
claude mcp add --transport http github https://api.githubcopilot.com/mcp -H "Authorization: Bearer $(grep GITHUB_PAT .env | cut -d '=' -f2)"
|
||||
```
|
||||
|
||||
#### Windows (PowerShell)
|
||||
|
||||
If you see `missing required argument 'name'`, put the server name immediately after `claude mcp add`:
|
||||
|
||||
```powershell
|
||||
$pat = "YOUR_GITHUB_PAT"
|
||||
claude mcp add github --transport http https://api.githubcopilot.com/mcp/ -H "Authorization: Bearer $pat"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Claude Desktop
|
||||
|
||||
> ⚠️ **Note**: Some users have reported compatibility issues with Claude Desktop and Docker-based MCP servers. We're investigating. If you experience issues, try using another MCP host, while we look into it!
|
||||
|
||||
### Prerequisites
|
||||
- Claude Desktop installed (latest version)
|
||||
- [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new)
|
||||
- [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
> **Note**: Claude Desktop supports MCP servers that are both local (stdio) and remote ("connectors"). Remote servers can generally be added via Settings → Connectors → "Add custom connector". However, the GitHub remote MCP server requires OAuth authentication through a registered GitHub App (or OAuth App), which is not currently supported. Use the local Docker setup instead.
|
||||
|
||||
### Configuration File Location
|
||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
|
||||
|
||||
### Local Server Setup (Docker)
|
||||
|
||||
Add this codeblock to your `claude_desktop_config.json`:
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Manual Setup Steps
|
||||
1. Open Claude Desktop
|
||||
2. Go to Settings → Developer → Edit Config
|
||||
3. Paste the code block above in your configuration file
|
||||
4. If you're navigating to the configuration file outside of the app:
|
||||
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
||||
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
||||
5. Open the file in a text editor
|
||||
6. Paste one of the code blocks above, based on your chosen configuration (remote or local)
|
||||
7. Replace `YOUR_GITHUB_PAT` with your actual token or $GITHUB_PAT environment variable
|
||||
8. Save the file
|
||||
9. Restart Claude Desktop
|
||||
|
||||
---
|
||||
|
||||
## Xcode (Claude Agent)
|
||||
|
||||
Xcode's Claude Agent uses the same `.claude.json` configuration format as the Claude Code CLI, but reads it from an Xcode-specific directory rather than the global config location.
|
||||
|
||||
### Configuration File Location
|
||||
|
||||
```
|
||||
~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude.json
|
||||
```
|
||||
|
||||
> Configurations placed here only affect Claude Agent when launched from Xcode. See [Apple's documentation](https://developer.apple.com/documentation/xcode/setting-up-coding-intelligence#Customize-the-Claude-Agent-and-Codex-environments) for more details.
|
||||
|
||||
### Remote Server Setup (Recommended)
|
||||
|
||||
Run the following command in Terminal to add the remote GitHub MCP server:
|
||||
|
||||
```bash
|
||||
claude mcp add-json github '{"type":"http","url":"https://api.githubcopilot.com/mcp/","headers":{"Authorization":"Bearer YOUR_GITHUB_PAT"}}' --config ~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude.json
|
||||
```
|
||||
|
||||
Or open the file in a text editor and add the `mcpServers` block manually:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Local Server Setup (Docker)
|
||||
|
||||
> **macOS note**: Xcode runs with a minimal `PATH` that typically excludes `/usr/local/bin` (Intel) and `/opt/homebrew/bin` (Apple Silicon). Use the full path to `docker` to ensure it can be found. Run `which docker` in Terminal to find the correct path on your system.
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "/usr/local/bin/docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "/usr/local/bin/docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Setup Steps
|
||||
1. Create or open `~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/.claude.json`
|
||||
2. Add the configuration block above
|
||||
3. Replace `YOUR_GITHUB_PAT` with your actual token
|
||||
4. Restart Xcode
|
||||
|
||||
---
|
||||
|
||||
|
||||
**Authentication Failed:**
|
||||
- Verify PAT has `repo` scope
|
||||
- Check token hasn't expired
|
||||
|
||||
**Remote Server:**
|
||||
- Verify URL: `https://api.githubcopilot.com/mcp`
|
||||
|
||||
**Docker Issues (Local Only):**
|
||||
- Ensure Docker Desktop is running
|
||||
- Try: `docker pull ghcr.io/github/github-mcp-server`
|
||||
- If pull fails: `docker logout ghcr.io` then retry
|
||||
|
||||
**Server Not Starting / Tools Not Showing:**
|
||||
- Run `claude mcp list` to view currently configured MCP servers
|
||||
- Validate JSON syntax
|
||||
- If using an environment variable to store your PAT, make sure you're properly sourcing your PAT using the environment variable
|
||||
- Restart Claude Code and check `/mcp` command
|
||||
- Delete the GitHub server by running `claude mcp remove github` and repeating the setup process with a different method
|
||||
- Make sure you're running Claude Code within the project you're currently working on to ensure the MCP configuration is properly scoped to your project
|
||||
- Check logs:
|
||||
- Claude Code: Use `/mcp` command
|
||||
- Claude Desktop: `ls ~/Library/Logs/Claude/` and `cat ~/Library/Logs/Claude/mcp-server-*.log` (macOS) or `%APPDATA%\Claude\logs\` (Windows)
|
||||
|
||||
---
|
||||
|
||||
## Important Notes
|
||||
|
||||
- The npm package `@modelcontextprotocol/server-github` is deprecated as of April 2025
|
||||
- Remote server requires Streamable HTTP support (check your Claude version)
|
||||
- For Claude Code configuration scopes, see the `--scope` flag documentation in the [Remote Server Setup](#remote-server-setup-streamable-http) section
|
||||
@@ -0,0 +1,81 @@
|
||||
# Install GitHub MCP Server in Cline
|
||||
|
||||
[Cline](https://github.com/cline/cline) is an AI coding assistant that runs in VS Code-compatible editors (VS Code, Cursor, Windsurf, etc.). For general setup information (prerequisites, Docker installation, security best practices), see the [Installation Guides README](./README.md).
|
||||
|
||||
## Remote Server
|
||||
|
||||
Cline stores MCP settings in `cline_mcp_settings.json`. To edit it, click the Cline icon in your editor's sidebar, open the menu in the top right corner of the Cline panel, and select **"MCP Servers"**. You can add a remote server through the **"Remote Servers"** tab, or click **"Configure MCP Servers"** to edit the JSON directly.
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"type": "streamableHttp",
|
||||
"disabled": false,
|
||||
"headers": {
|
||||
"Authorization": "Bearer <YOUR_GITHUB_PAT>"
|
||||
},
|
||||
"autoApprove": []
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens). To customize toolsets, add server-side headers like `X-MCP-Toolsets` or `X-MCP-Readonly` to the `headers` object — see [Server Configuration Guide](../server-configuration.md).
|
||||
|
||||
> **Important:** The transport type must be `"streamableHttp"` (camelCase, no hyphen). Using `"streamable-http"` or omitting the type will cause Cline to fall back to SSE, resulting in a `405` error.
|
||||
|
||||
## Local Server (Docker)
|
||||
|
||||
1. Click the Cline icon in your editor's sidebar (or open the command palette and search for "Cline"), then click the **MCP Servers** icon (server stack icon at the top of the Cline panel), and click **"Configure MCP Servers"** to open `cline_mcp_settings.json`.
|
||||
2. Add one of the configurations below. The OAuth option needs no token; for the PAT option, replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens).
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **SSE error 405 with remote server**: Ensure `"type"` is set to `"streamableHttp"` (camelCase, no hyphen) in `cline_mcp_settings.json`. Using `"streamable-http"` or omitting `"type"` causes Cline to fall back to SSE, which this server does not support.
|
||||
- **Authentication failures**: Verify your PAT has the required scopes
|
||||
- **Docker issues**: Ensure Docker Desktop is installed and running
|
||||
@@ -0,0 +1,134 @@
|
||||
# Install GitHub MCP Server in OpenAI Codex
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. OpenAI Codex (MCP-enabled) installed / available
|
||||
2. A [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new)
|
||||
|
||||
> The remote GitHub MCP server is hosted by GitHub at `https://api.githubcopilot.com/mcp/` and supports Streamable HTTP.
|
||||
|
||||
## Remote Configuration
|
||||
|
||||
Edit `~/.codex/config.toml` (shared by CLI and IDE extension) and add:
|
||||
|
||||
```toml
|
||||
[mcp_servers.github]
|
||||
url = "https://api.githubcopilot.com/mcp/"
|
||||
# Replace with your real PAT (least-privilege scopes). Do NOT commit this.
|
||||
bearer_token_env_var = "GITHUB_PAT_TOKEN"
|
||||
```
|
||||
|
||||
You can also add it via the Codex CLI:
|
||||
|
||||
```bash
|
||||
codex mcp add github --url https://api.githubcopilot.com/mcp/ --bearer-token-env-var GITHUB_PAT_TOKEN
|
||||
```
|
||||
|
||||
The `--bearer-token-env-var` option is required for PAT-authenticated access to the hosted GitHub MCP server.
|
||||
|
||||
<details>
|
||||
<summary><b>Storing Your PAT Securely</b></summary>
|
||||
<br>
|
||||
|
||||
For security, avoid hardcoding your token. One common approach:
|
||||
|
||||
1. Store your token in `.env` file
|
||||
```
|
||||
GITHUB_PAT_TOKEN=ghp_your_token_here
|
||||
```
|
||||
|
||||
2. Add to .gitignore
|
||||
```bash
|
||||
echo -e ".env" >> .gitignore
|
||||
```
|
||||
</details>
|
||||
|
||||
## Local Docker Configuration
|
||||
|
||||
Use this if you prefer a local, self-hosted instance instead of the remote HTTP server. See the [OpenAI documentation for configuration](https://developers.openai.com/codex/mcp) for the authoritative schema.
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```toml
|
||||
[mcp_servers.github]
|
||||
command = "docker"
|
||||
args = ["run", "-i", "--rm", "-p", "127.0.0.1:8085:8085", "-e", "GITHUB_OAUTH_CALLBACK_PORT", "ghcr.io/github/github-mcp-server"]
|
||||
env = { GITHUB_OAUTH_CALLBACK_PORT = "8085" }
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```toml
|
||||
[mcp_servers.github]
|
||||
command = "docker"
|
||||
args = ["run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server"]
|
||||
env = { GITHUB_PERSONAL_ACCESS_TOKEN = "ghp_your_token_here" }
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
After starting Codex (CLI or IDE):
|
||||
1. Run `/mcp` in the TUI or use the IDE MCP panel; confirm `github` shows tools.
|
||||
2. Ask: "List my GitHub repositories".
|
||||
3. If tools are missing:
|
||||
- Check token validity & scopes.
|
||||
- Confirm correct table name: `[mcp_servers.github]`.
|
||||
|
||||
## Usage
|
||||
|
||||
After setup, Codex can interact with GitHub directly. It will use the default tool set automatically but can be [configured](../../README.md#default-toolset). Try these example prompts:
|
||||
|
||||
**Repository Operations:**
|
||||
- "List my GitHub repositories"
|
||||
- "Show me recent issues in [owner/repo]"
|
||||
- "Create a new issue in [owner/repo] titled 'Bug: fix login'"
|
||||
|
||||
**Pull Requests:**
|
||||
- "List open pull requests in [owner/repo]"
|
||||
- "Show me the diff for PR #123"
|
||||
- "Add a comment to PR #123: 'LGTM, approved'"
|
||||
|
||||
**Actions & Workflows:**
|
||||
- "Show me recent workflow runs in [owner/repo]"
|
||||
- "Trigger the 'deploy' workflow in [owner/repo]"
|
||||
|
||||
**Gists:**
|
||||
- "Create a gist with this code snippet"
|
||||
- "List my gists"
|
||||
|
||||
> **Tip**: Use `/mcp` in the Codex UI to see all available GitHub tools and their descriptions.
|
||||
|
||||
## Choosing Scopes for Your PAT
|
||||
|
||||
Minimal useful scopes (adjust as needed):
|
||||
- `repo` (general repository operations)
|
||||
- `workflow` (if you want Actions workflow access)
|
||||
- `read:org` (if accessing org-level resources)
|
||||
- `project` (for classic project boards)
|
||||
- `gist` (if using gist tools)
|
||||
|
||||
Use the principle of least privilege: add scopes only when a tool request fails due to permission.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Possible Cause | Fix |
|
||||
|-------|----------------|-----|
|
||||
| Authentication failed | Missing/incorrect PAT scope | Regenerate PAT; ensure `repo` scope present |
|
||||
| 401 Unauthorized (remote) | Token expired/revoked | Create new PAT; update `bearer_token_env_var` |
|
||||
| Server not listed | Wrong table name or syntax error | Use `[mcp_servers.github]`; validate TOML |
|
||||
| Tools missing / zero tools | Insufficient PAT scopes | Add needed scopes (workflow, gist, etc.) |
|
||||
| Token in file risks leakage | Committed accidentally | Rotate token; add file to `.gitignore` |
|
||||
|
||||
## Security Best Practices
|
||||
1. Never commit tokens into version control
|
||||
3. Rotate tokens periodically
|
||||
4. Restrict scopes up front; expand only when required
|
||||
5. Remove unused PATs from your GitHub account
|
||||
|
||||
## References
|
||||
- Remote server URL: `https://api.githubcopilot.com/mcp/`
|
||||
- Release binaries: [GitHub Releases](https://github.com/github/github-mcp-server/releases)
|
||||
- OpenAI Codex MCP docs: https://developers.openai.com/codex/mcp
|
||||
- Main project README: [Advanced configuration options](../../README.md)
|
||||
@@ -0,0 +1,201 @@
|
||||
# Install GitHub MCP Server in Copilot CLI
|
||||
|
||||
The GitHub MCP server comes pre-installed in Copilot CLI, with read-only tools enabled by default.
|
||||
|
||||
## Built-in Server
|
||||
|
||||
To verify the server is available, from an active Copilot CLI session:
|
||||
|
||||
```bash
|
||||
/mcp show github-mcp-server
|
||||
```
|
||||
|
||||
### Per-Session Customization
|
||||
|
||||
Use CLI flags to customize the server for a session:
|
||||
|
||||
```bash
|
||||
# Enable an additional toolset
|
||||
copilot --add-github-mcp-toolset discussions
|
||||
|
||||
# Enable multiple additional toolsets
|
||||
copilot --add-github-mcp-toolset discussions --add-github-mcp-toolset stargazers
|
||||
|
||||
# Enable all toolsets
|
||||
copilot --enable-all-github-mcp-tools
|
||||
|
||||
# Enable a specific tool
|
||||
copilot --add-github-mcp-tool list_discussions
|
||||
|
||||
# Disable the built-in server entirely
|
||||
copilot --disable-builtin-mcps
|
||||
```
|
||||
|
||||
Run `copilot --help` for all available flags. For the list of toolsets, see [Available toolsets](../../README.md#available-toolsets); for the list of tools, see [Tools](../../README.md#tools).
|
||||
|
||||
## Custom Configuration
|
||||
|
||||
You can configure the GitHub MCP server in Copilot CLI using either the interactive command or by manually editing the configuration file.
|
||||
|
||||
> **Server naming:** Name your server `github-mcp-server` to replace the built-in server, or use a different name (e.g., `github`) to run alongside it.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
2. For local server: [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
<details>
|
||||
<summary><b>Storing Your PAT Securely</b></summary>
|
||||
<br>
|
||||
|
||||
To set your PAT as an environment variable:
|
||||
|
||||
```bash
|
||||
# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.)
|
||||
export GITHUB_PERSONAL_ACCESS_TOKEN=your_token_here
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Method 1: Interactive Setup (Recommended)
|
||||
|
||||
From an active Copilot CLI session, run the interactive command:
|
||||
|
||||
```bash
|
||||
/mcp add
|
||||
```
|
||||
|
||||
Follow the prompts to configure the server.
|
||||
|
||||
### Method 2: Manual Setup
|
||||
|
||||
Create or edit the configuration file `~/.copilot/mcp-config.json` and add one of the following configurations:
|
||||
|
||||
#### Remote Server
|
||||
|
||||
Connect to the hosted MCP server:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ${GITHUB_PERSONAL_ACCESS_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For additional options like toolsets and read-only mode, see the [remote server documentation](../remote-server.md#optional-headers).
|
||||
|
||||
#### Local Docker
|
||||
|
||||
With Docker running, you can run the GitHub MCP server in a container:
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Binary
|
||||
|
||||
You can download the latest binary release from the [GitHub releases page](https://github.com/github/github-mcp-server/releases) or build it from source by running:
|
||||
|
||||
```bash
|
||||
go build -o github-mcp-server ./cmd/github-mcp-server
|
||||
```
|
||||
|
||||
Then configure (replace `/path/to/binary` with the actual path):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "/path/to/binary",
|
||||
"args": ["stdio"],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
1. Restart Copilot CLI
|
||||
2. Run `/mcp show` to list configured servers
|
||||
3. Try: "List my GitHub repositories"
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Local Server Issues
|
||||
|
||||
- **Docker errors**: Ensure Docker Desktop is running
|
||||
- **Image pull failures**: Try `docker logout ghcr.io` then retry
|
||||
|
||||
### Authentication Issues
|
||||
|
||||
- **Invalid PAT**: Verify your GitHub PAT has correct scopes:
|
||||
- `repo` - Repository operations
|
||||
- `read:packages` - Docker image access (if using Docker)
|
||||
- **Token expired**: Generate a new GitHub PAT
|
||||
|
||||
### Configuration Issues
|
||||
|
||||
- **Invalid JSON**: Validate your configuration:
|
||||
```bash
|
||||
cat ~/.copilot/mcp-config.json | jq .
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Copilot CLI Documentation](https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli)
|
||||
@@ -0,0 +1,143 @@
|
||||
# Install GitHub MCP Server in Cursor
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Cursor IDE installed (latest version)
|
||||
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
3. For local installation: [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
## Remote Server Setup (Recommended)
|
||||
|
||||
[](https://cursor.com/en/install-mcp?name=github&config=eyJ1cmwiOiJodHRwczovL2FwaS5naXRodWJjb3BpbG90LmNvbS9tY3AvIiwiaGVhZGVycyI6eyJBdXRob3JpemF0aW9uIjoiQmVhcmVyIFlPVVJfR0lUSFVCX1BBVCJ9fQ%3D%3D)
|
||||
|
||||
Uses GitHub's hosted server at https://api.githubcopilot.com/mcp/. Requires Cursor v0.48.0+ for Streamable HTTP support. While Cursor supports OAuth for some MCP servers, the GitHub server currently requires a Personal Access Token.
|
||||
|
||||
### Install steps
|
||||
|
||||
1. Click the install button above and follow the flow, or go directly to your global MCP configuration file at `~/.cursor/mcp.json` and enter the code block below
|
||||
2. In Tools & Integrations > MCP tools, click the pencil icon next to "github"
|
||||
3. Replace `YOUR_GITHUB_PAT` with your actual [GitHub Personal Access Token](https://github.com/settings/tokens)
|
||||
4. Save the file
|
||||
5. Restart Cursor
|
||||
|
||||
### Streamable HTTP Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Local Server Setup
|
||||
|
||||
[](https://cursor.com/en/install-mcp?name=github&config=eyJjb21tYW5kIjoiZG9ja2VyIHJ1biAtaSAtLXJtIC1lIEdJVEhVQl9QRVJTT05BTF9BQ0NFU1NfVE9LRU4gZ2hjci5pby9naXRodWIvZ2l0aHViLW1jcC1zZXJ2ZXIiLCJlbnYiOnsiR0lUSFVCX1BFUlNPTkFMX0FDQ0VTU19UT0tFTiI6IllPVVJfR0lUSFVCX1BBVCJ9fQ%3D%3D)
|
||||
|
||||
The local GitHub MCP server runs via Docker and requires Docker Desktop to be installed and running.
|
||||
|
||||
### Install steps
|
||||
|
||||
1. Click the install button above and follow the flow, or go directly to your global MCP configuration file at `~/.cursor/mcp.json` and enter the code block below
|
||||
2. In Tools & Integrations > MCP tools, click the pencil icon next to "github"
|
||||
3. Replace `YOUR_GITHUB_PAT` with your actual [GitHub Personal Access Token](https://github.com/settings/tokens)
|
||||
4. Save the file
|
||||
5. Restart Cursor
|
||||
|
||||
### Docker Configuration
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Important**: The npm package `@modelcontextprotocol/server-github` is no longer supported as of April 2025. Use the official Docker image `ghcr.io/github/github-mcp-server` instead.
|
||||
|
||||
## Configuration Files
|
||||
|
||||
- **Global (all projects)**: `~/.cursor/mcp.json`
|
||||
- **Project-specific**: `.cursor/mcp.json` in project root
|
||||
|
||||
## Verify Installation
|
||||
|
||||
1. Restart Cursor completely
|
||||
2. Check for green dot in Settings → Tools & Integrations → MCP Tools
|
||||
3. In chat/composer, check "Available Tools"
|
||||
4. Test with: "List my GitHub repositories"
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Remote Server Issues
|
||||
|
||||
- **Streamable HTTP not working**: Ensure you're using Cursor v0.48.0 or later
|
||||
- **Authentication failures**: Verify PAT has correct scopes
|
||||
- **Connection errors**: Check firewall/proxy settings
|
||||
|
||||
### Local Server Issues
|
||||
|
||||
- **Docker errors**: Ensure Docker Desktop is running
|
||||
- **Image pull failures**: Try `docker logout ghcr.io` then retry
|
||||
- **Docker not found**: Install Docker Desktop and ensure it's running
|
||||
|
||||
### General Issues
|
||||
|
||||
- **MCP not loading**: Restart Cursor completely after configuration
|
||||
- **Invalid JSON**: Validate that json format is correct
|
||||
- **Tools not appearing**: Check server shows green dot in MCP settings
|
||||
- **Check logs**: Look for MCP-related errors in Cursor logs
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Docker image**: `ghcr.io/github/github-mcp-server` (official and supported)
|
||||
- **npm package**: `@modelcontextprotocol/server-github` (deprecated as of April 2025 - no longer functional)
|
||||
- **Cursor specifics**: Supports both project and global configurations, uses `mcpServers` key
|
||||
@@ -0,0 +1,200 @@
|
||||
# Install GitHub MCP Server in Google Gemini CLI
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Google Gemini CLI installed (see [official Gemini CLI documentation](https://github.com/google-gemini/gemini-cli))
|
||||
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
3. For local installation: [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
<details>
|
||||
<summary><b>Storing Your PAT Securely</b></summary>
|
||||
<br>
|
||||
|
||||
For security, avoid hardcoding your token. Create or update `~/.gemini/.env` (where `~` is your home or project directory) with your PAT:
|
||||
|
||||
```bash
|
||||
# ~/.gemini/.env
|
||||
GITHUB_MCP_PAT=your_token_here
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## GitHub MCP Server Configuration
|
||||
|
||||
MCP servers for Gemini CLI are configured in its settings JSON under an `mcpServers` key.
|
||||
|
||||
- **Global configuration**: `~/.gemini/settings.json` where `~` is your home directory
|
||||
- **Project-specific**: `.gemini/settings.json` in your project directory
|
||||
|
||||
After securely storing your PAT, you can add the GitHub MCP server configuration to your settings file using one of the methods below. You may need to restart the Gemini CLI for changes to take effect.
|
||||
|
||||
> **Note:** For the most up-to-date configuration options, see the [main README.md](../../README.md).
|
||||
|
||||
### Method 1: Gemini Extension (Recommended)
|
||||
|
||||
The simplest way is to use GitHub's hosted MCP server via our gemini extension.
|
||||
|
||||
`gemini extensions install https://github.com/github/github-mcp-server`
|
||||
|
||||
> [!NOTE]
|
||||
> You will still need to have a personal access token with the appropriate scopes called `GITHUB_MCP_PAT` in your environment.
|
||||
|
||||
### Method 2: Remote Server
|
||||
|
||||
You can also connect to the hosted MCP server directly. After securely storing your PAT, configure Gemini CLI with:
|
||||
|
||||
```json
|
||||
// ~/.gemini/settings.json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"httpUrl": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer $GITHUB_MCP_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Method 3: Local Docker
|
||||
|
||||
With docker running, you can run the GitHub MCP server in a container.
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
// ~/.gemini/settings.json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
// ~/.gemini/settings.json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_MCP_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Method 4: Binary
|
||||
|
||||
You can download the latest binary release from the [GitHub releases page](https://github.com/github/github-mcp-server/releases) or build it from source by running `go build -o github-mcp-server ./cmd/github-mcp-server`.
|
||||
|
||||
Then, replacing `/path/to/binary` with the actual path to your binary, configure Gemini CLI with:
|
||||
|
||||
```json
|
||||
// ~/.gemini/settings.json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "/path/to/binary",
|
||||
"args": ["stdio"],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_MCP_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To log in with OAuth instead of a PAT (no token to create or store), omit `GITHUB_PERSONAL_ACCESS_TOKEN` — the native binary uses a random loopback callback port, so no extra configuration is needed. See **[Local Server OAuth Login](../oauth-login.md)**.
|
||||
|
||||
## Verification
|
||||
|
||||
To verify that the GitHub MCP server has been configured, start Gemini CLI in your terminal with `gemini`, then:
|
||||
|
||||
1. **Check MCP server status**:
|
||||
|
||||
```
|
||||
/mcp list
|
||||
```
|
||||
|
||||
```
|
||||
ℹConfigured MCP servers:
|
||||
|
||||
🟢 github - Ready (96 tools, 2 prompts)
|
||||
Tools:
|
||||
- github__add_comment_to_pending_review
|
||||
- github__add_issue_comment
|
||||
- github__add_sub_issue
|
||||
...
|
||||
```
|
||||
|
||||
2. **Test with a prompt**
|
||||
```
|
||||
List my GitHub repositories
|
||||
```
|
||||
|
||||
## Additional Configuration
|
||||
|
||||
You can find more MCP configuration options for Gemini CLI here: [MCP Configuration Structure](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html#configuration-structure). For example, bypassing tool confirmations or excluding specific tools.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Local Server Issues
|
||||
|
||||
- **Docker errors**: Ensure Docker Desktop is running
|
||||
```bash
|
||||
docker --version
|
||||
```
|
||||
- **Image pull failures**: Try `docker logout ghcr.io` then retry
|
||||
- **Docker not found**: Install Docker Desktop and ensure it's running
|
||||
|
||||
### Authentication Issues
|
||||
|
||||
- **Invalid PAT**: Verify your GitHub PAT has correct scopes:
|
||||
- `repo` - Repository operations
|
||||
- `read:packages` - Docker image access (if using Docker)
|
||||
- **Token expired**: Generate a new GitHub PAT
|
||||
|
||||
### Configuration Issues
|
||||
|
||||
- **Invalid JSON**: Validate your configuration:
|
||||
```bash
|
||||
cat ~/.gemini/settings.json | jq .
|
||||
```
|
||||
- **MCP connection issues**: Check logs for connection errors:
|
||||
```bash
|
||||
gemini --debug "test command"
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- Gemini CLI Docs > [MCP Configuration Structure](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html#configuration-structure)
|
||||
@@ -0,0 +1,181 @@
|
||||
# Install GitHub MCP Server in OpenCode
|
||||
|
||||
[OpenCode](https://opencode.ai) is a terminal-based AI coding agent that exposes MCP servers under the `mcp` key in `opencode.json` (or `opencode.jsonc`). For general setup information (prerequisites, Docker installation, security best practices), see the [Installation Guides README](./README.md).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. OpenCode installed (`brew install sst/tap/opencode` or see [OpenCode install docs](https://opencode.ai/docs/))
|
||||
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
3. For local installation: [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
> [!IMPORTANT]
|
||||
> The OpenCode docs note that the GitHub MCP server can add a lot of tokens to your context. Consider limiting toolsets — for example, by setting `X-MCP-Toolsets` on the remote server or `--toolsets` on the local server — to keep prompts within your model's context window. See the [Server Configuration Guide](../server-configuration.md) and the [main README's toolsets section](../../README.md#available-toolsets).
|
||||
|
||||
## Remote Server (Recommended)
|
||||
|
||||
Uses GitHub's hosted server at `https://api.githubcopilot.com/mcp/`. Edit your [OpenCode config](https://opencode.ai/docs/config/) (typically `~/.config/opencode/opencode.json`, or `opencode.json` in your project root) and add the following under `mcp`:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"github": {
|
||||
"type": "remote",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"enabled": true,
|
||||
"oauth": false,
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens). The `oauth: false` setting disables OpenCode's automatic OAuth discovery and tells it to use the PAT in `Authorization` instead — without this, OpenCode may try the OAuth flow first.
|
||||
|
||||
### Using an environment variable for the PAT
|
||||
|
||||
OpenCode supports environment-variable interpolation in config values via `{env:VAR_NAME}`. To avoid putting your PAT directly in `opencode.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"github": {
|
||||
"type": "remote",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"enabled": true,
|
||||
"oauth": false,
|
||||
"headers": {
|
||||
"Authorization": "Bearer {env:GITHUB_PERSONAL_ACCESS_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Set `GITHUB_PERSONAL_ACCESS_TOKEN` in your shell environment before starting OpenCode.
|
||||
|
||||
## Local Server (Docker)
|
||||
|
||||
The local GitHub MCP server runs via Docker and requires Docker Desktop (or another Docker runtime) to be installed and running.
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"github": {
|
||||
"type": "local",
|
||||
"command": [
|
||||
"docker", "run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"enabled": true,
|
||||
"environment": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"github": {
|
||||
"type": "local",
|
||||
"command": [
|
||||
"docker", "run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"enabled": true,
|
||||
"environment": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> OpenCode expects `command` as a **single array** combining the executable and its arguments (e.g. `["docker", "run", "-i", ...]`), and the env-var key is `environment` (not `env`). This differs from hosts like Zed and Cursor.
|
||||
|
||||
## Verify Installation
|
||||
|
||||
1. Restart OpenCode (or start a new session).
|
||||
2. Check that the server is discovered:
|
||||
```sh
|
||||
opencode mcp list
|
||||
```
|
||||
3. Try a prompt that references the server by name to bias the model toward its tools:
|
||||
```
|
||||
Use the github tool to list my recently merged pull requests.
|
||||
```
|
||||
|
||||
## Managing the Server
|
||||
|
||||
OpenCode exposes a few useful subcommands for MCP servers:
|
||||
|
||||
| Command | Purpose |
|
||||
| --- | --- |
|
||||
| `opencode mcp list` | List configured MCP servers and their auth/connection status. |
|
||||
| `opencode mcp debug github` | Show auth status, test HTTP connectivity, and walk through OAuth discovery for the `github` server. |
|
||||
| `opencode mcp auth github` | Trigger an OAuth flow manually (only relevant if `oauth` is not set to `false`). |
|
||||
| `opencode mcp logout github` | Clear stored OAuth tokens for the server. |
|
||||
|
||||
## Disabling Tools Per-Agent
|
||||
|
||||
Because the GitHub MCP server can register a large number of tools, you may want to **disable them globally** and **re-enable them only for specific agents**. OpenCode uses the `<server-name>_*` glob pattern to match all tools from a server:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"github": {
|
||||
"type": "remote",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"enabled": true,
|
||||
"oauth": false,
|
||||
"headers": { "Authorization": "Bearer {env:GITHUB_PERSONAL_ACCESS_TOKEN}" }
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"github_*": false
|
||||
},
|
||||
"agent": {
|
||||
"github-helper": {
|
||||
"tools": { "github_*": true }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This pattern is recommended by the [OpenCode MCP docs](https://opencode.ai/docs/mcp-servers/) for servers with many tools.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **`401 Unauthorized` from the remote server**: confirm your PAT is valid and not expired. If you set `oauth: false`, OpenCode will not attempt an OAuth fallback — the `Authorization` header must be correct.
|
||||
- **Server marked failed in `opencode mcp list`**: run `opencode mcp debug github` to see the exact connectivity and auth diagnostics.
|
||||
- **Tools missing from prompts**: check that `enabled: true` is set on the server and that you have not disabled `github_*` in your `tools` block without re-enabling it for the current agent.
|
||||
- **Context window exceeded**: the GitHub MCP server can register many tools. Use server-side toolset filtering (`X-MCP-Toolsets` header) to register only the toolsets you need.
|
||||
- **Docker errors on the local server**: ensure Docker Desktop is running and the `ghcr.io/github/github-mcp-server` image has been pulled (`docker pull ghcr.io/github/github-mcp-server`).
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Configuration key**: OpenCode uses `mcp` (not `mcpServers` or `context_servers`).
|
||||
- **Type discriminator**: every entry must include `"type": "local"` or `"type": "remote"`.
|
||||
- **Command shape**: `command` is a single array combining the executable and its arguments.
|
||||
- **Environment variable key**: `environment` (not `env`).
|
||||
- **OAuth**: enabled by default for remote servers. Set `"oauth": false` when using PAT-in-`Authorization`, otherwise OpenCode may try OAuth first.
|
||||
- **Env interpolation**: use `{env:VAR_NAME}` in string values to read from the shell environment instead of hard-coding secrets.
|
||||
@@ -0,0 +1,357 @@
|
||||
# Install GitHub MCP Server in Copilot IDEs
|
||||
|
||||
Quick setup guide for the GitHub MCP server in GitHub Copilot across different IDEs. For VS Code instructions, refer to the [VS Code install guide in the README](/README.md#installation-in-vs-code)
|
||||
|
||||
### Requirements:
|
||||
- **GitHub Copilot License**: Any Copilot plan (Free, Pro, Pro+, Business, Enterprise) for Copilot access
|
||||
- **GitHub Account**: Individual GitHub account (organization/enterprise membership optional) for GitHub MCP server access
|
||||
- **MCP Servers in Copilot Policy**: Organizations assigning Copilot seats must enable this policy for all MCP access in Copilot for VS Code and Copilot Coding Agent – all other Copilot IDEs will migrate to this policy in the coming months
|
||||
- **Editor Preview Policy**: Organizations assigning Copilot seats must enable this policy for OAuth access while the Remote GitHub MCP Server is in public preview
|
||||
|
||||
> **Note:** All Copilot IDEs now support the remote GitHub MCP server. VS Code offers OAuth authentication, while Visual Studio, JetBrains IDEs, Xcode, and Eclipse currently use PAT authentication with OAuth support coming soon.
|
||||
|
||||
## Visual Studio
|
||||
|
||||
Requires Visual Studio 2022 version 17.14.9 or later.
|
||||
|
||||
### Remote Server (Recommended)
|
||||
|
||||
The remote GitHub MCP server is hosted by GitHub and provides automatic updates with no local setup required.
|
||||
|
||||
#### Configuration
|
||||
1. Create an `.mcp.json` file in your solution or %USERPROFILE% directory.
|
||||
2. Add this configuration:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
3. Save the file. Wait for CodeLens to update to offer a way to authenticate to the new server, activate that and pick the GitHub account to authenticate with.
|
||||
4. In the GitHub Copilot Chat window, switch to Agent mode.
|
||||
5. Activate the tool picker in the Chat window and enable one or more tools from the "github" MCP server.
|
||||
|
||||
### Local Server
|
||||
|
||||
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
|
||||
|
||||
#### Configuration
|
||||
1. Create an `.mcp.json` file in your solution or %USERPROFILE% directory.
|
||||
2. Add this configuration. Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"type": "stdio",
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm", "-p", "127.0.0.1:8085:8085", "-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
```json
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"id": "github_pat",
|
||||
"description": "GitHub personal access token",
|
||||
"type": "promptString",
|
||||
"password": true
|
||||
}
|
||||
],
|
||||
"servers": {
|
||||
"github": {
|
||||
"type": "stdio",
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_pat}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
3. Save the file. Wait for CodeLens to update to offer a way to provide user inputs, activate that and paste in a PAT you generate from https://github.com/settings/tokens.
|
||||
4. In the GitHub Copilot Chat window, switch to Agent mode.
|
||||
5. Activate the tool picker in the Chat window and enable one or more tools from the "github" MCP server.
|
||||
|
||||
**Documentation:** [Visual Studio MCP Guide](https://learn.microsoft.com/visualstudio/ide/mcp-servers)
|
||||
|
||||
---
|
||||
|
||||
## JetBrains IDEs
|
||||
|
||||
Agent mode and MCP support available in public preview across IntelliJ IDEA, PyCharm, WebStorm, and other JetBrains IDEs.
|
||||
|
||||
### Remote Server (Recommended)
|
||||
|
||||
The remote GitHub MCP server is hosted by GitHub and provides automatic updates with no local setup required.
|
||||
|
||||
> **Note**: OAuth authentication for the remote GitHub server is not yet supported in JetBrains IDEs. You must use a Personal Access Token (PAT).
|
||||
|
||||
#### Configuration Steps
|
||||
1. Install/update the GitHub Copilot plugin
|
||||
2. Click **GitHub Copilot icon in the status bar** → **Edit Settings** → **Model Context Protocol** → **Configure**
|
||||
3. Add configuration:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"requestInit": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
4. Press `Ctrl + S` or `Command + S` to save, or close the `mcp.json` file. The configuration should take effect immediately and restart all the MCP servers defined. You can restart the IDE if needed.
|
||||
|
||||
### Local Server
|
||||
|
||||
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
|
||||
|
||||
#### Configuration
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Documentation:** [JetBrains Copilot Guide](https://plugins.jetbrains.com/plugin/17718-github-copilot)
|
||||
|
||||
---
|
||||
|
||||
## Xcode
|
||||
|
||||
Agent mode and MCP support now available in public preview for Xcode.
|
||||
|
||||
### Remote Server (Recommended)
|
||||
|
||||
The remote GitHub MCP server is hosted by GitHub and provides automatic updates with no local setup required.
|
||||
|
||||
> **Note**: OAuth authentication for the remote GitHub server is not yet supported in Xcode. You must use a Personal Access Token (PAT).
|
||||
|
||||
#### Configuration Steps
|
||||
1. Install/update [GitHub Copilot for Xcode](https://github.com/github/CopilotForXcode)
|
||||
2. Open **GitHub Copilot for Xcode app** → **Agent Mode** → **🛠️ Tool Picker** → **Edit Config**
|
||||
3. Configure your MCP servers:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"requestInit": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Local Server
|
||||
|
||||
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
|
||||
|
||||
#### Configuration
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Documentation:** [Xcode Copilot Guide](https://devblogs.microsoft.com/xcode/github-copilot-exploring-agent-mode-and-mcp-support-in-public-preview-for-xcode/)
|
||||
|
||||
---
|
||||
|
||||
## Eclipse
|
||||
|
||||
MCP support available with Eclipse 2024-03+ and latest version of the GitHub Copilot plugin.
|
||||
|
||||
### Remote Server (Recommended)
|
||||
|
||||
The remote GitHub MCP server is hosted by GitHub and provides automatic updates with no local setup required.
|
||||
|
||||
> **Note**: OAuth authentication for the remote GitHub server is not yet supported in Eclipse. You must use a Personal Access Token (PAT).
|
||||
|
||||
#### Configuration Steps
|
||||
1. Install GitHub Copilot extension from Eclipse Marketplace
|
||||
2. Click the **GitHub Copilot icon** → **Edit Preferences** → **MCP** (under **GitHub Copilot**)
|
||||
3. Add GitHub MCP server configuration:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"requestInit": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
4. Click the "Apply and Close" button in the preference dialog and the configuration will take effect automatically.
|
||||
|
||||
### Local Server
|
||||
|
||||
For users who prefer to run the GitHub MCP server locally. Requires Docker installed and running.
|
||||
|
||||
#### Configuration
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Documentation:** [Eclipse Copilot plugin](https://marketplace.eclipse.org/content/github-copilot)
|
||||
|
||||
---
|
||||
|
||||
## GitHub Personal Access Token
|
||||
|
||||
For PAT authentication, see our [Personal Access Token documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) for setup instructions.
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
After setup:
|
||||
1. Restart your IDE completely
|
||||
2. Open Agent mode in Copilot Chat
|
||||
3. Try: *"List recent issues in this repository"*
|
||||
4. Copilot can now access GitHub data and perform repository operations
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Connection issues**: Verify GitHub PAT permissions and IDE version compatibility
|
||||
- **Authentication errors**: Check if your organization has enabled the MCP policy for Copilot
|
||||
- **Tools not appearing**: Restart IDE after configuration changes and check error logs
|
||||
- **Local server issues**: Ensure Docker is running for Docker-based setups
|
||||
@@ -0,0 +1,83 @@
|
||||
# Install GitHub MCP Server in Roo Code
|
||||
|
||||
[Roo Code](https://github.com/RooCodeInc/Roo-Code) is an AI coding assistant that runs in VS Code-compatible editors (VS Code, Cursor, Windsurf, etc.). For general setup information (prerequisites, Docker installation, security best practices), see the [Installation Guides README](./README.md).
|
||||
|
||||
## Remote Server
|
||||
|
||||
### Step-by-step setup
|
||||
|
||||
1. Click the **Roo Code icon** in your editor's sidebar to open the Roo Code pane
|
||||
2. Click the **gear icon** (⚙️) in the top navigation of the Roo Code pane, then click on **"MCP Servers"** icon on the left.
|
||||
3. Scroll to the bottom and click **"Edit Global MCP"** (for all projects) or **"Edit Project MCP"** (for the current project only)
|
||||
4. Add the configuration below to the opened file (`mcp_settings.json` or `.roo/mcp.json`)
|
||||
5. Replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens)
|
||||
6. Save the file — the server should connect automatically
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"type": "streamable-http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> **Important:** The `type` must be `"streamable-http"` (with hyphen). Using `"http"` or omitting the type will fail.
|
||||
|
||||
To customize toolsets, add server-side headers like `X-MCP-Toolsets` or `X-MCP-Readonly` to the `headers` object — see [Server Configuration Guide](../server-configuration.md).
|
||||
|
||||
## Local Server (Docker)
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (replace `YOUR_GITHUB_PAT`; it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Connection failures**: Ensure `type` is `streamable-http`, not `http`
|
||||
- **Authentication failures**: Verify PAT is prefixed with `Bearer ` in the `Authorization` header
|
||||
- **Docker issues**: Ensure Docker Desktop is running
|
||||
@@ -0,0 +1,32 @@
|
||||
# Install GitHub MCP Server in Rovo Dev CLI
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Rovo Dev CLI installed (latest version)
|
||||
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
|
||||
## MCP Server Setup
|
||||
|
||||
Uses GitHub's hosted server at https://api.githubcopilot.com/mcp/.
|
||||
|
||||
### Install steps
|
||||
|
||||
1. Run `acli rovodev mcp` to open the MCP configuration for Rovo Dev CLI
|
||||
2. Add configuration by following example below.
|
||||
3. Replace `YOUR_GITHUB_PAT` with your actual [GitHub Personal Access Token](https://github.com/settings/tokens)
|
||||
4. Save the file and restart Rovo Dev CLI with `acli rovodev`
|
||||
|
||||
### Example configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,136 @@
|
||||
# Install GitHub MCP Server in Windsurf
|
||||
|
||||
## Prerequisites
|
||||
1. Windsurf IDE installed (latest version)
|
||||
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
3. For local installation: [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
## Remote Server Setup (Recommended)
|
||||
|
||||
The remote GitHub MCP server is hosted by GitHub at `https://api.githubcopilot.com/mcp/` and supports Streamable HTTP protocol. Windsurf currently supports PAT authentication only.
|
||||
|
||||
### Streamable HTTP Configuration
|
||||
Windsurf supports Streamable HTTP servers with a `serverUrl` field:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"serverUrl": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Local Server Setup
|
||||
|
||||
### Docker Installation (Required)
|
||||
**Important**: The npm package `@modelcontextprotocol/server-github` is no longer supported as of April 2025. Use the official Docker image `ghcr.io/github/github-mcp-server` instead.
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-p",
|
||||
"127.0.0.1:8085:8085",
|
||||
"-e",
|
||||
"GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run",
|
||||
"-i",
|
||||
"--rm",
|
||||
"-e",
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Installation Steps
|
||||
|
||||
### Via Plugin Store
|
||||
1. Open Windsurf and navigate to Cascade
|
||||
2. Click the **Plugins** icon or **hammer icon** (🔨)
|
||||
3. Search for "GitHub MCP Server"
|
||||
4. Click **Install** and enter your PAT when prompted
|
||||
5. Click **Refresh** (🔄)
|
||||
|
||||
### Manual Configuration
|
||||
1. Click the hammer icon (🔨) in Cascade
|
||||
2. Click **Configure** to open `~/.codeium/windsurf/mcp_config.json`
|
||||
3. Add your chosen configuration from above
|
||||
4. Save the file
|
||||
5. Click **Refresh** (🔄) in the MCP toolbar
|
||||
|
||||
## Configuration Details
|
||||
|
||||
- **File path**: `~/.codeium/windsurf/mcp_config.json`
|
||||
- **Scope**: Global configuration only (no per-project support)
|
||||
- **Format**: Must be valid JSON (use a linter to verify)
|
||||
|
||||
## Verification
|
||||
|
||||
After installation:
|
||||
1. Look for "1 available MCP server" in the MCP toolbar
|
||||
2. Click the hammer icon to see available GitHub tools
|
||||
3. Test with: "List my GitHub repositories"
|
||||
4. Check for green dot next to the server name
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Remote Server Issues
|
||||
- **Authentication failures**: Verify PAT has correct scopes and hasn't expired
|
||||
- **Connection errors**: Check firewall/proxy settings for HTTPS connections
|
||||
- **Streamable HTTP not working**: Ensure you're using the correct `serverUrl` field format
|
||||
|
||||
### Local Server Issues
|
||||
- **Docker errors**: Ensure Docker Desktop is running
|
||||
- **Image pull failures**: Try `docker logout ghcr.io` then retry
|
||||
- **Docker not found**: Install Docker Desktop and ensure it's running
|
||||
|
||||
### General Issues
|
||||
- **Invalid JSON**: Validate with [jsonlint.com](https://jsonlint.com)
|
||||
- **Tools not appearing**: Restart Windsurf completely
|
||||
- **Check logs**: `~/.codeium/windsurf/logs/`
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Official repository**: [github/github-mcp-server](https://github.com/github/github-mcp-server)
|
||||
- **Remote server URL**: `https://api.githubcopilot.com/mcp/`
|
||||
- **Docker image**: `ghcr.io/github/github-mcp-server` (official and supported)
|
||||
- **npm package**: `@modelcontextprotocol/server-github` (deprecated as of April 2025 - no longer functional)
|
||||
- **Windsurf limitations**: No environment variable interpolation, global config only
|
||||
@@ -0,0 +1,47 @@
|
||||
# Install GitHub MCP Server in Xcode
|
||||
|
||||
Xcode currently supports two built-in coding agents: **Codex** (powered by OpenAI) and **Claude Agent** (powered by Anthropic). Follow the standard installation guide for each agent, with one important difference: Xcode uses its own isolated configuration directories for each agent, separate from your global config.
|
||||
|
||||
> Configurations placed in these directories only affect agents when launched from Xcode. See [Apple's documentation](https://developer.apple.com/documentation/xcode/setting-up-coding-intelligence#Customize-the-Claude-Agent-and-Codex-environments) for more details.
|
||||
|
||||
## Configuration Directories
|
||||
|
||||
| Agent | Configuration Directory |
|
||||
|-------|------------------------|
|
||||
| Codex | `~/Library/Developer/Xcode/CodingAssistant/codex/` |
|
||||
| Claude Agent | `~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/` |
|
||||
|
||||
Place your MCP server configuration in the relevant directory above rather than the default location used by the standalone CLI.
|
||||
|
||||
## Setup Guides
|
||||
|
||||
- **[Codex](install-codex.md)** — configure `config.toml` inside `~/Library/Developer/Xcode/CodingAssistant/codex/`
|
||||
- **[Claude Agent](install-claude.md#xcode-claude-agent)** — configure `.claude.json` inside `~/Library/Developer/Xcode/CodingAssistant/ClaudeAgentConfig/`
|
||||
|
||||
## macOS Path Note
|
||||
|
||||
Xcode runs with a minimal `PATH` that typically excludes common binary locations. If you are using a local STDIO server (e.g. Docker or a pre-built binary), use the **full path** to the command in your config. Run `which docker` (or `which github-mcp-server`) in Terminal to find the correct path on your system. Common locations:
|
||||
|
||||
| Installation | Typical path |
|
||||
|---|---|
|
||||
| Docker (Intel Mac) | `/usr/local/bin/docker` |
|
||||
| Docker (Apple Silicon) | `/usr/local/bin/docker` |
|
||||
| Homebrew (Intel Mac) | `/usr/local/bin/` |
|
||||
| Homebrew (Apple Silicon) | `/opt/homebrew/bin/` |
|
||||
|
||||
> **Logging in with OAuth?** You can run the local server with no PAT — it opens a browser login on first use and keeps the token in memory only. With Docker this needs a fixed callback port published to loopback (`-p 127.0.0.1:8085:8085 -e GITHUB_OAUTH_CALLBACK_PORT` with `GITHUB_OAUTH_CALLBACK_PORT=8085`); a native binary uses a random loopback port and needs no extra configuration. See **[Local Server OAuth Login](../oauth-login.md)**.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Possible Cause | Fix |
|
||||
|-------|----------------|-----|
|
||||
| Tools not loading | Config placed in wrong directory | Ensure config is in the Xcode-specific path above, not `~/.codex/` or `~/.claude.json` |
|
||||
| Command not found (STDIO) | Xcode's PATH excludes binary location | Use the full path (e.g. `/usr/local/bin/docker` or `/opt/homebrew/bin/docker`); run `which docker` in Terminal to confirm |
|
||||
| Docker not found | Docker not running | Start Docker Desktop and restart Xcode |
|
||||
| Authentication failed | Invalid or expired PAT | Regenerate PAT and update config |
|
||||
|
||||
## References
|
||||
|
||||
- [Apple Developer Documentation — Setting up coding intelligence](https://developer.apple.com/documentation/xcode/setting-up-coding-intelligence#Customize-the-Claude-Agent-and-Codex-environments)
|
||||
- [Codex MCP documentation](https://developers.openai.com/codex/mcp)
|
||||
- Main project README: [Advanced configuration options](../../README.md)
|
||||
@@ -0,0 +1,128 @@
|
||||
# Install GitHub MCP Server in Zed
|
||||
|
||||
[Zed](https://zed.dev) is a high-performance multiplayer code editor with native MCP support. Zed exposes MCP servers under the `context_servers` settings key. For general setup information (prerequisites, Docker installation, security best practices), see the [Installation Guides README](./README.md).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Zed installed (latest version — Zed v0.224.0+ recommended for the modern `agent.tool_permissions` settings shape)
|
||||
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
|
||||
3. For local installation: [Docker](https://www.docker.com/) installed and running
|
||||
|
||||
## Installation Methods
|
||||
|
||||
There are two ways to install the GitHub MCP server in Zed:
|
||||
|
||||
- **Option A — Zed Extension (easiest):** a community-maintained [GitHub MCP extension](https://zed.dev/extensions/mcp-server-github) is available in the Zed extension gallery. Install it from the Agent Panel's top-right menu → "View Server Extensions", or from the command palette via the `zed: extensions` action. After installation, Zed pops up a modal asking for your GitHub Personal Access Token.
|
||||
- **Option B — Custom Server (recommended for the official remote endpoint):** add the configuration manually to `settings.json` to use either GitHub's hosted remote server or the official Docker image directly. The rest of this guide covers Option B.
|
||||
|
||||
## Remote Server (Recommended)
|
||||
|
||||
Uses GitHub's hosted server at `https://api.githubcopilot.com/mcp/`. Open your Zed [settings file](https://zed.dev/docs/configuring-zed.html#settings-files) (Command Palette → `zed: open settings`) and add the configuration below under `context_servers`.
|
||||
|
||||
```json
|
||||
{
|
||||
"context_servers": {
|
||||
"github": {
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"Authorization": "Bearer YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Replace `YOUR_GITHUB_PAT` with your [GitHub Personal Access Token](https://github.com/settings/tokens). To customize toolsets, add server-side headers like `X-MCP-Toolsets` or `X-MCP-Readonly` to the `headers` object — see the [Server Configuration Guide](../server-configuration.md).
|
||||
|
||||
> [!NOTE]
|
||||
> If you omit the `Authorization` header, Zed will attempt the standard MCP OAuth flow on first use. The GitHub MCP server does not currently advertise OAuth for non-Copilot hosts, so a Personal Access Token in the `Authorization` header is the supported path.
|
||||
|
||||
## Local Server (Docker)
|
||||
|
||||
The local GitHub MCP server runs via Docker and requires Docker Desktop (or another Docker runtime) to be installed and running.
|
||||
|
||||
Log in with OAuth instead of a token. On github.com the official image already includes the app credentials, so you provide none yourself — the server opens a browser login on first use and keeps the token in memory only. In Docker, publish a fixed callback port to loopback:
|
||||
|
||||
```json
|
||||
{
|
||||
"context_servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_OAUTH_CALLBACK_PORT": "8085"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See **[Local Server OAuth Login](../oauth-login.md)** for the native-binary flow (no fixed port), headless/device-code fallback, GitHub Enterprise, and bringing your own OAuth or GitHub App.
|
||||
|
||||
To authenticate with a Personal Access Token instead (it takes precedence over OAuth):
|
||||
|
||||
```json
|
||||
{
|
||||
"context_servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Zed expects `command` as a **string** plus a separate `args` array, not a single array combining both. This differs from hosts like OpenCode and Claude Desktop.
|
||||
|
||||
## Verify Installation
|
||||
|
||||
1. Open the Agent Panel and click into its Settings view (or run `agent: open settings`).
|
||||
2. Find `github` in the context servers list. A green indicator dot with the tooltip "Server is active" confirms a working configuration. Other colors and tooltip messages indicate startup or auth errors.
|
||||
3. Try a prompt that should invoke a tool — for example, `List my recent GitHub pull requests`. Zed will prompt for tool approval before the first call unless your `agent.tool_permissions.default` is set to `"allow"`.
|
||||
|
||||
## Tool Permissions (Optional)
|
||||
|
||||
Zed v0.224.0+ controls tool approval via `agent.tool_permissions`. Approve a specific GitHub MCP tool without per-call prompts by using the `mcp:<server>:<tool_name>` key format:
|
||||
|
||||
```json
|
||||
{
|
||||
"agent": {
|
||||
"tool_permissions": {
|
||||
"default": "confirm",
|
||||
"rules": [
|
||||
{ "tool": "mcp:github:list_pull_requests", "permission": "allow" },
|
||||
{ "tool": "mcp:github:list_issues", "permission": "allow" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See the [Zed tool permissions docs](https://zed.dev/docs/ai/tool-permissions.html) for the full schema.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Server indicator stays red / "Server is not running"**: check the Agent Panel's settings view for the per-server error string. Most common cause is invalid JSON in `settings.json` — Zed surfaces JSON parse errors in the editor itself.
|
||||
- **`401 Unauthorized`**: verify your PAT has not expired and includes the scopes for the tools you intend to call. The remote endpoint will reject requests with no `Authorization` header (no anonymous access).
|
||||
- **Tools missing from prompts**: confirm the Agent profile in use has not disabled the server. If you're using a [custom profile](https://zed.dev/docs/ai/agent-panel.html#custom-profiles), make sure `enable_all_context_servers` is `true` or that `github` is explicitly listed.
|
||||
- **Docker errors on the local server**: ensure Docker Desktop is running and the `ghcr.io/github/github-mcp-server` image has been pulled at least once. Try `docker pull ghcr.io/github/github-mcp-server` from a terminal.
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Configuration key**: Zed uses `context_servers` (not `mcpServers`).
|
||||
- **Command shape**: `command` is a string + separate `args` array.
|
||||
- **OAuth**: omitting `Authorization` triggers Zed's MCP OAuth flow, but the GitHub MCP server's PAT-based auth is the supported path today.
|
||||
- **External agents**: MCP servers configured in `context_servers` are forwarded to [external agents](https://zed.dev/docs/ai/external-agents.html) via the Agent Client Protocol.
|
||||
@@ -0,0 +1,266 @@
|
||||
# Local Server OAuth Login (stdio)
|
||||
|
||||
The local (stdio) GitHub MCP Server can log you in with OAuth instead of a
|
||||
Personal Access Token (PAT). On first use it walks you through GitHub's
|
||||
authorization flow in your browser and keeps the resulting token **in memory
|
||||
only** — nothing is written to disk.
|
||||
|
||||
Official released binaries and the `ghcr.io/github/github-mcp-server` image ship
|
||||
with a registered GitHub OAuth application baked in, so on **github.com** you can
|
||||
start the server with no token and no client ID at all. To target a different
|
||||
host (GitHub Enterprise Server or `ghe.com`), or to use your own application,
|
||||
pass `--oauth-client-id` (see [Bring your own app](#bring-your-own-app)).
|
||||
|
||||
> OAuth login applies to the **stdio** server only. The remote server and the
|
||||
> `http` command have their own authentication; see
|
||||
> [Remote Server](remote-server.md).
|
||||
|
||||
## Contents
|
||||
|
||||
- [How it works](#how-it-works)
|
||||
- [Quick start](#quick-start)
|
||||
- [Configuration reference](#configuration-reference)
|
||||
- [Scope filtering](#scope-filtering)
|
||||
- [Running in Docker](#running-in-docker)
|
||||
- [Headless and device-code fallback](#headless-and-device-code-fallback)
|
||||
- [URL elicitation and the security advisory](#url-elicitation-and-the-security-advisory)
|
||||
- [Bring your own app](#bring-your-own-app)
|
||||
- [GitHub Enterprise Server and ghe.com](#github-enterprise-server-and-ghecom)
|
||||
- [Building from source with baked-in credentials](#building-from-source-with-baked-in-credentials)
|
||||
|
||||
## How it works
|
||||
|
||||
The server prefers the **authorization code flow with PKCE**: it starts a
|
||||
loopback callback server on your machine, opens GitHub's authorization page, and
|
||||
exchanges the returned code for a token. GitHub requires a client secret at the
|
||||
token endpoint (for both OAuth Apps and GitHub Apps), so the exchange sends it
|
||||
together with the PKCE verifier. Because this is a public, distributed client,
|
||||
that secret is baked into the binary and is **not truly confidential** — PKCE is
|
||||
what secures the flow: it binds the authorization code to this one login attempt,
|
||||
so a code intercepted on the loopback redirect can't be redeemed anywhere else.
|
||||
|
||||
To present the authorization URL, the server uses the most secure channel your
|
||||
MCP client offers, in order:
|
||||
|
||||
1. **Open your browser automatically** (native runs).
|
||||
2. **URL elicitation** — the client prompts you with the link out of band, so the
|
||||
URL never enters the model's context. Requires a client that supports MCP
|
||||
elicitation (e.g. VS Code 1.101+).
|
||||
3. **A message in the first tool response** — a last resort for clients without
|
||||
elicitation. This includes a [security advisory](#url-elicitation-and-the-security-advisory).
|
||||
|
||||
If the authorization-code flow can't be used — for example, a container with no
|
||||
published callback port — the server falls back to the
|
||||
[device-code flow](#headless-and-device-code-fallback).
|
||||
|
||||
GitHub App tokens that expire are refreshed transparently using the refresh
|
||||
token, so long-running sessions keep working without re-authorizing.
|
||||
|
||||
## Quick start
|
||||
|
||||
**Native binary (recommended).** Best experience: a random loopback port is
|
||||
used and your browser opens automatically. On github.com with an official build,
|
||||
no flags are needed:
|
||||
|
||||
```bash
|
||||
github-mcp-server stdio
|
||||
```
|
||||
|
||||
With your own application:
|
||||
|
||||
```bash
|
||||
github-mcp-server stdio --oauth-client-id <YOUR_CLIENT_ID>
|
||||
```
|
||||
|
||||
VS Code (`.vscode/mcp.json`), using your own app:
|
||||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "/path/to/github-mcp-server",
|
||||
"args": ["stdio", "--oauth-client-id", "<YOUR_CLIENT_ID>"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For Docker, see [Running in Docker](#running-in-docker) — containers need a fixed
|
||||
callback port.
|
||||
|
||||
## Configuration reference
|
||||
|
||||
OAuth login is configured with these stdio flags (each has an environment
|
||||
variable equivalent). Flags apply only to the `stdio` command.
|
||||
|
||||
| Flag | Environment variable | Description |
|
||||
|------|----------------------|-------------|
|
||||
| `--oauth-client-id` | `GITHUB_OAUTH_CLIENT_ID` | OAuth App or GitHub App client ID. Enables OAuth login when no token is set. Defaults to the baked-in app on github.com for official builds. |
|
||||
| `--oauth-client-secret` | `GITHUB_OAUTH_CLIENT_SECRET` | Client secret, **if your app requires one**. For distributed clients this is a public, non-confidential credential. |
|
||||
| `--oauth-scopes` | `GITHUB_OAUTH_SCOPES` | Comma-separated scopes to request. Also [filters tools](#scope-filtering) to those scopes. Defaults to the full supported set. |
|
||||
| `--oauth-callback-port` | `GITHUB_OAUTH_CALLBACK_PORT` | Fixed local port for the callback server. Defaults to a random port; set a fixed port when mapping it through Docker. |
|
||||
|
||||
A static token still takes precedence: if `GITHUB_PERSONAL_ACCESS_TOKEN` is set,
|
||||
the server uses it and skips OAuth entirely.
|
||||
|
||||
## Scope filtering
|
||||
|
||||
The scopes you request determine which tools are exposed. Requesting the full
|
||||
supported set (the default) hides no tools. Narrowing `--oauth-scopes` both
|
||||
narrows the token's grant **and** filters out tools that would need a scope you
|
||||
didn't request, so the tool list reflects what the token can actually do.
|
||||
|
||||
For example, requesting only `repo,read:org` hides tools that require `gist`,
|
||||
`workflow`, `notifications`, and so on.
|
||||
|
||||
## Running in Docker
|
||||
|
||||
A container can't reach a random loopback port on your host, so Docker OAuth
|
||||
needs a **fixed** callback port that you publish into the container. Use port
|
||||
**8085** to match the official app's registered callback URL.
|
||||
|
||||
```bash
|
||||
docker run -i --rm \
|
||||
-p 127.0.0.1:8085:8085 \
|
||||
-e GITHUB_OAUTH_CALLBACK_PORT=8085 \
|
||||
ghcr.io/github/github-mcp-server
|
||||
```
|
||||
|
||||
VS Code (`.vscode/mcp.json`):
|
||||
|
||||
```json
|
||||
{
|
||||
"servers": {
|
||||
"github": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"run", "-i", "--rm",
|
||||
"-p", "127.0.0.1:8085:8085",
|
||||
"-e", "GITHUB_OAUTH_CALLBACK_PORT",
|
||||
"ghcr.io/github/github-mcp-server"
|
||||
],
|
||||
"env": { "GITHUB_OAUTH_CALLBACK_PORT": "8085" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Because the container can't open your host browser, the authorization URL
|
||||
arrives via [URL elicitation](#url-elicitation-and-the-security-advisory) or the
|
||||
tool-response message. After you authorize, your browser hits
|
||||
`localhost:8085`, which Docker forwards into the container's callback.
|
||||
|
||||
If you bring your own app for Docker, register its callback URL as exactly
|
||||
`http://localhost:8085/callback`.
|
||||
|
||||
> **Two safety properties to be aware of with a fixed port:**
|
||||
>
|
||||
> - **Publish to loopback only** (`-p 127.0.0.1:8085:8085`, not `-p 8085:8085`).
|
||||
> Inside a container the callback necessarily listens on all interfaces, so a
|
||||
> plain publish would expose the authorization code to your network. The
|
||||
> server logs a warning reminding you of this when it binds inside a container.
|
||||
> - **A busy port is fatal, by design.** With a fixed port, if the server can't
|
||||
> bind it (another process already holds it), it **stops with an error** rather
|
||||
> than silently falling back to the device flow. A port you didn't get could
|
||||
> belong to another user's process positioned to receive the redirect, so the
|
||||
> server refuses to continue. Free the port or choose a different
|
||||
> `--oauth-callback-port`.
|
||||
|
||||
## Headless and device-code fallback
|
||||
|
||||
When there's no usable browser or callback — a remote shell, CI, or a container
|
||||
started without a published port — the server uses GitHub's **device-code
|
||||
flow**. You'll get a short code and a verification URL to open on any device:
|
||||
|
||||
```
|
||||
Visit https://github.com/login/device and enter the code WDJB-MJHT to authorize
|
||||
the GitHub MCP Server.
|
||||
```
|
||||
|
||||
The server polls GitHub until you finish authorizing, then continues. No
|
||||
callback port is involved, so this works anywhere.
|
||||
|
||||
## URL elicitation and the security advisory
|
||||
|
||||
URL elicitation lets your MCP client present the authorization URL to you
|
||||
directly, keeping it **out of the model's context** — the model never sees the
|
||||
link or any code embedded in it. This is the most secure way to hand off the
|
||||
authorization step.
|
||||
|
||||
If your client doesn't support elicitation, the server falls back to placing the
|
||||
URL in a tool response and appends a short advisory:
|
||||
|
||||
> Note: your MCP client does not appear to support secure URL elicitation. For
|
||||
> improved security, consider asking your agent, CLI, or IDE to add it (for
|
||||
> example, by opening an issue).
|
||||
|
||||
If you see this, your authorization still works — but consider asking your client
|
||||
vendor to add elicitation support.
|
||||
|
||||
## Bring your own app
|
||||
|
||||
You need your own application when targeting a non-github.com host, or when you'd
|
||||
rather not use the baked-in app. Either application type works:
|
||||
|
||||
- **[Create an OAuth App](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app)** —
|
||||
simplest to set up. Grants the scopes you request.
|
||||
- **[Register a GitHub App](https://docs.github.com/en/apps/creating-github-apps/registering-a-github-app/registering-a-github-app)** —
|
||||
finer-grained, per-resource permissions and short-lived tokens that refresh
|
||||
automatically. Enable **Device Flow** in the app settings if you want the
|
||||
[headless fallback](#headless-and-device-code-fallback).
|
||||
|
||||
When registering, set the authorization callback URL:
|
||||
|
||||
- **Native runs** use a random loopback port. For loopback redirects GitHub does
|
||||
not require the callback port to match, so registering
|
||||
`http://localhost/callback` is sufficient.
|
||||
- **Docker / fixed port** must match exactly: register
|
||||
`http://localhost:8085/callback` (or whichever port you publish).
|
||||
|
||||
Then pass the client ID (and secret, only if your app requires one):
|
||||
|
||||
```bash
|
||||
github-mcp-server stdio \
|
||||
--oauth-client-id <YOUR_CLIENT_ID> \
|
||||
--oauth-client-secret <YOUR_CLIENT_SECRET>
|
||||
```
|
||||
|
||||
## GitHub Enterprise Server and ghe.com
|
||||
|
||||
The baked-in app is registered on github.com only, so it is **not** used when you
|
||||
set a custom host. GitHub Enterprise Server and `ghe.com` (Enterprise Cloud with
|
||||
data residency) users must **bring their own app** registered on that host and
|
||||
pass `--oauth-client-id`.
|
||||
|
||||
Set the host with `--gh-host` / `GITHUB_HOST`; the server derives the OAuth
|
||||
authorization, token, and device endpoints from it, so login is directed at your
|
||||
instance's authorization server rather than github.com:
|
||||
|
||||
```bash
|
||||
github-mcp-server stdio \
|
||||
--gh-host https://github.example.com \
|
||||
--oauth-client-id <YOUR_CLIENT_ID>
|
||||
```
|
||||
|
||||
- For GitHub Enterprise Server, prefix the host with `https://`.
|
||||
- For `ghe.com`, use `https://YOURSUBDOMAIN.ghe.com`.
|
||||
|
||||
Register the app's callback URL on the same host (e.g.
|
||||
`http://localhost/callback` for native runs, or `http://localhost:8085/callback`
|
||||
for Docker).
|
||||
|
||||
## Building from source with baked-in credentials
|
||||
|
||||
Official builds embed the default OAuth client via linker flags at build time, so
|
||||
they are not present in the source tree. To produce your own build with embedded
|
||||
credentials, set them with `-ldflags`:
|
||||
|
||||
```bash
|
||||
go build -ldflags "\
|
||||
-X github.com/github/github-mcp-server/internal/buildinfo.OAuthClientID=<CLIENT_ID> \
|
||||
-X github.com/github/github-mcp-server/internal/buildinfo.OAuthClientSecret=<CLIENT_SECRET>" \
|
||||
./cmd/github-mcp-server
|
||||
```
|
||||
|
||||
Without these, a source build simply has no baked-in app and expects
|
||||
`--oauth-client-id` (or a PAT) at runtime.
|
||||
@@ -0,0 +1,216 @@
|
||||
# Policies & Governance for the GitHub MCP Server
|
||||
|
||||
Organizations and enterprises have several existing control mechanisms for the GitHub MCP server on GitHub.com:
|
||||
- MCP servers in Copilot Policy
|
||||
- Copilot Editor Preview Policy (temporary)
|
||||
- OAuth App Access Policies
|
||||
- GitHub App Installation
|
||||
- Personal Access Token (PAT) policies
|
||||
- SSO Enforcement
|
||||
|
||||
This document outlines how these policies apply to different deployment modes, authentication methods, and host applications – while providing guidance for managing GitHub MCP Server access across your organization.
|
||||
|
||||
## How the GitHub MCP Server Works
|
||||
|
||||
The GitHub MCP Server provides access to GitHub resources and capabilities through a standardized protocol, with flexible deployment and authentication options tailored to different use cases. It supports two deployment modes, both built on the same underlying codebase.
|
||||
|
||||
### 1. Local GitHub MCP Server
|
||||
* **Runs:** Locally alongside your IDE or application
|
||||
* **Authentication & Controls:** Requires Personal Access Tokens (PATs). Users must generate and configure a PAT to connect. Managed via [PAT policies](https://docs.github.com/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization#restricting-access-by-personal-access-tokens).
|
||||
* Can optionally use GitHub App installation tokens when embedded in a GitHub App-based tool (rare).
|
||||
|
||||
**Supported SKUs:** Can be used with GitHub Enterprise Server (GHES) and GitHub Enterprise Cloud (GHEC).
|
||||
|
||||
### 2. Remote GitHub MCP Server
|
||||
* **Runs:** As a hosted service accessed over the internet
|
||||
* **Authentication & Controls:** (determined by the chosen authentication method)
|
||||
* **GitHub App Installation Tokens:** Uses a signed JWT to request installation access tokens (similar to the OAuth 2.0 client credentials flow) to operate as the application itself. Provides granular control via [installation](https://docs.github.com/apps/using-github-apps/installing-a-github-app-from-a-third-party#requirements-to-install-a-github-app), [permissions](https://docs.github.com/apps/creating-github-apps/registering-a-github-app/choosing-permissions-for-a-github-app) and [repository access controls](https://docs.github.com/apps/using-github-apps/reviewing-and-modifying-installed-github-apps#modifying-repository-access).
|
||||
* **OAuth Authorization Code Flow:** Uses the standard OAuth 2.0 Authorization Code flow. Controlled via [OAuth App access policies](https://docs.github.com/organizations/managing-oauth-access-to-your-organizations-data/about-oauth-app-access-restrictions) for OAuth apps. For GitHub Apps that sign in ([are authorized by](https://docs.github.com/apps/using-github-apps/authorizing-github-apps)) a user, control access to your organization via [installation](https://docs.github.com/apps/using-github-apps/installing-a-github-app-from-a-third-party#requirements-to-install-a-github-app).
|
||||
* **Personal Access Tokens (PATs):** Managed via [PAT policies](https://docs.github.com/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization#restricting-access-by-personal-access-tokens).
|
||||
* **SSO enforcement:** Applies when using OAuth Apps, GitHub Apps, and PATs to access resources in organizations and enterprises with SSO enabled. Acts as an overlay control. Users must have a valid SSO session for your organization or enterprise when signing into the app or creating the token in order for the token to access your resources. Learn more in the [SSO documentation](https://docs.github.com/enterprise-cloud@latest/authentication/authenticating-with-single-sign-on/about-authentication-with-single-sign-on#about-oauth-apps-github-apps-and-sso).
|
||||
|
||||
**Supported Platforms:** Currently available only on GitHub Enterprise Cloud (GHEC). Remote hosting for GHES is not supported at this time.
|
||||
|
||||
> **Note:** This does not apply to the Local GitHub MCP Server, which uses PATs and does not rely on GitHub App installations.
|
||||
|
||||
#### Enterprise Install Considerations
|
||||
|
||||
- When using the Remote GitHub MCP Server, if authenticating with OAuth instead of PAT, each host application must have a registered GitHub App (or OAuth App) to authenticate on behalf of the user.
|
||||
- Enterprises may choose to install these apps in multiple organizations (e.g., per team or department) to scope access narrowly, or at the enterprise level to centralize access control across all child organizations.
|
||||
- Enterprise installation is only supported for GitHub Apps. OAuth Apps can only be installed on a per organization basis in multi-org enterprises.
|
||||
|
||||
### Security Principles for Both Modes
|
||||
* **Authentication:** Required for all operations, no anonymous access
|
||||
* **Authorization:** Access enforced by GitHub's native permission model. Users and apps cannot use an MCP server to access more resources than they could otherwise access normally via the API.
|
||||
* **Communication:** All data transmitted over HTTPS with optional SSE for real-time updates
|
||||
* **Rate Limiting:** Subject to GitHub API rate limits based on authentication method
|
||||
* **Token Storage:** Tokens should be stored securely using platform-appropriate credential storage
|
||||
* **Audit Trail:** All underlying API calls are logged in GitHub's audit log when available
|
||||
|
||||
For integration architecture and implementation details, see the [Host Integration Guide](https://github.com/github/github-mcp-server/blob/main/docs/host-integration.md).
|
||||
|
||||
## Where It's Used
|
||||
|
||||
The GitHub MCP server can be accessed in various environments (referred to as "host" applications):
|
||||
* **First-party Hosts:** GitHub Copilot in VS Code, Visual Studio, JetBrains, Eclipse, and Xcode with integrated MCP support, as well as Copilot Coding Agent.
|
||||
* **Third-party Hosts:** Editors outside the GitHub ecosystem, such as Claude, Cursor, Windsurf, and Cline, that support connecting to MCP servers, as well as AI chat applications like Claude Desktop and other AI assistants that connect to MCP servers to fetch GitHub context or execute write actions.
|
||||
|
||||
## What It Can Access
|
||||
|
||||
The MCP server accesses GitHub resources based on the permissions granted through the chosen authentication method (PAT, OAuth, or GitHub App). These may include:
|
||||
* Repository contents (files, branches, commits)
|
||||
* Issues and pull requests
|
||||
* Organization and team metadata
|
||||
* User profile information
|
||||
* Actions workflow runs, logs, and statuses
|
||||
* Security and vulnerability alerts (if explicitly granted)
|
||||
|
||||
Access is always constrained by GitHub's public API permission model and the authenticated user's privileges.
|
||||
|
||||
## Control Mechanisms
|
||||
|
||||
### 1. Copilot Editors (first-party) → MCP Servers in Copilot Policy
|
||||
|
||||
* **Policy:** MCP servers in Copilot
|
||||
* **Location:** Enterprise/Org → Policies → Copilot
|
||||
* **What it controls:** When disabled, **completely blocks all GitHub MCP Server access** (both remote and local) for affected Copilot editors. Currently applies to VS Code and Copilot Coding Agent, with more Copilot editors expected to migrate to this policy over time.
|
||||
* **Impact when disabled:** Host applications governed by this policy cannot connect to the GitHub MCP Server through any authentication method (OAuth, PAT, or GitHub App).
|
||||
* **What it does NOT affect:**
|
||||
* MCP support in Copilot on IDEs that are still in public preview (Visual Studio, JetBrains, Xcode, Eclipse)
|
||||
* Third-party IDE or host apps (like Claude, Cursor, Windsurf) not governed by GitHub's Copilot policies
|
||||
* Community-authored MCP servers using GitHub's public APIs
|
||||
|
||||
> **Important:** This policy provides comprehensive control over GitHub MCP Server access in Copilot editors. When disabled, users in affected applications will not be able to use the GitHub MCP Server regardless of deployment mode (remote or local) or authentication method.
|
||||
|
||||
#### Temporary: Copilot Editor Preview Policy
|
||||
|
||||
* **Policy:** Editor Preview Features
|
||||
* **Status:** Being phased out as editors migrate to the "MCP servers in Copilot" policy above, and once the Remote GitHub MCP server goes GA
|
||||
* **What it controls:** When disabled, prevents remaining Copilot editors from using the Remote GitHub MCP Server through OAuth connections in all first-party and third-party host applications (does not affect local deployments or PAT authentication)
|
||||
|
||||
> **Note:** As Copilot editors migrate from the "Copilot Editor Preview" policy to the "MCP servers in Copilot" policy, the scope of control becomes more centralized, blocking both remote and local GitHub MCP Server access when disabled. Access in third-party hosts is governed separately by OAuth App, GitHub App, and PAT policies.
|
||||
|
||||
### 2. Third-Party Host Apps (e.g., Claude, Cursor, Windsurf) → OAuth App or GitHub App Controls
|
||||
|
||||
#### a. OAuth App Access Policies
|
||||
* **Control Mechanism:** OAuth App access restrictions
|
||||
* **Location:** Org → Settings → Third-party Access → OAuth app policy
|
||||
* **How it works:**
|
||||
* Organization admins must approve OAuth App requests before host apps can access organization data
|
||||
* Only applies when the host registers an OAuth App AND the user connects via OAuth 2.0 flow
|
||||
|
||||
#### b. GitHub App Installation
|
||||
* **Control Mechanism:** GitHub App installation and permissions
|
||||
* **Location:** Org → Settings → Third-party Access → GitHub Apps
|
||||
* **What it controls:** Organization admins must install the app, select repositories, and grant permissions before the app can access organization-owned data or resources through the Remote GitHub Server.
|
||||
* **How it works:**
|
||||
* Organization admins must install the app, specify repositories, and approve permissions
|
||||
* Only applies when the host registers a GitHub App AND the user authenticates through that flow
|
||||
|
||||
> **Note:** The authentication methods available depend on what your host application supports. While PATs work with any remote MCP-compatible host, OAuth and GitHub App authentication are only available if the host has registered an app with GitHub. Check your host application's documentation or support for more info.
|
||||
|
||||
### 3. PAT Access from Any Host → PAT Restrictions
|
||||
|
||||
* **Types:** Fine-grained PATs (recommended) and Classic tokens (legacy)
|
||||
* **Location:**
|
||||
* User level: [Personal Settings → Developer Settings → Personal Access Tokens](https://docs.github.com/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#fine-grained-personal-access-tokens)
|
||||
* Enterprise/Organization level: [Enterprise/Organization → Settings → Personal Access Tokens](https://docs.github.com/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization) (to control PAT creation/access policies)
|
||||
* **What it controls:** Applies to all host apps and both local & remote GitHub MCP servers when users authenticate via PAT.
|
||||
* **How it works:** Access limited to the repositories and scopes selected on the token.
|
||||
* **Limitations:** PATs do not adhere to OAuth App policies and GitHub App installation controls. They are user-scoped and not recommended for production automation.
|
||||
* **Organization controls:**
|
||||
* Classic PATs: Can be completely disabled organization-wide
|
||||
* Fine-grained PATs: Cannot be disabled but require explicit approval for organization access
|
||||
|
||||
> **Recommendation:** We recommend using fine-grained PATs over classic tokens. Classic tokens have broader scopes and can be disabled in organization settings.
|
||||
|
||||
### 4. SSO Enforcement (overlay control)
|
||||
|
||||
* **Location:** Enterprise/Organization → SSO settings
|
||||
* **What it controls:** OAuth tokens and PATs must map to a recent SSO login to access SSO-protected organization data.
|
||||
* **How it works:** Applies to ALL host apps when using OAuth or PATs.
|
||||
|
||||
> **Exception:** Does NOT apply to GitHub App installation tokens (these are installation-scoped, not user-scoped)
|
||||
|
||||
## Current Limitations
|
||||
|
||||
While the GitHub MCP Server provides dynamic tooling and capabilities, the following enterprise governance features are not yet available:
|
||||
|
||||
### Single Enterprise/Organization-Level Toggle
|
||||
|
||||
GitHub does not provide a single toggle that blocks all GitHub MCP server traffic for every user. Admins can achieve equivalent coverage by combining the controls shown here:
|
||||
* **First-party Copilot Editors (GitHub Copilot in VS Code, Visual Studio, JetBrains, Eclipse):**
|
||||
* Disable the "MCP servers in Copilot" policy for comprehensive control
|
||||
* Or disable the Editor Preview Features policy (for editors still using the legacy policy)
|
||||
* **Third-party Host Applications:**
|
||||
* Configure OAuth app restrictions
|
||||
* Manage GitHub App installations
|
||||
* **PAT Access in All Host Applications:**
|
||||
* Implement fine-grained PAT policies (applies to both remote and local deployments)
|
||||
|
||||
### MCP-Specific Audit Logging
|
||||
|
||||
At present, MCP traffic appears in standard GitHub audit logs as normal API calls. Purpose-built logging for MCP is on the roadmap, but the following views are not yet available:
|
||||
* Real-time list of active MCP connections
|
||||
* Dashboards showing granular MCP usage data, like tools or host apps
|
||||
* Granular, action-by-action audit logs
|
||||
|
||||
Until those arrive, teams can continue to monitor MCP activity through existing API log entries and OAuth/GitHub App events.
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
### For Organizations
|
||||
|
||||
**GitHub App Management**
|
||||
* Review [GitHub App installations](https://docs.github.com/apps/using-github-apps/reviewing-and-modifying-installed-github-apps) regularly
|
||||
* Audit permissions and repository access
|
||||
* Monitor installation events in audit logs
|
||||
* Document approved GitHub Apps and their business purposes
|
||||
|
||||
**OAuth App Governance**
|
||||
* Manage [OAuth App access policies](https://docs.github.com/organizations/managing-oauth-access-to-your-organizations-data/about-oauth-app-access-restrictions)
|
||||
* Establish review processes for approved applications
|
||||
* Monitor which third-party applications are requesting access
|
||||
* Maintain an allowlist of approved OAuth applications
|
||||
|
||||
**Token Management**
|
||||
* Mandate fine-grained Personal Access Tokens over classic tokens
|
||||
* Establish token expiration policies (90 days maximum recommended)
|
||||
* Implement automated token rotation reminders
|
||||
* Review and enforce [PAT restrictions](https://docs.github.com/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization) at the appropriate level
|
||||
|
||||
### For Developers and Users
|
||||
|
||||
**Authentication Security**
|
||||
* Prioritize OAuth 2.0 flows over long-lived tokens
|
||||
* Prefer fine-grained PATs to PATs (Classic)
|
||||
* Store tokens securely using platform-appropriate credential management
|
||||
* Store credentials in secret management systems, not source code
|
||||
|
||||
**Scope Minimization**
|
||||
* Request only the minimum required scopes for your use case
|
||||
* Regularly review and revoke unused token permissions
|
||||
* Use repository-specific access instead of organization-wide access
|
||||
* Document why each permission is needed for your integration
|
||||
|
||||
## Resources
|
||||
|
||||
**MCP:**
|
||||
* [Model Context Protocol Specification](https://modelcontextprotocol.io/specification/2025-03-26)
|
||||
* [Model Context Protocol Authorization](https://modelcontextprotocol.io/specification/draft/basic/authorization)
|
||||
|
||||
**GitHub Governance & Controls:**
|
||||
* [Managing OAuth App Access](https://docs.github.com/organizations/managing-oauth-access-to-your-organizations-data/about-oauth-app-access-restrictions)
|
||||
* [GitHub App Permissions](https://docs.github.com/apps/creating-github-apps/registering-a-github-app/choosing-permissions-for-a-github-app)
|
||||
* [Updating permissions for a GitHub App](https://docs.github.com/apps/using-github-apps/approving-updated-permissions-for-a-github-app)
|
||||
* [PAT Policies](https://docs.github.com/organizations/managing-programmatic-access-to-your-organization/setting-a-personal-access-token-policy-for-your-organization)
|
||||
* [Fine-grained PATs](https://docs.github.com/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#fine-grained-personal-access-tokens)
|
||||
* [Setting a PAT policy for your organization](https://docs.github.com/organizations/managing-oauth-access-to-your-organizations-data/about-oauth-app-access-restrictions)
|
||||
|
||||
---
|
||||
|
||||
**Questions or Feedback?**
|
||||
|
||||
Open an [issue in the github-mcp-server repository](https://github.com/github/github-mcp-server/issues) with the label "policies & governance" attached.
|
||||
|
||||
This document reflects GitHub MCP Server policies as of July 2025. Policies and capabilities continue to evolve based on customer feedback and security best practices.
|
||||
@@ -0,0 +1,145 @@
|
||||
# Remote GitHub MCP Server 🚀
|
||||
|
||||
[](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) [](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D&quality=insiders)
|
||||
|
||||
Easily connect to the GitHub MCP Server using the hosted version – no local setup or runtime required.
|
||||
|
||||
**URL:** https://api.githubcopilot.com/mcp/
|
||||
|
||||
## About
|
||||
|
||||
The remote GitHub MCP server is built using this repository as a library, and binding it into GitHub server infrastructure with an internal repository. You can open issues and propose changes in this repository, and we regularly update the remote server to include the latest version of this code.
|
||||
|
||||
The remote server has [additional tools](#toolsets-only-available-in-the-remote-mcp-server) that are not available in the local MCP server, such as the `create_pull_request_with_copilot` tool for invoking Copilot coding agent.
|
||||
|
||||
## Remote MCP Toolsets
|
||||
|
||||
Below is a table of available toolsets for the remote GitHub MCP Server. Each toolset is provided as a distinct URL so you can mix and match to create the perfect combination of tools for your use-case. Add `/readonly` to the end of any URL to restrict the tools in the toolset to only those that enable read access. We also provide the option to use [headers](#headers) instead.
|
||||
|
||||
<!-- START AUTOMATED TOOLSETS -->
|
||||
| Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |
|
||||
| ---- | ----------- | ------- | ------------------------- | -------------- | ----------------------------------- |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/apps-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/apps-light.png"><img src="../pkg/octicons/icons/apps-light.png" width="20" height="20" alt="apps"></picture><br>`default` | Default toolset | https://api.githubcopilot.com/mcp/ | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2F%22%7D) | [read-only](https://api.githubcopilot.com/mcp/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=github&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/apps-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/apps-light.png"><img src="../pkg/octicons/icons/apps-light.png" width="20" height="20" alt="apps"></picture><br>`all` | All available GitHub MCP tools | https://api.githubcopilot.com/mcp/x/all | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-all&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fall%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/all/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-all&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fall%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/workflow-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/workflow-light.png"><img src="../pkg/octicons/icons/workflow-light.png" width="20" height="20" alt="workflow"></picture><br>`actions` | GitHub Actions workflows and CI/CD operations | https://api.githubcopilot.com/mcp/x/actions | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-actions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Factions%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/actions/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-actions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Factions%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/code-square-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/code-square-light.png"><img src="../pkg/octicons/icons/code-square-light.png" width="20" height="20" alt="code-square"></picture><br>`code_quality` | GitHub Code Quality related tools | https://api.githubcopilot.com/mcp/x/code_quality | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-code_quality&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcode_quality%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/code_quality/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-code_quality&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcode_quality%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/codescan-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/codescan-light.png"><img src="../pkg/octicons/icons/codescan-light.png" width="20" height="20" alt="codescan"></picture><br>`code_security` | Code security related tools, such as GitHub Code Scanning | https://api.githubcopilot.com/mcp/x/code_security | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-code_security&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcode_security%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/code_security/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-code_security&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcode_security%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/copilot-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/copilot-light.png"><img src="../pkg/octicons/icons/copilot-light.png" width="20" height="20" alt="copilot"></picture><br>`copilot` | Copilot related tools | https://api.githubcopilot.com/mcp/x/copilot | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/copilot/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/dependabot-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/dependabot-light.png"><img src="../pkg/octicons/icons/dependabot-light.png" width="20" height="20" alt="dependabot"></picture><br>`dependabot` | Dependabot tools | https://api.githubcopilot.com/mcp/x/dependabot | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-dependabot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdependabot%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/dependabot/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-dependabot&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdependabot%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/comment-discussion-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/comment-discussion-light.png"><img src="../pkg/octicons/icons/comment-discussion-light.png" width="20" height="20" alt="comment-discussion"></picture><br>`discussions` | GitHub Discussions related tools | https://api.githubcopilot.com/mcp/x/discussions | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-discussions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdiscussions%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/discussions/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-discussions&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fdiscussions%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/logo-gist-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/logo-gist-light.png"><img src="../pkg/octicons/icons/logo-gist-light.png" width="20" height="20" alt="logo-gist"></picture><br>`gists` | GitHub Gist related tools | https://api.githubcopilot.com/mcp/x/gists | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-gists&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgists%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/gists/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-gists&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgists%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/git-branch-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/git-branch-light.png"><img src="../pkg/octicons/icons/git-branch-light.png" width="20" height="20" alt="git-branch"></picture><br>`git` | GitHub Git API related tools for low-level Git operations | https://api.githubcopilot.com/mcp/x/git | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-git&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgit%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/git/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-git&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgit%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/issue-opened-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/issue-opened-light.png"><img src="../pkg/octicons/icons/issue-opened-light.png" width="20" height="20" alt="issue-opened"></picture><br>`issues` | GitHub Issues related tools | https://api.githubcopilot.com/mcp/x/issues | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-issues&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fissues%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/issues/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-issues&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fissues%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/tag-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/tag-light.png"><img src="../pkg/octicons/icons/tag-light.png" width="20" height="20" alt="tag"></picture><br>`labels` | GitHub Labels related tools | https://api.githubcopilot.com/mcp/x/labels | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-labels&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Flabels%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/labels/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-labels&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Flabels%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/bell-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/bell-light.png"><img src="../pkg/octicons/icons/bell-light.png" width="20" height="20" alt="bell"></picture><br>`notifications` | GitHub Notifications related tools | https://api.githubcopilot.com/mcp/x/notifications | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-notifications&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fnotifications%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/notifications/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-notifications&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fnotifications%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/organization-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/organization-light.png"><img src="../pkg/octicons/icons/organization-light.png" width="20" height="20" alt="organization"></picture><br>`orgs` | GitHub Organization related tools | https://api.githubcopilot.com/mcp/x/orgs | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-orgs&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Forgs%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/orgs/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-orgs&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Forgs%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/project-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/project-light.png"><img src="../pkg/octicons/icons/project-light.png" width="20" height="20" alt="project"></picture><br>`projects` | GitHub Projects related tools | https://api.githubcopilot.com/mcp/x/projects | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-projects&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fprojects%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/projects/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-projects&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fprojects%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/git-pull-request-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/git-pull-request-light.png"><img src="../pkg/octicons/icons/git-pull-request-light.png" width="20" height="20" alt="git-pull-request"></picture><br>`pull_requests` | GitHub Pull Request related tools | https://api.githubcopilot.com/mcp/x/pull_requests | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-pull_requests&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fpull_requests%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/pull_requests/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-pull_requests&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fpull_requests%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/repo-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/repo-light.png"><img src="../pkg/octicons/icons/repo-light.png" width="20" height="20" alt="repo"></picture><br>`repos` | GitHub Repository related tools | https://api.githubcopilot.com/mcp/x/repos | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-repos&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Frepos%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/repos/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-repos&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Frepos%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/shield-lock-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/shield-lock-light.png"><img src="../pkg/octicons/icons/shield-lock-light.png" width="20" height="20" alt="shield-lock"></picture><br>`secret_protection` | Secret protection related tools, such as GitHub Secret Scanning | https://api.githubcopilot.com/mcp/x/secret_protection | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-secret_protection&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecret_protection%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/secret_protection/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-secret_protection&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecret_protection%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/shield-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/shield-light.png"><img src="../pkg/octicons/icons/shield-light.png" width="20" height="20" alt="shield"></picture><br>`security_advisories` | Security advisories related tools | https://api.githubcopilot.com/mcp/x/security_advisories | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-security_advisories&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecurity_advisories%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/security_advisories/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-security_advisories&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecurity_advisories%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/star-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/star-light.png"><img src="../pkg/octicons/icons/star-light.png" width="20" height="20" alt="star"></picture><br>`stargazers` | GitHub Stargazers related tools | https://api.githubcopilot.com/mcp/x/stargazers | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-stargazers&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fstargazers%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/stargazers/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-stargazers&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fstargazers%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/people-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/people-light.png"><img src="../pkg/octicons/icons/people-light.png" width="20" height="20" alt="people"></picture><br>`users` | GitHub User related tools | https://api.githubcopilot.com/mcp/x/users | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-users&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fusers%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/users/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-users&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fusers%2Freadonly%22%7D) |
|
||||
<!-- END AUTOMATED TOOLSETS -->
|
||||
|
||||
### Additional _Remote_ Server Toolsets
|
||||
|
||||
These toolsets are only available in the remote GitHub MCP Server and are not included in the local MCP server.
|
||||
|
||||
<!-- START AUTOMATED REMOTE TOOLSETS -->
|
||||
| Name | Description | API URL | 1-Click Install (VS Code) | Read-only Link | 1-Click Read-only Install (VS Code) |
|
||||
| ---- | ----------- | ------- | ------------------------- | -------------- | ----------------------------------- |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/copilot-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/copilot-light.png"><img src="../pkg/octicons/icons/copilot-light.png" width="20" height="20" alt="copilot"></picture><br>`copilot_spaces` | Copilot Spaces tools | https://api.githubcopilot.com/mcp/x/copilot_spaces | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot_spaces&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot_spaces%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/copilot_spaces/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-copilot_spaces&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fcopilot_spaces%2Freadonly%22%7D) |
|
||||
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/book-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/book-light.png"><img src="../pkg/octicons/icons/book-light.png" width="20" height="20" alt="book"></picture><br>`github_support_docs_search` | Retrieve documentation to answer GitHub product and support questions. Topics include: GitHub Actions Workflows, Authentication, ... | https://api.githubcopilot.com/mcp/x/github_support_docs_search | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-github_support_docs_search&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgithub_support_docs_search%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/github_support_docs_search/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-github_support_docs_search&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fgithub_support_docs_search%2Freadonly%22%7D) |
|
||||
<!-- END AUTOMATED REMOTE TOOLSETS -->
|
||||
|
||||
### Optional Headers
|
||||
|
||||
The Remote GitHub MCP server has optional headers equivalent to the Local server env vars or flags:
|
||||
|
||||
- `X-MCP-Toolsets`: Comma-separated list of toolsets to enable. E.g. "repos,issues".
|
||||
- Equivalent to `GITHUB_TOOLSETS` env var or `--toolsets` flag for Local server.
|
||||
- If the list is empty, default toolsets will be used. Invalid or unknown toolsets are silently ignored without error and will not prevent the server from starting. Whitespace is ignored.
|
||||
- `X-MCP-Tools`: Comma-separated list of tools to enable. E.g. "get_file_contents,issue_read,pull_request_read".
|
||||
- Equivalent to `GITHUB_TOOLS` env var or `--tools` flag for Local server.
|
||||
- Invalid tools will throw an error and prevent the server from starting. Whitespace is ignored.
|
||||
- `X-MCP-Readonly`: Enables only "read" tools.
|
||||
- Equivalent to `GITHUB_READ_ONLY` env var for Local server.
|
||||
- If this header is empty, "false", "f", "no", "n", "0", or "off" (ignoring whitespace and case), it will be interpreted as false. All other values are interpreted as true.
|
||||
- `X-MCP-Lockdown`: Enables lockdown mode, hiding public issue details created by users without push access.
|
||||
- Equivalent to `GITHUB_LOCKDOWN_MODE` env var for Local server.
|
||||
- If this header is empty, "false", "f", "no", "n", "0", or "off" (ignoring whitespace and case), it will be interpreted as false. All other values are interpreted as true.
|
||||
- `X-MCP-Insiders`: Enables insiders mode for early access to new features.
|
||||
- Equivalent to `GITHUB_INSIDERS` env var or `--insiders` flag for Local server.
|
||||
- If this header is empty, "false", "f", "no", "n", "0", or "off" (ignoring whitespace and case), it will be interpreted as false. All other values are interpreted as true.
|
||||
|
||||
> **Looking for examples?** See the [Server Configuration Guide](./server-configuration.md) for common recipes like minimal setups, read-only mode, and combining tools with toolsets.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Toolsets": "repos,issues",
|
||||
"X-MCP-Readonly": "true",
|
||||
"X-MCP-Lockdown": "false"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Insiders Mode
|
||||
|
||||
The remote GitHub MCP Server offers an insiders version with early access to new features and experimental tools. You can enable insiders mode in two ways:
|
||||
|
||||
1. **Via URL path** - Append `/insiders` to the URL:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/insiders"
|
||||
}
|
||||
```
|
||||
|
||||
2. **Via header** - Set the `X-MCP-Insiders` header to `true`:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Insiders": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Both methods can be combined with other path modifiers (like `/readonly`) and headers.
|
||||
|
||||
### URL Path Parameters
|
||||
|
||||
The Remote GitHub MCP server supports the following URL path patterns:
|
||||
|
||||
- `/` - Default toolset (see ["default" toolset](../README.md#default-toolset))
|
||||
- `/readonly` - Default toolset in read-only mode
|
||||
- `/insiders` - Default toolset with insiders mode enabled
|
||||
- `/readonly/insiders` - Default toolset in read-only mode with insiders mode enabled
|
||||
- `/x/all` - All available toolsets
|
||||
- `/x/all/readonly` - All available toolsets in read-only mode
|
||||
- `/x/all/insiders` - All available toolsets with insiders mode enabled
|
||||
- `/x/all/readonly/insiders` - All available toolsets in read-only mode with insiders mode enabled
|
||||
- `/x/{toolset}` - Single specific toolset
|
||||
- `/x/{toolset}/readonly` - Single specific toolset in read-only mode
|
||||
- `/x/{toolset}/insiders` - Single specific toolset with insiders mode enabled
|
||||
- `/x/{toolset}/readonly/insiders` - Single specific toolset in read-only mode with insiders mode enabled
|
||||
|
||||
Note: `{toolset}` can only be a single toolset, not a comma-separated list. To combine multiple toolsets, use the `X-MCP-Toolsets` header instead. Path modifiers like `/readonly` and `/insiders` can be combined with the `X-MCP-Insiders` or `X-MCP-Readonly` headers.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/x/issues/readonly"
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
# PAT Scope Filtering
|
||||
|
||||
The GitHub MCP Server automatically filters available tools based on your classic Personal Access Token's (PAT) OAuth scopes. This ensures you only see tools that your token has permission to use, reducing clutter and preventing errors from attempting operations your token can't perform.
|
||||
|
||||
> **Note:** This feature applies to **classic PATs** (tokens starting with `ghp_`). Fine-grained PATs, GitHub App installation tokens, and server-to-server tokens don't support scope detection and show all tools.
|
||||
|
||||
## How It Works
|
||||
|
||||
When the server starts with a classic PAT, it makes a lightweight HTTP HEAD request to the GitHub API to discover your token's scopes from the `X-OAuth-Scopes` header. Tools that require scopes your token doesn't have are automatically hidden.
|
||||
|
||||
**Example:** If your token only has `repo` and `gist` scopes, you won't see tools that require `admin:org`, `project`, or `notifications` scopes.
|
||||
|
||||
## PAT vs OAuth Authentication
|
||||
|
||||
| Authentication | Scope Handling |
|
||||
|---------------|----------------|
|
||||
| **Classic PAT** (`ghp_`) | Filters tools at startup based on token scopes—tools requiring unavailable scopes are hidden |
|
||||
| **OAuth** (remote server only) | Uses OAuth scope challenges—when a tool needs a scope you haven't granted, you're prompted to authorize it |
|
||||
| **Fine-grained PAT** (`github_pat_`) | No filtering—all tools shown, API enforces permissions |
|
||||
| **GitHub App** (`ghs_`) | No filtering—all tools shown, permissions based on app installation |
|
||||
| **Server-to-server** | No filtering—all tools shown, permissions based on app/token configuration |
|
||||
|
||||
With OAuth, the remote server can dynamically request additional scopes as needed. With PATs, scopes are fixed at token creation, so the server proactively hides tools you can't use.
|
||||
|
||||
## OAuth Scope Challenges (Remote Server)
|
||||
|
||||
When using the [remote MCP server](./remote-server.md) with OAuth authentication, the server uses a different approach called **scope challenges**. Instead of hiding tools upfront, all tools are available, and the server requests additional scopes on-demand when you try to use a tool that requires them.
|
||||
|
||||
**How it works:**
|
||||
1. You attempt to use a tool (e.g., creating an issue)
|
||||
2. If your current OAuth token lacks the required scope, the server returns an OAuth scope challenge
|
||||
3. Your MCP client prompts you to authorize the additional scope
|
||||
4. After authorization, the operation completes successfully
|
||||
|
||||
This provides a smoother user experience for OAuth users since you only grant permissions as needed, rather than requesting all scopes upfront.
|
||||
|
||||
## Checking Your Token's Scopes
|
||||
|
||||
To see what scopes your token has, you can run:
|
||||
|
||||
```bash
|
||||
curl -sI -H "Authorization: Bearer $GITHUB_PERSONAL_ACCESS_TOKEN" \
|
||||
https://api.github.com/user | grep -i x-oauth-scopes
|
||||
```
|
||||
|
||||
Example output:
|
||||
```
|
||||
x-oauth-scopes: delete_repo, gist, read:org, repo
|
||||
```
|
||||
|
||||
## Scope Hierarchy
|
||||
|
||||
Some scopes implicitly include others:
|
||||
|
||||
- `repo` → includes `public_repo`, `security_events`
|
||||
- `admin:org` → includes `write:org` → includes `read:org`
|
||||
- `project` → includes `read:project`
|
||||
|
||||
This means if your token has `repo`, tools requiring `security_events` will also be available.
|
||||
|
||||
Each tool in the [README](../README.md#tools) lists its required and accepted OAuth scopes.
|
||||
|
||||
## Public Repository Access
|
||||
|
||||
Read-only tools that only require `repo` or `public_repo` scopes are **always visible**, even if your token doesn't have these scopes. This is because these tools work on public repositories without authentication.
|
||||
|
||||
For example, `get_file_contents` is always available—you can read files from any public repository regardless of your token's scopes. However, write operations like `create_or_update_file` will be hidden if your token lacks `repo` scope.
|
||||
|
||||
> **Note:** The GitHub API doesn't return `public_repo` in the `X-OAuth-Scopes` header—it's implicit. The server handles this by not filtering read-only repository tools.
|
||||
|
||||
## Graceful Degradation
|
||||
|
||||
If the server cannot fetch your token's scopes (e.g., network issues, rate limiting), it logs a warning and continues **without filtering**. This ensures the server remains usable even when scope detection fails.
|
||||
|
||||
```
|
||||
WARN: failed to fetch token scopes, continuing without scope filtering
|
||||
```
|
||||
|
||||
## Classic vs Fine-Grained Personal Access Tokens
|
||||
|
||||
**Classic PATs** (`ghp_` prefix) support OAuth scopes and return them in the `X-OAuth-Scopes` header. Scope filtering works fully with these tokens.
|
||||
|
||||
**Fine-grained PATs** (`github_pat_` prefix) use a different permission model based on repository access and specific permissions rather than OAuth scopes. They don't return the `X-OAuth-Scopes` header, so scope filtering is skipped. All tools will be available, but the GitHub API will still enforce permissions at the API level—you'll get errors if you try to use tools your token doesn't have permission for.
|
||||
|
||||
## GitHub App and Server-to-Server Tokens
|
||||
|
||||
**GitHub App installation tokens** (`ghs_` prefix) and other server-to-server tokens use a permission model based on the app's installation permissions rather than OAuth scopes. These tokens don't return the `X-OAuth-Scopes` header, so scope filtering is skipped. The GitHub API enforces permissions based on the app's configuration.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| Missing expected tools | Token lacks required scope | [Edit your PAT's scopes](https://github.com/settings/tokens) in GitHub settings |
|
||||
| All tools visible despite limited PAT | Scope detection failed | Check logs for warnings about scope fetching |
|
||||
| "Insufficient permissions" errors | Tool visible but scope insufficient | This shouldn't happen with scope filtering; report as bug |
|
||||
|
||||
> **Tip:** You can adjust the scopes of an existing classic PAT at any time via [GitHub's token settings](https://github.com/settings/tokens). After updating scopes, restart the MCP server to pick up the changes.
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Server Configuration Guide](./server-configuration.md)
|
||||
- [GitHub PAT Documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
|
||||
- [OAuth Scopes Reference](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)
|
||||
@@ -0,0 +1,479 @@
|
||||
# Server Configuration Guide
|
||||
|
||||
This guide helps you choose the right configuration for your use case and shows you how to apply it. For the complete reference of available toolsets and tools, see the [README](../README.md#tool-configuration).
|
||||
|
||||
## Quick Reference
|
||||
We currently support the following ways in which the GitHub MCP Server can be configured:
|
||||
|
||||
| Configuration | Remote Server | Local Server |
|
||||
|---------------|---------------|--------------|
|
||||
| Toolsets | `X-MCP-Toolsets` header or `/x/{toolset}` URL | `--toolsets` flag or `GITHUB_TOOLSETS` env var |
|
||||
| Individual Tools | `X-MCP-Tools` header | `--tools` flag or `GITHUB_TOOLS` env var |
|
||||
| Exclude Tools | `X-MCP-Exclude-Tools` header | `--exclude-tools` flag or `GITHUB_EXCLUDE_TOOLS` env var |
|
||||
| Read-Only Mode | `X-MCP-Readonly` header or `/readonly` URL | `--read-only` flag or `GITHUB_READ_ONLY` env var |
|
||||
| Lockdown Mode | `X-MCP-Lockdown` header | `--lockdown-mode` flag or `GITHUB_LOCKDOWN_MODE` env var |
|
||||
| Insiders Mode | `X-MCP-Insiders` header or `/insiders` URL | `--insiders` flag or `GITHUB_INSIDERS` env var |
|
||||
| Feature Flags | `X-MCP-Features` header | `--features` flag |
|
||||
| Scope Filtering | Always enabled | Always enabled |
|
||||
| Server Name/Title | Not available | `GITHUB_MCP_SERVER_NAME` / `GITHUB_MCP_SERVER_TITLE` env vars or `github-mcp-server-config.json` |
|
||||
|
||||
> **Default behavior:** If you don't specify any configuration, the server uses the **default toolsets**: `context`, `issues`, `pull_requests`, `repos`, `users`.
|
||||
|
||||
---
|
||||
|
||||
## How Configuration Works
|
||||
|
||||
All configuration options are **composable**: you can combine toolsets, individual tools, excluded tools, read-only mode and lockdown mode in any way that suits your workflow.
|
||||
|
||||
Note: **read-only** mode acts as a strict security filter that takes precedence over any other configuration, by disabling write tools even when explicitly requested.
|
||||
|
||||
Note: **excluded tools** takes precedence over toolsets and individual tools — listed tools are always excluded, even if their toolset is enabled or they are explicitly added via `--tools` / `X-MCP-Tools`.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
The examples below use VS Code configuration format to illustrate the concepts. If you're using a different MCP host (Cursor, Claude Desktop, JetBrains, etc.), your configuration might need to look slightly different. See [installation guides](./installation-guides) for host-specific setup.
|
||||
|
||||
### Enabling Specific Tools
|
||||
|
||||
**Best for:** users who know exactly what they need and want to optimize context usage by loading only the tools they will use.
|
||||
|
||||
**Example:**
|
||||
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Tools": "get_file_contents,get_me,pull_request_read"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--tools=get_file_contents,get_me,pull_request_read"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
### Enabling Specific Toolsets
|
||||
|
||||
**Best for:** Users who want to enable multiple related toolsets.
|
||||
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Toolsets": "issues,pull_requests"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--toolsets=issues,pull_requests"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
### Enabling Toolsets + Tools
|
||||
|
||||
**Best for:** Users who want broad functionality from some areas, plus specific tools from others.
|
||||
|
||||
Enable entire toolsets, then add individual tools from toolsets you don't want fully enabled.
|
||||
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Toolsets": "repos,issues",
|
||||
"X-MCP-Tools": "get_gist,pull_request_read"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--toolsets=repos,issues",
|
||||
"--tools=get_gist,pull_request_read"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Result:** All repository and issue tools, plus just the gist tools you need.
|
||||
|
||||
---
|
||||
|
||||
### Excluding Specific Tools
|
||||
|
||||
**Best for:** Users who want to enable a broad toolset but need to exclude specific tools for security, compliance, or to prevent undesired behavior.
|
||||
|
||||
Listed tools are removed regardless of any other configuration — even if their toolset is enabled or they are individually added.
|
||||
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Toolsets": "pull_requests",
|
||||
"X-MCP-Exclude-Tools": "create_pull_request,merge_pull_request"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--toolsets=pull_requests",
|
||||
"--exclude-tools=create_pull_request,merge_pull_request"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
**Result:** All pull request tools except `create_pull_request` and `merge_pull_request` — the user gets read and review tools only.
|
||||
|
||||
---
|
||||
|
||||
### Read-Only Mode
|
||||
|
||||
**Best for:** Security conscious users who want to ensure the server won't allow operations that modify issues, pull requests, repositories etc.
|
||||
|
||||
When active, this mode will disable all tools that are not read-only even if they were requested.
|
||||
|
||||
**Example:**
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
**Option A: Header**
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Toolsets": "issues,repos,pull_requests",
|
||||
"X-MCP-Readonly": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Option B: URL path**
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/x/all/readonly"
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--toolsets=issues,repos,pull_requests",
|
||||
"--read-only"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
> Even if `issues` toolset contains `create_issue`, it will be excluded in read-only mode.
|
||||
|
||||
---
|
||||
|
||||
### Lockdown Mode
|
||||
|
||||
**Best for:** Public repositories where you want to limit content from users without push access.
|
||||
|
||||
Lockdown mode ensures the server only surfaces content in public repositories from users with push access to that repository. Private repositories are unaffected, and collaborators retain full access to their own content.
|
||||
|
||||
**Example:**
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Lockdown": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--lockdown-mode"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
### Insiders Mode
|
||||
|
||||
**Best for:** Users who want early access to experimental features and new tools before they reach general availability.
|
||||
|
||||
Insiders Mode unlocks experimental features, such as [MCP Apps](#mcp-apps) support. We created this mode to have a way to roll out experimental features and collect feedback. So if you are using Insiders, please don't hesitate to share your feedback with us! Features in Insiders Mode may change, evolve, or be removed based on user feedback.
|
||||
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
**Option A: URL path**
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/insiders"
|
||||
}
|
||||
```
|
||||
|
||||
**Option B: Header**
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Insiders": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--insiders"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
See [Insiders Features](./insiders-features.md) for a full list of what's available in Insiders Mode.
|
||||
|
||||
---
|
||||
|
||||
### MCP Apps
|
||||
|
||||
[MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) is an extension to the Model Context Protocol that enables servers to deliver interactive user interfaces to end users. Instead of returning plain text that the LLM must interpret and relay, tools can render forms, profiles, and dashboards right in the chat.
|
||||
|
||||
MCP Apps is enabled by [Insiders Mode](#insiders-mode), or independently via the `remote_mcp_ui_apps` feature flag.
|
||||
|
||||
**Supported tools:**
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `get_me` | Displays your GitHub user profile with avatar, bio, and stats in a rich card |
|
||||
| `issue_write` | Opens an interactive form to create or update issues |
|
||||
| `create_pull_request` | Provides a full PR creation form to create a pull request (or a draft pull request) |
|
||||
|
||||
**Client requirements:** MCP Apps requires a host that supports the [MCP Apps extension](https://modelcontextprotocol.io/docs/extensions/apps). Currently tested with VS Code (`chat.mcp.apps.enabled` setting).
|
||||
|
||||
<table>
|
||||
<tr><th>Remote Server</th><th>Local Server</th></tr>
|
||||
<tr valign="top">
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/",
|
||||
"headers": {
|
||||
"X-MCP-Features": "remote_mcp_ui_apps"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "stdio",
|
||||
"command": "go",
|
||||
"args": [
|
||||
"run",
|
||||
"./cmd/github-mcp-server",
|
||||
"stdio",
|
||||
"--features=remote_mcp_ui_apps"
|
||||
],
|
||||
"env": {
|
||||
"GITHUB_PERSONAL_ACCESS_TOKEN": "${input:github_token}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
---
|
||||
|
||||
### Scope Filtering
|
||||
|
||||
**Automatic feature:** The server handles OAuth scopes differently depending on authentication type:
|
||||
|
||||
- **Classic PATs** (`ghp_` prefix): Tools are filtered at startup based on token scopes—you only see tools you have permission to use
|
||||
- **OAuth** (remote server): Uses scope challenges—when a tool needs a scope you haven't granted, you're prompted to authorize it
|
||||
- **Other tokens**: No filtering—all tools shown, API enforces permissions
|
||||
|
||||
This happens transparently—no configuration needed. If scope detection fails for a classic PAT (e.g., network issues), the server logs a warning and continues with all tools available.
|
||||
|
||||
See [Scope Filtering](./scope-filtering.md) for details on how filtering works with different token types.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Problem | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| Server fails to start | Invalid tool name in `--tools` or `X-MCP-Tools` | Check tool name spelling; use exact names from [Tools list](../README.md#tools) |
|
||||
| Write tools not working | Read-only mode enabled | Remove `--read-only` flag or `X-MCP-Readonly` header |
|
||||
| Tools missing | Toolset not enabled | Add the required toolset or specific tool |
|
||||
|
||||
---
|
||||
|
||||
## Useful links
|
||||
|
||||
- [README: Tool Configuration](../README.md#tool-configuration)
|
||||
- [README: Available Toolsets](../README.md#available-toolsets) — Complete list of toolsets
|
||||
- [README: Tools](../README.md#tools) — Complete list of individual tools
|
||||
- [Remote Server Documentation](./remote-server.md) — Remote-specific options and headers
|
||||
- [Installation Guides](./installation-guides) — Host-specific setup instructions
|
||||
@@ -0,0 +1,105 @@
|
||||
# Streamable HTTP Server
|
||||
|
||||
The Streamable HTTP mode enables the GitHub MCP Server to run as an HTTP service, allowing clients to connect via standard HTTP protocols. This mode is ideal for deployment scenarios where stdio transport isn't suitable, such as reverse proxy setups, containerized environments, or distributed architectures.
|
||||
|
||||
## Features
|
||||
|
||||
- **Streamable HTTP Transport** — Full HTTP server with streaming support for real-time tool responses
|
||||
- **OAuth Metadata Endpoints** — Standard `.well-known/oauth-protected-resource` discovery for OAuth clients
|
||||
- **Scope Challenge Support** — Automatic scope validation with proper HTTP 403 responses and `WWW-Authenticate` headers
|
||||
- **Scope Filtering** — Restrict available tools based on authenticated credentials and permissions
|
||||
- **Custom Base Paths** — Support for reverse proxy deployments with customizable base URLs
|
||||
|
||||
## Running the Server
|
||||
|
||||
### Basic HTTP Server
|
||||
|
||||
Start the server on the default port (8082):
|
||||
|
||||
```bash
|
||||
github-mcp-server http
|
||||
```
|
||||
|
||||
The server will be available at `http://localhost:8082`.
|
||||
|
||||
### With Scope Challenge
|
||||
|
||||
Enable scope validation to enforce GitHub permission checks:
|
||||
|
||||
```bash
|
||||
github-mcp-server http --scope-challenge
|
||||
```
|
||||
|
||||
When `--scope-challenge` is enabled, requests with insufficient scopes receive a `403 Forbidden` response with a `WWW-Authenticate` header indicating the required scopes.
|
||||
|
||||
### With OAuth Metadata Discovery
|
||||
|
||||
For use behind reverse proxies or with custom domains, expose OAuth metadata endpoints:
|
||||
|
||||
```bash
|
||||
github-mcp-server http --scope-challenge --base-url https://myserver.com --base-path /mcp
|
||||
```
|
||||
|
||||
The OAuth protected resource metadata's `resource` attribute will be populated with the full URL to the server's protected resource endpoint:
|
||||
|
||||
```json
|
||||
{
|
||||
"resource_name": "GitHub MCP Server",
|
||||
"resource": "https://myserver.com/mcp",
|
||||
"authorization_servers": [
|
||||
"https://github.com/login/oauth"
|
||||
],
|
||||
"scopes_supported": [
|
||||
"repo",
|
||||
...
|
||||
],
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
This allows OAuth clients to discover authentication requirements and endpoint information automatically.
|
||||
|
||||
### Behind a Trusted Proxy (advanced)
|
||||
|
||||
By default, the server ignores the `X-Forwarded-Host` and `X-Forwarded-Proto` headers when constructing OAuth resource metadata URLs, so an untrusted client cannot influence the URL advertised to MCP clients. For most deployments, setting `--base-url` to the externally visible URL is the right approach.
|
||||
|
||||
If the server sits behind an internal forwarder that you fully control (for example, an in-cluster gateway that needs to preserve the originating hostname per request), you can opt into honoring those headers:
|
||||
|
||||
```bash
|
||||
github-mcp-server http --trust-proxy-headers
|
||||
```
|
||||
|
||||
Equivalent environment variable: `GITHUB_TRUST_PROXY_HEADERS=1`. Only enable this when the upstream proxy is trusted to set or strip these headers; otherwise prefer `--base-url`. When `--base-url` is set, it always takes precedence and `--trust-proxy-headers` has no effect.
|
||||
|
||||
## Client Configuration
|
||||
|
||||
### Using OAuth Authentication
|
||||
|
||||
If your IDE or client has GitHub credentials configured (i.e. VS Code), simply reference the HTTP server:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "http://localhost:8082"
|
||||
}
|
||||
```
|
||||
|
||||
The server will use the client's existing GitHub authentication.
|
||||
|
||||
### Using Bearer Tokens or Custom Headers
|
||||
|
||||
To provide PAT credentials, or to customize server behavior preferences, you can include additional headers in the client configuration:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "http",
|
||||
"url": "http://localhost:8082",
|
||||
"headers": {
|
||||
"Authorization": "Bearer ghp_yourtokenhere",
|
||||
"X-MCP-Toolsets": "default",
|
||||
"X-MCP-Readonly": "true"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See [Remote Server](./remote-server.md) documentation for more details on client configuration options.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Testing
|
||||
|
||||
This project uses a combination of unit tests and end-to-end (e2e) tests to ensure correctness and stability.
|
||||
|
||||
## Unit Testing Patterns
|
||||
|
||||
- Unit tests are located alongside implementation, with filenames ending in `_test.go`.
|
||||
- Currently the preference is to use internal tests i.e. test files do not have `_test` package suffix.
|
||||
- Tests use [testify](https://github.com/stretchr/testify) for assertions and require statements. Use `require` when continuing the test is not meaningful, for example it is almost never correct to continue after an error expectation.
|
||||
- REST mocking is performed with the in-repo `MockHTTPClientWithHandlers` helpers; GraphQL mocking uses `githubv4mock`.
|
||||
- Each tool's schema is snapshotted and checked for changes using the `toolsnaps` utility (see below).
|
||||
- Tests are designed to be explicit and verbose to aid maintainability and clarity.
|
||||
- Handler unit tests should take the form of:
|
||||
1. Test tool snapshot
|
||||
1. Very important expectations against the schema (e.g. `ReadOnly` annotation)
|
||||
1. Behavioural tests in table-driven form
|
||||
|
||||
## End-to-End (e2e) Tests
|
||||
|
||||
- E2E tests are located in the [`e2e/`](../e2e/) directory. See the [e2e/README.md](../e2e/README.md) for full details on running and debugging these tests.
|
||||
|
||||
## toolsnaps: Tool Schema Snapshots
|
||||
|
||||
- The `toolsnaps` utility ensures that the JSON schema for each tool does not change unexpectedly.
|
||||
- Snapshots are stored in `__toolsnaps__/*.snap` files, where `*` represents the name of the tool
|
||||
- When running tests, the current tool schema is compared to the snapshot. If there is a difference, the test will fail and show a diff.
|
||||
- If you intentionally change a tool's schema, update the snapshots by running tests with the environment variable: `UPDATE_TOOLSNAPS=true go test ./...`
|
||||
- In CI (when `GITHUB_ACTIONS=true`), missing snapshots will cause a test failure to ensure snapshots are always
|
||||
committed.
|
||||
|
||||
## Notes
|
||||
|
||||
- Some tools that mutate global state (e.g., marking all notifications as read) are tested primarily with unit tests, not e2e, to avoid side effects.
|
||||
- For more on the limitations and philosophy of the e2e suite, see the [e2e/README.md](../e2e/README.md).
|
||||
@@ -0,0 +1,74 @@
|
||||
# Tool Renaming Guide
|
||||
|
||||
How to safely rename MCP tools without breaking existing user configurations.
|
||||
|
||||
## Overview
|
||||
|
||||
When tools are renamed, users who have the old tool name in their MCP configuration (for example, in `X-MCP-Tools` headers for the remote MCP server or `--tools` flags for the local MCP server) would normally get errors.
|
||||
The deprecation alias system allows us to maintain backward compatibility by silently resolving old tool names to their new canonical names.
|
||||
|
||||
This allows us to rename tools safely, without introducing breaking changes for users that have a hard reference to those tools in their server configuration.
|
||||
|
||||
## Quick Steps
|
||||
|
||||
1. **Rename the tool** in your code (as usual, this will imply a range of changes like updating the tool registration, the tests and the toolsnaps).
|
||||
2. **Add a deprecation alias** in [pkg/github/deprecated_tool_aliases.go](../pkg/github/deprecated_tool_aliases.go):
|
||||
```go
|
||||
var DeprecatedToolAliases = map[string]string{
|
||||
"old_tool_name": "new_tool_name",
|
||||
}
|
||||
```
|
||||
3. **Update documentation** (README, etc.) to reference the new canonical name
|
||||
|
||||
That's it. The server will silently resolve old names to new ones. This will work across both local and remote MCP servers.
|
||||
|
||||
## Example
|
||||
|
||||
If renaming `get_issue` to `issue_read`:
|
||||
|
||||
```go
|
||||
var DeprecatedToolAliases = map[string]string{
|
||||
"get_issue": "issue_read",
|
||||
}
|
||||
```
|
||||
|
||||
A user with this configuration:
|
||||
```json
|
||||
{
|
||||
"--tools": "get_issue,get_file_contents"
|
||||
}
|
||||
```
|
||||
|
||||
Will get `issue_read` and `get_file_contents` tools registered, with no errors.
|
||||
|
||||
## Current Deprecations
|
||||
|
||||
<!-- START AUTOMATED ALIASES -->
|
||||
| Old Name | New Name |
|
||||
|----------|----------|
|
||||
| `add_project_item` | `projects_write` |
|
||||
| `cancel_workflow_run` | `actions_run_trigger` |
|
||||
| `delete_project_item` | `projects_write` |
|
||||
| `delete_workflow_run_logs` | `actions_run_trigger` |
|
||||
| `download_workflow_run_artifact` | `actions_get` |
|
||||
| `get_project` | `projects_get` |
|
||||
| `get_project_field` | `projects_get` |
|
||||
| `get_project_item` | `projects_get` |
|
||||
| `get_workflow` | `actions_get` |
|
||||
| `get_workflow_job` | `actions_get` |
|
||||
| `get_workflow_job_logs` | `actions_get` |
|
||||
| `get_workflow_run` | `actions_get` |
|
||||
| `get_workflow_run_logs` | `actions_get` |
|
||||
| `get_workflow_run_usage` | `actions_get` |
|
||||
| `list_project_fields` | `projects_list` |
|
||||
| `list_project_items` | `projects_list` |
|
||||
| `list_projects` | `projects_list` |
|
||||
| `list_workflow_jobs` | `actions_list` |
|
||||
| `list_workflow_run_artifacts` | `actions_list` |
|
||||
| `list_workflow_runs` | `actions_list` |
|
||||
| `list_workflows` | `actions_list` |
|
||||
| `rerun_failed_jobs` | `actions_run_trigger` |
|
||||
| `rerun_workflow_run` | `actions_run_trigger` |
|
||||
| `run_workflow` | `actions_run_trigger` |
|
||||
| `update_project_item` | `projects_write` |
|
||||
<!-- END AUTOMATED ALIASES -->
|
||||
@@ -0,0 +1,201 @@
|
||||
# Toolsets and Icons
|
||||
|
||||
This document explains how to work with toolsets and icons in the GitHub MCP Server.
|
||||
|
||||
## Toolset Overview
|
||||
|
||||
Toolsets are logical groupings of related tools. Each toolset has metadata defined in `pkg/github/tools.go`:
|
||||
|
||||
```go
|
||||
ToolsetMetadataRepos = inventory.ToolsetMetadata{
|
||||
ID: "repos",
|
||||
Description: "GitHub Repository related tools",
|
||||
Default: true,
|
||||
Icon: "repo",
|
||||
}
|
||||
```
|
||||
|
||||
### Toolset Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `ID` | `ToolsetID` | Unique identifier used in URLs and CLI flags (e.g., `repos`, `issues`) |
|
||||
| `Description` | `string` | Human-readable description shown in documentation |
|
||||
| `Default` | `bool` | Whether this toolset is enabled by default |
|
||||
| `Icon` | `string` | Octicon name for visual representation in MCP clients |
|
||||
|
||||
## Adding Icons to Toolsets
|
||||
|
||||
Icons help users quickly identify toolsets in MCP-compatible clients. We use [Primer Octicons](https://primer.style/foundations/icons) for all icons.
|
||||
|
||||
### Step 1: Choose an Octicon
|
||||
|
||||
Browse the [Octicon gallery](https://primer.style/foundations/icons) and select an appropriate icon. Use the base name without size suffix (e.g., `repo` not `repo-16`).
|
||||
|
||||
### Step 2: Add Icon to Required Icons List
|
||||
|
||||
Icons are defined in `pkg/octicons/required_icons.txt`, which is the single source of truth for which icons should be embedded:
|
||||
|
||||
```
|
||||
# Required icons for the GitHub MCP Server
|
||||
# Add new icons below (one per line)
|
||||
repo
|
||||
issue-opened
|
||||
git-pull-request
|
||||
your-new-icon # Add your icon here
|
||||
```
|
||||
|
||||
### Step 3: Fetch the Icon Files
|
||||
|
||||
Run the fetch-icons script to download and convert the icon:
|
||||
|
||||
```bash
|
||||
# Fetch a specific icon
|
||||
script/fetch-icons your-new-icon
|
||||
|
||||
# Or fetch all required icons
|
||||
script/fetch-icons
|
||||
```
|
||||
|
||||
This script:
|
||||
- Downloads the 24px SVG from [Primer Octicons](https://github.com/primer/octicons)
|
||||
- Converts to PNG with light theme (dark icons for light backgrounds)
|
||||
- Converts to PNG with dark theme (white icons for dark backgrounds)
|
||||
- Saves both variants to `pkg/octicons/icons/`
|
||||
|
||||
**Requirements:** The script requires `rsvg-convert`:
|
||||
- Ubuntu/Debian: `sudo apt-get install librsvg2-bin`
|
||||
- macOS: `brew install librsvg`
|
||||
|
||||
### Step 4: Update the Toolset Metadata
|
||||
|
||||
Add or update the `Icon` field in the toolset definition:
|
||||
|
||||
```go
|
||||
// In pkg/github/tools.go
|
||||
ToolsetMetadataRepos = inventory.ToolsetMetadata{
|
||||
ID: "repos",
|
||||
Description: "GitHub Repository related tools",
|
||||
Default: true,
|
||||
Icon: "repo", // Add this line
|
||||
}
|
||||
```
|
||||
|
||||
### Step 5: Regenerate Documentation
|
||||
|
||||
Run the documentation generator to update all markdown files:
|
||||
|
||||
```bash
|
||||
go run ./cmd/github-mcp-server generate-docs
|
||||
```
|
||||
|
||||
This updates icons in:
|
||||
- `README.md` - Toolsets table and tool section headers
|
||||
- `docs/remote-server.md` - Remote toolsets table
|
||||
|
||||
## Remote-Only Toolsets
|
||||
|
||||
Some toolsets are only available in the remote GitHub MCP Server (hosted at `api.githubcopilot.com`). These are defined in `pkg/github/tools.go` with their icons, but are not registered with the local server:
|
||||
|
||||
```go
|
||||
// Remote-only toolsets
|
||||
ToolsetMetadataCopilot = inventory.ToolsetMetadata{
|
||||
ID: "copilot",
|
||||
Description: "Copilot related tools",
|
||||
Icon: "copilot",
|
||||
}
|
||||
```
|
||||
|
||||
The `RemoteOnlyToolsets()` function returns the list of these toolsets for documentation generation.
|
||||
|
||||
To add a new remote-only toolset:
|
||||
|
||||
1. Add the metadata definition in `pkg/github/tools.go`
|
||||
2. Add it to the slice returned by `RemoteOnlyToolsets()`
|
||||
3. Regenerate documentation
|
||||
|
||||
## Tool Icon Inheritance
|
||||
|
||||
Individual tools inherit icons from their parent toolset. When a tool is registered with a toolset, its icons are automatically set:
|
||||
|
||||
```go
|
||||
// In pkg/inventory/server_tool.go
|
||||
toolCopy.Icons = tool.Toolset.Icons()
|
||||
```
|
||||
|
||||
This means you only need to set the icon once on the toolset, and all tools in that toolset will display the same icon.
|
||||
|
||||
## How Icons Work in MCP
|
||||
|
||||
The MCP protocol supports tool icons via the `icons` field. We provide icons in two formats:
|
||||
|
||||
1. **Data URIs** - Base64-encoded PNG images embedded in the tool definition
|
||||
2. **Light/Dark variants** - Both theme variants are provided for proper display
|
||||
|
||||
The `octicons.Icons()` function generates the MCP-compatible icon objects:
|
||||
|
||||
```go
|
||||
// Returns []mcp.Icon with both light and dark variants
|
||||
icons := octicons.Icons("repo")
|
||||
```
|
||||
|
||||
## Existing Toolset Icons
|
||||
|
||||
| Toolset | Octicon Name |
|
||||
|---------|--------------|
|
||||
| Context | `person` |
|
||||
| Repositories | `repo` |
|
||||
| Issues | `issue-opened` |
|
||||
| Pull Requests | `git-pull-request` |
|
||||
| Git | `git-branch` |
|
||||
| Users | `people` |
|
||||
| Organizations | `organization` |
|
||||
| Actions | `workflow` |
|
||||
| Code Quality | `code-square` |
|
||||
| Code Security | `codescan` |
|
||||
| Secret Protection | `shield-lock` |
|
||||
| Dependabot | `dependabot` |
|
||||
| Discussions | `comment-discussion` |
|
||||
| Gists | `logo-gist` |
|
||||
| Security Advisories | `shield` |
|
||||
| Projects | `project` |
|
||||
| Labels | `tag` |
|
||||
| Stargazers | `star` |
|
||||
| Notifications | `bell` |
|
||||
| Copilot | `copilot` |
|
||||
| Support Search | `book` |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Icons not appearing in documentation
|
||||
|
||||
1. Ensure PNG files exist in `pkg/octicons/icons/` with `-light.png` and `-dark.png` suffixes
|
||||
2. Run `go run ./cmd/github-mcp-server generate-docs` to regenerate
|
||||
3. Check that the `Icon` field is set on the toolset metadata
|
||||
|
||||
### Icons not appearing in MCP clients
|
||||
|
||||
1. Verify the client supports MCP tool icons
|
||||
2. Check that the octicons package is properly generating base64 data URIs
|
||||
3. Ensure the icon name matches a file in `pkg/octicons/icons/`
|
||||
|
||||
## CI Validation
|
||||
|
||||
The following tests run in CI to catch icon issues early:
|
||||
|
||||
### `pkg/octicons.TestEmbeddedIconsExist`
|
||||
|
||||
Verifies that all icons listed in `pkg/octicons/required_icons.txt` have corresponding PNG files embedded.
|
||||
|
||||
### `pkg/github.TestAllToolsetIconsExist`
|
||||
|
||||
Verifies that all toolset `Icon` fields reference icons that are properly embedded.
|
||||
|
||||
### `pkg/github.TestToolsetMetadataHasIcons`
|
||||
|
||||
Ensures all toolsets have an `Icon` field set.
|
||||
|
||||
If any of these tests fail:
|
||||
1. Add the missing icon to `pkg/octicons/required_icons.txt`
|
||||
2. Run `script/fetch-icons` to download the icon
|
||||
3. Commit the new icon files
|
||||
Reference in New Issue
Block a user