Skip to content

Commit da5e30e

Browse files
Add comprehensive copilot instructions for repository
Co-authored-by: SamMorrowDrums <[email protected]>
1 parent 3dd3625 commit da5e30e

File tree

1 file changed

+280
-0
lines changed

1 file changed

+280
-0
lines changed

.github/copilot-instructions.md

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# GitHub MCP Server - Copilot Instructions
2+
3+
## Project Overview
4+
5+
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.
6+
7+
**Key Details:**
8+
- **Language:** Go 1.24+ (~38k lines of code)
9+
- **Type:** MCP server application with CLI interface
10+
- **Primary Package:** github-mcp-server (stdio MCP server - **this is the main focus**)
11+
- **Secondary Package:** mcpcurl (testing utility - don't break it, but not the priority)
12+
- **Framework:** Uses mark3labs/mcp-go for MCP protocol, google/go-github for GitHub API
13+
- **Size:** ~60MB repository, 70 Go files
14+
15+
## Critical Build & Validation Steps
16+
17+
### Required Commands (Run Before Committing)
18+
19+
**ALWAYS run these commands in this exact order before using report_progress or finishing work:**
20+
21+
1. **Format Code:** `script/lint` (this runs `gofmt -s -w .` then `golangci-lint`)
22+
2. **Run Tests:** `script/test` (runs `go test -race ./...`)
23+
3. **Update Documentation:** `script/generate-docs` (if you modified MCP tools/toolsets)
24+
25+
**These commands are FAST:** Lint ~1s, Tests ~1s (cached), Build ~1s
26+
27+
### When Modifying MCP Tools/Endpoints
28+
29+
If you change any MCP tool definitions or schemas:
30+
1. Run tests with `UPDATE_TOOLSNAPS=true go test ./...` to update toolsnaps
31+
2. Commit the updated `.snap` files in `pkg/github/__toolsnaps__/`
32+
3. Run `script/generate-docs` to update README.md
33+
4. Toolsnaps document API surface and ensure changes are intentional
34+
35+
### Common Build Commands
36+
37+
```bash
38+
# Download dependencies (rarely needed - usually cached)
39+
go mod download
40+
41+
# Build the server binary
42+
go build -v ./cmd/github-mcp-server
43+
44+
# Run the server
45+
./github-mcp-server stdio
46+
47+
# Run specific package tests
48+
go test ./pkg/github -v
49+
50+
# Run specific test
51+
go test ./pkg/github -run TestGetMe
52+
```
53+
54+
## Project Structure
55+
56+
### Directory Layout
57+
58+
```
59+
.
60+
├── cmd/
61+
│ ├── github-mcp-server/ # Main MCP server entry point (PRIMARY FOCUS)
62+
│ └── mcpcurl/ # MCP testing utility (secondary - don't break it)
63+
├── pkg/ # Public API packages
64+
│ ├── github/ # GitHub API MCP tools implementation
65+
│ │ └── __toolsnaps__/ # Tool schema snapshots (*.snap files)
66+
│ ├── toolsets/ # Toolset configuration & management
67+
│ ├── errors/ # Error handling utilities
68+
│ ├── sanitize/ # HTML/content sanitization
69+
│ ├── log/ # Logging utilities
70+
│ ├── raw/ # Raw data handling
71+
│ ├── buffer/ # Buffer utilities
72+
│ └── translations/ # i18n translation support
73+
├── internal/ # Internal implementation packages
74+
│ ├── ghmcp/ # GitHub MCP server core logic
75+
│ ├── githubv4mock/ # GraphQL API mocking for tests
76+
│ ├── toolsnaps/ # Toolsnap validation system
77+
│ └── profiler/ # Performance profiling
78+
├── e2e/ # End-to-end tests (require GitHub PAT)
79+
├── script/ # Build and maintenance scripts
80+
├── docs/ # Documentation
81+
├── .github/workflows/ # CI/CD workflows
82+
└── [config files] # See below
83+
```
84+
85+
### Key Configuration Files
86+
87+
- **go.mod / go.sum:** Go module dependencies (Go 1.24.0+)
88+
- **.golangci.yml:** Linter configuration (v2 format, ~15 linters enabled)
89+
- **Dockerfile:** Multi-stage build (golang:1.25.3-alpine → distroless)
90+
- **server.json:** MCP server metadata for registry
91+
- **.goreleaser.yaml:** Release automation config
92+
- **.gitignore:** Excludes bin/, dist/, vendor/, *.DS_Store, github-mcp-server binary
93+
94+
### Important Scripts (script/ directory)
95+
96+
- **script/lint** - Runs `gofmt` + `golangci-lint`. **MUST RUN** before committing
97+
- **script/test** - Runs `go test -race ./...` (full test suite)
98+
- **script/generate-docs** - Updates README.md tool documentation. Run after tool changes
99+
- **script/licenses** - Updates third-party license files when dependencies change
100+
- **script/licenses-check** - Validates license compliance (runs in CI)
101+
- **script/get-me** - Quick test script for get_me tool
102+
- **script/get-discussions** - Quick test for discussions
103+
- **script/tag-release** - **NEVER USE THIS** - releases are managed separately
104+
105+
## GitHub Workflows (CI/CD)
106+
107+
All workflows run on push/PR unless noted. Located in `.github/workflows/`:
108+
109+
1. **go.yml** - Build and test on ubuntu/windows/macos. Runs `script/test` and builds binary
110+
2. **lint.yml** - Runs golangci-lint v2.5 with actions/setup-go stable
111+
3. **docs-check.yml** - Verifies README.md is up-to-date by running generate-docs and checking git diff
112+
4. **code-scanning.yml** - CodeQL security analysis for Go and GitHub Actions
113+
5. **license-check.yml** - Runs `script/licenses-check` to validate compliance
114+
6. **docker-publish.yml** - Publishes container image to ghcr.io
115+
7. **goreleaser.yml** - Creates releases (main branch only)
116+
8. **registry-releaser.yml** - Updates MCP registry
117+
118+
**All of these must pass for PR merge.** If docs-check fails, run `script/generate-docs` and commit changes.
119+
120+
## Testing Guidelines
121+
122+
### Unit Tests
123+
124+
- Use `testify` for assertions (`require` for critical checks, `assert` for non-blocking)
125+
- Tests are in `*_test.go` files alongside implementation (internal tests, not `_test` package)
126+
- Mock GitHub API with `go-github-mock` (REST) or `githubv4mock` (GraphQL)
127+
- Test structure for tools:
128+
1. Test tool snapshot
129+
2. Verify critical schema properties (e.g., ReadOnly annotation)
130+
3. Table-driven behavioral tests
131+
132+
### Toolsnaps (Tool Schema Snapshots)
133+
134+
- Every MCP tool has a JSON schema snapshot in `pkg/github/__toolsnaps__/*.snap`
135+
- Tests fail if current schema differs from snapshot (shows diff)
136+
- To update after intentional changes: `UPDATE_TOOLSNAPS=true go test ./...`
137+
- **MUST commit updated .snap files** - they document API changes
138+
- Missing snapshots cause CI failure
139+
140+
### End-to-End Tests
141+
142+
- Located in `e2e/` directory with `e2e_test.go`
143+
- **Require GitHub PAT token** - you usually cannot run these yourself
144+
- Run with: `GITHUB_MCP_SERVER_E2E_TOKEN=<token> go test -v --tags e2e ./e2e`
145+
- Tests interact with live GitHub API via Docker container
146+
- **Keep e2e tests updated when changing MCP tools**
147+
- **Use only the e2e test style** when modifying tests in this directory
148+
- For debugging: `GITHUB_MCP_SERVER_E2E_DEBUG=true` runs in-process (no Docker)
149+
150+
## Code Style & Linting
151+
152+
### Go Code Requirements
153+
154+
- **gofmt with simplify flag (-s)** - Automatically run by `script/lint`
155+
- **golangci-lint v2.5.0** with these linters enabled:
156+
- bodyclose, gocritic, gosec, makezero, misspell, nakedret, revive
157+
- errcheck, staticcheck, govet, ineffassign, unused
158+
- Exclusions for: third_party/, builtin/, examples/, generated code
159+
160+
### Go Naming Conventions
161+
162+
- **Acronyms in identifiers:** Use `ID` not `Id`, `API` not `Api`, `URL` not `Url`, `HTTP` not `Http`
163+
- Examples: `userID`, `getAPI`, `parseURL`, `HTTPClient`
164+
- This applies to variable names, function names, struct fields, etc.
165+
166+
### Code Patterns
167+
168+
- **Keep changes minimal and focused** on the specific issue being addressed
169+
- Prefer explicit over clever code
170+
- Use table-driven tests for behavioral testing
171+
- Comment sparingly - code should be self-documenting
172+
- Follow standard Go conventions (Effective Go, Go proverbs)
173+
- **Test changes thoroughly** before committing
174+
175+
## Common Development Workflows
176+
177+
### Adding a New MCP Tool
178+
179+
1. Add tool implementation in `pkg/github/` (e.g., `foo_tools.go`)
180+
2. Register tool in appropriate toolset in `pkg/github/` or `pkg/toolsets/`
181+
3. Write unit tests following the tool test pattern
182+
4. Run `UPDATE_TOOLSNAPS=true go test ./...` to create snapshot
183+
5. Run `script/generate-docs` to update README
184+
6. Run `script/lint` and `script/test` before committing
185+
7. If e2e tests are relevant, update `e2e/e2e_test.go` using existing test style
186+
8. Commit code + snapshots + README changes together
187+
188+
### Fixing a Bug
189+
190+
1. Write a failing test that reproduces the bug
191+
2. Fix the bug with minimal changes
192+
3. Verify test passes and existing tests still pass
193+
4. Run `script/lint` and `script/test`
194+
5. If tool schema changed, update toolsnaps (see above)
195+
196+
### Updating Dependencies
197+
198+
1. Update `go.mod` (e.g., `go get -u ./...` or manually)
199+
2. Run `go mod tidy`
200+
3. Run `script/licenses` to update license files
201+
4. Run `script/test` to verify nothing broke
202+
5. Commit go.mod, go.sum, and third-party-licenses* files
203+
204+
## Common Errors & Solutions
205+
206+
### "Documentation is out of date" in CI
207+
208+
**Fix:** Run `script/generate-docs` and commit README.md changes
209+
210+
### Toolsnap mismatch failures
211+
212+
**Fix:** Run `UPDATE_TOOLSNAPS=true go test ./...` and commit updated .snap files
213+
214+
### Lint failures
215+
216+
**Fix:** Run `script/lint` locally - it will auto-format and show issues. Fix manually reported issues.
217+
218+
### License check failures
219+
220+
**Fix:** Run `script/licenses` to regenerate license files after dependency changes
221+
222+
### Test failures after changing a tool
223+
224+
**Likely causes:**
225+
1. Forgot to update toolsnaps - run with `UPDATE_TOOLSNAPS=true`
226+
2. Changed behavior broke existing tests - verify intent and fix tests
227+
3. Schema change not reflected in test - update test expectations
228+
229+
## Environment Variables
230+
231+
- **GITHUB_PERSONAL_ACCESS_TOKEN** - Required for server operation and e2e tests
232+
- **GITHUB_HOST** - For GitHub Enterprise Server (prefix with `https://`)
233+
- **GITHUB_TOOLSETS** - Comma-separated toolset list (overrides --toolsets flag)
234+
- **GITHUB_READ_ONLY** - Set to "1" for read-only mode
235+
- **GITHUB_DYNAMIC_TOOLSETS** - Set to "1" for dynamic toolset discovery
236+
- **UPDATE_TOOLSNAPS** - Set to "true" when running tests to update snapshots
237+
- **GITHUB_MCP_SERVER_E2E_TOKEN** - Token for e2e tests
238+
- **GITHUB_MCP_SERVER_E2E_DEBUG** - Set to "true" for in-process e2e debugging
239+
240+
## Key Files Reference
241+
242+
### Root Directory Files
243+
```
244+
.dockerignore - Docker build exclusions
245+
.gitignore - Git exclusions (includes bin/, dist/, vendor/, binaries)
246+
.golangci.yml - Linter configuration
247+
.goreleaser.yaml - Release automation
248+
CODE_OF_CONDUCT.md - Community guidelines
249+
CONTRIBUTING.md - Contribution guide (fork, clone, test, lint workflow)
250+
Dockerfile - Multi-stage Go build
251+
LICENSE - MIT license
252+
README.md - Main documentation (auto-generated sections)
253+
SECURITY.md - Security policy
254+
SUPPORT.md - Support resources
255+
gemini-extension.json - Gemini CLI configuration
256+
go.mod / go.sum - Go dependencies
257+
server.json - MCP server registry metadata
258+
```
259+
260+
### Main Entry Point
261+
262+
`cmd/github-mcp-server/main.go` - Uses cobra for CLI, viper for config, supports:
263+
- `stdio` command (default) - MCP stdio transport
264+
- `generate-docs` command - Documentation generation
265+
- Flags: --toolsets, --read-only, --dynamic-toolsets, --gh-host, --log-file
266+
267+
## Important Reminders
268+
269+
1. **PRIMARY FOCUS:** The local stdio MCP server (github-mcp-server) - this is what you should work on and test with
270+
2. **ALWAYS** trust these instructions first - only search if information is incomplete or incorrect
271+
3. **NEVER** use `script/tag-release` or push tags
272+
4. **NEVER** skip `script/lint` before committing Go code changes
273+
5. **ALWAYS** update toolsnaps when changing MCP tool schemas
274+
6. **ALWAYS** run `script/generate-docs` after modifying tools
275+
7. For specific test files, use `go test ./path -run TestName` not full suite
276+
8. E2E tests require PAT token - you likely cannot run them
277+
9. Toolsnaps are API documentation - treat changes seriously
278+
10. Build/test/lint are very fast (~1s each) - run frequently
279+
11. CI failures for docs-check or license-check have simple fixes (run the script)
280+
12. mcpcurl is secondary - don't break it, but it's not the priority

0 commit comments

Comments
 (0)