78 lines
4.8 KiB
Markdown
78 lines
4.8 KiB
Markdown
# gopls MCP server & native `LSP` tool reference
|
|
|
|
## Table of contents
|
|
|
|
- [Starting the server](#starting-the-server)
|
|
- [Registering with Claude Code](#registering-with-claude-code)
|
|
- [MCP tools](#mcp-tools)
|
|
- [The native `LSP` tool](#the-native-lsp-tool)
|
|
- [What the MCP server can and cannot do](#what-the-mcp-server-can-and-cannot-do)
|
|
|
|
## Starting the server
|
|
|
|
A standalone gopls instance speaking MCP over stdin/stdout, launched fresh per session, no LSP client involved:
|
|
|
|
```bash
|
|
gopls mcp
|
|
```
|
|
|
|
Only sees files as they exist **on disk** — an edit made through a different tool but not yet saved is invisible to it. This is the right mode for an agent-only workflow with no attached editor.
|
|
|
|
## Registering with Claude Code
|
|
|
|
```bash
|
|
claude mcp add gopls -- gopls mcp
|
|
```
|
|
|
|
## MCP tools
|
|
|
|
Eight tools, all keyed by name/path/query rather than cursor position — this is the main ergonomic difference from the native `LSP` tool.
|
|
|
|
| Tool | Purpose | Example |
|
|
| --- | --- | --- |
|
|
| `go_workspace` | Learn the workspace's overall structure — module, multi-module workspace, or GOPATH project. Call this first, once per session. | `go_workspace({})` |
|
|
| `go_vulncheck` | On-demand reachability check: which known vulnerabilities does the _current_ build actually reach. Run right after `go_workspace` if in a Go workspace, and again after any `go.mod` change. | `go_vulncheck({"pattern":"./..."})` |
|
|
| `go_search` | Fuzzy search for a type, function, or variable by name across the workspace — use when you don't know the exact location. | `go_search({"query":"server"})` |
|
|
| `go_file_context` | Summarize a file's dependencies on other files in the _same package_. Run this immediately after reading any Go file for the first time. | `go_file_context({"file":"/path/to/server.go"})` |
|
|
| `go_package_api` | Show a package's public API — most valuable for third-party dependencies or sibling packages in a monorepo you haven't read file-by-file. | `go_package_api({"packagePaths":["example.com/internal/storage"]})` |
|
|
| `go_symbol_references` | Find every reference to a symbol — run before modifying any definition to gauge the blast radius. | `go_symbol_references({"file":"/path/to/server.go","symbol":"Server.Run"})` |
|
|
| `go_diagnostics` | Build/analysis errors for the given files — mandatory after every edit. | `go_diagnostics({"files":["/path/to/server.go"]})` |
|
|
| `go_rename_symbol` | Rename a symbol and every reference to it, workspace-wide, with the same safety checks as LSP rename (blocks changes that would break interface satisfaction). | — |
|
|
|
|
See [SKILL.md](../SKILL.md#efficient-workflows) for the Read/Edit workflow order these tools are designed to be chained in.
|
|
|
|
## The native `LSP` tool
|
|
|
|
Claude Code's built-in editor-style integration — a different mechanism from the MCP server above, worth wiring in addition to it, not instead of it.
|
|
|
|
**Enabling it:**
|
|
|
|
1. Set the environment variable `ENABLE_LSP_TOOL=1` (off by default).
|
|
2. Install `gopls` (`go install golang.org/x/tools/gopls@latest`).
|
|
3. Install the official `gopls-lsp@claude-plugins-official` marketplace plugin to wire `gopls` as the Go language server backing the tool.
|
|
|
|
**Operations**, all keyed by `line`/`character` rather than name/path:
|
|
|
|
- `goToDefinition`
|
|
- `findReferences`
|
|
- `hover`
|
|
- `documentSymbol`
|
|
- `workspaceSymbol`
|
|
- `goToImplementation`
|
|
- call hierarchy
|
|
|
|
`goToTypeDefinition` is intentionally absent from this list — the native tool does not expose it, so type-definition navigation has no agent-invocable path (see [features.md](features.md#navigation)).
|
|
|
|
Because these need a location up front, they're most efficient once you already have one — right after a grep or a file read — rather than as the first move in an investigation (that's what `go_search` on the MCP server is for).
|
|
|
|
**Its unique value:** compiler diagnostics are pushed into context **automatically after every edit**, with no explicit diagnostics call needed — the MCP server's `go_diagnostics` requires an explicit invocation each time.
|
|
|
|
## What the MCP server can and cannot do
|
|
|
|
The gopls MCP server wraps LSP functionality with these boundaries:
|
|
|
|
- **Can**: read files from the filesystem and return their contents; execute `go` commands to load package metadata (which may reach `proxy.golang.org` and write to the local Go module/build cache); write to gopls's own cache/configuration files; upload telemetry if the user has opted in.
|
|
- **Cannot**: make arbitrary writes to the source tree outside of the edits a tool call explicitly returns; make arbitrary network requests beyond what `go` itself needs to resolve the build.
|
|
|
|
Either mode — MCP or native `LSP` — only ever reasons about code that is present and resolvable in the local build: the workspace plus every dependency exactly as pinned in `go.sum`, including `replace` directives. For anything outside that boundary, → See `samber/cc-skills-golang@golang-pkg-go-dev` skill (`godig`).
|