Skip to content

Commit 0e23aaf

Browse files
committed
* 'main' of https://github.com/github/github-mcp-server: Add Gemini CLI extension (github#1232) Adding default toolset as configuration (github#1229)
2 parents 9006cbb + 84ae009 commit 0e23aaf

File tree

7 files changed

+420
-31
lines changed

7 files changed

+420
-31
lines changed

README.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,12 @@ Alternatively, to manually configure VS Code, choose the appropriate JSON block
8787
8888
### Configuration
8989

90-
#### Default toolset configuration
91-
92-
The default configuration is:
93-
- context
94-
- repos
95-
- issues
96-
- pull_requests
97-
- users
90+
#### Toolset configuration
9891

9992
See [Remote Server Documentation](docs/remote-server.md) for full details on remote server configuration, toolsets, headers, and advanced usage. This file provides comprehensive instructions and examples for connecting, customizing, and installing the remote GitHub MCP Server in VS Code and other MCP hosts.
10093

94+
When no toolsets are specified, [default toolsets](#default-toolset) are used.
95+
10196
#### Enterprise Cloud with data residency (ghe.com)
10297

10398
GitHub Enterprise Cloud can also make use of the remote server.
@@ -329,7 +324,7 @@ The GitHub MCP Server supports enabling or disabling specific groups of function
329324

330325
_Toolsets are not limited to Tools. Relevant MCP Resources and Prompts are also included where applicable._
331326

332-
The Local GitHub MCP Server follows the same [default toolset configuration](#default-toolset-configuration) as the remote version.
327+
When no toolsets are specified, [default toolsets](#default-toolset) are used.
333328

334329
#### Specifying Toolsets
335330

@@ -359,7 +354,9 @@ docker run -i --rm \
359354
ghcr.io/github/github-mcp-server
360355
```
361356

362-
### The "all" Toolset
357+
### Special toolsets
358+
359+
#### "all" toolset
363360

364361
The special toolset `all` can be provided to enable all available toolsets regardless of any other configuration:
365362

@@ -373,6 +370,22 @@ Or using the environment variable:
373370
GITHUB_TOOLSETS="all" ./github-mcp-server
374371
```
375372

373+
#### "default" toolset
374+
The default toolset `default` is the configuration that gets passed to the server if no toolsets are specified.
375+
376+
The default configuration is:
377+
- context
378+
- repos
379+
- issues
380+
- pull_requests
381+
- users
382+
383+
To keep the default configuration and add additional toolsets:
384+
385+
```bash
386+
GITHUB_TOOLSETS="default,stargazers" ./github-mcp-server
387+
```
388+
376389
### Available Toolsets
377390

378391
The following sets of tools are available:

cmd/github-mcp-server/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ var (
4545
return fmt.Errorf("failed to unmarshal toolsets: %w", err)
4646
}
4747

48+
// No passed toolsets configuration means we enable the default toolset
4849
if len(enabledToolsets) == 0 {
49-
enabledToolsets = github.GetDefaultToolsetIDs()
50+
enabledToolsets = []string{github.ToolsetMetadataDefault.ID}
5051
}
5152

5253
stdioServerConfig := ghmcp.StdioServerConfig{

docs/installation-guides/install-gemini-cli.md

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ For security, avoid hardcoding your token. Create or update `~/.gemini/.env` (wh
1414

1515
```bash
1616
# ~/.gemini/.env
17-
GITHUB_PAT=your_token_here
17+
GITHUB_MCP_PAT=your_token_here
1818
```
1919

2020
</details>
@@ -30,9 +30,18 @@ After securely storing your PAT, you can add the GitHub MCP server configuration
3030

3131
> **Note:** For the most up-to-date configuration options, see the [main README.md](../../README.md).
3232
33-
### Method 1: Remote Server (Recommended)
33+
### Method 1: Gemini Extension (Recommended)
3434

35-
The simplest way is to use GitHub's hosted MCP server:
35+
The simplest way is to use GitHub's hosted MCP server via our gemini extension.
36+
37+
`gemini extensions install https://github.com/github/github-mcp-server`
38+
39+
> [!NOTE]
40+
> You will still need to have a personal access token with the appropriate scopes called `GITHUB_MCP_PAT` in your environment.
41+
42+
### Method 2: Remote Server
43+
44+
You can also connect to the hosted MCP server directly. After securely storing your PAT, configure Gemini CLI with:
3645

3746
```json
3847
// ~/.gemini/settings.json
@@ -41,14 +50,14 @@ The simplest way is to use GitHub's hosted MCP server:
4150
"github": {
4251
"httpUrl": "https://api.githubcopilot.com/mcp/",
4352
"headers": {
44-
"Authorization": "Bearer $GITHUB_PAT"
53+
"Authorization": "Bearer $GITHUB_MCP_PAT"
4554
}
4655
}
4756
}
4857
}
4958
```
5059

51-
### Method 2: Local Docker
60+
### Method 3: Local Docker
5261

5362
With docker running, you can run the GitHub MCP server in a container:
5463

@@ -67,14 +76,14 @@ With docker running, you can run the GitHub MCP server in a container:
6776
"ghcr.io/github/github-mcp-server"
6877
],
6978
"env": {
70-
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_PAT"
79+
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_MCP_PAT"
7180
}
7281
}
7382
}
7483
}
7584
```
7685

77-
### Method 3: Binary
86+
### Method 4: Binary
7887

7988
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`.
8089

@@ -88,7 +97,7 @@ Then, replacing `/path/to/binary` with the actual path to your binary, configure
8897
"command": "/path/to/binary",
8998
"args": ["stdio"],
9099
"env": {
91-
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_PAT"
100+
"GITHUB_PERSONAL_ACCESS_TOKEN": "$GITHUB_MCP_PAT"
92101
}
93102
}
94103
}

gemini-extension.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "github",
3+
"version": "1.0.0",
4+
"mcpServers": {
5+
"github": {
6+
"description": "Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.",
7+
"httpUrl": "https://api.githubcopilot.com/mcp/",
8+
"headers": {
9+
"Authorization": "Bearer $GITHUB_MCP_PAT"
10+
}
11+
}
12+
}
13+
}

internal/ghmcp/server.go

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,10 @@ func NewMCPServer(cfg MCPServerConfig) (*server.MCPServer, error) {
106106
},
107107
}
108108

109-
enabledToolsets := cfg.EnabledToolsets
110-
if cfg.DynamicToolsets {
111-
// filter "all" from the enabled toolsets
112-
enabledToolsets = make([]string, 0, len(cfg.EnabledToolsets))
113-
for _, toolset := range cfg.EnabledToolsets {
114-
if toolset != "all" {
115-
enabledToolsets = append(enabledToolsets, toolset)
116-
}
117-
}
109+
enabledToolsets, invalidToolsets := cleanToolsets(cfg.EnabledToolsets, cfg.DynamicToolsets)
110+
111+
if len(invalidToolsets) > 0 {
112+
fmt.Fprintf(os.Stderr, "Invalid toolsets ignored: %s\n", strings.Join(invalidToolsets, ", "))
118113
}
119114

120115
// Generate instructions based on enabled toolsets
@@ -470,3 +465,57 @@ func (t *bearerAuthTransport) RoundTrip(req *http.Request) (*http.Response, erro
470465
req.Header.Set("Authorization", "Bearer "+t.token)
471466
return t.transport.RoundTrip(req)
472467
}
468+
469+
// cleanToolsets cleans and handles special toolset keywords:
470+
// - Duplicates are removed from the result
471+
// - Removes whitespaces
472+
// - Validates toolset names and returns invalid ones separately
473+
// - "all": Returns ["all"] immediately, ignoring all other toolsets
474+
// - when dynamicToolsets is true, filters out "all" from the enabled toolsets
475+
// - "default": Replaces with the actual default toolset IDs from GetDefaultToolsetIDs()
476+
// Returns: (validToolsets, invalidToolsets)
477+
func cleanToolsets(enabledToolsets []string, dynamicToolsets bool) ([]string, []string) {
478+
seen := make(map[string]bool)
479+
result := make([]string, 0, len(enabledToolsets))
480+
invalid := make([]string, 0)
481+
validIDs := github.GetValidToolsetIDs()
482+
483+
// Add non-default toolsets, removing duplicates and trimming whitespace
484+
for _, toolset := range enabledToolsets {
485+
trimmed := strings.TrimSpace(toolset)
486+
if trimmed == "" {
487+
continue
488+
}
489+
if !seen[trimmed] {
490+
seen[trimmed] = true
491+
if trimmed != github.ToolsetMetadataDefault.ID && trimmed != github.ToolsetMetadataAll.ID {
492+
// Validate the toolset name
493+
if validIDs[trimmed] {
494+
result = append(result, trimmed)
495+
} else {
496+
invalid = append(invalid, trimmed)
497+
}
498+
}
499+
}
500+
}
501+
502+
hasDefault := seen[github.ToolsetMetadataDefault.ID]
503+
hasAll := seen[github.ToolsetMetadataAll.ID]
504+
505+
// Handle "all" keyword - return early if not in dynamic mode
506+
if hasAll && !dynamicToolsets {
507+
return []string{github.ToolsetMetadataAll.ID}, invalid
508+
}
509+
510+
// Expand "default" keyword to actual default toolsets
511+
if hasDefault {
512+
for _, defaultToolset := range github.GetDefaultToolsetIDs() {
513+
if !seen[defaultToolset] {
514+
result = append(result, defaultToolset)
515+
seen[defaultToolset] = true
516+
}
517+
}
518+
}
519+
520+
return result, invalid
521+
}

0 commit comments

Comments
 (0)