@treedy/lsp-mcp
v0.2.8
Published
Unified MCP server aggregating multi-language LSP backends for code intelligence
Maintainers
Readme
@treedy/lsp-mcp
One MCP server for Python, TypeScript/JavaScript, and Vue code intelligence.
It pre-registers unified LSP tools (hover, definition, diagnostics, etc.), auto-detects language from file path, and auto-starts backends on first use.
By default, published builds are lean: they do not include bundled backend runtime payloads.
Backends are resolved on-demand via npx / uvx.
60-Second Setup
- Add to your MCP client config:
{
"mcpServers": {
"lsp-mcp": {
"command": "npx",
"args": ["@treedy/lsp-mcp@latest"]
}
}
}- Try these first calls:
status
list_backends
hover file=/abs/path/to/file.py line=10 column=5
diagnostics path=/abs/path/to/project
git_diagnosticsstart_backend is optional now. Backends are started automatically when a tool needs them.
What You Get
- Unified tools across languages:
hover,definition,references,search,diagnostics,rename, etc. - Language-specific refactor tools where needed:
- Python:
python_move,python_change_signature,python_function_signature - TypeScript:
typescript_move,typescript_function_signature
- Python:
- Meta/admin tools:
status,list_backends,check_versions,update_backend,reload_config,switch_workspace,switch_workspace_for_language,discover_language_workspaces,semantic_session_start,doctor,expand_result - Built-in prompts for agent workflows and best practices
Tool Model (Current)
Unified tools (preferred)
Use these directly; language is inferred from file/path:
- Navigation:
hover,definition,implementation,type_definition,call_hierarchy,type_hierarchy,document_highlight,selection_range,folding_range,document_link,linked_editing_range,semantic_tokens,moniker,references,peek_definition,workspace_symboltype_hierarchy,semantic_tokens,linked_editing_range, andinlay_hint_resolveuse strict backend methods when available, otherwise return explicitfallback_used=true+approximate=trueresults.
- Hinting:
inlay_hints,inlay_hint_resolve,read_file_with_hints - Composite semantic workflow:
semantic_navigate(optional search -> definition -> references -> read_file_with_hints)mode='deep'(default) runs full workflow;mode='fast'skips heavy hint reads unless explicitly requestedstrategy='balanced'|'definition_first'|'references_first'controls step ordering for latency/recall tradeoffs
- Incremental diagnostics:
diagnostics_delta(delta vs previous diagnostics snapshot) - Editing support:
completions,signature_help,prepare_rename,rename,code_action,run_code_action,code_lens - Analysis:
diagnostics,git_diagnostics,symbols,search,summarize_file,read_file_with_hints,project_structure - Sync/edit loop:
update_document
Compatibility aliases are also available for older clients, for example:
python_hover, typescript_definition, python_diagnostics.
High-volume output controls
For large repos, use preview arguments to reduce token usage:
search/workspace_symbol:preview_limitorpage_size(default200), pluscursorfor next pagediagnostics:preview_limitorpage_size(default200),summary_only(defaultfalse), pluscursordiagnostics_delta:preview_limit/page_sizeplus optionalseverity,source,hotspot_limitfilters, andcursorfor paged change items- Returns
delta.file_summary[]anddelta.top_hotspots[]for per-file triage in large workspaces
- Returns
doctor:page_size(default50) pluscursorfor long environment reportsdoctor: setcheck_latest_versions=trueto probe registry latest version drift (slower, network-dependent)doctor: usecapability_snapshot_idto reuse probed capability matrix and skip repeated backend capability probing- Strict semantic errors include structured
recovery_plan[](type,tool,args,command) and cost fields:latency_ms,result_size,truncated,cursor_available - Semantic responses include
confidenceandconfidence_reasonfor fallback/approximation awareness project_structure:max_depth(default3),max_entries(default300)summarize_file:max_symbols(default200)read_file_with_hints:start_line(default1),max_lines(default300)project_structure/summarize_file/read_file_with_hints: also supportpage_size+cursor
Paged responses include:
page:{ shown, offset, page_size, has_more, next_cursor }next: ready-to-call arguments for the next page (viaexpand_result)- Cursors are signed and expire automatically (TTL-based) for safer paging.
Strict semantic error shape (example):
{
"error": "LANGUAGE_WORKSPACE_REQUIRED",
"error_code": "LANGUAGE_WORKSPACE_REQUIRED",
"tool": "hover",
"strict_mode": true,
"resolved_language": "typescript",
"resolved_workspace": null,
"next_step": "Call switch_workspace_for_language(language='typescript', path='/abs/project/root') before using semantic tools.",
"recovery_plan": [
{
"step": 1,
"action": "set_language_workspace",
"type": "tool_call",
"tool": "switch_workspace_for_language",
"args": {
"language": "typescript",
"path": "/abs/project/root"
},
"command": "switch_workspace_for_language(language='typescript', path='/abs/project/root')",
"reason": "Semantic tools require an explicit per-language workspace mapping."
}
],
"latency_ms": null,
"result_size": 0,
"cursor_available": false,
"truncated": false,
"confidence": 0.25,
"confidence_reason": "Strict workspace precondition failed; no semantic result available."
}Language-specific tools
- Python-only:
python_move,python_change_signature,python_function_signature - TypeScript-only:
typescript_move,typescript_function_signature
Server/meta tools
status,list_backends,start_backend,update_backend,check_versions,reload_config,switch_python_backend,switch_workspace,switch_workspace_for_language,discover_language_workspaces,semantic_session_start,doctor,expand_resultdiscover_language_workspacesinput:root(optional),max_depth(optional, default2),apply(optional, defaultfalse)semantic_session_startinput:language(optional),workspace(optional),file(optional),start_backend(optional, defaulttrue)- In mixed-language monorepos, semantic tools require language workspace mapping (set via
switch_workspace_for_languageordiscover_language_workspaces(..., apply=true)). doctornow includesworkspaceDependencyChecks.language_workspace_discoverywith suggested per-language workspace commands.doctorincludesbackendPackageDriftto show installed backend version vs latest policy and upgrade next steps.doctorincludesbackendVersionSummary(stable schema withschema_version,counts,by_language,lookup_stats) for quick LLM triage.doctorincludesworkspaceDependencyChecks.python_bundled_runtimein bundled mode, with optional executable probe results whenprobe_backends=true.doctorincludesbenchmarkInsightsfrom the latest benchmark report (.tmp/benchmark-latest.jsonby default) for runtime budget recommendations.- If baseline exists (
.tmp/benchmark-baseline.jsonby default),benchmarkInsights.trendincludes regression/improvement deltas. - If benchmark cases include
*_coldand*_warmpairs,benchmarkInsights.warmupsummarizes warm-start deltas.
- If baseline exists (
doctorincludesllmSemanticDefaultswith ready-to-use parameter presets for:semantic_navigate(mode,strategy,page_size,reference_preview,hint_max_lines)diagnostics_delta(page_size,preview_limit,hotspot_limit)- plus
rationale[]explaining why these defaults were chosen
Example fields exposed for client/LLM orchestration:
{
"backend_runtime_mode": "registry",
"backend_packages": [
{
"language": "typescript",
"package": "@treedy/typescript-lsp-mcp",
"package_ref": "@treedy/typescript-lsp-mcp@latest",
"registry": "npm",
"resolver": "npx",
"provider": "typescript-lsp-mcp",
"install_command": "npx --yes @treedy/typescript-lsp-mcp@latest",
"update_command": "npx --yes @treedy/typescript-lsp-mcp@latest",
"default_channel": "latest",
"auto_update_enabled": true,
"minimum_supported_version": "0.1.0"
}
],
"backendPackageDrift": {
"typescript": {
"installed_version": "0.2.0",
"minimum_supported_version": "0.1.0",
"minimum_status": "supported",
"drift_status": "policy_aligned",
"latest_registry_version": "0.2.0",
"latest_status": "up_to_date",
"next_step": "No action needed.",
"latest_next_step": "Installed version matches latest policy."
}
},
"backendVersionSummary": {
"schema_version": 1,
"check_latest_versions": true,
"lookup_stats": {
"schema_version": 1,
"enabled": true,
"cache_ttl_ms": 300000,
"requested": 3,
"cache_hits": 2,
"inflight_hits": 0,
"executed": 1,
"succeeded": 1,
"failed": 0,
"skipped": 0
},
"counts": {
"languages": 3,
"below_minimum": 0,
"outdated": 0,
"policy_drift": 0,
"bundled_static": 0,
"unknown_latest": 0
}
}
}Prompts (Skills)
code-navigationrefactoringcode-analysislsp-rulesexplore-projectdebug-filelsp-quick-start
Configuration
You can configure with env vars or .lsp-mcp.json in your workspace.
Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| LSP_MCP_PYTHON_ENABLED | true | Enable Python backend |
| LSP_MCP_PYTHON_PROVIDER | python-lsp-mcp | Python provider (python-lsp-mcp or pyright-mcp) |
| LSP_MCP_TYPESCRIPT_ENABLED | true | Enable TypeScript backend |
| LSP_MCP_VUE_ENABLED | true | Enable Vue backend |
| LSP_MCP_AUTO_UPDATE | true | Update backend packages to latest on startup/update |
| LSP_MCP_BACKEND_RUNTIME_MODE | registry | Backend runtime strategy: registry (default), auto, bundled |
| LSP_MCP_REQUIRE_BUNDLED_BACKENDS | false | Legacy strict bundled mode (equivalent to runtime mode bundled) |
| LSP_MCP_EAGER_START | false | Start all enabled backends when server boots |
| LSP_MCP_IDLE_TIMEOUT | 600 | Backend idle timeout in seconds |
Auto-update behavior
When LSP_MCP_AUTO_UPDATE=true:
python-lsp-mcpviauvx --upgrade python-lsp-mcppyright-mcpvianpx --yes @treedy/pyright-mcp@latesttypescript-lsp-mcpvianpx --yes @treedy/typescript-lsp-mcp@latestvue-lsp-mcpvianpx --yes @treedy/vue-lsp-mcp@latest
Runtime dependency expectations
- Lean mode (default): backend packages are fetched when first used (
LSP_MCP_BACKEND_RUNTIME_MODE=registry). - Bundled mode: set
LSP_MCP_BACKEND_RUNTIME_MODE=bundledorLSP_MCP_REQUIRE_BUNDLED_BACKENDS=true. - Required host tools:
- TypeScript/Vue/Pyright backends:
node+npx - Python backend:
uv(oruvx) - Vue semantic features additionally require project-local deps in the Vue workspace:
typescript@vue/language-server
- Use
doctorto get structured dependency checks and install commands. - Optional benchmark paths:
LSP_MCP_BENCHMARK_REPORT_PATH(default.tmp/benchmark-latest.json)LSP_MCP_BENCHMARK_BASELINE_PATH(default.tmp/benchmark-baseline.json)
Better Out-of-Box Experience (Recommended)
- Use absolute file paths for the first calls to avoid inference edge cases.
- Call
switch_workspace path=/abs/project/rootto set the global root for non-semantic flows (search, project exploration). - For semantic tools (hover/definition/references/diagnostics), set per-language roots via
switch_workspace_for_languageordiscover_language_workspaces(..., apply=true). - For mixed-language repos, prefer
git_diagnosticsbefore broaddiagnostics path=. - If startup speed matters, set
LSP_MCP_EAGER_START=true.
Development
# Install deps
bun install
# Machine-readable benchmark report
bun run benchmark:report
# Optional trend diff (compare with .tmp/benchmark-baseline.json)
bun run benchmark:diff
# Build local dist/ (lean default, no bundled backends)
bun run build
# Build local dist/ + bundled backends (for offline/dev integration runs)
bun run build:bundled
# Run in watch mode
bun run dev
# Full integration suite (builds bundled mode first)
bun run test
# Benchmark-focused suite (zod + fastapi + vitesse)
bun run test:benchmark
# Reporting template for benchmark runs
# docs/techbet-report-template.md
# Legacy smoke script (kept for low-level checks)
bun run test:legacy
# Prompt integration tests
bun test test/integration/prompts.test.ts
# Manual inspection
bun run inspectorLicense
MIT
