MCP HubMCP Hub
jonrad

lsp-mcp

by: jonrad

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.

29created 23/02/2025
Visit
LLM
LSP

📌Overview

Purpose: The LSP MCP framework serves as a Model Context Protocol server that equips language models (LLMs) and AI agents with integrated capabilities from the Language Server Protocol (LSP), enabling access to language-aware context from codebases.

Overview: LSP MCP is designed to enhance AI interactions with code through the LSP, allowing for sophisticated understanding and analysis of various programming languages. It supports multiple LSP instances simultaneously, thus broadening the scope of AI capabilities in multi-language environments.

Key Features:

  • Multiple LSP Support: Enables simultaneous interaction with various programming languages, enhancing flexibility and usability for developers working in multi-language projects.

  • Dynamic LSP Method Generation: Automatically generates supported LSP methods using the LSP JSON Schema, streamlining the integration process and ensuring compatibility with various language servers.


LSP MCP

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.

Example

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.

Warning

This is in a POC state.

Features

  • Multiple LSPs (Multiple programming language support) at the same time
  • Dynamically generates supported LSP method from LSP JSON Schema

Quick Start

Claude Desktop

Using Docker (Recommended)

Modify claude_desktop_config.json 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>.

Using npx

Note: Claude Desktop is finicky with npx it seems. Sometimes it says the mcp fails but the tools still work.

{
  "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.

Cursor

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>)

MCP CLI Client

Follow the instructions for Claude but the config file is located in ~/.llm/config.json.

The ABCs (Introduction)

What is an MCP?

What is an LSP?

Development

yarn
yarn mcp-cli # Interactive MCP tool to help with development
yarn dev --help # Get the CLI help

Decisions

  • Started with Python using multilspy client library but switched to Node for broader LSP support and better tooling.
  • Using low-level MCP SDK for more control.
  • Using zod for config validation (already a dependency for MCP SDK).
  • Always use an LSP even for unknown languages (may revisit).
  • LSPs start only when requested to prevent resource overuse.

Roadmap

  • Sync capabilities between the LSP client and LSP server.
  • Auto-generate the LSP JSON Schema or find where it's published.
  • Make JSON schema a CLI argument to avoid updating code for new schemas.
  • Connect to already running LSP servers (via multiplexing).
  • Switch to Taskfile for task management.
  • Create a proper release process.

References