Claude Code LSP Plugins: Real Code Intelligence for Claude

Two things. After every file edit Claude makes, the language server reports errors and warnings back, so type errors and missing imports surface without running a compiler. And Claude can navigate code properly — jump to definitions, find references, get type information on hover, list symbols and trace call hierarchies — instead of relying on text search.
No. The plugin configures the connection; you install the binary yourself. If it is missing, the plugin Errors tab shows that the executable was not found on your path, which is exactly what it sounds like. Install the binary for your language and restart.
C and C++, C#, Go, Java, Kotlin, Lua, PHP, Python, Rust, Swift and TypeScript each have a plugin in the official marketplace. For anything else, you can write your own by adding an LSP configuration file to a plugin with the server command, its arguments and a file-extension-to-language mapping.
An entry with an invalid configuration is skipped silently rather than reported, so it shows up in neither the working servers nor the Errors tab. Run Claude Code with the debug flag to see why it was rejected. A server that is configured correctly but whose binary is missing does appear in the Errors tab.
The cost is memory rather than speed, and it depends on the project. Servers such as rust-analyzer and pyright can use a lot on a large repository. If that causes problems, disabling the plugin is reasonable — Claude falls back to its built-in search tools. Monorepos can also produce false unresolved-import diagnostics if the workspace is misconfigured.

Key Takeaway
An LSP plugin connects a language server to Claude Code, which gives Claude two things it otherwise lacks: diagnostics reported back after every edit it makes, and navigation that resolves symbols rather than matching text. The plugin configures the connection; you install the language server binary yourself.
I watched Claude rename a method across a TypeScript codebase by searching for the name, and it did a decent job — right up to a call site in a file where the same name belonged to a different class. Grep cannot tell those apart. A language server can, and the difference is not a small improvement in accuracy but a different kind of operation.
That is the whole argument for installing one, and it takes about two minutes. This post covers what Claude actually gains, the eleven languages with official plugins and the binary each needs, what to do when a server does not start, writing your own configuration for a language nobody has covered, and the two real costs — memory, and false positives in a badly configured monorepo.
Two capabilities, and the first one changes behaviour more than the second. Once a server is running, edits are checked as they happen rather than at the end of a long chain of changes, which means an error introduced in step two gets noticed in step two rather than surviving to whenever someone runs a build.
The two capabilities:
| Capability | What it means in practice |
|---|---|
| Automatic diagnostics | After every file edit Claude makes, the language server reports errors and warnings back. Type errors, missing imports and syntax problems surface without running a compiler or linter, and Claude fixes what it introduced in the same turn |
| Code navigation | Jump to definition, find references, hover for type information, list symbols, find implementations, trace call hierarchies. Availability varies by language and environment, but all of it beats grep on a codebase where names repeat |
You can read the diagnostics yourself. When Claude Code shows an indicator such as three new diagnostic issues in two files, the transcript viewer key opens them. That is worth doing the first few times, because seeing what the server reports tells you whether it is configured correctly far faster than waiting to notice its absence.
The official marketplace carries a plugin for each of these. The pattern is the same every time: install the plugin, install the binary, restart. Nothing installs the binary for you, and the failure when it is missing is clear rather than mysterious.
# Plugin Binary you install yourself
clangd-lsp clangd C / C++
csharp-lsp csharp-ls C#
gopls-lsp gopls Go
jdtls-lsp jdtls Java
kotlin-lsp kotlin-language-server Kotlin
lua-lsp lua-language-server Lua
php-lsp intelephense PHP
pyright-lsp pyright-langserver Python
rust-analyzer-lsp rust-analyzer Rust
swift-lsp sourcekit-lsp Swift
typescript-lsp typescript-language-server TypeScript
/plugin install typescript-lsp@claude-plugins-official
# The plugin configures the connection. It does NOT install the
# binary. "Executable not found in $PATH" in the /plugin Errors
# tab means exactly that and nothing worse.Two failures look similar and mean opposite things. A server that starts and then fails appears in the plugin Errors tab, most often with a message that the executable was not found — which means the binary is not on your path and the fix is to install it. An entry with an invalid configuration is skipped silently instead, so it appears nowhere at all.
That second case is the one that wastes time. If you have added a server and nothing happens, and nothing appears in the Errors tab, assume the configuration is wrong rather than that the feature is not working, and run Claude Code with the debug flag to see the reason. Reloading plugins picks up changes without restarting, and does reload plugin language servers along with everything else.
For anything the official plugins do not cover, a language server is a few lines of JSON in a file at your plugin root. The three fields that matter are the command to run, its arguments, and the mapping from file extension to language identifier. Test it locally with a directory flag before you package it for anyone else.
// .lsp.json at the plugin root — NOT inside .claude-plugin/
{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}
# Test it without installing anything:
claude --plugin-dir ./my-lsp-plugin
# Then check the /plugin Errors tab:
# "Executable not found in $PATH" -> the binary is missing
# nothing listed at all -> the entry was INVALID and
# silently skipped; run
# claude --debug to see why
# /reload-plugins picks up changes without restarting, and does
# reload plugin LSP servers along with everything else.Reading the capability list undersells this, because the interesting part is what stops happening rather than what starts:
The cost is memory, and on a large project it is real. Servers such as the Rust and Python ones can consume a great deal on a big repository, to the point of causing problems on a modest machine. If that happens, disabling the plugin and letting Claude fall back to its built-in search tools is a legitimate answer rather than a defeat.
In a monorepo where the workspace is not configured the way the language server expects, you can get unresolved-import errors for internal packages that build perfectly well. These are false positives and they do not stop Claude editing the code, but they are noise in exactly the channel you installed the server to make trustworthy — so it is worth fixing the workspace configuration rather than learning to ignore the warnings.
Every plugin costs something at startup and in context, so the honest advice is to install a language server for the languages you actually work in and skip the rest. Claude Code helps here: it lists marketplace plugins you installed but have not used in at least two weeks across at least ten sessions, so a plugin you added optimistically eventually tells you it was not needed.
Language server activity counts as use. A server that delivers diagnostics or answers a navigation request marks its plugin as used, so an LSP plugin that is quietly doing its job will not be flagged as unused — which was not always true, and is the reason an old install may have looked idle for a while before it started being counted properly.
Install the plugin for the language you spend most of your time in, install the binary, and read the first few diagnostics yourself so you know the connection is live. If you work in a monorepo, fix the workspace configuration early rather than tolerating false positives, because a diagnostics channel you have learned to ignore is worse than none. And if a server eats your memory on a large repository, turn it off — the built-in search tools are not helpless.
Sources & further reading