# 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.

- Skill: `karellen/lsp-investigate` (Agent Skill)
- Install (CLI): `npx skillmds@latest add karellen/lsp-investigate`
- Raw SKILL.md: https://api.skillmd.com/api/skills/karellen/lsp-investigate/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: karellen (https://skillmd.com/u/karellen)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/karellen/lsp-investigate

---


# 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.

