Skip to main content
Glama
beruang
by beruang

MCP LSP — Code Intelligence Server

Node.js TypeScript MCP License

A Model Context Protocol (MCP) stdio server that wraps language servers to expose a safe, read-oriented code-intelligence tool surface for coding agents. Supports TypeScript, JavaScript, Python, Go, and Rust — 59 tools across navigation, diagnostics, refactoring, deep understanding, hierarchy, lifecycle, and operations.


Table of Contents


Related MCP server: agent-workspace-mcp

Quick Start

# Prerequisites: install language servers
npm install -g typescript-language-server pyright
# Go and Rust: install gopls and rust-analyzer via your package manager

# Clone and install
git clone https://github.com/beruang/lsp-mcp.git
cd lsp-mcp
pnpm install

# Build
pnpm run build

# Point at a workspace and start
WORKSPACE_PATH=/path/to/your/project node dist/index.js

Connect any MCP client to the server's stdio transport.


Prerequisites

Dependency

Version

Purpose

Node.js

>= 20

Runtime

pnpm

Package management

typescript-language-server

TypeScript/JavaScript LSP backend

pyright-langserver

Python LSP backend

gopls

Go LSP backend

rust-analyzer

Rust LSP backend

Language servers must be on $PATH. The server checks availability via lsp_list_supported_languages.


Installation

pnpm install

Dependencies: @modelcontextprotocol/sdk, vscode-jsonrpc, vscode-languageserver-types, zod, diff.


Configuration

Environment Variables

Variable

Required

Default

Description

WORKSPACE_PATH

No

process.cwd()

Absolute path to the workspace root

Runtime Config (V4)

Variable

Default

Description

LSP_MAX_REFERENCES

200

Max references returned

LSP_MAX_WORKSPACE_SYMBOLS

100

Max workspace symbols

LSP_MAX_DIAGNOSTICS

500

Max diagnostics

LSP_MAX_COMPLETION_ITEMS

50

Max completion items

LSP_MAX_CHANGED_FILES

100

Max files in rename preview

LSP_MAX_EDITS

1000

Max edits in workspace edit

LSP_MAX_CONTEXT_CHARACTERS

20000

Max context characters

LSP_TIMEOUT_HOVER_MS

3000

Hover timeout

LSP_TIMEOUT_DEFINITION_MS

5000

Definition timeout

LSP_TIMEOUT_REFERENCES_MS

10000

References timeout

LSP_REQUEST_LOG_MAX_ENTRIES

500

Request log ring buffer size

LSP_RAW_REQUEST_ENABLED

false

Enable debug raw request tool

LSP_VERBOSE_LOGGING

false

Verbose logging

Use lsp_get_config to inspect effective configuration and lsp_update_runtime_config to adjust limits, timeouts, cache TTLs, and debug flags at runtime (in-memory only).


Architecture

src/
├── index.ts                          # Entry point — MCP server bootstrap
├── config/
│   ├── languageServers.ts            # Language server registry
│   ├── defaults.ts                   # Default runtime config values
│   ├── envConfig.ts                  # Environment variable parsing
│   └── runtimeConfig.ts              # In-memory config merge + validation
├── lsp/
│   ├── LspClient.ts                  # LSP connection: spawn, initialize, request, shutdown
│   ├── LspClientManager.ts           # Per-language client pool + state queries
│   ├── LspState.ts                   # 8-state machine with validated transitions
│   ├── capabilities.ts               # Server capabilities extraction
│   ├── diagnosticsCache.ts           # publishDiagnostics notification cache
│   ├── documentStore.ts              # didOpen/didChange state tracking
│   └── normalize.ts                  # LSP → normalized shape converters
├── mcp/
│   ├── registerTools.ts              # All 59 MCP tool registrations
│   ├── toolErrors.ts                 # Structured error envelope
│   └── schemas.ts                    # Zod schemas
├── navigation/                       # V3: declaration, typeDef, implementation, signatureHelp, completion
├── hierarchy/                        # V3: call hierarchy + type hierarchy (prepare, incoming/outgoing, super/subtypes)
├── workspaceEdit/                    # V2: parse, validate, preview workspace edits
├── codeActions/                      # V2: code action cache + normalization
├── diagnostics/                      # V2: snapshot store, compare, wait-for-diagnostics
├── context/                          # V3: enclosing symbol, symbol context, file outline
├── analysis/                         # V3: change impact, fix candidates, explain diagnostics
├── formatting/                       # V2: format + range format preview
├── refactor/                         # V2: prepare rename, organize imports
├── composite/                        # V1: diagnostics summary, inspect symbol
├── diff/                             # V1: applyTextEdits, workspaceEditToDiff
├── semantic/                         # V3: fixDiagnosticCandidates, explainDiagnostics, analyzeChangeImpact
├── documents/                        # V4: open, close, sync, save, list documents
├── ops/                              # V4: server status, restart, shutdown, readiness, liveness, workspace status
├── observability/                    # V4: request tracker, request log
├── cache/                            # V4: cache status + selective clearing
├── debug/                            # V4: raw request (disabled by default, method denylist)
├── safety/
│   ├── paths.ts                      # Workspace containment check
│   └── limits.ts                     # Truncation caps and timeouts
└── utils/
    ├── asyncTimeout.ts               # Promise race with timeout
    ├── uri.ts                        # URI ↔ path conversion
    ├── symbols.ts                    # Symbol kind normalization
    ├── ids.ts                        # ID generation
    ├── text.ts                       # Text utilities
    └── time.ts                       # Time utilities

API Reference

Every tool returns either a success payload or a structured error:

{
  "error": {
    "code": "path_outside_workspace",
    "message": "Human-readable description",
    "details": {}
  }
}

Navigation & Discovery

Tool

LSP Method

Description

lsp_hover

textDocument/hover

Type information and documentation at cursor

lsp_definition

textDocument/definition

Go-to-definition locations

lsp_references

textDocument/references

Find all references to a symbol

lsp_document_symbols

textDocument/documentSymbol

Symbol outline for a file

lsp_workspace_symbols

workspace/symbol

Workspace-wide symbol search

lsp_declaration

textDocument/declaration

Go-to-declaration

lsp_type_definition

textDocument/typeDefinition

Go-to-type-definition

lsp_implementation

textDocument/implementation

Find implementations

Diagnostics

Tool

Description

lsp_diagnostics

Cached diagnostics for a file or workspace-wide

lsp_diagnostics_summary

Grouped diagnostics with root-cause heuristic

lsp_wait_for_diagnostics

Wait for fresh diagnostics after a change

lsp_snapshot_diagnostics

Save a named diagnostic snapshot for comparison

lsp_compare_diagnostics

Diff two diagnostic snapshots

lsp_explain_diagnostics

Cluster diagnostics and identify root causes

lsp_fix_diagnostic_candidates

Multi-source fix suggestions (hover + code actions + definition)

Refactoring & Editing

Tool

LSP Method

Description

lsp_rename_preview

textDocument/rename

Preview rename via WorkspaceEdit + unified diff

lsp_prepare_rename

textDocument/prepareRename

Check if rename is valid at a position

lsp_code_actions_preview

textDocument/codeAction

Preview code actions with diffs

lsp_resolve_code_action

codeAction/resolve

Resolve a cached code action

lsp_format_preview

textDocument/formatting

Preview formatting with diff

lsp_range_format_preview

textDocument/rangeFormatting

Preview range formatting with diff

lsp_organize_imports_preview

textDocument/organizeImports

Preview import organization with diff

lsp_workspace_edit_preview

Preview any WorkspaceEdit + unified diff

lsp_validate_workspace_edit

Validate WorkspaceEdit safety

Deep Understanding

Tool

LSP Method

Description

lsp_signature_help

textDocument/signatureHelp

Function signature at call site

lsp_completion

textDocument/completion

Code completion suggestions

lsp_inspect_symbol

composite

Aggregate: hover + definition + refs + risk hints

lsp_symbol_context

composite

Surrounding symbols at a position

lsp_enclosing_symbol

composite

Innermost enclosing symbol

lsp_file_outline

composite

File-level symbol outline

Hierarchy & Impact

Tool

LSP Method

Description

lsp_prepare_call_hierarchy

textDocument/prepareCallHierarchy

Prepare call hierarchy for a symbol

lsp_incoming_calls

callHierarchy/incomingCalls

Who calls this symbol

lsp_outgoing_calls

callHierarchy/outgoingCalls

What this symbol calls

lsp_prepare_type_hierarchy

textDocument/prepareTypeHierarchy

Prepare type hierarchy

lsp_supertypes

typeHierarchy/supertypes

Super-types of a symbol

lsp_subtypes

typeHierarchy/subtypes

Sub-types of a symbol

lsp_analyze_change_impact

composite

Cross-file impact analysis for a proposed change

Server Lifecycle

Tool

Description

lsp_server_status

Runtime status for all configured language servers

lsp_restart_server

Restart a language server (reopens docs, clears diagnostics)

lsp_shutdown_server

Graceful shutdown with timeout

lsp_list_supported_languages

Configured languages, extensions, commands, binary availability

lsp_get_capabilities

Normalized LSP capabilities per language

Document Lifecycle

Tool

LSP Method

Description

lsp_open_document

textDocument/didOpen

Register a document with the LSP server

lsp_close_document

textDocument/didClose

Unregister a document

lsp_sync_document

textDocument/didChange

Notify LSP of content changes

lsp_save_document

textDocument/didSave

Notify LSP of a save

lsp_list_open_documents

All currently tracked open documents

Health

Tool

Description

lsp_health_check

Server health and per-language LSP capabilities

lsp_readiness

Workspace + language server availability check

lsp_liveness

Fast liveness check + optional memory stats

Observability & Cache

Tool

Description

lsp_request_log

LSP request history with filtering

lsp_clear_request_log

Clear request log entries

lsp_cache_status

Entry counts for all internal caches

lsp_clear_caches

Selective or full cache clearing

Configuration

Tool

Description

lsp_get_config

Effective config (defaults → env → runtime overrides)

lsp_update_runtime_config

In-memory config updates (limits, timeouts, caches, debug)

Debug

Tool

Description

lsp_raw_request

Raw LSP request with method denylist (disabled by default)

Multi-Workspace

Tool

Description

lsp_list_workspaces

Known workspaces (foundation)

lsp_workspace_status

Status for a specific workspace (foundation)


Error Handling

Every tool returns errors in a uniform envelope:

{
  "error": {
    "code": "path_outside_workspace",
    "message": "Path is outside workspace: /etc/passwd",
    "details": {}
  }
}

Error Codes

Code

Trigger

path_outside_workspace

filePath does not resolve inside WORKSPACE_PATH

unsupported_language

File extension has no registered LSP server

file_not_found

File does not exist on disk

lsp_server_unavailable

Language server binary not on $PATH

lsp_server_not_initialized

Server not initialized

lsp_request_failed

LSP request returned an error

lsp_request_timeout

LSP request exceeded its deadline

lsp_capability_unsupported

Server does not support the capability

declaration_not_supported

Server lacks declaration provider

type_definition_not_supported

Server lacks type definition provider

implementation_not_supported

Server lacks implementation provider

signature_help_not_supported

Server lacks signature help provider

completion_not_supported

Server lacks completion provider

call_hierarchy_not_supported

Server lacks call hierarchy provider

call_hierarchy_item_not_found

Hierarchy item ID not found

call_hierarchy_item_expired

Hierarchy item TTL expired

type_hierarchy_not_supported

Server lacks type hierarchy provider

type_hierarchy_item_not_found

Type hierarchy item ID not found

type_hierarchy_item_expired

Type hierarchy item TTL expired

change_impact_analysis_incomplete

Change impact partial results

diagnostic_not_found

Diagnostic index not found

invalid_config_key

Unknown config key in update

invalid_config_value

Invalid config value (e.g., negative limit)

immutable_config_key

Attempt to change workspacePath at runtime

server_not_found

Language not configured

restart_rate_limited

Too many restarts in window

raw_request_disabled

Debug tool is disabled

method_denied

LSP method blocked by denylist

document_not_found

Document not in open documents store


Safety Model

The server is designed for read-oriented coding agents:

Guard

Mechanism

Workspace containment

Every file path validated against WORKSPACE_PATH

No file writes

All tools are read-only; lsp_rename_preview returns a diff but never applies edits

Result caps

All list results are truncated with configurable limits

Timeouts

Every LSP request has a per-method deadline

Structured errors

All errors use the uniform { error: { code, message, details } } envelope

Request log privacy

Logs method, duration, status — never full file contents (unless verbose logging explicitly enabled)

Method denylist

lsp_raw_request blocks workspace/applyEdit, workspace/executeCommand, and other dangerous methods

Restart rate limiting

Max 3 restarts per 60s per language

State machine validation

Invalid LSP state transitions are logged and rejected


Development

pnpm run typecheck     # TypeScript type-check
pnpm run lint          # ESLint (zero warnings)
pnpm run lint:fix      # ESLint auto-fix
pnpm run dev           # Run with tsx (no build)
pnpm run build         # Build to dist/
pnpm run start         # Start built artifact

Pre-commit Hook

husky + lint-staged:

  1. eslint --fix --max-warnings 0

  2. pnpm run typecheck

  3. pnpm run verify:decoupling

Conventions

  • Module system: ESM ("type": "module", NodeNext)

  • TypeScript: strict, target ES2022

  • Testing: node --test + tsx

  • Linting: ESLint with @typescript-eslint, zero-warnings policy


Testing

pnpm test              # All unit tests
npm run test:safety    # Safety tests
npm run test:integration  # Integration tests (requires language servers)

Coverage

  • 106+ tests across unit, integration, and safety suites

  • 5 languages: TypeScript, JavaScript, Python, Go, Rust

  • V1-V3 regression: all passing with every V4 change


Supported Languages

Language

Extensions

Language Server

Language ID

TypeScript

.ts, .tsx

typescript-language-server --stdio

typescript

JavaScript

.js, .jsx

typescript-language-server --stdio

typescript

Python

.py

pyright-langserver --stdio

python

Go

.go

gopls

go

Rust

.rs

rust-analyzer

rust

Adding a language:

  1. Entry in src/config/languageServers.ts

  2. Binary on $PATH

  3. Optional waitConfig in src/lsp/diagnosticsCache.ts


Troubleshooting

lsp_server_unavailable

which typescript-language-server pyright-langserver gopls rust-analyzer
npm install -g typescript-language-server pyright

Use lsp_list_supported_languages to check binary availability at runtime.

path_outside_workspace

Set WORKSPACE_PATH to the project root. Symlinks are resolved before containment check.

No diagnostics

Diagnostics are cached from publishDiagnostics notifications. For cold cache, use lsp_diagnostics with workspaceWide: true to trigger a warm-up pass, or lsp_wait_for_diagnostics.

Stale diagnostics after external edit

Use lsp_sync_document to notify the LSP of changes, then lsp_wait_for_diagnostics. For bulk recovery, lsp_restart_server with reopenDocuments: true.


Changelog

Version

Focus

Key Additions

V4

Production operations

Server lifecycle, document lifecycle, observability, cache, config, health, debug, multi-workspace (21 tools)

V3

Deep understanding

Hierarchy (call + type), declaration, type definition, implementation, signature help, completion, impact analysis (17 tools)

V2

Safe refactoring

Preview-first editing — rename, code actions, formatting, organize imports, diagnostics snapshots (11 tools)

V1

Semantic navigation

Hover, definition, references, symbols, diagnostics, rename preview, inspect (10 tools)


License

MIT

F
license - not found
-
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/beruang/lsp-mcp'

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