Full-featured, well-typed, and easy-to-use LSP client
Project description
LSP Client
A production-ready, async-first Python client for the Language Server Protocol (LSP). Built for developers who need fine-grained control, container isolation, and extensibility when integrating language intelligence into their tools.
Why lsp-client?
lsp-client is engineered for developers building production-grade tooling that requires precise control over language server environments:
- 🧩 Intelligent Capability Management: Zero-overhead mixin system with automatic registration, negotiation, and availability checks. Only access methods for registered capabilities.
- 🎯 Complete LSP 3.17 Support: Full specification implementation with pre-configured clients for multiple popular language servers. Easily extendable for custom servers and capabilities.
- 🐳 Container-First Architecture: Containers as first-class citizens with workspace mounting, path translation, and lifecycle management. Pre-built images available, seamless switching between local and container environments.
- ⚡ Production-Ready & Modern: Explicit environment control with no auto-downloads. Built with async patterns, comprehensive error handling, retries, and full type safety.
Quick Start
Installation
# Recommended: Use uv for modern Python dependency management
uv add lsp-client
# Or with pip
pip install lsp-client
Local Language Server
The following code snippet can be run as-is, try it out:
# install pyrefly with `uv tool install pyrefly` first
import anyio
from lsp_client import Position
from lsp_client.clients.pyrefly import PyreflyClient
async def main():
async with PyreflyClient() as client:
refs = await client.request_references(
file_path="example.py",
position=Position(10, 5)
)
for ref in refs:
print(f"Reference at {ref.uri}: {ref.range}")
anyio.run(main)
Containerized Language Server
async def main():
workspace = Path.cwd()
async with PyrightClient(
server=PyrightContainerServer(),
workspace=workspace
) as client:
# Find definition of a symbol
definitions = await client.request_definition_locations(
file_path="example.py",
position=Position(10, 5)
)
for def_loc in definitions:
print(f"Definition at {def_loc.uri}: {def_loc.range}")
anyio.run(main)
More Examples
The examples/ directory contains comprehensive usage examples:
pyright_container.py- Using Pyright in Docker for Python analysisrust_analyzer.py- Rust code intelligence with Rust-Analyzerpyrefly.py- Python linting and analysis with Pyreflyprotocol.py- Direct LSP protocol usage
Run examples with:
uv run examples/pyright_container.py
Client Definition
Defining a custom client is super easy with the capability mixin:
@define
class MyPythonClient(
Client,
WithRequestHover, # textDocument/hover
WithRequestDefinition, # textDocument/definition
WithRequestReferences, # textDocument/references
WithNotifyDidChangeConfiguration, # workspace/didChangeConfiguration
# ... and other capabilities as needed
):
def create_default_servers(self) -> DefaultServers:
return DefaultServers(
# support both local ...
local=LocalServer(program="pylsp", args=["--stdio"]),
# ... and containerized server!
container=ContainerServer(image="ghcr.io/observerw/lsp-client/python-lsp-server")
)
def create_initialization_options(self) -> dict:
return {"plugins": {"pyflakes": {"enabled": True}}} # custom init options
def check_server_compatibility(self, info: lsp_type.ServerInfo | None) -> None:
return # Custom compatibility checks if needed
Current Supported Language Servers
| Language Server | Module Path | Language | Container Image |
|---|---|---|---|
| Pyright | lsp_client.clients.pyright |
Python | ghcr.io/lsp-client/pyright:latest |
| Pyrefly | lsp_client.clients.pyrefly |
Python | ghcr.io/lsp-client/pyrefly:latest |
| Ty | lsp_client.clients.ty |
Python | ghcr.io/lsp-client/ty:latest |
| Rust Analyzer | lsp_client.clients.rust_analyzer |
Rust | ghcr.io/lsp-client/rust-analyzer:latest |
| Deno | lsp_client.clients.deno |
TypeScript/JavaScript | ghcr.io/lsp-client/deno:latest |
| TypeScript Language Server | lsp_client.clients.typescript |
TypeScript/JavaScript | ghcr.io/lsp-client/typescript:latest |
| Gopls | lsp_client.clients.gopls |
Go | ghcr.io/lsp-client/gopls:latest |
Container images are automatically updated weekly to ensure access to the latest language server versions.
Key Benefits
- Method Safety: You can only call methods for capabilities you've registered. No runtime surprises from unavailable capabilities.
- Automatic Registration: The mixin system automatically handles client registration, capability negotiation, and availability checks behind the scenes.
- Zero Boilerplate: No manual capability checking, no complex initialization logic, no error handling for missing capabilities.
- Type Safety: Full type annotations ensure you get compile-time guarantees about available methods.
- Composability: Mix and match exactly the capabilities you need, creating perfectly tailored clients.
Contributing
We welcome contributions! Please see our Contributing Guide for details on:
- Adding new language server support
- Extending protocol capabilities
- Container image updates
- Development workflow
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built on the Language Server Protocol specification
- Uses lsprotocol for LSP type definitions
- Architecture inspired by multilspy and other LSP clients
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lsp_client-0.2.3.tar.gz.
File metadata
- Download URL: lsp_client-0.2.3.tar.gz
- Upload date:
- Size: 47.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9ec2aa8ba23fdb35b87f5c980fd8a24ce93053ac99e1e7c60c961576372c8b90
|
|
| MD5 |
dc320c8fb74a5d206f76e7a50e3788c6
|
|
| BLAKE2b-256 |
d90e23e930e8977606c33424ebe2c04701d88ad7d04234aa51a349a9b5f0d7b4
|
Provenance
The following attestation bundles were made for lsp_client-0.2.3.tar.gz:
Publisher:
release.yml on lsp-client/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lsp_client-0.2.3.tar.gz -
Subject digest:
9ec2aa8ba23fdb35b87f5c980fd8a24ce93053ac99e1e7c60c961576372c8b90 - Sigstore transparency entry: 790366654
- Sigstore integration time:
-
Permalink:
lsp-client/python-sdk@df367cbc8da660c047ba55ec4d406e7a6af750c3 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/lsp-client
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@df367cbc8da660c047ba55ec4d406e7a6af750c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file lsp_client-0.2.3-py3-none-any.whl.
File metadata
- Download URL: lsp_client-0.2.3-py3-none-any.whl
- Upload date:
- Size: 94.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b7af51c1fd953d57950a79a81f81f411b1ab65900c0c1e30804df9105f78db8b
|
|
| MD5 |
60ec3cf156fb997b540ed7d78dffc29b
|
|
| BLAKE2b-256 |
4736d85fbb0f6495a3e29a9309ce79853e9025ee38c64f55e2c5cf161bfc4bd8
|
Provenance
The following attestation bundles were made for lsp_client-0.2.3-py3-none-any.whl:
Publisher:
release.yml on lsp-client/python-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lsp_client-0.2.3-py3-none-any.whl -
Subject digest:
b7af51c1fd953d57950a79a81f81f411b1ab65900c0c1e30804df9105f78db8b - Sigstore transparency entry: 790366663
- Sigstore integration time:
-
Permalink:
lsp-client/python-sdk@df367cbc8da660c047ba55ec4d406e7a6af750c3 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/lsp-client
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@df367cbc8da660c047ba55ec4d406e7a6af750c3 -
Trigger Event:
push
-
Statement type: