Lsp Investigate
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-mcpmust be installed and on PATH- An LSP server for the target language on PATH:
- C/C++:
clangd— install viapip install --user karellen-lsp-mcp[clangd]or system package manager - Java/Kotlin:
jdtls— install viapip install --user karellen-lsp-mcp[jdtls] - Python:
pyright— install viapip install --user karellen-lsp-mcp[pyright] - Rust:
rust-analyzer— install viarustup component add rust-analyzer - All servers:
pip install --user karellen-lsp-mcp[all]
- C/C++:
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
lsp_hoverto get the signature and docslsp_read_definitionto see the implementationlsp_call_tree_incomingto get the full caller treelsp_call_tree_outgoingto get the full callee tree
Assessing Change Impact
lsp_find_referencesto find all usages of the symbol being changedlsp_call_tree_incomingto get the full caller tree- For each caller,
lsp_hoverto understand how it uses the symbol lsp_diagnosticson affected files after making changes
Tracing a Bug
- Start at the file where the bug manifests
lsp_document_symbolsto find relevant functionslsp_read_definitionto follow suspicious callslsp_call_tree_incomingto trace the data flow backwardslsp_hoveron variables to check types
Understanding a Class Hierarchy
lsp_type_tree_supertypesto get the full supertype treelsp_type_tree_subtypesto get the full subtype treelsp_document_symbolson key classes to compare their structurelsp_find_referenceson 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_projectfirst to find the correct root for each language (whereCargo.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_hoveris fast and often provides enough context (type signature, docs) without needing to read the full file. - Use LSP instead of grepping.
lsp_find_referencesis 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_statusshows 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_indexto 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_idto release resources.