Skip to content

Add MCP Server support to LSP4IJ to expose LSP and DAP features as MCP tools #1581

Description

@angelozerr

Add MCP Server support to LSP4IJ

Context: existing MCP servers for LSP and DAP

Several projects already expose LSP and DAP features as MCP tools, which is a great idea: it allows AI assistants to leverage language intelligence (diagnostics, completions, hover, rename, code actions...) or debugging capabilities (breakpoints, call stack, variable inspection...) directly from their MCP client.

Existing LSP MCP projects:

  • lsp-mcp — spawns a language server as a subprocess and acts as an LSP client to expose features as MCP tools
  • Language-Server-MCP-Bridge — a universal VSCode extension that bridges LSP capabilities to MCP tools, but runs externally to the IDE
  • cclsp

Existing DAP MCP projects:

  • Similar approaches exist for DAP, spawning a debug adapter externally and acting as a DAP client

The problem with these approaches

All these projects share the same fundamental architecture: they spawn the language or debug server as an external subprocess and implement their own LSP/DAP client to communicate with it. This leads to several significant issues:

  • Double process: the language server is started twice — once by the IDE, once by the MCP bridge — consuming extra memory and CPU
  • No shared state: the MCP bridge has its own LSP/DAP client instance, completely disconnected from what the IDE sees. Diagnostics, caches, indexes, and document state can diverge
  • No project context: the bridge starts the language server naively, without the configuration, workspace setup, or initialization options that the IDE provides
  • No support for custom LSP requests/notifications: each language server can define proprietary extensions (e.g. rust-analyzer/expandMacro, qute/dataModel). A generic bridge doesn't know about them and can't expose them as MCP tools
  • No support for LSP commands: language servers expose custom commands (e.g. via workspace/executeCommand). Again, a generic bridge has to hardcode them
  • Duplicated configuration management: didChangeConfiguration must be handled by the bridge separately, leading to potential config drift between the IDE and the AI
  • Cold server: the language server started by the bridge has no warmup — no indexed workspace, no cached symbols — leading to slower and less accurate results compared to the already-running IDE server

The LSP4IJ approach: deep IDE integration

LSP4IJ takes a fundamentally different approach. Instead of being yet another external LSP/DAP client, the MCP server lives inside the IDE and delegates everything to LSP4IJ, which already manages the full lifecycle of language and debug servers.

The architecture is:

LLM → MCP Server → LSP4IJ (LSP/DAP client) → Language / Debug Server

Instead of:

LLM → MCP Server (LSP/DAP client) → Language / Debug Server

This means:

  • Single process: the MCP server reuses the language server already started and warmed up by LSP4IJ. No extra memory, no cold start
  • Shared state: the AI sees exactly what the IDE sees — same diagnostics, same index, same document state, in real time
  • Full project context: LSP4IJ already handles workspace initialization, didChangeConfiguration, and all the configuration defined in the JetBrains settings (including the JSON editor for user-defined language servers). The MCP server inherits all of this for free
  • Custom LSP requests and notifications: since LSP4IJ manages the LSP client, plugins that extend it can expose their proprietary LSP extensions as MCP tools without the MCP server needing to know anything about them
  • LSP commands: same — workspace/executeCommand and server-specific commands are handled by LSP4IJ and can be exposed transparently
  • No LSP/DAP knowledge required in the MCP server: the MCP server is completely agnostic of the underlying protocol. It doesn't speak LSP or DAP — it just calls LSP4IJ APIs

Standard MCP tools provided by LSP4IJ

LSP4IJ will provide a set of standard MCP tools out of the box:

  • List all configured language servers and their status
  • Find language servers matching a given file or project
  • Start / stop a language server
  • Get server capabilities
  • Execute a language server command
  • Standard LSP features: diagnostics, hover, completion, references, rename, code actions, inlay hints, etc.
  • Create user-defined language servers when none match the project files

Extension point for custom MCP tools

A key feature of this integration is an extension point that allows any plugin using LSP4IJ to register its own MCP tools. This means a plugin can expose its proprietary LSP extensions or DAP capabilities as first-class MCP tools, without modifying LSP4IJ itself.

Example: the Qute plugin (part of the Quarkus Tools for IntelliJ) manages its own language server via LSP4IJ. It can register a qute/dataModel MCP tool that exposes the Qute data model — a custom LSP request that only the Qute language server understands, and that no generic bridge could ever expose correctly.

Future work: DAP support

The same architecture applies naturally to DAP. LSP4IJ already manages debug adapters, so the MCP server could expose DAP capabilities as tools:

  • Start / stop a debug session
  • Set breakpoints
  • Read call stack and variable state at a breakpoint
  • Observe and analyze the runtime state of a running debug session

This would allow an AI assistant to act as an intelligent debug observer: it can read the exact state of a debug session running in JetBrains — variables, stack frames, exceptions — and help diagnose bugs without the user having to describe what they see.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions