From 3dd362544af15f2886992ee8ec51f1d5dd494f66 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:11:39 +0000 Subject: [PATCH 1/4] Initial plan From da5e30ed02cb39ace14251abf614a7aee3f4a04f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:21:34 +0000 Subject: [PATCH 2/4] Add comprehensive copilot instructions for repository Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com> --- .github/copilot-instructions.md | 280 ++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 000000000..3e65d1ce8 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,280 @@ +# GitHub MCP Server - Copilot Instructions + +## Project Overview + +This is the **GitHub MCP Server**, a Model Context Protocol (MCP) server that connects AI tools to GitHub's platform. It enables AI agents to manage repositories, issues, pull requests, workflows, and more through natural language. + +**Key Details:** +- **Language:** Go 1.24+ (~38k lines of code) +- **Type:** MCP server application with CLI interface +- **Primary Package:** github-mcp-server (stdio MCP server - **this is the main focus**) +- **Secondary Package:** mcpcurl (testing utility - don't break it, but not the priority) +- **Framework:** Uses mark3labs/mcp-go for MCP protocol, google/go-github for GitHub API +- **Size:** ~60MB repository, 70 Go files + +## Critical Build & Validation Steps + +### Required Commands (Run Before Committing) + +**ALWAYS run these commands in this exact order before using report_progress or finishing work:** + +1. **Format Code:** `script/lint` (this runs `gofmt -s -w .` then `golangci-lint`) +2. **Run Tests:** `script/test` (runs `go test -race ./...`) +3. **Update Documentation:** `script/generate-docs` (if you modified MCP tools/toolsets) + +**These commands are FAST:** Lint ~1s, Tests ~1s (cached), Build ~1s + +### When Modifying MCP Tools/Endpoints + +If you change any MCP tool definitions or schemas: +1. Run tests with `UPDATE_TOOLSNAPS=true go test ./...` to update toolsnaps +2. Commit the updated `.snap` files in `pkg/github/__toolsnaps__/` +3. Run `script/generate-docs` to update README.md +4. Toolsnaps document API surface and ensure changes are intentional + +### Common Build Commands + +```bash +# Download dependencies (rarely needed - usually cached) +go mod download + +# Build the server binary +go build -v ./cmd/github-mcp-server + +# Run the server +./github-mcp-server stdio + +# Run specific package tests +go test ./pkg/github -v + +# Run specific test +go test ./pkg/github -run TestGetMe +``` + +## Project Structure + +### Directory Layout + +``` +. +├── cmd/ +│ ├── github-mcp-server/ # Main MCP server entry point (PRIMARY FOCUS) +│ └── mcpcurl/ # MCP testing utility (secondary - don't break it) +├── pkg/ # Public API packages +│ ├── github/ # GitHub API MCP tools implementation +│ │ └── __toolsnaps__/ # Tool schema snapshots (*.snap files) +│ ├── toolsets/ # Toolset configuration & management +│ ├── errors/ # Error handling utilities +│ ├── sanitize/ # HTML/content sanitization +│ ├── log/ # Logging utilities +│ ├── raw/ # Raw data handling +│ ├── buffer/ # Buffer utilities +│ └── translations/ # i18n translation support +├── internal/ # Internal implementation packages +│ ├── ghmcp/ # GitHub MCP server core logic +│ ├── githubv4mock/ # GraphQL API mocking for tests +│ ├── toolsnaps/ # Toolsnap validation system +│ └── profiler/ # Performance profiling +├── e2e/ # End-to-end tests (require GitHub PAT) +├── script/ # Build and maintenance scripts +├── docs/ # Documentation +├── .github/workflows/ # CI/CD workflows +└── [config files] # See below +``` + +### Key Configuration Files + +- **go.mod / go.sum:** Go module dependencies (Go 1.24.0+) +- **.golangci.yml:** Linter configuration (v2 format, ~15 linters enabled) +- **Dockerfile:** Multi-stage build (golang:1.25.3-alpine → distroless) +- **server.json:** MCP server metadata for registry +- **.goreleaser.yaml:** Release automation config +- **.gitignore:** Excludes bin/, dist/, vendor/, *.DS_Store, github-mcp-server binary + +### Important Scripts (script/ directory) + +- **script/lint** - Runs `gofmt` + `golangci-lint`. **MUST RUN** before committing +- **script/test** - Runs `go test -race ./...` (full test suite) +- **script/generate-docs** - Updates README.md tool documentation. Run after tool changes +- **script/licenses** - Updates third-party license files when dependencies change +- **script/licenses-check** - Validates license compliance (runs in CI) +- **script/get-me** - Quick test script for get_me tool +- **script/get-discussions** - Quick test for discussions +- **script/tag-release** - **NEVER USE THIS** - releases are managed separately + +## GitHub Workflows (CI/CD) + +All workflows run on push/PR unless noted. Located in `.github/workflows/`: + +1. **go.yml** - Build and test on ubuntu/windows/macos. Runs `script/test` and builds binary +2. **lint.yml** - Runs golangci-lint v2.5 with actions/setup-go stable +3. **docs-check.yml** - Verifies README.md is up-to-date by running generate-docs and checking git diff +4. **code-scanning.yml** - CodeQL security analysis for Go and GitHub Actions +5. **license-check.yml** - Runs `script/licenses-check` to validate compliance +6. **docker-publish.yml** - Publishes container image to ghcr.io +7. **goreleaser.yml** - Creates releases (main branch only) +8. **registry-releaser.yml** - Updates MCP registry + +**All of these must pass for PR merge.** If docs-check fails, run `script/generate-docs` and commit changes. + +## Testing Guidelines + +### Unit Tests + +- Use `testify` for assertions (`require` for critical checks, `assert` for non-blocking) +- Tests are in `*_test.go` files alongside implementation (internal tests, not `_test` package) +- Mock GitHub API with `go-github-mock` (REST) or `githubv4mock` (GraphQL) +- Test structure for tools: + 1. Test tool snapshot + 2. Verify critical schema properties (e.g., ReadOnly annotation) + 3. Table-driven behavioral tests + +### Toolsnaps (Tool Schema Snapshots) + +- Every MCP tool has a JSON schema snapshot in `pkg/github/__toolsnaps__/*.snap` +- Tests fail if current schema differs from snapshot (shows diff) +- To update after intentional changes: `UPDATE_TOOLSNAPS=true go test ./...` +- **MUST commit updated .snap files** - they document API changes +- Missing snapshots cause CI failure + +### End-to-End Tests + +- Located in `e2e/` directory with `e2e_test.go` +- **Require GitHub PAT token** - you usually cannot run these yourself +- Run with: `GITHUB_MCP_SERVER_E2E_TOKEN= go test -v --tags e2e ./e2e` +- Tests interact with live GitHub API via Docker container +- **Keep e2e tests updated when changing MCP tools** +- **Use only the e2e test style** when modifying tests in this directory +- For debugging: `GITHUB_MCP_SERVER_E2E_DEBUG=true` runs in-process (no Docker) + +## Code Style & Linting + +### Go Code Requirements + +- **gofmt with simplify flag (-s)** - Automatically run by `script/lint` +- **golangci-lint v2.5.0** with these linters enabled: + - bodyclose, gocritic, gosec, makezero, misspell, nakedret, revive + - errcheck, staticcheck, govet, ineffassign, unused +- Exclusions for: third_party/, builtin/, examples/, generated code + +### Go Naming Conventions + +- **Acronyms in identifiers:** Use `ID` not `Id`, `API` not `Api`, `URL` not `Url`, `HTTP` not `Http` +- Examples: `userID`, `getAPI`, `parseURL`, `HTTPClient` +- This applies to variable names, function names, struct fields, etc. + +### Code Patterns + +- **Keep changes minimal and focused** on the specific issue being addressed +- Prefer explicit over clever code +- Use table-driven tests for behavioral testing +- Comment sparingly - code should be self-documenting +- Follow standard Go conventions (Effective Go, Go proverbs) +- **Test changes thoroughly** before committing + +## Common Development Workflows + +### Adding a New MCP Tool + +1. Add tool implementation in `pkg/github/` (e.g., `foo_tools.go`) +2. Register tool in appropriate toolset in `pkg/github/` or `pkg/toolsets/` +3. Write unit tests following the tool test pattern +4. Run `UPDATE_TOOLSNAPS=true go test ./...` to create snapshot +5. Run `script/generate-docs` to update README +6. Run `script/lint` and `script/test` before committing +7. If e2e tests are relevant, update `e2e/e2e_test.go` using existing test style +8. Commit code + snapshots + README changes together + +### Fixing a Bug + +1. Write a failing test that reproduces the bug +2. Fix the bug with minimal changes +3. Verify test passes and existing tests still pass +4. Run `script/lint` and `script/test` +5. If tool schema changed, update toolsnaps (see above) + +### Updating Dependencies + +1. Update `go.mod` (e.g., `go get -u ./...` or manually) +2. Run `go mod tidy` +3. Run `script/licenses` to update license files +4. Run `script/test` to verify nothing broke +5. Commit go.mod, go.sum, and third-party-licenses* files + +## Common Errors & Solutions + +### "Documentation is out of date" in CI + +**Fix:** Run `script/generate-docs` and commit README.md changes + +### Toolsnap mismatch failures + +**Fix:** Run `UPDATE_TOOLSNAPS=true go test ./...` and commit updated .snap files + +### Lint failures + +**Fix:** Run `script/lint` locally - it will auto-format and show issues. Fix manually reported issues. + +### License check failures + +**Fix:** Run `script/licenses` to regenerate license files after dependency changes + +### Test failures after changing a tool + +**Likely causes:** +1. Forgot to update toolsnaps - run with `UPDATE_TOOLSNAPS=true` +2. Changed behavior broke existing tests - verify intent and fix tests +3. Schema change not reflected in test - update test expectations + +## Environment Variables + +- **GITHUB_PERSONAL_ACCESS_TOKEN** - Required for server operation and e2e tests +- **GITHUB_HOST** - For GitHub Enterprise Server (prefix with `https://`) +- **GITHUB_TOOLSETS** - Comma-separated toolset list (overrides --toolsets flag) +- **GITHUB_READ_ONLY** - Set to "1" for read-only mode +- **GITHUB_DYNAMIC_TOOLSETS** - Set to "1" for dynamic toolset discovery +- **UPDATE_TOOLSNAPS** - Set to "true" when running tests to update snapshots +- **GITHUB_MCP_SERVER_E2E_TOKEN** - Token for e2e tests +- **GITHUB_MCP_SERVER_E2E_DEBUG** - Set to "true" for in-process e2e debugging + +## Key Files Reference + +### Root Directory Files +``` +.dockerignore - Docker build exclusions +.gitignore - Git exclusions (includes bin/, dist/, vendor/, binaries) +.golangci.yml - Linter configuration +.goreleaser.yaml - Release automation +CODE_OF_CONDUCT.md - Community guidelines +CONTRIBUTING.md - Contribution guide (fork, clone, test, lint workflow) +Dockerfile - Multi-stage Go build +LICENSE - MIT license +README.md - Main documentation (auto-generated sections) +SECURITY.md - Security policy +SUPPORT.md - Support resources +gemini-extension.json - Gemini CLI configuration +go.mod / go.sum - Go dependencies +server.json - MCP server registry metadata +``` + +### Main Entry Point + +`cmd/github-mcp-server/main.go` - Uses cobra for CLI, viper for config, supports: +- `stdio` command (default) - MCP stdio transport +- `generate-docs` command - Documentation generation +- Flags: --toolsets, --read-only, --dynamic-toolsets, --gh-host, --log-file + +## Important Reminders + +1. **PRIMARY FOCUS:** The local stdio MCP server (github-mcp-server) - this is what you should work on and test with +2. **ALWAYS** trust these instructions first - only search if information is incomplete or incorrect +3. **NEVER** use `script/tag-release` or push tags +4. **NEVER** skip `script/lint` before committing Go code changes +5. **ALWAYS** update toolsnaps when changing MCP tool schemas +6. **ALWAYS** run `script/generate-docs` after modifying tools +7. For specific test files, use `go test ./path -run TestName` not full suite +8. E2E tests require PAT token - you likely cannot run them +9. Toolsnaps are API documentation - treat changes seriously +10. Build/test/lint are very fast (~1s each) - run frequently +11. CI failures for docs-check or license-check have simple fixes (run the script) +12. mcpcurl is secondary - don't break it, but it's not the priority \ No newline at end of file From 5ce2753fdf7d7b5b4819f7dabd9a916fe3842a6a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 10 Nov 2025 09:31:27 +0000 Subject: [PATCH 3/4] Add library usage and code quality guidelines to copilot instructions Co-authored-by: SamMorrowDrums <4811358+SamMorrowDrums@users.noreply.github.com> --- .github/copilot-instructions.md | 36 ++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 3e65d1ce8..8672f53cc 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -11,6 +11,14 @@ This is the **GitHub MCP Server**, a Model Context Protocol (MCP) server that co - **Secondary Package:** mcpcurl (testing utility - don't break it, but not the priority) - **Framework:** Uses mark3labs/mcp-go for MCP protocol, google/go-github for GitHub API - **Size:** ~60MB repository, 70 Go files +- **Library Usage:** This repository is also used as a library by the remote server. Functions that could be called by other repositories should be exported (capitalized), even if not required internally. Preserve existing export patterns. + +**Code Quality Standards:** +- **Popular Open Source Repository** - High bar for code quality and clarity +- **Comprehension First** - Code must be clear to a wide audience +- **Clean Commits** - Atomic, focused changes with clear messages +- **Structure** - Always maintain or improve, never degrade +- **Code over Comments** - Prefer self-documenting code; comment only when necessary ## Critical Build & Validation Steps @@ -166,11 +174,14 @@ All workflows run on push/PR unless noted. Located in `.github/workflows/`: ### Code Patterns - **Keep changes minimal and focused** on the specific issue being addressed -- Prefer explicit over clever code +- **Prefer clarity over cleverness** - code must be understandable by a wide audience +- **Atomic commits** - each commit should be a complete, logical change +- **Maintain or improve structure** - never degrade code organization - Use table-driven tests for behavioral testing - Comment sparingly - code should be self-documenting - Follow standard Go conventions (Effective Go, Go proverbs) - **Test changes thoroughly** before committing +- Export functions (capitalize) if they could be used by other repos as a library ## Common Development Workflows @@ -267,14 +278,15 @@ server.json - MCP server registry metadata ## Important Reminders 1. **PRIMARY FOCUS:** The local stdio MCP server (github-mcp-server) - this is what you should work on and test with -2. **ALWAYS** trust these instructions first - only search if information is incomplete or incorrect -3. **NEVER** use `script/tag-release` or push tags -4. **NEVER** skip `script/lint` before committing Go code changes -5. **ALWAYS** update toolsnaps when changing MCP tool schemas -6. **ALWAYS** run `script/generate-docs` after modifying tools -7. For specific test files, use `go test ./path -run TestName` not full suite -8. E2E tests require PAT token - you likely cannot run them -9. Toolsnaps are API documentation - treat changes seriously -10. Build/test/lint are very fast (~1s each) - run frequently -11. CI failures for docs-check or license-check have simple fixes (run the script) -12. mcpcurl is secondary - don't break it, but it's not the priority \ No newline at end of file +2. **REMOTE SERVER:** Ignore remote server instructions when making code changes (unless specifically asked). This repo is used as a library by the remote server, so keep functions exported (capitalized) if they could be called by other repos, even if not needed internally. +3. **ALWAYS** trust these instructions first - only search if information is incomplete or incorrect +4. **NEVER** use `script/tag-release` or push tags +5. **NEVER** skip `script/lint` before committing Go code changes +6. **ALWAYS** update toolsnaps when changing MCP tool schemas +7. **ALWAYS** run `script/generate-docs` after modifying tools +8. For specific test files, use `go test ./path -run TestName` not full suite +9. E2E tests require PAT token - you likely cannot run them +10. Toolsnaps are API documentation - treat changes seriously +11. Build/test/lint are very fast (~1s each) - run frequently +12. CI failures for docs-check or license-check have simple fixes (run the script) +13. mcpcurl is secondary - don't break it, but it's not the priority \ No newline at end of file From e1c8f4375559679315e23212008c0bad09790d4c Mon Sep 17 00:00:00 2001 From: Sam Morrow Date: Tue, 18 Nov 2025 10:50:08 +0100 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .github/copilot-instructions.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 8672f53cc..bc7a647a6 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -26,7 +26,7 @@ This is the **GitHub MCP Server**, a Model Context Protocol (MCP) server that co **ALWAYS run these commands in this exact order before using report_progress or finishing work:** -1. **Format Code:** `script/lint` (this runs `gofmt -s -w .` then `golangci-lint`) +1. **Format Code:** `script/lint` (runs `gofmt -s -w .` then `golangci-lint`) 2. **Run Tests:** `script/test` (runs `go test -race ./...`) 3. **Update Documentation:** `script/generate-docs` (if you modified MCP tools/toolsets) @@ -115,7 +115,7 @@ go test ./pkg/github -run TestGetMe All workflows run on push/PR unless noted. Located in `.github/workflows/`: 1. **go.yml** - Build and test on ubuntu/windows/macos. Runs `script/test` and builds binary -2. **lint.yml** - Runs golangci-lint v2.5 with actions/setup-go stable +2. **lint.yml** - Runs golangci-lint-action v2.5 (GitHub Action) with actions/setup-go stable 3. **docs-check.yml** - Verifies README.md is up-to-date by running generate-docs and checking git diff 4. **code-scanning.yml** - CodeQL security analysis for Go and GitHub Actions 5. **license-check.yml** - Runs `script/licenses-check` to validate compliance @@ -160,7 +160,7 @@ All workflows run on push/PR unless noted. Located in `.github/workflows/`: ### Go Code Requirements - **gofmt with simplify flag (-s)** - Automatically run by `script/lint` -- **golangci-lint v2.5.0** with these linters enabled: +- **golangci-lint** with these linters enabled: - bodyclose, gocritic, gosec, makezero, misspell, nakedret, revive - errcheck, staticcheck, govet, ineffassign, unused - Exclusions for: third_party/, builtin/, examples/, generated code