Skip to main content
Glama

lsp-mcp

An MCP server that exposes LSP-backed code navigation and editing tools to LLM agents. Uses a single global config file to route any file extension to any language server(s) — no per-project configuration required.

Why

Serena is excellent but requires per-project .serena/ files to control which language server each project uses. lsp-mcp lets you define the policy once at ~/.config/lsp-mcp/config.yml and apply it to any project — including ones you don't own.

Related MCP server: local-skills-mcp

Installation

With uvx (recommended — no install needed)

uvx lsp-mcp --help

With uv run

git clone https://github.com/AFriemann/lsp-mcp
uv run --project /path/to/lsp-mcp lsp-mcp

Configuration

Create ~/.config/lsp-mcp/config.yml (or $XDG_CONFIG_HOME/lsp-mcp/config.yml):

servers:
  # Declare every language server you want to use.
  # command: list of tokens (no shell quoting needed).
  ty:
    command: [uvx, ty, server]

  ruff:
    command: [ruff, server]

  typescript-language-server:
    command: [npx, typescript-language-server, --stdio]

  gopls:
    command: [gopls]

file_handlers:
  # Map glob patterns to ordered lists of servers.
  # Navigation tools: first server returning a non-empty result wins.
  # Diagnostics: results from all servers are merged.
  "*.py":
    - server: ty          # type checker — first priority
    - server: ruff        # linter — second priority (also provides diagnostics)

  "*.ts":
    - server: typescript-language-server

  "*.js":
    - server: typescript-language-server

  "*.go":
    - server: gopls

Pattern matching

  • *.ext — matched against the basename only (e.g. *.py matches any .py file in any directory).

  • src/*.py — matched against the full path (use for path-style filtering).

  • Multiple handlers for the same pattern are concatenated in order; duplicates are removed by first occurrence.

Server binaries

Binaries are resolved lazily at server start time. A missing binary degrades just that one server — the others still work.

Adding to opencode

In your ~/.config/opencode/opencode.jsonc:

{
  "mcp": {
    "lsp-mcp": {
      "type": "local",
      "command": "uvx",
      "args": ["lsp-mcp"]
    }
  }
}

Or with a local clone:

{
  "mcp": {
    "lsp-mcp": {
      "type": "local",
      "command": "uv",
      "args": ["run", "--project", "/home/you/git/lsp-mcp", "lsp-mcp"]
    }
  }
}

Tools

All eight tools accept absolute file paths. Symbol names may be bare (my_func) or name-paths (MyClass/my_method) for nested symbols.

Tool

Description

LSP method

get_symbols_overview

List all symbols in a file

textDocument/documentSymbol

find_symbol

Search for a symbol by name across the workspace

workspace/symbol

find_declaration

Find where a symbol is defined

textDocument/definition

find_implementations

Find implementations of an interface/abstract method

textDocument/implementation

find_referencing_symbols

Find all references to a symbol

textDocument/references

replace_symbol_body

Replace a symbol's source text in-place

textDocument/documentSymbol + on-disk edit

rename_symbol

Rename a symbol across the workspace

textDocument/rename

get_diagnostics_for_file

Get merged diagnostics from all configured servers

textDocument/diagnostic (pull) or publishDiagnostics (push)

Tool parameters

get_symbols_overview(file_path)

  • file_path: absolute path to the source file

find_symbol(query, file_path="")

  • query: symbol name substring to search for

  • file_path: optional context file (selects which servers to query)

find_declaration(symbol, file_path)

  • symbol: bare name or name-path (MyClass/my_method)

  • file_path: absolute path to the file containing the symbol

find_implementations(symbol, file_path) — same parameters as find_declaration

find_referencing_symbols(symbol, file_path) — same parameters as find_declaration

replace_symbol_body(symbol, new_body, file_path)

  • symbol: bare name or name-path

  • new_body: full replacement source text (including the signature line)

  • file_path: absolute path to the file

rename_symbol(symbol, new_name, file_path)

  • symbol: bare name or name-path

  • new_name: new identifier

  • file_path: absolute path to the file

get_diagnostics_for_file(file_path)

  • file_path: absolute path to the source file

Response shape

Every tool returns a JSON object with:

  • The result data (symbols, locations, diagnostics, changed_files, success)

  • note: explanatory string when no result was found or no capable server is configured

  • warnings: list of non-fatal per-server error messages

Architecture

Five layers:

lsp_mcp/
  __main__.py        # CLI entry point
  server.py          # FastMCP app + 8 tool adapters
  types.py           # Shared response models
  dispatch/          # Routing (first-wins / merge), symbol resolution, edits
  lsp/               # GenericLanguageServer, ServerManager pool, capabilities
  config/            # Config loading, validation, glob resolver
  • Config defines the routing policy. One global file, no per-project files.

  • ServerManager maintains a persistent pool of running server processes keyed by (server_name, project_root). Servers start on demand, are reused across calls, and are idle-evicted after 15 minutes.

  • GenericLanguageServer subclasses multilspy's LanguageServer to launch any arbitrary command.

  • Dispatcher routes each tool call: resolves the file's matching servers, filters by capability, applies first-wins or merge semantics.

  • Edits apply on-disk changes with UTF-16-correct offset handling and notify open servers via didChange.

Development

git clone https://github.com/AFriemann/lsp-mcp
cd lsp-mcp
uv sync
uv run pytest
A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/afriemann/lsp-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server