Without a language server attached, Claude edits your code the same
way text search does — it can find where a string appears, but it has
no idea whether the edit it just made actually type-checks. A code
intelligence plugin changes that: Claude Code connects to the same
language server your editor uses, over the real Language Server
Protocol, and gets two things back — diagnostics after every edit, and
an LSP tool for navigating by symbol instead of by grep.
That second part is concrete, not vague “better understanding”: Claude can jump to a symbol’s definition, find every reference to it, get type information at a position, list the symbols in a file, search for a symbol by name across the whole workspace, find the implementations of an interface, and trace call hierarchies. All read-only, no permission prompt.
Setup is the same shape for every language #
Install the language server binary, install the matching plugin, then edit a file to confirm it started:
| Language | Plugin | Binary | Install the binary |
|---|---|---|---|
| Java | jdtls-lsp |
jdtls |
see the plugin’s README |
| Python | pyright-lsp |
pyright-langserver |
see the plugin’s README |
| TypeScript / Next.js | typescript-lsp |
typescript-language-server |
npm install -g typescript-language-server typescript |
Then install the plugin itself, from your shell (no session needed — handy in a setup script):
claude plugin install jdtls-lsp@claude-plugins-official(swap jdtls-lsp for pyright-lsp or typescript-lsp as needed).
Running /plugin install the same way inside a session doesn’t
install right away — it opens a review panel where you still pick a
scope (user, project, or local) before anything’s installed. Either
path, the install summary tells you what’s next: Plugin is now active means nothing more to do, Run /reload-plugins to apply means
run that in the open session rather than restarting it.
Confirm the binary is actually on the PATH of the shell you launched
claude from — which jdtls, which pyright-langserver, or which typescript-language-server — before you assume the plugin install is
the problem if nothing happens.
Watching it actually work — Java #
Ask Claude to introduce a real type error, then fix it. The first edit
after jdtls-lsp is installed starts the server, and you’ll see a line
under that edit:
Found 1 new diagnostic issues in 1 files (ctrl+o to expand)That’s jdtls reporting a real type error back through the LSP tool —
not Claude guessing from reading the file, an actual compiler-grade
check. Press Ctrl+O to expand and read it. Fix the error, edit
again, and the line updates to reflect the server’s live state.
Python and Next.js, same mechanics #
For Python, pyright-lsp gives the identical behavior —
pyright-langserver reports diagnostics after each edit and backs the
same LSP tool for jump-to-definition and find-references across your
modules.
For a Next.js project, typescript-lsp covers both .ts and .tsx,
so it’s one plugin for your API routes and your React components —
Claude gets prop-type errors on a component the same way it gets a
type mismatch in a route handler, through the same diagnostics line.
claude --cloud), Claude Code doesn’t start plugin language
servers at all — no diagnostics, no LSP tool, regardless of what’s
installed.
Why bother #
The real payoff isn’t autocomplete-style convenience — it’s that Claude catches its own mistakes before you do. An edit that introduces a missing import or a type mismatch gets flagged in the same turn it happened, instead of surfacing later when you run the build yourself. For a multi-file change, that’s the difference between Claude fixing its own regression immediately and you finding it three commits later.