grep does.
Quick Start
How It Works
Each tool call spawns a freshLSPClient, opens the document (didOpen), runs the query, and closes cleanly. There is no shared long-lived server process — every call is self-contained.
Choose the Right Tool
| Tool | Signature | Purpose | LSP Method |
|---|---|---|---|
lsp_definition | (file_path, line=None, character=None, symbol=None) | Go to definition of a symbol | textDocument/definition |
lsp_references | (file_path, line=None, character=None, symbol=None, include_declaration=True) | Find all references to a symbol | textDocument/references |
lsp_hover | (file_path, line, character) | Type / signature / doc at a position | textDocument/hover |
lsp_document_symbols | (file_path) | List symbols defined in a file | textDocument/documentSymbol |
lsp_workspace_symbols | (query, file_path=None) | Search symbols across the workspace | workspace/symbol |
Supported Languages
| Language | File Extensions | Default Server Binary |
|---|---|---|
| Python | .py, .pyi | pylsp (from python-lsp-server) |
| JavaScript | .js, .jsx, .mjs, .cjs | typescript-language-server |
| TypeScript | .ts, .tsx | typescript-language-server |
| Rust | .rs | rust-analyzer |
| Go | .go | gopls |
PATH. lsp_workspace_symbols without a file_path defaults to the Python language server.
Addressing: Position or Symbol
Position-taking tools (lsp_definition, lsp_references, lsp_hover) accept two addressing styles:
- Explicit position — pass
lineandcharacteras 0-indexed integers (LSP convention). The output uses 1-indexed numbers so results are human-readable. - Symbol name — pass
symbol="my_func"and the tool locates the first word-boundary occurrence of that name in the file, converting it to a position automatically.
lsp_hover requires an explicit (line, character) — it does not accept a symbol name.
Configuration Options
Python reference for the underlying LSP client
How
Agent(tools=[…]) resolves tool namesCommon Patterns
Investigate a symbol before refactoring Uselsp_definition to find where something is defined, then lsp_references to see every call site before changing anything:
Best Practices
Install the language server first
Install the language server first
Each language needs its server binary on If a server is missing the tool returns
PATH before the tools will work:Error: <lang> language server not installed; install it to use lsp navigation (falling back to grep is advised) — it never raises an exception.Prefer symbol= over line/character when position is unknown
Prefer symbol= over line/character when position is unknown
If you don’t already know the exact line number, pass
symbol="my_func" instead of guessing a position. The tool locates the first word-boundary occurrence for you, so results are always accurate.Narrow workspace-symbol queries
Narrow workspace-symbol queries
lsp_workspace_symbols caps output at 100 results and prints ... (N more; narrow your query) when the cap is hit. Use specific substrings — "parse_config" rather than "parse" — to stay inside the limit.Graceful degradation is by design
Graceful degradation is by design
When a language server is not installed the tools return a clear error string rather than raising. Check the return value for
Error: … not installed and fall back to grep-based tools (ast_grep, shell search) when needed.Related
Built-in Tool Registry
How to register and resolve tools with
Agent(tools=[…])LSP Service Command
The
praisonai lsp CLI command for managing the LSP service
