The Language Server Protocol (LSP) is an open-standard protocol developed by Microsoft. It enables communication between development tools and Language Servers. Language Servers can provide language-specific features such as code completion, documentation, and formatting, which is far easier than implementing language support from scratch. It also reduces the need for constant maintenance and tracking of changes in relevant languages and tools, making it easier to bring consistent language support to various development environments.
However, the canonical Custom Language Support provided by IntelliJ Platform still offers a wider range of integration with IDE features than handling and presenting data provided by a Language Server. Therefore, the LSP approach shouldn't be considered as a replacement for the existing language API, but rather as an added value.
Gain insights into the Language Server Protocol (LSP) and its capabilities while exploring the implementation journey of the Contextive plugin, designed to document and utilize domain terminology within codebases. Chris Simon shares the challenges faced and offers practical tips for aspiring LSP developers.
Supported IDEsThe integration with the Language Server Protocol is created as an extension to the commercial IntelliJ-based IDEs. Therefore, plugins using Language Server integration are not available in JetBrains products like IntelliJ IDEA Community Edition and Android Studio from Google.
The LSP API is publicly available as part of the IntelliJ Platform in the following IDEs: IntelliJ IDEA Ultimate, WebStorm, PhpStorm, PyCharm Professional, DataSpell, RubyMine, CLion, DataGrip, GoLand, Rider, and RustRover.
Since 2025.1, it is also supported in unified PyCharm without Pro subscription.
LSP Plugin SetupThe plugin must target IntelliJ IDEA Ultimate version 2023.2
or later.
Relevant build.gradle.kts configuration:
plugins { id("org.jetbrains.intellij.platform") version "2.7.1" } repositories { mavenCentral() intellijPlatform { defaultRepositories() } } dependencies { intellijPlatform { intellijIdeaUltimate("2025.2") } }
Upgrade the Gradle IntelliJ Plugin to the latest version. It will attach the LSP API sources and code documentation to the project.
Relevant build.gradle.kts configuration:
plugins { // ... id("org.jetbrains.intellij") version "1.17.4" } intellij { version = "2025.2" type = "IU" }
For projects based on the IntelliJ Platform Plugin Template, update the Gradle IntelliJ Plugin to the latest version, and amend the values in gradle.properties accordingly.
plugin.xmlThe plugin.xml configuration file must specify the dependency on the IntelliJ Platform Ultimate module:
<idea-plugin> <!-- ... --> <depends>com.intellij.modules.ultimate</depends> </idea-plugin>
IDE SetupSince 2024.2, LSP API sources are provided with the IntelliJ IDEA Ultimate sources
artifact. See Attaching Sources in the IDE on how to enable downloading sources. Then, use to open the LspServerManager
class. In the opened editor, invoke Download IntelliJ Platform sources to download and attach sources.
The LSP API sources are bundled in the IntelliJ IDEA Ultimate distribution and can be found within the $IDEA_INSTALLATION$/lib/src/src_lsp-openapi.zip archive.
Due to technical limitations in IDEs before 2024.1, it is necessary to manually attach sources to the IntelliJ IDEA Ultimate dependency. To do so, when reviewing the compiled class which belongs to the LSP API, run the Choose Sources... action, and point to the $IDEA_INSTALLATION$/lib/src/src_lsp-openapi.zip file.
Supported FeaturesThe LSP support provided by the IntelliJ Platform covers the following features for these releases:
2025.1Document Link (textDocument/documentLink
)
Color Preview (textDocument/documentColor
)
Document Save Notification (textDocument/didSave
) [2024.3.1]
Go To Type Declaration (textDocument/typeDefinition
) [2024.3.1]
Find Usages (textDocument/references
)
Completion Item Resolve Request (completionItem/resolve
)
Code Action Resolve Request (codeAction/resolve
)
Semantic Highlighting (textDocument/semanticTokens/full
) [2024.2.2]
Communication channel: Socket
Execute a command (workspace/executeCommand
)
Apply a WorkspaceEdit (workspace/applyEdit
)
Show Document Request (window/showDocument
)
Intention actions (textDocument/codeAction
)
Code formatting (textDocument/formatting
)
Request cancellation ($/cancelRequest
)
Quick documentation (textDocument/hover
) [2023.3.2]
Client-side file watcher (workspace/didChangeWatchedFiles
) [2023.3.2]
Communication channel: StdIO
Errors and warnings highlighting (textDocument/publishDiagnostics
)
Quick-fixes for errors and warnings (textDocument/codeAction
)
Code completion (textDocument/completion
)
Go to Declaration (textDocument/definition
)
As a reference, check out the Prisma ORM open-source plugin implementation: Prisma ORM LSP
Minimal LSP Plugin SetupImplement LspServerSupportProvider
and within the LspServerSupportProvider.fileOpened()
method, spin up the relevant LSP server descriptor, which can decide if the given file is supported by using the LspServerDescriptor.isSupportedFile()
check method.
Register it in com.intellij.platform.lsp.serverSupportProvider
extension point.
Tell how to start the server by implementing LspServerDescriptor.createCommandLine()
.
import com.intellij.platform.lsp.api.LspServerSupportProvider import com.intellij.platform.lsp.api.ProjectWideLspServerDescriptor internal class FooLspServerSupportProvider : LspServerSupportProvider { override fun fileOpened(project: Project, file: VirtualFile, serverStarter: LspServerStarter) { if (file.extension == "foo") { serverStarter.ensureServerStarted(FooLspServerDescriptor(project)) } } } private class FooLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "Foo") { override fun isSupportedFile(file: VirtualFile) = file.extension == "foo" override fun createCommandLine() = GeneralCommandLine("foo", "--stdio") }
A dedicated Language Services status bar widget is available to monitor the status of all LSP servers. Override LspServerSupportProvider.createLspServerWidgetItem()
to provide a custom icon and link to Settings page (if available).
override fun createLspServerWidgetItem( lspServer: LspServer, currentFile: VirtualFile? ) = LspServerWidgetItem( lspServer, currentFile, FooIcons.PluginIcon, FooConfigurable::class.java )
If there are configuration problems preventing from starting an LSP server, the plugin can provide a widget item with an error and give the user a hint how to fix the problem.
Language Server IntegrationLanguage Server is a separate process that analyzes source code and provides language-specific features to development tools. When creating a plugin that uses LSP within the IDE, there are two possibilities for providing a Language Server to end-users:
Bundle a Language Server implementation binary as a resource delivered with a plugin.
Provide a possibility for users to define the location of the Language Server binary in their environment.
The Prisma ORM plugin presents the first approach, which distributes the prisma-language-server.js script and uses a local Node.js interpreter to run it.
For more complex cases, the plugin may request to provide a detailed configuration with a dedicated Settings implementation.
CustomizationTo access LSP API source code and documentation see IDE Setup.
To fine-tune or disable the implementation of LSP-based features, plugins may return a customized LspCustomization
object from the LspServerDescriptor.lspCustomization
property. Available customization options are described by LspCustomization
's properties.
For example, see PrismaLspServerDescriptor
.
The new API is backward-compatible. Plugin LSP customizations implemented via deprecated LspServerDescriptor
's properties will work in 2025.2. New LSP features will be customizable only via the new API.
To fine-tune or disable the implementation of LSP-based features, plugins may override the corresponding properties of the LspServerDescriptor
class (see their documentation for details).
Note that LSP support is in active development and some customization options are available only in newer versions.
To handle custom (undocumented) requests and notifications from the LSP server, override the LspServerDescriptor.createLsp4jClient()
function and the Lsp4jClient
class according to their documentation.
To send custom (undocumented) requests and notifications to the LSP server, override LspServerDescriptor.lsp4jServerClass
property and implement the LspClientNotification
and/or LspRequest
classes. The documentation in the source code includes implementation examples.
All the IDE and LSP server communication logs are passed to the IDE log file.
To include them, add the following entry to the Help | Diagnostic Tools | Debug Log Settings⦠configuration dialog:
#com.intellij.platform.lsp
For more information, see the Logging section.
Integration OverviewIntegrating the Language Server Protocol (LSP) into a plugin for IntelliJ-based IDEs involves a trade-off between simple and fast language support and a complex custom language support plugin with IDE capabilities.
When considering the LSP-based approach, it is important to assess the following criteria for providing a Language Server to end users:
OS dependency of the Language Server.
Availability of the latest version online.
Compatibility with breaking changes between versions.
Feasibility of requesting the user to provide the Language Server binary path.
The following open-source plugins make use of LSP:
Explore third-party plugins using LSP on IntelliJ Platform Explorer.
If a topic is not covered in the above sections, let us know via the Was this page helpful? feedback form below or other channels.
Be specific about the topics and reasons for adding them and leave your email in case we need more details. Thanks for your feedback!
12 August 2025
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4