lsp-rename — Claude Code skill: safe symbol rename via LSP
Renames functions, methods, variables and types across a workspace in two phases: it lists every affected site first, then edits after you confirm.
npx skills add blackwell-systems/agent-lsp --skill lsp-rename -a claude-codeWhat lsp-rename does
The skill drives the agent-lsp MCP server. It locates the symbol definition, asks the language server whether a rename is valid at that spot, gathers all references and runs a dry run. You get a list of files and lines that would change. Then it stops: no edit lands until you answer “y”.
In the second phase it records diagnostics, performs the rename and compares errors afterwards. The server writes the edit itself, so nothing has to be reassembled from the response — that hand-copying is what used to mangle files with shifted ranges and clipped text.
Nothing runs without agent-lsp up. The skill calls mcp__lsp__start_lsp when the server is not initialized, and switching to another workspace needs an explicit start. If no references come back, it warns that the symbol may be unexported or dead code and asks whether to continue.
What it helps with
- rename a method and update every call site
- see which files change before anything is written
- rename a type or variable without grepping the repo by hand
- check whether the rename introduced new errors
- back out cleanly when the language server refuses the rename
Example prompts for the agent
- Rename
OldNametoNewNameacross the whole workspace - Show me every usage of
parseConfigbefore changing the name - Do a safe rename of the
UserIDsymbol toUserId
How to install lsp-rename
1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-rename -a claude-code2Manually: put the files in place
~/.claude/skills/lsp-rename/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/lsp-rename/
1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-rename -a codex2Manually: put the files in place
.agents/skills/lsp-rename/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-rename -a cursor2Manually: put the files in place
.cursor/skills/lsp-rename/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install blackwell-systems/agent-lsp lsp-rename2Manually: put the files in place
.github/skills/lsp-rename/SKILL.md1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-rename -a gemini-cli2Platform CLI
gemini skills install https://github.com/blackwell-systems/agent-lsp --path skills/lsp-renameManually: put the files in place
.devin/skills/lsp-rename/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-rename -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 lsp-rename
How do I install lsp-rename in Claude Code?
Run npx skills add blackwell-systems/agent-lsp --skill lsp-rename -a claude-code. The skill lands in ~/.claude/skills/lsp-rename/SKILL.md.
What does lsp-rename do?
It renames a symbol across the workspace through LSP. You see the affected sites first, and the edit is applied only after you confirm.
What does the skill need to work?
The agent-lsp MCP server plus a language server that supports referencesProvider, renameProvider and workspaceSymbolProvider. When LSP is not initialized, the skill calls mcp__lsp__start_lsp.
Source text
SKILL.md · MIT
---
name: lsp-rename
description: Two-phase safe rename across the entire workspace. Use when renaming any symbol, function, method, variable, type, or identifier — shows all affected sites before executing atomically via LSP. Never renames without confirmation.
argument-hint: "[old-name] [new-name]"
user-invocable: true
allowed-tools: mcp__lsp__go_to_symbol mcp__lsp__prepare_rename mcp__lsp__find_references mcp__lsp__rename_symbol mcp__lsp__apply_edit mcp__lsp__get_diagnostics
license: MIT
compatibility: Requires the agent-lsp MCP server (github.com/blackwell-systems/agent-lsp)
metadata:
required-capabilities: referencesProvider renameProvider workspaceSymbolProvider
tool_permissions:
phases:
prerequisites:
description: Initialize LSP if needed
allowed: ["mcp__lsp__start_lsp"]
forbidden: []
preview:
description: "Locate symbol, validate rename, enumerate references, dry-run"
allowed:
- "mcp__lsp__go_to_symbol"
- "mcp__lsp__prepare_rename"
- "mcp__lsp__find_references"
- "mcp__lsp__rename_symbol" # dry_run=true only
forbidden:
- "mcp__lsp__apply_edit"
- "Edit"
- "Write"
execute:
description: "Capture pre-rename diagnostics, execute rename (applies directly), verify"
allowed:
- "mcp__lsp__get_diagnostics"
- "mcp__lsp__rename_symbol" # dry_run=false
- "mcp__lsp__apply_edit"
forbidden:
- "mcp__lsp__simulate_*"
- "mcp__lsp__run_build"
global_forbidden:
- "mcp__lsp__format_document" # rename does not format
- "mcp__lsp__run_tests" # rename does not run tests
---
> Requires the agent-lsp MCP server.
# lsp-rename: Safe Symbol Rename
Renames a symbol across the workspace in two phases: preview first, then execute
only after explicit confirmation. Never renames without showing impact.
**Invocation:** User provides `old_name` (the symbol to rename) and `new_name`
(the replacement). Optionally provide `workspace_root` to scope the search.
---
## Prerequisites
If LSP is not yet initialized, call `mcp__lsp__start_lsp` with the workspace
root first. Auto-inference applies when file paths are provided, but an explicit
start is required when switching workspaces.
---
## Phase 1: Preview
Find the symbol, enumerate all references, and produce a dry-run preview.
**Do not apply any edits in this phase.**
### Step 1 — Locate the symbol
Call `mcp__lsp__go_to_symbol` with `symbol_path` set to `old_name`:
```
mcp__lsp__go_to_symbol
symbol_path: "old_name" # or "Package.OldName" for qualified paths
workspace_root: "<root>" # optional; omit to search entire workspace
```
This returns the definition location (file, line, column). If not found, report
the error and stop.
### Step 2 — Validate rename is possible
Call `mcp__lsp__prepare_rename` at the definition location from Step 1:
```
mcp__lsp__prepare_rename
file_path: "<file from Step 1>"
line: <line from Step 1>
column: <column from Step 1>
```
`prepare_rename` asks the language server whether a rename is valid at this
position. If it returns an error (e.g. the symbol is a keyword, a built-in, or
in a location the server cannot rename), **stop immediately** and report:
> Cannot rename `OldName`: <server error message>
> Common causes: built-in or keyword, imported external package, or position is
> not on the symbol name. Try locating the declaration site directly.
Only proceed to Step 3 if `prepare_rename` succeeds.
### Step 3 — Enumerate references
Call `mcp__lsp__find_references` at the definition location from Step 1:
```
mcp__lsp__find_references
file_path: "<file from Step 1>"
position_pattern: "<symbol>@@" # @@ immediately after the symbol name
# fallback: use line/column from Step 1 if position_pattern is unavailable
```
Collect all returned locations. Note the total count and the distinct files.
### Step 4 — Dry-run preview
Call `mcp__lsp__rename_symbol` with `dry_run=true`. **Do not call `apply_edit`.**
```
mcp__lsp__rename_symbol
file_path: "<file from Step 1>"
line: <line from Step 1>
column: <column from Step 1>
new_name: "<new_name>"
dry_run: true
```
The response includes a `workspace_edit` with all proposed changes and a
`preview.note` describing the scope.
### Step 5 — Report impact and hard stop
Display the preview summary to the user:
```
Rename preview: OldName -> NewName
Locations to update: N (from find_references count)
Files affected: M (distinct files in workspace_edit)
Language server: <gopls | typescript-language-server | rust-analyzer | ...>
Changes:
path/to/file1.go lines 12, 45, 78
path/to/file2.go line 3
...
```
**REQUIRED hard stop — do not proceed without explicit user confirmation:**
> Proceed with rename? [y/n]
Wait for user input. Do not apply any edit until the user answers "y" or "yes".
---
## Edge Case: 0 References
If `find_references` returns an empty list (the symbol exists but has no external
usages), warn the user before stopping:
> Warning: no references found for `OldName`. The symbol may be unexported,
> dead code, or the LSP index may be stale. Renaming will update only the
> declaration site.
> Proceed anyway? [y/n]
If user answers "n", stop. If "y", continue to Phase 2.
---
## Phase 2: Execute
Only enter this phase after the user answers "y" or "yes" to the confirmation
prompt in Phase 1.
### Step 1 — Capture pre-rename diagnostics
Before applying changes, capture the current diagnostic state:
```
mcp__lsp__get_diagnostics
file_path: "<one or more files in the workspace_edit>"
```
Store the result as `before_diagnostics`.
### Step 2 — Execute rename (applies directly)
Call `mcp__lsp__rename_symbol` without `dry_run` (or with `dry_run=false`):
```
mcp__lsp__rename_symbol
file_path: "<file from Phase 1 Step 1>"
line: <line from Phase 1 Step 1>
column: <column from Phase 1 Step 1>
new_name: "<new_name>"
```
Without `dry_run`, `rename_symbol` **applies the edit to disk itself** and returns
a summary (`Renamed to "NewName" across N location(s) in M file(s): ...`). Do
**not** call `apply_edit` afterward and do not reconstruct the edit by hand: the
edit never leaves the server as data you copy back, which is what previously
corrupted files (transposed range offsets, truncated `newText`). `apply_edit`
remains for its text-match mode (`file_path` + `old_text` + `new_text`), not for
committing a rename.
### Step 3 — Check diagnostics
Call `mcp__lsp__get_diagnostics` on the affected files and compare against
`before_diagnostics`:
```
mcp__lsp__get_diagnostics
file_path: "<affected files>"
```
Compute introduced vs. resolved errors and display the Diagnostic Summary (see
[references/patterns.md](references/patterns.md)).
---
## Output Format
After Phase 2 completes, display:
```
## Rename Summary
- Old name: OldName
- New name: NewName
- Files changed: M
- Locations updated: N
- Post-rename errors: 0
```
Follow with the Diagnostic Summary if any errors changed (format in
[references/patterns.md](references/patterns.md)).
Only show Diagnostic Summary sections where N > 0. A net change of 0 means the
rename is safe.
---
## Language Support
Tested with `gopls`, `typescript-language-server`, and `rust-analyzer`. Most
LSP-compliant servers support `textDocument/rename` — agent-lsp works with
any of the 30+ supported language servers that advertise rename capability.
Check your server's capability list via `mcp__lsp__get_server_capabilities` if
you are unsure.
© blackwell-systems · MIT · blackwell-systems/agent-lsp