| name | code-analysis |
| category | dev |
| description | LSP-based code analysis via mcpls MCP server. Use for compiler-accurate type inspection, go-to-definition, find-all-references, diagnostics, call hierarchy, workspace symbol search, code actions, rename refactoring, and document formatting. Provides real compiler errors — not guesses. Keywords: LSP, language server, type, definition, references, diagnostics, hover, symbol, call hierarchy, rename, refactor, code actions, rust-analyzer, pyright, gopls, clangd.
|
| license | MIT |
| compatibility | Requires mcpls MCP server (https://github.com/bug-ops/mcpls) configured as an MCP server. Works with any LSP 3.17+ compliant language server (rust-analyzer, pyright, typescript-language-server, gopls, clangd, zls). |
| metadata | {"author":"zeph","version":"1.0"} |
Code Analysis with LSP
Use LSP tools for accurate, compiler-verified code understanding. These tools require the mcpls
MCP server to be configured.
Positions
Positions are 1-based: line 1, column 1 is the first character. If you read a file and see
line numbers in the output, use those directly — no conversion needed (mcpls translates to 0-based
LSP positions internally).
File paths must be absolute. Relative paths will not resolve correctly.
Tool Reference
Code Intelligence
| Tool | Purpose | When to use |
|---|
get_hover | Type signature, inferred type, and documentation at a position | "What type is X?", "What does this function do?" |
get_definition | Navigate to where a symbol is defined | Read a function/type implementation before reasoning about it |
get_references | Find all usages of a symbol across the workspace | Before renaming, deleting, or changing a symbol's signature |
get_completions | Context-aware suggestions respecting types and scope | Exploring unknown APIs, discovering available methods |
get_document_symbols | Structured outline of a file (functions, types, constants, fields) | Understanding file structure without reading every line |
workspace_symbol_search | Search for a symbol by name across the entire workspace | Know a name but not which file defines it |
Diagnostics and Correctness
| Tool | Purpose | When to use |
|---|
get_diagnostics | Real compiler errors and warnings for a file | After editing code — always call to verify correctness |
get_cached_diagnostics | Previously cached diagnostics (no fresh check) | Quick check when file has not changed recently |
get_code_actions | Quick fixes, refactorings, source actions at a position | Fix diagnostics automatically, add missing imports |
Refactoring
| Tool | Purpose | When to use |
|---|
rename_symbol | Workspace-wide rename with full reference tracking | Always prefer over manual find-and-replace |
format_document | Apply language-specific formatting rules | After editing, before committing |
Call Hierarchy
| Tool | Purpose | When to use |
|---|
prepare_call_hierarchy | Get callable items at a position | First step before incoming/outgoing calls |
get_incoming_calls | Find all callers of a function | "Who calls this?" — impact analysis |
get_outgoing_calls | Find all callees of a function | "What does this call?" — dependency analysis |
Server Monitoring
| Tool | Purpose | When to use |
|---|
get_server_logs | Internal log messages from the language server | Debug "no results" issues, server startup failures |
get_server_messages | User-facing messages from the language server | Check for server notifications, progress, errors |
Workflow Patterns
Diagnostic-Driven Editing
After editing a file:
- Save the file to disk (diagnostics reflect the file on disk, not in-memory).
- Call
get_diagnostics on the changed file.
- For each error, call
get_code_actions to find available fixes.
- Apply fixes or edit manually.
- Repeat until
get_diagnostics returns an empty list.
Impact Analysis Before Refactoring
- Call
get_references on the symbol you intend to change.
- Review all usage sites to understand the blast radius.
- Make the change (or use
rename_symbol for renames).
- Call
get_diagnostics on all affected files.
Type Exploration
- Call
get_hover on an unknown symbol to see its type and documentation.
- Call
get_definition to read the implementation.
- Call
get_references to understand how other code uses it.
Call Graph Analysis
- Call
prepare_call_hierarchy on a function — this returns a call hierarchy item.
- Pass the item to
get_incoming_calls to see what calls it (consumers).
- Pass the item to
get_outgoing_calls to see what it calls (dependencies).
- Repeat recursively to trace deeper call chains.
Workspace Navigation
- Call
workspace_symbol_search with a partial name to find symbols across the project.
- Call
get_definition on the result to jump to the source.
- Call
get_document_symbols on the target file to understand its full structure.
Configuration
mcpls auto-detects language servers based on project markers:
| Language | Server | Markers |
|---|
| Rust | rust-analyzer | Cargo.toml, rust-toolchain.toml |
| Python | pyright | pyproject.toml, setup.py, requirements.txt |
| TypeScript | typescript-language-server | package.json, tsconfig.json |
| Go | gopls | go.mod, go.sum |
| C/C++ | clangd | CMakeLists.txt, compile_commands.json, Makefile |
| Zig | zls | build.zig, build.zig.zon |
Custom servers can be added in ~/.config/mcpls/mcpls.toml:
[[lsp_servers]]
language_id = "rust"
command = "rust-analyzer"
args = []
file_patterns = ["*.rs"]
timeout_seconds = 30
[lsp_servers.initialization_options]
check.command = "clippy"
Environment variables:
| Variable | Description | Default |
|---|
MCPLS_CONFIG | Path to config file | ~/.config/mcpls/mcpls.toml |
MCPLS_LOG | Log level (trace/debug/info/warn/error) | info |
MCPLS_LOG_JSON | Output logs as JSON | false |
Troubleshooting
No results from get_hover or get_definition
- The file may not be indexed yet. mcpls opens files lazily — the first access to a file
triggers indexing, which may take a few seconds for large projects.
- Call
get_server_logs to check if the language server is running and has finished indexing.
- Verify the language server is installed and in
$PATH (e.g., which rust-analyzer).
- Check that the project has the expected marker files (e.g.,
Cargo.toml for Rust).
get_diagnostics returns stale results
- Diagnostics reflect the file on disk. If you edited the file but did not save, the
diagnostics will be for the old content. Always save before calling
get_diagnostics.
- After a save, the language server needs time to re-analyze. Wait briefly and retry.
- Use
get_cached_diagnostics only when you know the file has not changed — it returns
push-based diagnostics from the server's last notification, which may be outdated.
Language server not starting
- Check
get_server_logs for startup errors.
- Verify the server binary is installed:
which rust-analyzer, which pyright, etc.
- Check the config file (
~/.config/mcpls/mcpls.toml) for misconfigured command or args.
- Ensure the project root contains the expected marker files for auto-detection.
- For non-standard setups, add an explicit
[[lsp_servers]] entry in the config.
Slow responses
- Initial indexing can take 10-30 seconds for large Rust workspaces. Subsequent calls are fast.
- Set
timeout_seconds higher in the config for large projects.
- Check
get_server_logs for memory or CPU warnings from the language server.
- For rust-analyzer, ensure
rust-analyzer.cargo.buildScripts.enable is not causing excessive
build script evaluation.
rename_symbol fails or misses references
rename_symbol only works on symbols the language server can resolve. If a symbol is in a
macro expansion or generated code, the rename may be partial.
- Always call
get_references first to verify the server can see all usage sites.
- After rename, call
get_diagnostics on affected files to catch any breakage.
Edge Cases
- Macro-generated code:
get_hover and get_definition may not resolve symbols inside
procedural macro expansions. Use get_references on the macro invocation site instead.
- Conditional compilation: Symbols behind
#[cfg(...)] may not be visible depending on the
active feature set. Configure the language server's feature flags accordingly.
- Multi-root workspaces: mcpls supports multiple roots via the
roots config option. Each
root gets its own language server instance.
- Large files:
get_document_symbols on very large files (10k+ lines) may be slow. Prefer
targeted get_hover or workspace_symbol_search instead.
- Cross-crate navigation:
get_definition may jump into dependency source code
(e.g., ~/.cargo/registry/). This is expected behavior — the language server resolves through
the full dependency graph.