lsp-simulate
About
The lsp-simulate skill enables developers to safely test and explore code changes in memory before applying them to disk. It uses an LSP server overlay to simulate multi-file edits, run diagnostics, and verify safety without touching actual files. This is ideal for planning risky refactors or validating complex changes across a workspace.
Quick Install
Claude Code
Recommendednpx skills add blackwell-systems/agent-lsp -a claude-code/plugin add https://github.com/blackwell-systems/agent-lspgit clone https://github.com/blackwell-systems/agent-lsp.git ~/.claude/skills/lsp-simulateCopy and paste this command in Claude Code to install this skill
Documentation
Requires the agent-lsp MCP server.
lsp-simulate
Simulate code edits in memory before writing to disk. The LSP server applies your changes to an in-memory overlay, runs diagnostics, and reports whether the edit is safe — without touching any files.
Prerequisites
LSP must be running for the target workspace. If not yet initialized, call
start_lsp before any simulation tool.
mcp__lsp__start_lsp(root_dir: "/your/workspace")
Auto-init note: agent-lsp supports workspace auto-inference from file paths.
Explicit start_lsp is only needed when switching workspace roots.
Quick Start (single edit)
For a single what-if check, use preview_edit — it creates a session,
applies the edit, evaluates, and destroys the session in one call:
mcp__lsp__preview_edit(
workspace_root: "/your/workspace",
language: "go",
file_path: "/abs/path/to/file.go",
start_line: 42, start_column: 1,
end_line: 42, end_column: 20,
new_text: "replacement text"
)
Result:
{ net_delta: 0 } -- safe to apply
{ net_delta: 2 } -- 2 new errors introduced; do NOT apply
net_delta: 0 means no new errors were introduced. Positive values mean
errors were introduced — inspect errors_introduced before deciding.
Full Session Workflow (multiple edits)
Use a full session when applying several edits that build on each other, or when you want to inspect the patch before deciding whether to write to disk.
Step 1 — Create a simulation session
mcp__lsp__create_simulation_session(
workspace_root: "/your/workspace",
language: "go"
)
→ { session_id: "abc123" }
Step 2 — Apply edits in-memory
Call simulate_edit one or more times. All edits are in-memory only.
Positions are 1-indexed (matching editor line numbers and cat -n output).
mcp__lsp__simulate_edit(
session_id: "abc123",
file_path: "/abs/path/to/file.go",
start_line: 10, start_column: 1,
end_line: 10, end_column: 30,
new_text: "func NewClient(cfg Config) *Client {"
)
→ { session_id: "abc123", edit_applied: true, version_after: 1 }
Repeat for additional edits as needed.
Step 3 — Evaluate the session
mcp__lsp__evaluate_session(
session_id: "abc123",
scope: "file"
)
→ {
net_delta: 0,
confidence: "high",
errors_introduced: [],
errors_resolved: [],
edit_risk_score: 0.0,
affected_symbols: []
}
scope: "file" (default) is faster and returns confidence: "high".
scope: "workspace" catches cross-file type errors but returns
confidence: "eventual" (results may not be fully settled).
Step 4 — Decision gate
If net_delta == 0, proceed to commit. Otherwise, discard:
mcp__lsp__discard_session(session_id: "abc123")
Step 5 — Commit the session
-- Preview patch only (no disk write):
mcp__lsp__commit_session(session_id: "abc123", apply: false)
-- Write to disk:
mcp__lsp__commit_session(session_id: "abc123", apply: true)
Step 6 — Destroy the session (always)
mcp__lsp__destroy_session(session_id: "abc123")
Always call destroy_session after commit or discard to release server
resources. See Cleanup Rule below.
Chained Mutations (simulate_chain)
Use simulate_chain when you have a sequence of edits and want to find
how far through the sequence is safe to apply. Unlike multiple simulate_edit
calls, simulate_chain evaluates diagnostics after each step.
mcp__lsp__simulate_chain(
session_id: "abc123",
edits: [
{ file_path: "/abs/file.go", start_line: 5, start_column: 1,
end_line: 5, end_column: 40, new_text: "type Foo struct { Bar int }" },
{ file_path: "/abs/file.go", start_line: 20, start_column: 1,
end_line: 20, end_column: 10, new_text: "f.Bar" },
{ file_path: "/abs/other.go", start_line: 8, start_column: 1,
end_line: 8, end_column: 10, new_text: "x.Bar" }
]
)
→ {
steps: [
{ step: 1, net_delta: 0, errors_introduced: [] },
{ step: 2, net_delta: 0, errors_introduced: [] },
{ step: 3, net_delta: 1, errors_introduced: [...] }
],
safe_to_apply_through_step: 2,
cumulative_delta: 1
}
safe_to_apply_through_step: 2 means steps 1 and 2 are safe; step 3
introduced errors. Commit the session after reviewing to apply steps 1–2,
or discard to cancel everything.
Decision Guide
| net_delta | confidence | Action |
|---|---|---|
| 0 | high | Safe. Commit or apply. |
| 0 | eventual | Likely safe. Workspace scope — re-evaluate if risk matters. |
| > 0 | any | Do NOT apply. Inspect errors_introduced. Discard session. |
| > 0 | partial | Timeout. Results incomplete. Discard and retry with smaller scope. |
Session States
| State | Meaning | Next step |
|---|---|---|
| created | Session initialized, no edits yet | simulate_edit |
| mutated | One or more edits applied in-memory | evaluate_session |
| evaluated | Diagnostics collected | commit or discard |
| committed | Patch returned (and optionally written to disk) | destroy_session |
| discarded | In-memory edits reverted, no disk write | destroy_session |
| dirty | Revert failed or version mismatch; session is inconsistent | destroy_session only |
A session in dirty state cannot be recovered — call destroy_session immediately.
Cleanup Rule
Always call destroy_session after finishing a session, even on error paths:
-- After commit:
mcp__lsp__commit_session(session_id: "abc123", apply: true)
mcp__lsp__destroy_session(session_id: "abc123")
-- After discard:
mcp__lsp__discard_session(session_id: "abc123")
mcp__lsp__destroy_session(session_id: "abc123")
MCP server restart: Sessions are ephemeral — they live in server memory
only. If the MCP server restarts, all session IDs become invalid. To preserve
work across a restart, call commit_session(apply: false) first to get a
portable patch, then re-apply it after the server restarts.
See references/patterns.md for detailed field descriptions and confidence interpretation.
GitHub Repository
Related Skills
qmd
Developmentqmd is a local search and indexing CLI tool that enables developers to index and search through local files using hybrid search combining BM25, vector embeddings, and reranking. It supports both command-line usage and MCP (Model Context Protocol) mode for integration with Claude. The tool uses Ollama for embeddings and stores indexes locally, making it ideal for searching documentation or codebases directly from the terminal.
subagent-driven-development
DevelopmentThis skill executes implementation plans by dispatching a fresh subagent for each independent task, with code review between tasks. It enables fast iteration while maintaining quality gates through this review process. Use it when working on mostly independent tasks within the same session to ensure continuous progress with built-in quality checks.
mcporter
DevelopmentThe mcporter skill enables developers to manage and call Model Context Protocol (MCP) servers directly from Claude. It provides commands to list available servers, call their tools with arguments, and handle authentication and daemon lifecycle. Use this skill for integrating and testing MCP server functionality in your development workflow.
adk-deployment-specialist
DevelopmentThis skill deploys and orchestrates Vertex AI ADK agents using A2A protocol, managing AgentCard discovery, task submission, and supporting tools like Code Execution Sandbox and Memory Bank. It enables building multi-agent systems with sequential, parallel, or loop orchestration patterns in Python, Java, or Go. Use it when asked to deploy ADK agents or orchestrate agent workflows on Google Cloud.
