Persona: You are a Go engineer who reaches for semantic code intelligence instead of grep whenever a question is about the resolved build — grep finds text,
finds meaning (types, call graphs, shadowing, implementation relationships).
Dependencies: —
go install golang.org/x/tools/gopls@latest
(v0.20+). The native
tool additionally needs
and the
gopls-lsp@claude-plugins-official
marketplace plugin (see
references/mcp.md).
is the official Go language server. It only answers questions about
your specific, locally resolved build — your workspace plus every dependency exactly as pinned in
, including
directives. For a package that isn't part of that build (versions, docs, licenses, CVEs of something you haven't added yet), → See
samber/cc-skills-golang@golang-pkg-go-dev
skill (
) instead.
Three ways to reach gopls
Not interchangeable — pick by what you already know and what you need back:
- gopls's own MCP server (preferred for most tasks) — purpose-built for agents: tools take names, file paths, and fuzzy queries instead of raw cursor positions. Register once per machine:
claude mcp add gopls -- gopls mcp
. Runs headless over stdio, no editor attached, only sees files saved to disk — the right default for an agent-only workflow. See references/mcp.md for every tool.
- The native tool — Claude Code's built-in editor-style integration. Off by default: set , install , and install the official
gopls-lsp@claude-plugins-official
marketplace plugin to wire it as the Go language server. Operations (, , , , , , call hierarchy) are keyed by /, so they're most useful once you already have a location — typically right after a grep or a read. Unique value: compiler diagnostics are pushed into context automatically after every edit, no explicit call needed.
- The CLI — same engine, invoked as
gopls <command> <file:line:col>
. The Go team documents it as experimental and debugging-only — "not efficient, complete, flexible, or officially supported." Use it when neither MCP nor the native tool is wired up, or for a one-shot scripted check. Positions are (1-indexed, UTF-8 bytes) or (0-indexed). See references/cli.md.
Preference order: MCP → native → CLI. MCP tools match how an agent thinks (by name/path, not cursor position); the native tool adds free automatic diagnostics; the CLI is the documented fallback of last resort. Wire as many as are available and let the task pick the tool — a query you already have a
for is cheap via
, a "where is X" query is cheap via
, a quick unattended check is cheap via the CLI.
Capability → CLI → MCP → native LSP
Full mapping of every capability to its CLI command, MCP tool, and native
op:
references/matrix.md.
Use cases
- Navigation — jump to a definition, an implementation, or trace a call graph before touching code you didn't write. Details: references/features.md.
- Code discovery — learn a workspace's shape (), fuzzy-search a symbol you can't place exactly (), or read a dependency's public surface () before using it.
- Documentation — hover for type/doc/size info, signature help while calling a function, or browse rendered package docs (, including internal packages pkg.go.dev never sees).
- Diagnostics & safety — compiler and analyzer errors after every edit ( / automatic with ), plus a lightweight reachability check: once as a baseline right after detecting the workspace, and again after any change.
- Formatting — canonical -equivalent formatting and import organization, both scriptable and code-action-driven.
- Refactoring — safe rename (blocks a change that would break interface satisfaction), extract/inline, and the full family (fill struct/switch, invert if, split/join lines, remove unused parameter, add struct tags, implement interface). Full catalog with gotchas: references/features.md.
Efficient workflows
These Read/Edit workflows encode the order that avoids redundant queries and half-applied edits — treat every step as required, not optional, even to save a round trip.
- Session start — call once to detect whether this is a Go workspace at all; if it is, immediately follow with a baseline to surface vulnerabilities the workspace already carries. This is unconditional, separate from the edit workflow's later check after a dependency change.
Read workflow (understand before touching anything):
- — layout (module/workspace/GOPATH); same call as the session-start check above if it hasn't run yet.
- — fuzzy-locate a type/function/variable by name.
- — right after reading any Go file for the first time, see what it pulls in from the rest of its package; re-run if that file's dependencies change.
- — a third-party dependency's or sibling package's public surface, without reading every file.
Edit workflow (iterate until diagnostics are clean):
- Read first (workflow above).
- before modifying any definition — judge the blast radius, then read every referencing file that needs a matching edit.
- Make all planned edits, including the reference-site edits, before moving on.
- on every changed file — mandatory after each modification, not an optional cleanup pass.
- Fix reported errors: review any suggested quick-fix diff before applying, then re-run diagnostics to confirm the fix landed. Ignore hint/info diagnostics unrelated to the task. A diagnostic message can paraphrase the surrounding source rather than quote it verbatim.
- Only if dependencies changed, run on the whole workspace — after diagnostics are clean, not before.
- Run
go test <changed-package-paths>
— not unless explicitly asked, since a full-repo run slows the iteration loop.
Gotchas worth knowing before you rely on a result:
- results only reflect the build configuration of the queried file — a query on will not surface matches in ; re-run under the relevant /build tags if a cross-platform result is missing.
- only shows static calls — calls through function values or interface methods are invisible to it; corroborate with when the call site matters.
- Extract/inline refactors are less rigorous than rename: comments are sometimes dropped, and generated files marked receive no code actions at all.
refactor.rewrite.fillStruct
searches only the current file above the cursor and needs the struct's package already imported — run first if the type was just typed in.
gopls vs godig vs Context7 vs govulncheck
only reasons about code present and resolvable in the local build:
- For anything not tied to that build (version history, license, ecosystem-wide importers, CVEs of a package not yet added) → See
samber/cc-skills-golang@golang-pkg-go-dev
skill () — it queries pkg.go.dev directly, no local checkout needed.
- For a comprehensive, whole-tree vulnerability audit (CI gates, periodic sweeps) rather than gopls's lightweight on-demand → See
samber/cc-skills-golang@golang-security
skill ().
- Context7 remains a fallback for non-Go docs or a Go module not indexed on pkg.go.dev.
The full task-to-tool matrix lives in the
samber/cc-skills-golang@golang-how-to
skill's "
vs gopls vs Context7 vs govulncheck" section.