Skip to content

Commit e8f5ae1

Browse files
Merge branch 'github:main' into main
2 parents baca9f4 + f51bd45 commit e8f5ae1

11 files changed

Lines changed: 440 additions & 348 deletions

File tree

.github/workflows/code-scanning.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ jobs:
3838
uses: actions/checkout@v5
3939

4040
- name: Initialize CodeQL
41-
uses: github/codeql-action/init@v3
41+
uses: github/codeql-action/init@v4
4242
with:
4343
languages: ${{ matrix.language }}
4444
build-mode: ${{ matrix.build-mode }}
@@ -52,13 +52,13 @@ jobs:
5252
threat-models: [ ]
5353
- name: Setup proxy for registries
5454
id: proxy
55-
uses: github/codeql-action/start-proxy@v3
55+
uses: github/codeql-action/start-proxy@v4
5656
with:
5757
registries_credentials: ${{ secrets.GITHUB_REGISTRIES_PROXY }}
5858
language: ${{ matrix.language }}
5959

6060
- name: Configure
61-
uses: github/codeql-action/resolve-environment@v3
61+
uses: github/codeql-action/resolve-environment@v4
6262
id: resolve-environment
6363
with:
6464
language: ${{ matrix.language }}
@@ -70,10 +70,10 @@ jobs:
7070
cache: false
7171

7272
- name: Autobuild
73-
uses: github/codeql-action/autobuild@v3
73+
uses: github/codeql-action/autobuild@v4
7474

7575
- name: Perform CodeQL Analysis
76-
uses: github/codeql-action/analyze@v3
76+
uses: github/codeql-action/analyze@v4
7777
env:
7878
CODEQL_PROXY_HOST: ${{ steps.proxy.outputs.proxy_host }}
7979
CODEQL_PROXY_PORT: ${{ steps.proxy.outputs.proxy_port }}

.github/workflows/docker-publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
# https://github.com/sigstore/cosign-installer
4747
- name: Install cosign
4848
if: github.event_name != 'pull_request'
49-
uses: sigstore/cosign-installer@d7543c93d881b35a8faa02e8e3605f69b7a1ce62 #v3.10.0
49+
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad #v4.0.0
5050
with:
5151
cosign-release: "v2.2.4"
5252

.github/workflows/moderator.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: AI Moderator
2+
on:
3+
issues:
4+
types: [opened]
5+
issue_comment:
6+
types: [created]
7+
pull_request_review_comment:
8+
types: [created]
9+
10+
jobs:
11+
spam-detection:
12+
runs-on: ubuntu-latest
13+
permissions:
14+
issues: write
15+
pull-requests: write
16+
models: read
17+
contents: read
18+
steps:
19+
- uses: actions/checkout@v4
20+
- uses: github/ai-moderator@v1
21+
with:
22+
token: ${{ secrets.GITHUB_TOKEN }}
23+
spam-label: 'spam'
24+
ai-label: 'ai-generated'
25+
minimize-detected-comments: true
26+
enable-spam-detection: true
27+
enable-link-spam-detection: true
28+
enable-ai-detection: true

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.25.1-alpine AS build
1+
FROM golang:1.25.3-alpine AS build
22
ARG VERSION="dev"
33

44
# Set the working directory

cmd/github-mcp-server/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func init() {
100100
func initConfig() {
101101
// Initialize Viper configuration
102102
viper.SetEnvPrefix("github")
103+
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
103104
viper.AutomaticEnv()
104105

105106
}

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: 18 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,24 @@ func NewMCPServer(cfg MCPServerConfig) (*server.MCPServer, error) {
106106
},
107107
}
108108

109-
enabledToolsets, invalidToolsets := cleanToolsets(cfg.EnabledToolsets, cfg.DynamicToolsets)
109+
enabledToolsets := cfg.EnabledToolsets
110+
111+
// If dynamic toolsets are enabled, remove "all" from the enabled toolsets
112+
if cfg.DynamicToolsets {
113+
enabledToolsets = github.RemoveToolset(enabledToolsets, github.ToolsetMetadataAll.ID)
114+
}
115+
116+
// Clean up the passed toolsets
117+
enabledToolsets, invalidToolsets := github.CleanToolsets(enabledToolsets)
118+
119+
// If "all" is present, override all other toolsets
120+
if github.ContainsToolset(enabledToolsets, github.ToolsetMetadataAll.ID) {
121+
enabledToolsets = []string{github.ToolsetMetadataAll.ID}
122+
}
123+
// If "default" is present, expand to real toolset IDs
124+
if github.ContainsToolset(enabledToolsets, github.ToolsetMetadataDefault.ID) {
125+
enabledToolsets = github.AddDefaultToolset(enabledToolsets)
126+
}
110127

111128
if len(invalidToolsets) > 0 {
112129
fmt.Fprintf(os.Stderr, "Invalid toolsets ignored: %s\n", strings.Join(invalidToolsets, ", "))
@@ -465,57 +482,3 @@ func (t *bearerAuthTransport) RoundTrip(req *http.Request) (*http.Response, erro
465482
req.Header.Set("Authorization", "Bearer "+t.token)
466483
return t.transport.RoundTrip(req)
467484
}
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)