| name | go-source-documentation |
| description | Add idiomatic, godoc-compliant documentation to Go source and test files. Use when user asks to document Go files, add doc comments, improve Go documentation, or mentions /document-go. Covers file headers, package comments, types, functions, interfaces, constants, variables, tests (with detailed explanations), benchmarks, fuzz tests, and examples. |
Go Source Documentation Skill
Activation
Activate this skill when the user:
- Asks to document Go source files or test files
- Asks to add doc comments to Go code
- Asks to improve or fix Go documentation
- Mentions
/document-go or /doc-go
- Asks to add file headers to Go files
- Asks to document a Go package
Prerequisites
Before starting, gather context:
- Read the target file(s) completely to understand structure and purpose
- Read related files in the same package to understand the package API surface
- Check existing tests to understand what behavior the code implements
- Identify the package role within the project architecture
- Use Context7 to verify current Go doc comment conventions if uncertain
Documentation Patterns
Pattern 1: Package Comment
Every package needs exactly one Package comment, typically in the main file or a dedicated doc.go:
package tools
Pattern 2: File Header Comment
For multi-file packages, each file gets a header describing its scope. The header goes immediately before the package declaration:
package tools
Pattern 3: Input Struct Documentation
Input structs define MCP tool parameters. Document the struct purpose and each field's role:
type MRCreateInput struct {
ProjectID string `json:"project_id" jsonschema:"required,description=Project ID or URL-encoded path"`
SourceBranch string `json:"source_branch" jsonschema:"required,description=Source branch name"`
TargetBranch string `json:"target_branch" jsonschema:"required,description=Target branch name"`
Title string `json:"title" jsonschema:"required,description=Title of the merge request"`
Description string `json:"description" jsonschema:"description=Detailed description (Markdown supported)"`
}
Pattern 4: Handler Function Documentation
Handler functions follow the pattern func toolName(ctx, client, input) (output, error):
func mrCreate(ctx context.Context, client *gitlabclient.Client, in MRCreateInput) (MROutput, error) {
Pattern 5: Output Struct Documentation
Output structs define the MCP tool response:
type MROutput struct {
IID int `json:"iid"`
Title string `json:"title"`
State string `json:"state"`
WebURL string `json:"web_url"`
SourceBranch string `json:"source_branch"`
TargetBranch string `json:"target_branch"`
Author string `json:"author"`
}
Pattern 6: Converter/Helper Functions
Internal helpers that transform data between API and MCP formats:
func mrToOutput(mr *gl.MergeRequest) MROutput {
Pattern 7: Registration Functions
Functions that wire tools into the MCP server:
func RegisterBranchTools(srv *server.MCPServer, client *gitlabclient.Client) {
Pattern 8: Test File Documentation
package tools
Pattern 9: Individual Test Function Documentation
Every test MUST have a detailed doc comment explaining:
- What: The specific function, behavior, or scenario being tested
- How: The test setup (mock configuration, inputs, preconditions)
- Expected: The specific assertions and expected outcomes
- Why: The business rule or edge case this test protects
func TestBranchCreate_Success(t *testing.T) {
Error scenario:
func TestBranchCreate_ProjectNotFound(t *testing.T) {
Pattern 10: Table-Driven Test Documentation
Document the overall strategy AND list all covered scenarios:
func TestBranchList_Scenarios(t *testing.T) {
Pattern 11: Test Helper Documentation
func newTestGitLabClient(t *testing.T, handler http.Handler) *gitlabclient.Client {
t.Helper()
Pattern 12: Interface Documentation
Document the contract, not the implementation. List the method set and explain the
behavioral expectations:
type ActionSpecProvider interface {
ActionSpecs(client *gitlabclient.Client) []toolutil.ActionSpec
}
Pattern 13: Deprecation Notices
Use the standard // Deprecated: directive (Go 1.19+) on its own paragraph:
func FormatResponse(data any) string {
Pattern 14: Benchmark and Fuzz Test Documentation
Benchmark tests document the operation being measured and any special setup:
func BenchmarkBranchList(b *testing.B) {
Fuzz tests document the invariant being checked and the seed corpus:
func FuzzParseProjectID(f *testing.F) {
Pattern 15: Example Function Documentation
Example functions appear in godoc under the symbol they demonstrate:
func ExampleNewClient() {
Pattern 16: BUG and TODO Annotations
Use // BUG(who): at package level for known bugs that appear in godoc.
Use // TODO: with a ticket reference for planned work (does NOT appear in godoc):
Decision Framework
For each symbol, decide the documentation level:
| Symbol Type | Exported? | Doc Required? | Level of Detail |
|---|
| Package | — | YES (one per package) | Purpose, scope, key types |
| Type/Struct | Yes | YES | What instances represent |
| Type/Struct | No | If non-obvious | Brief purpose |
| Interface | Yes | YES | Contract, behavioral expectations, concurrency |
| Function | Yes | YES | What it does, params, errors |
| Function | No | If non-obvious | Brief purpose |
| Method | Yes | YES | Start with receiver context |
| Const/Var group | Yes | YES | Group purpose |
| Const/Var group | No | If non-obvious | Brief purpose |
| Test function | — | YES | What/How/Expected/Why |
| Test helper | — | YES | What it creates/configures |
| Benchmark | — | YES | Operation measured, setup |
| Fuzz test | — | YES | Invariant, seed corpus |
| Example func | — | YES | What it demonstrates |
| Deprecation | — | YES | Deprecated: + replacement |
Validation Steps
After documenting each file:
- Analysis check:
golangci-lint run --build-tags e2e ./path/to/package/...
- Build check:
go build ./path/to/package/...
- Test check:
go test ./path/to/package/...
- Doc check:
go doc ./path/to/package — verify all exported symbols appear
- No logic changes: Confirm only comments were added/modified
Common Mistakes to Avoid
-
Changing code logic — NEVER modify function bodies, signatures, or variable names
-
Blank line between comment and declaration — renders as regular comment, not doc comment:
package branches
-
Not starting with symbol name — go doc synopsis will be wrong
-
Using block comments for doc comments — use // line comments (block /* */ style is non-idiomatic for doc comments)
-
Redundant comments — don't restate what the code already says clearly
-
Missing error documentation — always document when/why errors are returned
-
Forgetting test docs — test functions MUST have detailed documentation
-
Inconsistent tense — use present tense ("creates", "returns", not "will create")
-
Missing package comment — one file per package must have // Package name ...
-
Over-documenting — a clear name like UserID string doesn't need a comment saying "the user's ID"
-
Headings without blank line before — Go 1.19+ headings (# Heading) must have a blank // line before them
-
Doc links to unexported symbols — [unexportedFunc] won't resolve; only link to exported symbols
Project-Specific Notes
This project (gitlab-mcp-server) has specific patterns to recognize:
- MCP tool input structs have
jsonschema tags — mention the tool parameters they define
- Handler functions follow
func name(ctx, client, input) (output, error) — document the API operation
- ActionSpec functions describe canonical route metadata — document which actions and surfaces they feed
- Tests use
httptest — mention the API endpoint being mocked and HTTP method
- Constants like endpoint paths — document they are test fixtures for specific API routes
gitlabclient.Client wraps the GitLab API — reference it as [gitlabclient.Client]
toolutil helpers — reference using doc links: [toolutil.WrapErr], [toolutil.BuildPaginationResponse]
- Catalog registration — ordinary GitLab actions flow through
ActionSpecs and the canonical action catalog; package-level meta registration is historical compatibility context only