Ditch grep and Speed up Claude Code with LSPs

Mar 01, 2026

Grep is a text search. Code is not text — it’s a graph of symbols, types, and call chains. That gap is where Claude wastes most of its time. LSPs close it. Here’s what that looks like in practice. If you’re used to using intelligent LSP tools on modern editors, this is painful to watch.

Take renaming a status field on an Order model for example. status is one of the most common words in any codebase.

⏺ Bash(grep -rn "status" src/)
  ⎿  … +2,847 lines (ctrl+o to expand)

⏺ Bash(grep -rn "order\.status" src/)
  ⎿  src/api/orders.ts:34         if (order.status === 'pending')
     src/models/user.ts:8         status: UserStatus         ← wrong model
     src/api/webhooks.ts:91       response.status            ← HTTP status
     src/models/payment.ts:31     status: PaymentStatus      ← wrong model
     … +31 lines (ctrl+o to expand)

Grep matches the string, not the symbol. order.status catches anything named order with a status property — HTTP response objects, payment models, webhook payloads. Claude has to read each file to tell them apart.

With an LSP, findReferences on the status field in order.ts returns only references to that specific symbol:

⏺ LSP(findReferences, src/models/order.ts:12)
  ⎿  src/api/orders.ts:34
     src/api/orders.ts:67
     src/components/OrderBadge.tsx:8
     src/hooks/useOrderStatus.ts:19
     … +4 locations

9 exact locations. No false positives.

Other operations

That’s just one operation in the LSP specification. It has a bunch of others like (goToDefinition), inspecting a type inline (hover), listing what a class exposes (documentSymbol), finding a class by name across the whole codebase (workspaceSymbol), finding what implements an interface (goToImplementation), and tracing what calls a function (incomingCalls). Claude uses whichever fits the task.

Step 1 — Install the language servers

Each Claude LSP plugin is a thin wrapper — the actual language server binary needs to be on your PATH separately. Install only what you use.

npm i -g pyright                              # Python
npm i -g typescript-language-server typescript # TypeScript / JavaScript
go install golang.org/x/tools/gopls@latest    # Go
rustup component add rust-analyzer            # Rust
brew install jdtls                            # Java
brew install llvm                             # C / C++
dotnet tool install -g csharp-ls              # C#
npm i -g intelephense                         # PHP

Kotlin and Lua don’t have a standard package manager install — grab the latest binary from kotlin-language-server releases or lua-language-server releases and put it on your PATH. Swift ships with Xcode, nothing extra needed.

Step 2 — Install the Claude plugins

Check the official plugins repo for the latest available LSPs before installing. If you need a language not listed there, Piebald-AI/claude-code-lsps maintains a community collection — note this is not the official Anthropic registry, so review the plugin source before installing.

claude plugin install pyright-lsp
claude plugin install typescript-lsp
claude plugin install gopls-lsp
claude plugin install rust-analyzer-lsp
claude plugin install jdtls-lsp
claude plugin install clangd-lsp
claude plugin install csharp-lsp
claude plugin install php-lsp
claude plugin install kotlin-lsp
claude plugin install swift-lsp
claude plugin install lua-lsp

Verify they registered:

claude plugin list

Step 3 — Enable the plugins in settings

Add the plugins you installed to ~/.claude/settings.json. Create the file if it doesn’t exist.

{
  "ENABLE_LSP_TOOL": "1",
  "enabledPlugins": {
    "pyright-lsp@claude-plugins-official": true,
    "typescript-lsp@claude-plugins-official": true,
    "gopls-lsp@claude-plugins-official": true,
    "rust-analyzer-lsp@claude-plugins-official": true,
    "jdtls-lsp@claude-plugins-official": true,
    "clangd-lsp@claude-plugins-official": true,
    "csharp-lsp@claude-plugins-official": true,
    "php-lsp@claude-plugins-official": true,
    "kotlin-lsp@claude-plugins-official": true,
    "swift-lsp@claude-plugins-official": true,
    "lua-lsp@claude-plugins-official": true
  }
}

Only include entries for languages you actually installed.

Step 4 — Restart Claude

The LSP servers are started when Claude Code launches. Restart it to pick up the new plugins and settings.

Step 5 — Verify

Check the debug log to confirm the servers started:

grep "LSP server instance started" ~/.claude/debug/latest

You should see one line per language server, for example:

2026-03-01T13:59:38.874Z [DEBUG] LSP server instance started: plugin:typescript-lsp:typescript
2026-03-01T13:59:38.889Z [DEBUG] LSP server instance started: plugin:gopls-lsp:gopls
2026-03-01T13:59:38.960Z [DEBUG] LSP server instance started: plugin:pyright-lsp:pyright

If a server is missing, check that the LSP’s binary is on your PATH and that the plugin entry is in enabledPlugins.

Once the servers are running, you don’t need to do anything differently. Claude picks up the LSP automatically — the next refactor or call-chain trace just works faster.