Local code intelligence for real engineering workflows.
Find implementations, API usage, structural patterns, configs, and routes. Explain why something broke. Guard the API contract before merging.
29 MCP tools across 5 layers. Supports TypeScript and JavaScript (TS, TSX, JS, JSX, MJS, CJS). Local-only — no paid API, no external calls.
AI coding agents use grep to understand code. Grep finds text, not meaning. It can't follow types through aliases, can't distinguish imports from function calls, and returns false positives from comments and strings.
lsp-intelligence gives agents the same code understanding that VS Code has — type-aware references, call hierarchies, impact analysis — via the Model Context Protocol (MCP).
After installation, try in Claude Code:
"What breaks if I rename the UserService class?"
Under the hood, the agent calls:
{ "tool": "impact_trace", "arguments": { "symbol": "UserService" } }Or get a file overview without reading it:
{ "tool": "outline", "arguments": { "file_path": "/workspace/src/services/auth.ts" } }All tools that accept
file_pathrequire absolute paths.
Requires Node.js 20+. Dependencies are installed automatically on first session start.
Add the marketplace and install the plugin:
/plugin marketplace add perilevy/lsp-intelligence
/plugin install lsp-intelligence@lsp-intelligence
/reload-pluginsAdd to your project's .claude/settings.json — any teammate who clones the repo gets it automatically:
{
"extraKnownMarketplaces": {
"lsp-intelligence": {
"source": {
"source": "github",
"repo": "perilevy/lsp-intelligence"
}
}
},
"enabledPlugins": {
"lsp-intelligence@lsp-intelligence": true
}
}Use npm source in marketplace.json for version pinning and built-in dependency resolution:
{
"name": "lsp-intelligence",
"source": {
"source": "npm",
"package": "lsp-intelligence",
"version": "0.2.0"
}
}| Query | Text search (grep) | lsp-intelligence |
|---|---|---|
| Find all references to a function | Finds text matches | Semantic references — no false positives from comments or strings |
| Find references to a type alias | UserServiceConfig matches UserService) |
Exact symbol resolution — only true references |
| Cross-package references in monorepo | Type-aware semantic references across packages |
| Capability | Description |
|---|---|
| Follow type aliases | Trace through ReturnType<typeof X>, re-exports, and barrel files |
| Go to definition | Jump to the actual source, not just a text match |
| Call hierarchy | "Who calls this function?" / "What does this function call?" |
| Type signatures | Get the full type signature without reading the implementation |
| Impact analysis | "What breaks if I change this?" — one call, full answer |
| Semantic diff | Git changes → which symbols changed → blast radius per symbol |
| Context building | Trace an impact graph, extract only relevant code, token-budget the output |
| Rename preview | See every file that would change before committing a rename |
| Dead code detection | Find exports that nothing imports |
| Auto-import | Resolve the correct import path for any symbol |
Tested on a TypeScript monorepo (9 packages, ~200k LOC):
| Metric | Value |
|---|---|
| Engine ready | ~10s (scales with repo size) |
| Queries after warmup | 100-300ms |
| 21 queries end-to-end | ~16s total |
The engine initializes once per session and stays warm. Warmup includes spawning TypeScript Server and pre-opening all monorepo packages. Queries start as soon as the index is available — no fixed delay.
Direct LSP wrappers. Every tool accepts symbol names — agents never need to guess line numbers.
| Tool | Description |
|---|---|
find_references |
Find every usage of a symbol across the codebase. Semantic, not text. |
goto_definition |
Jump to where a symbol is defined. Follows imports and re-exports. |
goto_type_definition |
Find the type that defines a variable. |
hover |
Get full type signature and documentation. |
find_implementations |
Find concrete implementations of an interface. |
document_symbols |
List all symbols in a file. |
workspace_symbols |
Search for symbols by name across the workspace. |
call_hierarchy |
Trace incoming callers or outgoing callees. |
rename |
Preview a semantic rename across the codebase (dry-run by default). |
diagnostics |
Get type errors and warnings for a file. |
completions |
Code completion suggestions. |
file_imports |
List all imports of a file. |
file_exports |
List a file's public API including re-exports. |
Combine LSP, AST, and Git substrates into high-level operations.
| Tool | Description |
|---|---|
api_guard |
Detect public API contract changes — export diffs, structural classification, consumer impact, semver summary. |
root_cause_trace |
Trace the root cause of a TypeScript error — find the originating declaration change, not just the symptom. |
find_code |
Unified code search: behavior discovery, identifier/API usage, structural queries, config/route lookup, and implementation-root discovery. Routes automatically. |
find_pattern |
AST structural search — find code by pattern (e.g. useEffect($$$), try { $$$ } catch ($E) { $$$ }). |
inspect_symbol |
Hover + definition + references in one call. Full context about any symbol. |
batch_query |
Look up multiple symbols at once. Saves round-trips when exploring. |
impact_trace |
Follow a symbol through type aliases and re-exports to find ALL transitive usages. |
semantic_diff |
Analyze git diff semantically: identify changed symbols and their blast radius. |
find_test_files |
Find all test/spec/stories files that reference a symbol. |
explain_error |
Turn a TypeScript error into actionable context: expected type, actual type, and fix suggestion. |
Token-aware context building for agents.
| Tool | Description |
|---|---|
outline |
File structure with type signatures — understand a file without reading it. |
gather_context |
Trace impact graph from entry symbols, classify files as must-modify / verify-only / skip, return token-budgeted context. |
Post-edit verification.
| Tool | Description |
|---|---|
live_diagnostics |
Re-read a file after editing and check for new type errors. |
find_unused_exports |
Find exported symbols with zero cross-package importers. |
auto_import |
Resolve the correct import path for a symbol name. |
find_code supports five query classes, routed automatically:
| Class | Example query | What happens |
|---|---|---|
| Identifier / API usage | useEffect, Promise.all |
Usage index → exact call/import sites with enclosing context |
| Structural | useEffect that returns cleanup conditionally |
Identifier + structural predicates → AST evaluation on located nodes |
| Behavior / entrypoint | where do we validate permissions |
Fielded BM25 over declarations + JSDoc/comments + family hints |
| Config / route / flag | where is the feature flag configured |
Config index → JSON/YAML/env/package.json entries |
| Implementation root | where is this actually implemented |
Graph expansion → wrapper detection → root promotion |
┌─────────────────────────────────────────────────────────┐
│ Layer 4: Live Intelligence [state-mutating] │
│ live_diagnostics, find_unused_exports, auto_import │
├─────────────────────────────────────────────────────────┤
│ Layer 3: Context Engine [read-only] │
│ gather_context, outline │
├─────────────────────────────────────────────────────────┤
│ Layer 2: Intelligence Tools [read-only] │
│ api_guard, root_cause_trace, find_code, find_pattern, │
│ impact_trace, semantic_diff, inspect_symbol, │
│ batch_query, find_test_files, explain_error │
├─────────────────────────────────────────────────────────┤
│ Layer 1: Primitives [read-only] │
│ find_references, hover, definition, call_hierarchy, │
│ rename, diagnostics, symbols, imports, exports │
├─────────────────────────────────────────────────────────┤
│ Layer 0: LSP Engine [infrastructure] │
│ TypeScript Server spawn, monorepo preopen, │
│ symbol resolver, document manager │
└─────────────────────────────────────────────────────────┘
Each layer only depends on layers below it.
Works with any monorepo structure out of the box:
packages/,apps/,libs/,modules/,services/directory conventionspnpm-workspace.yamlpackage.jsonworkspaces (yarn, npm)
At startup, the engine discovers all workspace packages and pre-opens one file per package. This triggers TypeScript Server to build configured projects for every package, enabling cross-package reference finding — a common challenge with LSP tooling in monorepos.
Every tool accepts { symbol: "UserService" } instead of requiring { file_path, line, column }. The engine resolves names to positions via workspace/symbol with priority sorting. Agents never need to guess line numbers.
Requires Node.js 20+.
Installs the MCP server, hooks, and skills (/find, /why, /api-check, /verify, /check, /impact, /context, /diff) as a single package.
claude plugin add perilevy/lsp-intelligenceThe full experience — the agent gets code intelligence tools, guided workflows via skills, and automatic hooks.
For other AI agents (Copilot, Cursor, etc.) or if you only want the raw tools without hooks and skills.
Add to your .mcp.json:
{
"mcpServers": {
"lsp": {
"command": "npx",
"args": ["--registry", "https://registry.npmjs.org", "-y", "lsp-intelligence"],
"env": {
"LSP_WORKSPACE_ROOT": "${CLAUDE_PROJECT_DIR}"
}
}
}
}For contributors or debugging.
git clone https://github.com/perilevy/lsp-intelligence.git
cd lsp-intelligence
yarn install && yarn buildThen in .mcp.json:
{
"mcpServers": {
"lsp": {
"command": "node",
"args": ["/absolute/path/to/lsp-intelligence/dist/index.js"],
"env": {
"LSP_WORKSPACE_ROOT": "${CLAUDE_PROJECT_DIR}"
}
}
}
}git clone https://github.com/perilevy/lsp-intelligence.git
cd lsp-intelligence
yarn install
yarn build # clean build (rm -rf dist && tsc)
yarn test # vitest
yarn typecheck # TypeScript strict mode — no emit
yarn bench # search quality benchmarksTests verify cross-package reference resolution, symbol-name lookup, type alias tracing, impact trace traversal, search quality, context building, and output formatting — all against self-contained fixture repos at test-fixtures/. No external dependencies needed.
benchmarks/ contains reproducible quality cases for find_code, root_cause_trace, and api_guard. Every serious real-world failure should become a benchmark case.
- Not a universal semantic search engine. Strong on code structure, API usage, configs, and known patterns. Does not understand arbitrary business logic.
- Not a replacement for full-text search. Use grep for literal string matching.
find_codeuses text patterns internally but optimizes for code-aware ranking. - Not an AI model. All intelligence is local: AST analysis, LSP queries, fielded text ranking, adapter recipes. No paid API calls, no external services.
All dependencies are installed automatically. Under the hood: typescript-language-server for LSP, @modelcontextprotocol/sdk for MCP, @ast-grep/napi for structural patterns. Uses your project's own TypeScript version.