Skip to content

Commit c8cf1e9

Browse files
committed
Merge remote-tracking branch 'origin/main' into mcp-ui-apps-advanced
# Conflicts: # Dockerfile # pkg/github/issues.go # pkg/github/pullrequests.go # pkg/inventory/builder.go # ui/package-lock.json # ui/src/apps/issue-write/App.tsx # ui/src/apps/pr-write/App.tsx # ui/src/components/MarkdownEditor.tsx
2 parents fce0c3d + d44894e commit c8cf1e9

File tree

109 files changed

+1552
-7850
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

109 files changed

+1552
-7850
lines changed

.github/workflows/docker-publish.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,14 @@ jobs:
9393
key: ${{ runner.os }}-go-build-cache-${{ hashFiles('**/go.sum') }}
9494

9595
- name: Inject go-build-cache
96-
uses: reproducible-containers/buildkit-cache-dance@4b2444fec0c0fb9dbf175a96c094720a692ef810 # v2.1.4
96+
uses: reproducible-containers/buildkit-cache-dance@6f699a72a59e4252f05a7435430009b77e25fe06 # v3.3.1
9797
with:
98-
cache-source: go-build-cache
98+
cache-map: |
99+
{
100+
"go-build-cache/apk": "/var/cache/apk",
101+
"go-build-cache/pkg": "/go/pkg/mod",
102+
"go-build-cache/build": "/root/.cache/go-build"
103+
}
99104
100105
# Build and push Docker image with Buildx (don't push on PR)
101106
# https://github.com/docker/build-push-action

.github/workflows/lint.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ jobs:
2323
run: script/build-ui
2424
- uses: actions/setup-go@v6
2525
with:
26-
go-version: stable
26+
go-version: '1.25'
2727
- name: golangci-lint
2828
uses: golangci/golangci-lint-action@v9
2929
with:
30-
version: v2.5
30+
# sync with script/lint
31+
version: v2.9

.golangci.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ linters:
99
- gosec
1010
- makezero
1111
- misspell
12+
- modernize
1213
- nakedret
1314
- revive
1415
- errcheck
1516
- staticcheck
1617
- govet
1718
- ineffassign
19+
- intrange
1820
- unused
1921
exclusions:
2022
generated: lax
@@ -27,6 +29,11 @@ linters:
2729
- third_party$
2830
- builtin$
2931
- examples$
32+
- internal/githubv4mock
33+
rules:
34+
- linters:
35+
- revive
36+
text: "var-naming: avoid package names that conflict with Go standard library package names"
3037
settings:
3138
staticcheck:
3239
checks:

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ COPY ui/ ./ui/
77
RUN mkdir -p ./pkg/github/ui_dist && \
88
cd ui && npm run build
99

10-
FROM golang:1.25.6-alpine AS build
10+
FROM golang:1.25.7-alpine AS build
1111
ARG VERSION="dev"
1212

1313
# Set the working directory

cmd/github-mcp-server/generate_docs.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net/url"
77
"os"
8+
"slices"
89
"sort"
910
"strings"
1011

@@ -234,7 +235,7 @@ func writeToolDoc(buf *strings.Builder, tool inventory.ServerTool) {
234235

235236
for i, propName := range paramNames {
236237
prop := schema.Properties[propName]
237-
required := contains(schema.Required, propName)
238+
required := slices.Contains(schema.Required, propName)
238239
requiredStr := "optional"
239240
if required {
240241
requiredStr = "required"
@@ -289,15 +290,6 @@ func scopesEqual(a, b []string) bool {
289290
return true
290291
}
291292

292-
func contains(slice []string, item string) bool {
293-
for _, s := range slice {
294-
if s == item {
295-
return true
296-
}
297-
}
298-
return false
299-
}
300-
301293
// indentMultilineDescription adds the specified indent to all lines after the first line.
302294
// This ensures that multi-line descriptions maintain proper markdown list formatting.
303295
func indentMultilineDescription(description, indent string) string {
@@ -319,14 +311,14 @@ func replaceSection(content, startMarker, endMarker, newContent string) (string,
319311
start := fmt.Sprintf("<!-- %s -->", startMarker)
320312
end := fmt.Sprintf("<!-- %s -->", endMarker)
321313

322-
startIdx := strings.Index(content, start)
314+
before, _, ok := strings.Cut(content, start)
323315
endIdx := strings.Index(content, end)
324-
if startIdx == -1 || endIdx == -1 {
316+
if !ok || endIdx == -1 {
325317
return "", fmt.Errorf("markers not found: %s / %s", start, end)
326318
}
327319

328320
var buf strings.Builder
329-
buf.WriteString(content[:startIdx])
321+
buf.WriteString(before)
330322
buf.WriteString(start)
331323
buf.WriteString("\n")
332324
buf.WriteString(newContent)
@@ -426,6 +418,7 @@ func generateRemoteOnlyToolsetsDoc() string {
426418

427419
return strings.TrimSuffix(buf.String(), "\n")
428420
}
421+
429422
func generateDeprecatedAliasesDocs(docsPath string) error {
430423
// Read the current file
431424
content, err := os.ReadFile(docsPath) //#nosec G304

cmd/mcpcurl/main.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ type (
7373

7474
// RequestParams contains the tool name and arguments
7575
RequestParams struct {
76-
Name string `json:"name"`
77-
Arguments map[string]interface{} `json:"arguments"`
76+
Name string `json:"name"`
77+
Arguments map[string]any `json:"arguments"`
7878
}
7979

8080
// Content matches the response format of a text content response
@@ -308,8 +308,8 @@ func addCommandFromTool(toolsCmd *cobra.Command, tool *Tool, prettyPrint bool) {
308308
}
309309

310310
// buildArgumentsMap extracts flag values into a map of arguments
311-
func buildArgumentsMap(cmd *cobra.Command, tool *Tool) (map[string]interface{}, error) {
312-
arguments := make(map[string]interface{})
311+
func buildArgumentsMap(cmd *cobra.Command, tool *Tool) (map[string]any, error) {
312+
arguments := make(map[string]any)
313313

314314
for name, prop := range tool.InputSchema.Properties {
315315
switch prop.Type {
@@ -340,7 +340,7 @@ func buildArgumentsMap(cmd *cobra.Command, tool *Tool) (map[string]interface{},
340340
}
341341
case "object":
342342
if jsonStr, _ := cmd.Flags().GetString(name + "-json"); jsonStr != "" {
343-
var jsonArray []interface{}
343+
var jsonArray []any
344344
if err := json.Unmarshal([]byte(jsonStr), &jsonArray); err != nil {
345345
return nil, fmt.Errorf("error parsing JSON for %s: %w", name, err)
346346
}
@@ -355,7 +355,7 @@ func buildArgumentsMap(cmd *cobra.Command, tool *Tool) (map[string]interface{},
355355
}
356356

357357
// buildJSONRPCRequest creates a JSON-RPC request with the given tool name and arguments
358-
func buildJSONRPCRequest(method, toolName string, arguments map[string]interface{}) (string, error) {
358+
func buildJSONRPCRequest(method, toolName string, arguments map[string]any) (string, error) {
359359
id, err := rand.Int(rand.Reader, big.NewInt(10000))
360360
if err != nil {
361361
return "", fmt.Errorf("failed to generate random ID: %w", err)
@@ -432,7 +432,7 @@ func printResponse(response string, prettyPrint bool) error {
432432
// Extract text from content items of type "text"
433433
for _, content := range resp.Result.Content {
434434
if content.Type == "text" {
435-
var textContentObj map[string]interface{}
435+
var textContentObj map[string]any
436436
err := json.Unmarshal([]byte(content.Text), &textContentObj)
437437

438438
if err == nil {
@@ -445,7 +445,7 @@ func printResponse(response string, prettyPrint bool) error {
445445
}
446446

447447
// Fallback parsing as JSONL
448-
var textContentList []map[string]interface{}
448+
var textContentList []map[string]any
449449
if err := json.Unmarshal([]byte(content.Text), &textContentList); err != nil {
450450
return fmt.Errorf("failed to parse text content as a list: %w", err)
451451
}

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

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,48 @@
11
# Install GitHub MCP Server in Copilot CLI
22

3-
## Prerequisites
3+
The GitHub MCP server comes pre-installed in Copilot CLI, with read-only tools enabled by default.
44

5-
1. Copilot CLI installed (see [official Copilot CLI documentation](https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli))
6-
2. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
7-
3. For local installation: [Docker](https://www.docker.com/) installed and running
5+
## Built-in Server
6+
7+
To verify the server is available, from an active Copilot CLI session:
8+
9+
```bash
10+
/mcp show github-mcp-server
11+
```
12+
13+
### Per-Session Customization
14+
15+
Use CLI flags to customize the server for a session:
16+
17+
```bash
18+
# Enable an additional toolset
19+
copilot --add-github-mcp-toolset discussions
20+
21+
# Enable multiple additional toolsets
22+
copilot --add-github-mcp-toolset discussions --add-github-mcp-toolset stargazers
23+
24+
# Enable all toolsets
25+
copilot --enable-all-github-mcp-tools
26+
27+
# Enable a specific tool
28+
copilot --add-github-mcp-tool list_discussions
29+
30+
# Disable the built-in server entirely
31+
copilot --disable-builtin-mcps
32+
```
33+
34+
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).
35+
36+
## Custom Configuration
37+
38+
You can configure the GitHub MCP server in Copilot CLI using either the interactive command or by manually editing the configuration file.
39+
40+
> **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.
41+
42+
### Prerequisites
43+
44+
1. [GitHub Personal Access Token](https://github.com/settings/personal-access-tokens/new) with appropriate scopes
45+
2. For local server: [Docker](https://www.docker.com/) installed and running
846

947
<details>
1048
<summary><b>Storing Your PAT Securely</b></summary>
@@ -19,21 +57,17 @@ export GITHUB_PERSONAL_ACCESS_TOKEN=your_token_here
1957

2058
</details>
2159

22-
## GitHub MCP Server Configuration
23-
24-
You can configure the GitHub MCP server in Copilot CLI using either the interactive command or by manually editing the configuration file.
25-
2660
### Method 1: Interactive Setup (Recommended)
2761

28-
Use the Copilot CLI to interactively add the MCP server:
62+
From an active Copilot CLI session, run the interactive command:
2963

3064
```bash
3165
/mcp add
3266
```
3367

34-
Follow the prompts to configure the GitHub MCP server.
68+
Follow the prompts to configure the server.
3569

36-
### Method 2: Manual Configuration
70+
### Method 2: Manual Setup
3771

3872
Create or edit the configuration file `~/.copilot/mcp-config.json` and add one of the following configurations:
3973

@@ -45,6 +79,7 @@ Connect to the hosted MCP server:
4579
{
4680
"mcpServers": {
4781
"github": {
82+
"type": "http",
4883
"url": "https://api.githubcopilot.com/mcp/",
4984
"headers": {
5085
"Authorization": "Bearer ${GITHUB_PERSONAL_ACCESS_TOKEN}"
@@ -54,6 +89,8 @@ Connect to the hosted MCP server:
5489
}
5590
```
5691

92+
For additional options like toolsets and read-only mode, see the [remote server documentation](../remote-server.md#optional-headers).
93+
5794
#### Local Docker
5895

5996
With Docker running, you can run the GitHub MCP server in a container:
@@ -81,9 +118,13 @@ With Docker running, you can run the GitHub MCP server in a container:
81118

82119
#### Binary
83120

84-
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`.
121+
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:
85122

86-
Then, replacing `/path/to/binary` with the actual path to your binary, configure Copilot CLI with:
123+
```bash
124+
go build -o github-mcp-server ./cmd/github-mcp-server
125+
```
126+
127+
Then configure (replace `/path/to/binary` with the actual path):
87128

88129
```json
89130
{
@@ -101,35 +142,30 @@ Then, replacing `/path/to/binary` with the actual path to your binary, configure
101142

102143
## Verification
103144

104-
To verify that the GitHub MCP server has been configured:
105-
106-
1. Start or restart Copilot CLI
107-
2. The GitHub tools should be available for use in your conversations
145+
1. Restart Copilot CLI
146+
2. Run `/mcp show` to list configured servers
147+
3. Try: "List my GitHub repositories"
108148

109149
## Troubleshooting
110150

111151
### Local Server Issues
112152

113153
- **Docker errors**: Ensure Docker Desktop is running
114-
```bash
115-
docker --version
116-
```
117154
- **Image pull failures**: Try `docker logout ghcr.io` then retry
118-
- **Docker not found**: Install Docker Desktop and ensure it's running
119155

120156
### Authentication Issues
121157

122158
- **Invalid PAT**: Verify your GitHub PAT has correct scopes:
123-
- `repo` - Repository operations
124-
- `read:packages` - Docker image access (if using Docker)
159+
- `repo` - Repository operations
160+
- `read:packages` - Docker image access (if using Docker)
125161
- **Token expired**: Generate a new GitHub PAT
126162

127163
### Configuration Issues
128164

129165
- **Invalid JSON**: Validate your configuration:
130-
```bash
131-
cat ~/.copilot/mcp-config.json | jq .
132-
```
166+
```bash
167+
cat ~/.copilot/mcp-config.json | jq .
168+
```
133169

134170
## References
135171

e2e/e2e_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/github/github-mcp-server/internal/ghmcp"
1919
"github.com/github/github-mcp-server/pkg/github"
2020
"github.com/github/github-mcp-server/pkg/translations"
21-
gogithub "github.com/google/go-github/v79/github"
21+
gogithub "github.com/google/go-github/v82/github"
2222
"github.com/modelcontextprotocol/go-sdk/mcp"
2323
"github.com/stretchr/testify/require"
2424
)

0 commit comments

Comments
 (0)