lsp2mcp
Provides clangd-based C/C++ language-server queries for definitions, references, hover information, document symbols, and diagnostics; results are improved when a compilation database is available.
Provides CSS language-server support for standalone CSS files, including document symbols and diagnostics.
Provides Dart language-server integration for Dart projects, enabling definitions, references, hover information, document symbols, and diagnostics.
Provides Dart language-server integration for Flutter projects via the Flutter SDK’s language server command, enabling code navigation, hover information, symbols, and diagnostics.
Provides read-only language-server queries for JavaScript projects, including definitions, references, implementations, hover information, document symbols, and diagnostics via the TypeScript language server.
Provides Pyright-based Python language-server queries, including definitions, references, implementations, hover types and documentation, document symbols, and diagnostics.
Provides rust-analyzer integration for Rust projects, enabling definitions, references, implementations, hover information, document symbols, and diagnostics.
Provides read-only language-server queries for TypeScript projects, including definitions, references, implementations, hover type signatures and documentation, document symbols, and diagnostics.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@lsp2mcpwhere is theparseConfigfunction defined in src/index.ts?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
lsp2mcp starts the language servers already installed on your machine and exposes them as read-only MCP tools. It answers questions an agent cannot settle by searching text: where a symbol is defined, who references it, what type it has, what the compiler would complain about
Why
Plain text search cannot resolve types. interface implementations, overloads, re-exports and shadowed names all look identical to grep. Language servers do this resolution properly, but editor integrations are the only common way to reach them
AI coding agents typically run without a language server attached. lsp2mcp gives an agent the same queries an IDE has, over stdio MCP, reusing the servers you already trust
Related MCP server: universal-lsp
Install
Requires Node.js 20 or newer, and the language servers you want to use already on PATH
npm install -g @sglwsjxh/lsp2mcpCreate a config file next to the package or pass its path. A starting template ships as mcp.json.example
cp mcp.json.example mcp.jsonThe program reads mcp.json from its working directory. If the file is absent it fails loudly and prints the path it looked at, rather than silently falling back to the template
Register with a client
{
"mcp": {
"servers": {
"lsp2mcp": {
"type": "local",
"command": ["node", "/absolute/path/to/lsp2mcp/dist/index.js"],
"environment": {
"LSP2MCP_CONFIG": "/absolute/path/to/lsp2mcp/mcp.json"
}
}
}
}
}Absolute paths in the client entry are deliberate: the process working directory is owned by the client, not by this package
Configuration
Each entry maps a language to one command. The command is spawned directly when it resolves to an executable, and through cmd.exe when it resolves to a .cmd or .bat wrapper. This distinction matters on Windows only
{
"servers": {
"typescript": {
"extensions": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
"languageIds": { ".tsx": "typescriptreact", ".jsx": "javascriptreact" },
"command": ["typescript-language-server", "--stdio"]
},
"java": {
"extensions": [".java"],
"command": ["jdtls", "-data", "{root}/.jdtls-workspace"]
}
}
}Field | Required | Meaning |
| yes | File suffixes routed to this server, matched case-insensitively |
| yes | Executable plus arguments |
| no | Per-extension override of the LSP |
{root} inside any argument is replaced with the project root passed to lsp_init
Servers in the template
Language | Command | Extra requirement |
TypeScript / JavaScript |
| none |
Vue |
| project needs a local |
Python |
| none |
C# |
| none |
Rust |
| none |
Go |
| none |
C / C++ |
| a compilation database gives materially better results |
Dart / Flutter |
| Flutter SDK provides this command |
JSON |
| syntax checking only, no schema store lookup |
HTML |
| standalone |
CSS |
| standalone |
Java |
| needs |
Add or edit entries freely. Nothing about the language set is compiled in
Tools
All tools are read-only. There is no rename, format or code action, because those mutate your working tree and belong to an editing tool
Tool | Input | Returns |
|
| binds the project root, reports detected languages, starts nothing |
| none | state per language: ready, failed, crashed, missing command, plus the reason |
| optional | stops one or all servers and reaps their process tree |
|
| where the symbol is declared |
|
| all usages, paginated |
|
| implementations of an interface or abstract member |
|
| resolved type signature and documentation |
|
| symbols in one file with line numbers |
|
| errors and warnings with severity, code and range |
line and character are 1-based, matching editor display and file readers. They are converted internally for the 0-based LSP wire format
Servers start on demand. Calling lsp_definition on a .py file for a project whose Python server is not running yet starts it, waits for initialize, then serves the request
Behavior notes
A server that never declared a capability returns an explicit "not supported by this language server" instead of an empty list, so absence never reads as success
Crashed servers are restarted on the next call and reported through
lsp_healthDiagnostics arrive asynchronously. A query waits within a bounded timeout rather than returning immediately empty
On Windows, stopping a server kills the whole process tree.
jdtlsspawnscmdthenpythonthenjava, and killing only the direct child leaves orphans holding hundreds of megabytesBefore the Java server starts,
<root>/.jdtls-workspace/is created and a.gitignorecontaining*is written into it, so the workspace never shows up ingit status. The same rule covers any argument that points at a hidden directory inside the project. Other servers need no such handling because they do not write into your tree
Vue single-file components
.vue needs two servers, and they do different halves of the job. @vue/language-server 3 and later dropped its own pipe to the TypeScript server and made the client responsible for relaying tsserver traffic: the server emits a tsserver/request notification and blocks until a matching tsserver/response arrives. Without that relay every query on a .vue file hangs until timeout
lsp2mcp implements the relay. Starting a vue server always brings up the typescript server for the same root first and routes the requests through it
The remaining split is real, not a bug:
Query on a | Answered by |
|
|
|
|
| both, merged and deduplicated by file, line, column and message |
Every response names the server that answered, so a fallback never looks like a native result
Script-region semantics also need the TypeScript plugin loaded in the typescript entry:
"typescript": {
"extensions": [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
"command": ["typescript-language-server", "--stdio"],
"initialization": {
"plugins": [
{
"name": "@vue/typescript-plugin",
"location": "PATH/TO/node_modules/@vue/language-server",
"languages": ["vue"]
}
]
}
}location is a directory that contains the plugin under its node_modules; the plugin must be the same version as the running @vue/language-server. Without that block, template structure and syntax diagnostics still work, but hover, definition and references inside <script> return nothing
Known limits
jdtlsdoes not advertisediagnosticProvider, so Java diagnostics come frompublishDiagnosticspushes and a fresh file may need a moment to settle. It does advertiseimplementationProviderMarkdown servers are not included.
vscode-markdown-language-serverrequires a client that answers its privatemarkdown/parserequest, which generic LSP clients do not implementPosition-based tools need the token to be under the cursor position you pass. Selecting a whole identifier range is ambiguous; point at its start
No automatic project discovery. The agent passes
rootexplicitly, because scanning a directory tree is slow and does not prove which project a file belongs to
Development
npm ci
npm run typecheck
npm run build
node dist/index.jsdist/ is gitignored and is what gets published
License
Apache License 2.0. See LICENSE
This server cannot be deployed
Maintenance
Related MCP Connectors
Lean 4 MCP server: compile, prove theorems, and formalize math with Mathlib.
The Remote MCP server acts as a standardized bridge between LLM applications (like Claude, ChatGPT, and Cursor) and external services, enabling AI agents to access external tools and resources. Its primary capability is providing a centralized search tool to discover other MCP servers and their respective tools. Unlike local implementations, it runs remotely with OAuth authentication and permission controls for security.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Related MCP Servers
- FlicenseAqualityDmaintenanceAn MCP stdio server that wraps language servers to expose read-oriented code-intelligence tools (hover, definition, references, diagnostics, etc.) for coding agents, supporting TypeScript/JavaScript and Python.561-
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to query language intelligence over MCP, including definitions, references, symbols, and code relationship graphs across many languages, all in one native process with no external language servers.Apache 2.0
- FlicenseNot gradedqualityAmaintenanceEnables AI coding agents and MCP clients to pull real-time language-server data from a running editor instance, including diagnostics, hover/definition/signature and type information, and symbol references with usage context. It also supports workspace-wide symbol renaming, opening files, and command execution, letting agents validate changes without waiting on slow tsc/eslint runs.-
- FlicenseNot gradedqualityAmaintenanceEnables AI coding agents and MCP clients to query real-time LSP diagnostics, type information, definitions, references, and workspace-wide symbol renaming through the editor's language servers, avoiding slow tsc/eslint checks.-