{"owner":"github","repo":"github-mcp-server","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":[".github/copilot-instructions.md"],"files":{".github/copilot-instructions.md":"# GitHub MCP Server - Copilot Instructions\n\n## Project Overview\n\nThis 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.\n\n**Key Details:**\n- **Language:** Go 1.24+ (~38k lines of code)\n- **Type:** MCP server application with CLI interface\n- **Primary Package:** github-mcp-server (stdio MCP server - **this is the main focus**)\n- **Secondary Package:** mcpcurl (testing utility - don't break it, but not the priority)\n- **Framework:** Uses modelcontextprotocol/go-sdk for MCP protocol, google/go-github for GitHub API\n- **Size:** ~60MB repository, 70 Go files\n- **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.\n\n**Code Quality Standards:**\n- **Popular Open Source Repository** - High bar for code quality and clarity\n- **Comprehension First** - Code must be clear to a wide audience\n- **Clean Commits** - Atomic, focused changes with clear messages\n- **Structure** - Always maintain or improve, never degrade\n- **Code over Comments** - Prefer self-documenting code; comment only when necessary\n\n## Critical Build & Validation Steps\n\n### Required Commands (Run Before Committing)\n\n**ALWAYS run these commands in this exact order before using report_progress or finishing work:**\n\n1. **Format Code:** `script/lint` (runs `gofmt -s -w .` then `golangci-lint`)\n2. **Run Tests:** `script/test` (runs `go test -race ./...`)\n3. **Update Documentation:** `script/generate-docs` (if you modified MCP tools/toolsets)\n\n**These commands are FAST:** Lint ~1s, Tests ~1s (cached), Build ~1s\n\n### When Modifying MCP Tools/Endpoints\n\nIf you change any MCP tool definitions or schemas:\n1. Run tests with `UPDATE_TOOLSNAPS=true go test ./...` to update toolsnaps\n2. Commit the updated `.snap` files in `pkg/github/__toolsnaps__/`\n3. Run `script/generate-docs` to update README.md\n4. Toolsnaps document API surface and ensure changes are intentional\n\n### Common Build Commands\n\n```bash\n# Download dependencies (rarely needed - usually cached)\ngo mod download\n\n# Build the server binary\ngo build -v ./cmd/github-mcp-server\n\n# Run the server\n./github-mcp-server stdio\n\n# Run specific package tests\ngo test ./pkg/github -v\n\n# Run specific test\ngo test ./pkg/github -run TestGetMe\n```\n\n## Project Structure\n\n### Directory Layout\n\n```\n.\n├── cmd/\n│   ├── github-mcp-server/    # Main MCP server entry point (PRIMARY FOCUS)\n│   └── mcpcurl/              # MCP testing utility (secondary - don't break it)\n├── pkg/                      # Public API packages\n│   ├── github/               # GitHub API MCP tools implementation\n│   │   └── __toolsnaps__/    # Tool schema snapshots (*.snap files)\n│   ├── toolsets/             # Toolset configuration & management\n│   ├── errors/               # Error handling utilities\n│   ├── sanitize/             # HTML/content sanitization\n│   ├── log/                  # Logging utilities\n│   ├── raw/                  # Raw data handling\n│   ├── buffer/               # Buffer utilities\n│   └── translations/         # i18n translation support\n├── internal/                 # Internal implementation packages\n│   ├── ghmcp/                # GitHub MCP server core logic\n│   ├── githubv4mock/         # GraphQL API mocking for tests\n│   ├── toolsnaps/            # Toolsnap validation system\n│   └── profiler/             # Performance profiling\n├── e2e/                      # End-to-end tests (require GitHub PAT)\n├── script/                   # Build and maintenance scripts\n├── docs/                     # Documentation\n├── .github/workflows/        # CI/CD workflows\n└── [config files]            # See below\n```\n\n### Key Configuration Files\n\n- **go.mod / go.sum:** Go module dependencies (Go 1.24.0+)\n- **.golangci.yml:** Linter configuration (v2 format, ~15 linters enabled)\n- **Dockerfile:** Multi-stage build (golang:1.25.8-alpine → distroless)\n- **server.json:** MCP server metadata for registry\n- **.goreleaser.yaml:** Release automation config\n- **.gitignore:** Excludes bin/, dist/, vendor/, *.DS_Store, github-mcp-server binary\n\n### Important Scripts (script/ directory)\n\n- **script/lint** - Runs `gofmt` + `golangci-lint`. **MUST RUN** before committing\n- **script/test** - Runs `go test -race ./...` (full test suite)\n- **script/generate-docs** - Updates README.md tool documentation. Run after tool changes\n- **script/licenses** - Updates third-party license files when dependencies change\n- **script/licenses-check** - Validates license compliance (runs in CI)\n- **script/get-me** - Quick test script for get_me tool\n- **script/get-discussions** - Quick test for discussions\n- **script/tag-release** - **NEVER USE THIS** - releases are managed separately\n\n## GitHub Workflows (CI/CD)\n\nAll workflows run on push/PR unless noted. Located in `.github/workflows/`:\n\n1. **go.yml** - Build and test on ubuntu/windows/macos. Runs `script/test` and builds binary\n2. **lint.yml** - Runs golangci-lint-action v2.5 (GitHub Action) with actions/setup-go stable\n3. **docs-check.yml** - Verifies README.md is up-to-date by running generate-docs and checking git diff\n4. **code-scanning.yml** - CodeQL security analysis for Go and GitHub Actions\n5. **license-check.yml** - Runs `script/licenses-check` to validate compliance\n6. **docker-publish.yml** - Publishes container image to ghcr.io\n7. **goreleaser.yml** - Creates releases (main branch only)\n8. **registry-releaser.yml** - Updates MCP registry\n\n**All of these must pass for PR merge.** If docs-check fails, run `script/generate-docs` and commit changes.\n\n## Testing Guidelines\n\n### Unit Tests\n\n- Use `testify` for assertions (`require` for critical checks, `assert` for non-blocking)\n- Tests are in `*_test.go` files alongside implementation (internal tests, not `_test` package)\n- Mock GitHub API with `go-github-mock` (REST) or `githubv4mock` (GraphQL)\n- Test structure for tools:\n  1. Test tool snapshot\n  2. Verify critical schema properties (e.g., ReadOnly annotation)\n  3. Table-driven behavioral tests\n\n### Toolsnaps (Tool Schema Snapshots)\n\n- Every MCP tool has a JSON schema snapshot in `pkg/github/__toolsnaps__/*.snap`\n- Tests fail if current schema differs from snapshot (shows diff)\n- To update after intentional changes: `UPDATE_TOOLSNAPS=true go test ./...`\n- **MUST commit updated .snap files** - they document API changes\n- Missing snapshots cause CI failure\n\n### End-to-End Tests\n\n- Located in `e2e/` directory with `e2e_test.go`\n- **Require GitHub PAT token** - you usually cannot run these yourself\n- Run with: `GITHUB_MCP_SERVER_E2E_TOKEN=<token> go test -v --tags e2e ./e2e`\n- Tests interact with live GitHub API via Docker container\n- **Keep e2e tests updated when changing MCP tools**\n- **Use only the e2e test style** when modifying tests in this directory\n- For debugging: `GITHUB_MCP_SERVER_E2E_DEBUG=true` runs in-process (no Docker)\n\n## Code Style & Linting\n\n### Go Code Requirements\n\n- **gofmt with simplify flag (-s)** - Automatically run by `script/lint`\n- **golangci-lint** with these linters enabled:\n  - bodyclose, gocritic, gosec, makezero, misspell, nakedret, revive\n  - errcheck, staticcheck, govet, ineffassign, unused\n- Exclusions for: third_party/, builtin/, examples/, generated code\n\n### Go Naming Conventions\n\n- **Acronyms in identifiers:** Use `ID` not `Id`, `API` not `Api`, `URL` not `Url`, `HTTP` not `Http`\n- Examples: `userID`, `getAPI`, `parseURL`, `HTTPClient`\n- This applies to variable names, function names, struct fields, etc.\n\n### Code Patterns\n\n- **Keep changes minimal and focused** on the specific issue being addressed\n- **Prefer clarity over cleverness** - code must be understandable by a wide audience\n- **Atomic commits** - each commit should be a complete, logical change\n- **Maintain or improve structure** - never degrade code organization\n- Use table-driven tests for behavioral testing\n- Comment sparingly - code should be self-documenting\n- Follow standard Go conventions (Effective Go, Go proverbs)\n- **Test changes thoroughly** before committing\n- Export functions (capitalize) if they could be used by other repos as a library\n\n## Common Development Workflows\n\n### Adding a New MCP Tool\n\n1. Add tool implementation in `pkg/github/` (e.g., `foo_tools.go`)\n2. Register tool in appropriate toolset in `pkg/github/` or `pkg/toolsets/`\n3. Write unit tests following the tool test pattern\n4. Run `UPDATE_TOOLSNAPS=true go test ./...` to create snapshot\n5. Run `script/generate-docs` to update README\n6. Run `script/lint` and `script/test` before committing\n7. If e2e tests are relevant, update `e2e/e2e_test.go` using existing test style\n8. Commit code + snapshots + README changes together\n\n### Fixing a Bug\n\n1. Write a failing test that reproduces the bug\n2. Fix the bug with minimal changes\n3. Verify test passes and existing tests still pass\n4. Run `script/lint` and `script/test`\n5. If tool schema changed, update toolsnaps (see above)\n\n### Updating Dependencies\n\n1. Update `go.mod` (e.g., `go get -u ./...` or manually)\n2. Run `go mod tidy`\n3. Run `script/licenses` to update license files\n4. Run `script/test` to verify nothing broke\n5. Commit go.mod, go.sum, and third-party-licenses* files\n\n## Common Errors & Solutions\n\n### \"Documentation is out of date\" in CI\n\n**Fix:** Run `script/generate-docs` and commit README.md changes\n\n### Toolsnap mismatch failures\n\n**Fix:** Run `UPDATE_TOOLSNAPS=true go test ./...` and commit updated .snap files\n\n### Lint failures\n\n**Fix:** Run `script/lint` locally - it will auto-format and show issues. Fix manually reported issues.\n\n### License check failures\n\n**Fix:** Run `script/licenses` to regenerate license files after dependency changes\n\n### Test failures after changing a tool\n\n**Likely causes:**\n1. Forgot to update toolsnaps - run with `UPDATE_TOOLSNAPS=true`\n2. Changed behavior broke existing tests - verify intent and fix tests\n3. Schema change not reflected in test - update test expectations\n\n## Environment Variables\n\n- **GITHUB_PERSONAL_ACCESS_TOKEN** - Required for server operation and e2e tests\n- **GITHUB_HOST** - For GitHub Enterprise Server (prefix with `https://`)\n- **GITHUB_TOOLSETS** - Comma-separated toolset list (overrides --toolsets flag)\n- **GITHUB_READ_ONLY** - Set to \"1\" for read-only mode\n- **UPDATE_TOOLSNAPS** - Set to \"true\" when running tests to update snapshots\n- **GITHUB_MCP_SERVER_E2E_TOKEN** - Token for e2e tests\n- **GITHUB_MCP_SERVER_E2E_DEBUG** - Set to \"true\" for in-process e2e debugging\n\n## Key Files Reference\n\n### Root Directory Files\n```\n.dockerignore        - Docker build exclusions\n.gitignore          - Git exclusions (includes bin/, dist/, vendor/, binaries)\n.golangci.yml       - Linter configuration\n.goreleaser.yaml    - Release automation\nCODE_OF_CONDUCT.md  - Community guidelines\nCONTRIBUTING.md     - Contribution guide (fork, clone, test, lint workflow)\nDockerfile          - Multi-stage Go build\nLICENSE             - MIT license\nREADME.md           - Main documentation (auto-generated sections)\nSECURITY.md         - Security policy\nSUPPORT.md          - Support resources\ngemini-extension.json - Gemini CLI configuration\ngo.mod / go.sum     - Go dependencies\nserver.json         - MCP server registry metadata\n```\n\n### Main Entry Point\n\n`cmd/github-mcp-server/main.go` - Uses cobra for CLI, viper for config, supports:\n- `stdio` command (default) - MCP stdio transport\n- `generate-docs` command - Documentation generation\n- Flags: --toolsets, --read-only, --gh-host, --log-file\n\n## Important Reminders\n\n1. **PRIMARY FOCUS:** The local stdio MCP server (github-mcp-server) - this is what you should work on and test with\n2. **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.\n3. **ALWAYS** trust these instructions first - only search if information is incomplete or incorrect\n4. **NEVER** use `script/tag-release` or push tags\n5. **NEVER** skip `script/lint` before committing Go code changes\n6. **ALWAYS** update toolsnaps when changing MCP tool schemas\n7. **ALWAYS** run `script/generate-docs` after modifying tools\n8. For specific test files, use `go test ./path -run TestName` not full suite\n9. E2E tests require PAT token - you likely cannot run them\n10. Toolsnaps are API documentation - treat changes seriously\n11. Build/test/lint are very fast (~1s each) - run frequently\n12. CI failures for docs-check or license-check have simple fixes (run the script)\n13. mcpcurl is secondary - don't break it, but it's not the priority"}}