Investigate code using LSP tools. Register a project, then use definitions, references, call hierarchies, type hierarchies, hover, and diagnostics to understand code structure, trace bugs, and assess change impact.
3 stars
0 votes
0 copies
0 views
Added September 30, 2026
ai-agentspythonrustgojavakotlinc++
Works with
mcp
Security analysis
A92/100
mediumInstalls packages at runtime which could introduce malicious dependencies
Installs into .claude/skills of the current project.
Are you the author of Lsp Investigate?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/karellen-lsp-investigate)
---
description: Investigate code using LSP tools. Register a project, then use definitions, references, call hierarchies, type hierarchies, hover, and diagnostics to understand code structure, trace bugs, and assess change impact.
---
# LSP Code Investigation
Use this skill when you need to understand code structure, trace bugs through call
chains, find all usages of a symbol, or check compiler diagnostics across a codebase.
## Prerequisites
- `karellen-lsp-mcp` must be installed and on PATH
- An LSP server for the target language on PATH:
- **C/C++**: `clangd` — install via `pip install --user karellen-lsp-mcp[clangd]` or system package manager
- **Java/Kotlin**: `jdtls` — install via `pip install --user karellen-lsp-mcp[jdtls]`
- **Python**: `pyright` — install via `pip install --user karellen-lsp-mcp[pyright]`
- **Rust**: `rust-analyzer` — install via `rustup component add rust-analyzer`
- **All servers**: `pip install --user karellen-lsp-mcp[all]`
## Workflow
### 1. Register the Project
Optionally scan first to see what languages are present:
```
lsp_scan_languages(project_path="/path/to/project")
```
Then register:
```
lsp_register_project(project_path="/path/to/project")
```
Auto-detection identifies the language, build system, and LSP server configuration.
See `/karellen-lsp-mcp:lsp-register` for detailed registration options.
### 2. Understand a Symbol
Start with hover to get the type signature without reading the file:
```
lsp_hover(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
```
Then jump to the definition, declaration, or type definition:
```
lsp_read_definition(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
lsp_read_declaration(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
lsp_read_type_definition(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
```
### 3. Trace Usage and Impact
Find all references or implementations:
```
lsp_find_references(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
lsp_find_implementations(project_id="<id>", file_path="/path/to/file.java", line=10, character=14)
```
Search for symbols by name across the project:
```
lsp_workspace_symbols(project_id="<id>", query="MyClassName")
```
Trace call chains — use the recursive tree tools to get the full hierarchy in one shot:
```
lsp_call_tree_incoming(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
lsp_call_tree_outgoing(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
```
Or use the single-level versions if you only need immediate callers/callees:
```
lsp_call_hierarchy_incoming(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
lsp_call_hierarchy_outgoing(project_id="<id>", file_path="/path/to/file.cpp", line=42, character=10)
```
### 4. Understand Type Hierarchies
Get the full recursive type tree in one shot:
```
lsp_type_tree_supertypes(project_id="<id>", file_path="/path/to/file.java", line=10, character=14)
lsp_type_tree_subtypes(project_id="<id>", file_path="/path/to/file.java", line=10, character=14)
```
Or single-level:
```
lsp_type_hierarchy_supertypes(project_id="<id>", file_path="/path/to/file.java", line=10, character=14)
lsp_type_hierarchy_subtypes(project_id="<id>", file_path="/path/to/file.java", line=10, character=14)
```
### 5. Get File Overview
List all symbols in a file to understand its structure:
```
lsp_document_symbols(project_id="<id>", file_path="/path/to/file.cpp")
```
### 6. Check Diagnostics
Get compiler errors and warnings for a specific file:
```
lsp_diagnostics(project_id="<id>", file_path="/path/to/file.cpp")
```
### 7. Clean Up
```
lsp_deregister_project(registration_id="<registration_id>")
```
## Investigation Strategies
### Understanding an Unfamiliar Function
1. `lsp_hover` to get the signature and docs
2. `lsp_read_definition` to see the implementation
3. `lsp_call_tree_incoming` to get the full caller tree
4. `lsp_call_tree_outgoing` to get the full callee tree
### Assessing Change Impact
1. `lsp_find_references` to find all usages of the symbol being changed
2. `lsp_call_tree_incoming` to get the full caller tree
3. For each caller, `lsp_hover` to understand how it uses the symbol
4. `lsp_diagnostics` on affected files after making changes
### Tracing a Bug
1. Start at the file where the bug manifests
2. `lsp_document_symbols` to find relevant functions
3. `lsp_read_definition` to follow suspicious calls
4. `lsp_call_tree_incoming` to trace the data flow backwards
5. `lsp_hover` on variables to check types
### Understanding a Class Hierarchy
1. `lsp_type_tree_supertypes` to get the full supertype tree
2. `lsp_type_tree_subtypes` to get the full subtype tree
3. `lsp_document_symbols` on key classes to compare their structure
4. `lsp_find_references` on interface methods to see polymorphic usage
## Key Rules
- **NEVER run build system commands** (`cmake`, `make`, `meson`, `cargo build`, `gradle`,
`mvn`, `pip install`, etc.) on the user's project. The LSP adapter handles build
configuration automatically. Register the project and let the adapter handle it.
- **Register at the language-specific project root**, not the repository root. In
monorepos or polyglot projects, use `lsp_detect_project` first to find the correct
root for each language (where `Cargo.toml`, `pyproject.toml`, `CMakeLists.txt`, etc.
lives). Registering at a parent directory that lacks the language's build system marker
will fail or produce no results.
- **Hover before reading.** `lsp_hover` is fast and often provides enough context
(type signature, docs) without needing to read the full file.
- **Use LSP instead of grepping.** `lsp_find_references` is semantically aware; it
finds actual references, not string matches.
- **Check indexing status on large codebases.** Cross-file queries wait for indexing
automatically, but `lsp_indexing_status` shows progress.
- **All positions are 1-based.**
- **All tools accept `timeout`.** Optional timeout parameter (seconds) overrides the
default readiness timeout. Use higher values for large codebases (e.g. `timeout=300`).
- **Use `lsp_regenerate_index` to rebuild.** If the index is stale or corrupt, this
cleans managed data and force-restarts the LSP server.
- **Always deregister when done** using the `registration_id` to release resources.