Bridges Language Server Protocol capabilities into MCP, letting Claude analyze code with the same intelligence your IDE uses. Connects to TypeScript, Python, or other LSP servers to expose methods like textDocument/documentSymbol, textDocument/hover, and textDocument/definition. Instead of asking Claude to guess about code structure or types, you get precise symbol information, type definitions, and semantic analysis. Works through Docker or npx, supporting multiple LSP servers simultaneously. Essentially gives your AI assistant the same contextual understanding of your codebase that VSCode or other LSP-aware editors have, but accessible through natural language queries.
An Model Context Protocol (MCP) server that provides LLMs/AI Agents with the capabilities of a language server protocol (LSP) server. This gives the AI the ability to get language aware context from the codebase.
Input:
Use lsp to give me insights into the following typescript code:
let foo = "bar";
function x() {
let foo = 123;
console.log(foo);
}
x();
console.log(foo);
Output:
I'll use LSP (Language Server Protocol) to analyze your TypeScript code. Let me break down what's happening:
Here's what the code does and the insights from LSP analysis:
1. Variable Shadowing:
There are two variables named foo:
A global foo (string type) initialized with the value "bar"
A local foo (number type) inside the function x() initialized with the value 123
2. Execution Flow:
First, the global foo is declared and assigned the value "bar"
When function x() is called, the local foo variable is declared and assigned 123
The console.log(foo) inside the function outputs 123 (the local variable)
After the function finishes, console.log(foo) outputs "bar" (the global variable)
3. Scope Isolation:
The LSP confirms that TypeScript correctly identifies the different types:
The global foo is a string type
The local foo inside the function is a number type
Changes to the local foo don't affect the global foo
This is a classic example of variable shadowing in JavaScript/TypeScript, where a local variable with the same name as a global variable takes precedence within its scope.
This is in a POC state.
Modify claude_desktop_config.json (As described in the MCP Docs) with the following:
{
"mcpServers": {
"lsp": {
"command": "docker",
"args": ["run", "-i", "--rm", "docker.io/jonrad/lsp-mcp:0.3.1"]
}
}
}
You'll likely want to share some files with the container by passing docker -v /local_dir:/remote_dir. Then you can ask Claude about the files in /remote_dir/<filename>.
Note: Claude Desktop is finicky with npx it seems. Sometimes it says the mcp fails but the tools still work. I'll look into this... later 😊
{
"mcpServers": {
"lsp": {
"command": "npx",
"args": ["-y", "--silent", "git+https://github.com/jonrad/lsp-mcp", "--lsp", "npx -y --silent -p 'typescript@5.7.3' -p 'typescript-language-server@4.3.3' typescript-language-server --stdio"]
}
}
}
This will provide Claude with the LSP capabilities of the typescript language server. You can modify the language server by switching the --lsp argument (and then restarting Claude).
Multiple LSPs at the same time is not yet supported.
Follow the instructions provided by Cursor. For settings, choose Type = command and Command = docker run ... as mentioned above for claude (eg docker run -i --rm -v <LOCAL_DIR>:<REMOTE_DIR> jonrad/lsp-mcp:<version>)
Follow the instructions for Claude but the config file is located in ~/.llm/config.json
yarn
yarn mcp-cli # Interactive MCP tool to help with development
yarn dev --help # Get the CLI help
This is just a list of things I'd like to do eventually. There is no timeline or order for these.
ray0907/git-mcp-server
cyanheads/git-mcp-server
io.github.b1ff/atlassian-dc-mcp-bitbucket
io.github.b1ff/atlassian-dc-mcp-jira
com.mcparmory/atlassian-jira
sirlordt/vscode-terminal-mcp