| name | multilspy-reference |
| description | Reference for the multilspy Python LSP client library. Use when working on src-python/main.py, modifying LSP queries, or troubleshooting hover/completion extraction. |
| user-invocable | true |
| allowed-tools | Read, Grep, Glob |
Multilspy Reference
What is Multilspy
Multilspy is a Python library that provides a unified interface to Language Server Protocol (LSP) servers for multiple languages. It handles server lifecycle, file management, and LSP request/response marshalling.
Repo: https://github.com/microsoft/multilspy (and eventually https://github.com/microsoft/multilspy)
Configuration
from multilspy import LanguageServer, SyncLanguageServer
from multilspy.multilspy_config import MultilspyConfig
from multilspy.multilspy_logger import MultilspyLogger
config = MultilspyConfig.from_dict({"code_language": "python"})
logger = MultilspyLogger()
lsp = LanguageServer.create(config, logger, "/path/to/project")
sync_lsp = SyncLanguageServer.create(config, logger, "/path/to/project")
Supported Languages
python, java, rust, csharp, typescript, javascript, go, dart, ruby, kotlin, cpp
Config Options
MultilspyConfig(
code_language: str,
trace_lsp_communication: bool,
start_independent_lsp_process: bool
)
Server Lifecycle
async with lsp.start_server():
result = await lsp.request_hover(file_path, line, col)
with sync_lsp.start_server():
result = sync_lsp.request_hover(file_path, line, col)
LSP Query Methods
All methods take a relative file path (relative to project root), line (0-based), and column (0-based).
request_hover
result = await lsp.request_hover(file_path: str, line: int, column: int) -> Hover | None
Returns Hover with:
class Hover(TypedDict):
contents: MarkupContent
range: Range | None
The contents.value typically contains markdown with code blocks and documentation separated by ---.
request_completions
result = await lsp.request_completions(file_path: str, line: int, column: int) -> list[CompletionItem]
Returns list of CompletionItem:
class CompletionItem(TypedDict):
completionText: str
kind: CompletionItemKind
detail: str | None
request_definition
result = await lsp.request_definition(file_path: str, line: int, column: int) -> list[Location]
request_references
result = await lsp.request_references(file_path: str, line: int, column: int) -> list[Location]
request_document_symbols
result = await lsp.request_document_symbols(file_path: str) -> list[UnifiedSymbolInformation]
File Management
Files must be opened before querying:
async with lsp.start_server():
with lsp.open_file(relative_path):
hover = await lsp.request_hover(relative_path, line, col)
Note: In the current twoslash-python implementation (src-python/main.py), file opening is handled internally by the batch processing pipeline.
Type Definitions
class Position(TypedDict):
line: int
character: int
class Range(TypedDict):
start: Position
end: Position
class Location(TypedDict):
uri: str
range: Range
absolutePath: str
relativePath: str
class CompletionItemKind(IntEnum):
Text = 1
Method = 2
Function = 3
Constructor = 4
Field = 5
Variable = 6
Class = 7
Interface = 8
Module = 9
Property = 10
Keyword = 14
Snippet = 15
Constant = 21
class SymbolKind(IntEnum):
File = 1
Module = 2
Namespace = 3
Class = 5
Method = 6
Property = 7
Function = 12
Variable = 13
Constant = 14
How twoslash-python Uses Multilspy
In src-python/main.py, the PyTwoslash class:
- Creates a
LanguageServer with code_language: "python" config
- Extracts symbols from the target file using AST (
symbol.py)
- Starts the LSP server
- Sends hover requests in batches (default: 20 per batch) with timeout
- Parses hover responses: splits on
--- to separate type info from docs
- Extracts
@param, @returns etc. tags from docs
- Creates
NodeHover objects with position, text, docs, tags
- Saves as JSON compatible with the TypeScript transformer
Common Issues
- Hover returns None: The LSP needs the project's dependencies installed. Make sure the project's virtualenv is active or packages are importable
- Timeout errors: Default 10s per hover. Increase with
--hover-timeout for large projects
- Wrong positions: multilspy uses 0-based line/column. The AST parser uses 1-based lines, so subtract 1 when converting
Key Source Files
- Main implementation:
src-python/main.py
- Symbol extraction:
src-python/symbol.py
- Multilspy source:
context/multilspy/src/multilspy/language_server.py
- Multilspy types:
context/multilspy/src/multilspy/multilspy_types.py
- Multilspy config:
context/multilspy/src/multilspy/multilspy_config.py
- Test examples:
context/multilspy/tests/multilspy/test_multilspy_typescript.py