lsp-client
npx skills add https://github.com/lsp-client/lsp-client --skill lsp-client
Agent 安装分布
Skill 文档
LSP Client
Semantic code analysis using Language Server Protocol (LSP) clients. Provides language-aware code navigation, symbol search, and safe refactoring capabilities.
Quick Start
Three ways to use the library:
1. Use Pre-built Language Clients
import anyio
from pathlib import Path
from lsp_client import Position
from lsp_client.clients.pyright import PyrightClient
async def main():
workspace = Path.cwd()
async with PyrightClient(workspace=workspace) as client:
definitions = await client.request_definition_locations(
file_path="src/main.py",
position=Position(line=10, character=5)
)
for def_loc in definitions:
file = client.from_uri(def_loc.uri)
print(f"Definition at {file}:{def_loc.range.start.line}")
anyio.run(main)
2. Create Custom Client with Selected Capabilities
See scripts/custom_client_template.py for a complete template.
Key pattern – inherit from capability mixins:
from attrs import define
from lsp_client.clients.base import PythonClientBase
from lsp_client.capability.request import (
WithRequestHover,
WithRequestDefinition,
WithRequestReferences,
)
@define
class MyClient(
PythonClientBase,
WithRequestHover,
WithRequestDefinition,
WithRequestReferences,
):
...
3. Use Ready-Made Scripts
Run standalone analysis scripts without writing code:
# Analyze symbol at position
python scripts/basic_analysis.py src/main.py 10 5
# Find all symbols in file
python scripts/find_all_symbols.py file src/main.py
# Search workspace symbols
python scripts/find_all_symbols.py workspace MyClass
# Safe rename with preview
python scripts/safe_rename.py src/main.py 10 5 new_name
Common Workflows
Exploring Unfamiliar Codebase
Task: Understand how a function is used across the project
Approach:
- Find definition:
client.request_definition_locations() - Find all references:
client.request_references() - Get type info:
client.request_hover()
Script: python scripts/basic_analysis.py <file> <line> <char>
Safe Refactoring
Task: Rename a symbol across the entire workspace
Approach:
- Preview changes:
client.request_rename_edits() - Review affected files
- Apply:
client.apply_workspace_edit()
Script: python scripts/safe_rename.py <file> <line> <char> <new_name>
Symbol Search
Task: Find all classes/functions matching a pattern
Approach:
- Workspace-wide:
client.request_workspace_symbol_list(query="MyClass") - File-specific:
client.request_document_symbol_list(file_path=...)
Script:
python scripts/find_all_symbols.py workspace <query>python scripts/find_all_symbols.py file <path>
Available Clients
See references/language_servers.md for full list.
Quick reference:
- Python:
PyrightClient,PyreflyClient,BasedpyrightClient,TyClient - Rust:
RustAnalyzerClient - TypeScript/JS:
TypescriptClient,DenoClient - Go:
GoplsClient - Java:
JdtlsClient
All clients support both local (subprocess) and container (Docker) modes.
Capability System
The library uses capability mixins to compose exactly the features needed.
Selecting Capabilities
See references/capabilities.md for complete list.
Common combinations:
Basic navigation:
WithRequestDefinitionWithRequestReferencesWithRequestHover
IDE-like features:
- Add
WithRequestCompletion - Add
WithRequestSignatureHelp - Add
WithRequestCodeAction
Symbol search:
WithRequestDocumentSymbol(file-level)WithRequestWorkspaceSymbol(project-wide)
Refactoring:
WithRequestRenameWithRequestCodeActionWithRequestWorkspaceEdit
Why Capability Mixins?
- Type safety: Only methods for registered capabilities exist
- Automatic negotiation: Client tells server what it supports
- Zero boilerplate: No manual capability checking
- Composability: Mix exactly what you need
Local vs Container Servers
Every client supports dual server backends:
Local Server (Subprocess)
from lsp_client.clients.pyright import PyrightClient
async with PyrightClient() as client:
# Uses local pyright-langserver if available
...
Pros: Fast startup, direct file access
Cons: Requires server installed locally
Container Server (Docker)
from lsp_client.clients.pyright import PyrightClient, PyrightContainerServer
async with PyrightClient(server=PyrightContainerServer()) as client:
# Uses ghcr.io/lsp-client/pyright:latest
...
Pros: Zero installation, consistent environment
Cons: Docker overhead, path translation
Automatic Fallback
If no server specified, library tries:
- Explicit
server=argument (if provided) - Local installation
- Container fallback
- Auto-install hook (if defined)
Key Concepts
Position
LSP uses 0-indexed line and character positions:
from lsp_client import Position
# Line 10, character 5 (0-indexed)
pos = Position(line=10, character=5)
URI vs File Path
LSP servers work with URIs. The client handles conversion:
# Server returns URI
location = await client.request_definition_locations(...)
# Convert back to file path
file_path = client.from_uri(location.uri)
Async Context Manager
Always use async with to ensure proper cleanup:
async with Client(...) as client:
# Client initialized, server running
result = await client.request_hover(...)
# Server automatically shut down
Advanced Features
Configuration Management
Clients come with sensible defaults. Override as needed:
@define
class MyClient(PyrightClient):
def create_default_config(self):
return {
"python": {
"analysis": {
"typeCheckingMode": "strict",
}
}
}
Server Lifecycle Hooks
Customize server behavior with hooks:
from lsp_client.server.local import LocalServer
@define
class CustomServer(LocalServer):
async def setup(self, workspace):
# Before server starts
...
async def on_started(self, workspace, sender):
# After server ready
...
async def on_shutdown(self):
# Before cleanup
...
See library’s examples/custom_hooks.py for details.
Troubleshooting
Server Not Found
Symptom: “Could not find language server”
Solution: Either install locally or use container:
from lsp_client.clients.pyright import PyrightContainerServer
client = PyrightClient(server=PyrightContainerServer())
Path Translation Issues
When using containers, always work with workspace-relative paths:
# Good
await client.request_hover(file_path="src/main.py", ...)
# Bad (absolute paths won't translate correctly)
await client.request_hover(file_path="/Users/me/project/src/main.py", ...)
Resources
Scripts
basic_analysis.py– Hover, definition, references for a symbolfind_all_symbols.py– Document/workspace symbol searchsafe_rename.py– Preview and apply rename refactoringcustom_client_template.py– Template for creating custom clients
References
capabilities.md– Complete list of available LSP capabilitieslanguage_servers.md– Supported language servers and selection guide