go-semantic-tools — Claude Code skill: analyze Go code by type
Finds function calls, interface implementations, and dependency graphs in Go via gopls and go list, not text search. Understands implicit interfaces, embedding, and cross-package dependencies that grep misses.
npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a claude-codeWhat go-semantic-tools does
The skill uses Go's semantic toolchain instead of regex. gopls references locates every call to a function—including calls through interfaces and hidden dependencies. gopls implementation shows which types satisfy an interface or which interfaces a type fulfills. go list maps the package dependency graph, go doc prints the API without implementation clutter.
Includes ready-made workflows: before changing a function, find all its callers; before adding to an interface, list every implementation; before refactoring, verify architectural layering through the import graph. gopls rename -w renames a symbol everywhere, not confusing UserID as a field with UserID as a local variable. gopls check and go vet deliver diagnostics without opening an editor.
Requires Go toolchain and gopls v0.20+. Works via MCP server for agents or CLI. Text search remains the tool for string literals, comments, and code that doesn't compile yet.
What it helps with
- find all callers of a function through interfaces and embedding
- list which types implement an interface before modifying it
- verify the import graph and confirm architectural boundaries
- rename a symbol correctly everywhere it is used
- explore an unfamiliar package through its exported API
Example prompts for the agent
- Find every place where the
Processfunction ininternal/service/user.goline 42 is called - Show me which types satisfy the
Storeinterface defined ininternal/store/store.go - What's the dependency graph for the
internal/paymentspackage?
How to install go-semantic-tools
1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a claude-code2Manually: put the files in place
~/.claude/skills/go-semantic-tools/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/go-semantic-tools/
1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a codex2Manually: put the files in place
.agents/skills/go-semantic-tools/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a cursor2Manually: put the files in place
.cursor/skills/go-semantic-tools/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install eduardo-sl/go-agent-skills go-semantic-tools2Manually: put the files in place
.github/skills/go-semantic-tools/SKILL.md1Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a gemini-cli2Platform CLI
gemini skills install https://github.com/eduardo-sl/go-agent-skills --path 'skills/(workflow)/go-semantic-tools'Manually: put the files in place
.devin/skills/go-semantic-tools/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about go-semantic-tools
How do I install go-semantic-tools in Claude Code?
Run npx skills add eduardo-sl/go-agent-skills --skill go-semantic-tools -a claude-code, then check ~/.claude/skills/go-semantic-tools/SKILL.md.
What does go-semantic-tools do?
It finds function call sites, interface implementations, dependency graphs, and performs refactoring using type-aware gopls and go list commands. It sees relationships grep cannot.
How is go-semantic-tools different from grep?
grep searches text; gopls references searches symbols by type—it won't confuse UserID in different contexts and will find calls through interfaces. Use grep for literals and comments, gopls for code.
Source text
SKILL.md · MIT
---
name: go-semantic-tools
description: >
Navigate and analyze Go codebases semantically with the toolchain instead
of text search: gopls via its MCP server or CLI (references,
implementations, call hierarchy, rename, extract/inline code actions,
diagnostics), go list for the dependency graph, go doc for APIs. Use when:
"find all callers", "who implements this interface", "where is this used",
"trace the dependency graph", "explore this codebase", "find usages before
changing", "map the module".
Not for: performing the refactor (go-refactoring), judging the
architecture (go-architecture-review), writing documentation
(go-documentation).
user-invocable: true
license: MIT
compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain. Requires gopls (go install golang.org/x/tools/gopls@latest); v0.20+ for the MCP server.
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(gofmt:*) Bash(gopls:*)
metadata:
author: eduardo-sl
version: "1.2.0"
---
# Go Semantic Tools
grep finds strings; the toolchain finds meaning. Method names repeat
across types, interfaces are satisfied implicitly, and dot-imports lie
to text search. Before changing shared code, get the truth from tools
that understand types.
Detailed reference material, loaded on demand:
- `references/mcp-and-code-actions.md` — `gopls mcp` setup and tools, the
read/edit loop, CLI code actions, build-tag gotchas.
Read a reference file only when the summary below is not enough.
## 0. Pick the Interface
| Interface | Prefer it when |
|---|---|
| gopls MCP server (`gopls mcp`, v0.20+) | Working as an agent — tools take symbol names and file paths, not cursor positions |
| The harness's built-in LSP integration, if enabled | You already have a position, and want diagnostics pushed after every edit |
| `gopls` CLI (below) | Scripts and one-off checks; the Go team documents it as a debugging interface |
With the MCP server, follow its loop: `go_symbol_references` before
changing a definition, `go_diagnostics` after every edit until clean,
`go_vulncheck` after `go.mod` changes, then `go test` on the changed
packages only. Setup and the tool list: `references/mcp-and-code-actions.md`.
## 1. Choose the Tool
| Question | Command |
|---|---|
| Where is this symbol used? | `gopls references file.go:LINE:COL` |
| Where is it defined? | `gopls definition file.go:LINE:COL` |
| Who implements this interface? / which interfaces does this type satisfy? | `gopls implementation file.go:LINE:COL` |
| Who calls this function (transitively)? | `gopls call_hierarchy file.go:LINE:COL` |
| What's in this package's API? | `go doc ./internal/service` / `go doc pkg Symbol` |
| Which packages exist / depend on what? | `go list ./...`, `go list -deps`, `go list -json` |
| Find a symbol by name across the module | `gopls workspace_symbol Name` |
| Symbols in one file | `gopls symbols file.go` |
Positions are `file.go:line:column` (1-based). Get line/column from a
prior search or `gopls symbols`. All gopls commands run from within the
module and need a warm build cache — run `go build ./...` once first.
## 2. Standard Investigation Flows
### Before changing a function
```bash
gopls references internal/service/user.go:42:6 # every call site, typed
gopls call_hierarchy internal/service/user.go:42:6
```
Text search for `Process(` would surface every type's `Process`;
`references` returns only this one's call sites — including usages via
interfaces and embeddings that grep cannot see.
### Mapping an interface
```bash
# On the interface name: all implementations
gopls implementation internal/store/store.go:15:6
# On a method of a concrete type: interfaces it satisfies
gopls implementation internal/store/postgres/user.go:30:18
```
Run this before adding a method to an interface — every implementation
listed will break.
### Understanding the dependency graph
```bash
go list ./... # all packages
go list -f '{{.ImportPath}} -> {{join .Imports " "}}' ./... # direct edges
go list -deps ./cmd/api | grep myorg # everything a binary pulls in
go list -json ./internal/service | jq .Imports # machine-readable
```
Use this to verify layering claims ("domain imports nothing") instead
of trusting directory names.
### Exploring an unfamiliar API
```bash
go doc ./internal/payments # package overview
go doc ./internal/payments Gateway # one symbol, with doc comment
go doc -all ./internal/payments # full API surface
```
Prefer this to opening files: it shows the exported contract without
implementation noise.
## 3. Semantic Rename
```bash
gopls rename -w internal/service/user.go:42:6 ProcessOrder
```
Renames the symbol everywhere it's referenced — through interfaces,
embedding, and test packages. Never rename an identifier with
find-and-replace; `UserID` the field and `UserID` the local variable
are different symbols with the same spelling.
## 4. Diagnostics Without an Editor
```bash
gopls check ./internal/... # type errors + analyzer findings per file
go vet ./... # the vet suite standalone
```
`gopls check` surfaces the same diagnostics an IDE user sees — run it
when reviewing code you haven't opened in an editor.
## 5. Refactoring Code Actions
```bash
gopls codeaction internal/order/service.go:42:2-58:3 # list
gopls codeaction -kind=refactor.extract.function -exec -diff \
internal/order/service.go:42:2-58:3 # preview
```
Extract (function, method, variable, constant, to new file), inline call,
fill struct/switch, invert `if`, remove an unused parameter at every call
site — each type-aware, unlike a hand edit. Diff before writing; extract
and inline are best-effort with comments.
## 6. When grep Is Still Right
- String literals: log messages, SQL, config keys, error text.
- Comments, TODOs, documentation.
- Code that doesn't compile yet — gopls needs a type-checkable package;
grep works on broken trees.
- Quick existence checks ("is this env var referenced anywhere?").
Rule of thumb: identifiers → gopls; literals and prose → grep.
## Verification Checklist
1. Call sites enumerated with `gopls references` (not grep) before changing any shared symbol
2. Interface changes preceded by `gopls implementation` on the interface
3. Renames performed with `gopls rename -w`, never text replacement
4. Layering assumptions verified with `go list` import data
5. Unfamiliar packages explored via `go doc` before reading implementations
6. `gopls check` / `go vet` run when reviewing without an editor
7. grep reserved for literals, comments, and non-compiling code
8. Diagnostics checked after every edit (MCP `go_diagnostics` or `gopls check`)
9. Cross-platform symbols queried with the matching `GOOS`/build tags
© eduardo-sl · MIT · eduardo-sl/go-agent-skills