LeIndex
Semantic code intelligence for humans and AI agents — a Program Dependence Graph, hybrid neural search, and 18 structural tools behind one small daemon.
Ask LeIndex where authentication lives, what breaks if you rename a function, or how the indexer resumes across phases — and get the symbols, callers, and source back in milliseconds, not a dump of files to read.
you: "where is request validation enforced?"
LeIndex: src/http/request_validator.rs validate_session (0.92)
src/middleware/input_guard.rs authorize_user (0.84)
callers: 3 · callees: 7 · blast radius: 12 files
v2.0.0 — the resource revolution, completed
v2.0.0 rebuilt LeIndex around one idea: a code index should never be the
biggest process on your machine. The architecture work (one user-scoped
daemon + tiny stdio shims, content-addressed generation storage, a streaming
bounded indexing pipeline, an admit/defer/reduce memory controller) is
benchmarked in BENCHMARKS.md — including MRR@10 = 1.0000
against the v1.9.5 baseline, so none of it cost retrieval quality. The
final rounds of hardening, all measured on this repository's own source
(457 files / 20,500 nodes / 122,000 edges):
| before | after | |
|---|---|---|
| Re-index tail after "saving to storage..." | 85.7 s | 5.0 s (17x) |
| Neural embeddings recomputed per re-index | 10,242 rows | only changed content |
| Concurrent embed daemons after a config change | stacked (OOM'd a 64 GiB box) | 1, RSS-capped, idle-evicted |
| Silent degradation in tool responses | empty relations as fact | explicit notes + direction labels |
| One-shot CLI vs MCP feature parity | enrichment silently skipped | same enrichment, honest budgets |
How: a client-side content-addressed embedding cache (probe hits locally,
embed only misses — an all-hit run never loads the model), edge-level PDG
diffing on save (unchanged graphs write nothing), a single-daemon policy
with zombie-aware cleanup and a sibling-aware memory floor, and honest
reporting end to end (impact direction labels, impact_note when a zero
could mean degradation, signature_scope on incremental counts).
The intelligence stack behind it
- 37 active language grammars today — Rust, TypeScript/JavaScript, Go, Python, Java, C/C++, C#, Ruby, PHP, Swift, Kotlin, Scala, Elixir, Erlang, Haskell, Zig, R, and more — on a roadmap to 100+; each grammar is an individually gated crate that cannot regress the build.
- Documentation is first-class: markdown/rst/adoc/txt files index as heading-section nodes, so "how do generations work" retrieves the exact ARCHITECTURE section — not the whole handbook.
- Leiden community detection (feature-flagged, default on) clusters the
call/data/containment graph;
project-mapcan group by community andimpact-analysisreports community crossings. - SCIP precision tier (on by default;
LEINDEX_FEATURE_PRECISION_INGEST=falsedisables): when a language indexer such asrust-analyzer scipis present, LeIndex merges its exact definitions and relationships into the PDG — upgrading heuristic edges to confidence 1.0 and marking precision-confirmed symbols. Missing indexers degrade silently to the tree-sitter tier. - Engram query phrase-book (opt-in:
LEINDEX_FEATURE_ENGRAM=1): a persistent, content-addressed table of neural query embeddings under~/.leindex/engram/. A repeated query is served without waking the embedder (no worker spawn, no network round trip); keys include the embedder identity, so a changed model never serves stale vectors. Bounded (20,000 rows / 256 MiB, LRU) and reported inleindex_analyze mode=diagnostics. Query embeddings only; index-time neural reuse is the existing global embed cache.
The retrieval quality claims are gated by a deterministic benchmark — internal fixtures plus a vendored subset of the CoSQA (ACL 2021) human-annotated query/code benchmark — see the agent-task benchmark methodology.
What agents see: 4 MCP tools
Four routers instead of twenty schemas — a mode / action argument picks the
operation, every other argument passes straight through:
| Tool | Selector | Branches |
|---|---|---|
leindex_explore |
mode |
search (hybrid semantic, default) · find (exact text / regex / symbol names — indexed, always live, any path on disk) · symbol_lookup · read_file · read_symbol · project_map · file_summary · context |
leindex_analyze |
mode |
deep (semantic + PDG traversal, default) · impact (transitive blast radius) · diagnostics · git_status · git_diff (PDG-enriched) |
leindex_edit |
action (required) |
preview → apply (dry-run supported) · rename (atomic multi-file, preview-first) · write |
leindex_manage |
action |
index (pollable job, default) · phase (5-phase architectural review) |
find is a native trigram index (the technique behind Zoekt) built with each
index run: about a millisecond on a 700-file repository, results always read from
the live file, and any directory outside the index is scanned on the fly with no
setup. Every branch takes tier (l0 card · l1 overview · l2 full detail),
and argument detail lives in the leindex://tools/guide MCP resource. The
original per-tool names (leindex_search, leindex_edit_apply, …) still work
as direct calls.
Every tool is also on the CLI — the same handlers, the same output:
leindex tools list --verbose
leindex tools inspect leindex_explore
leindex tools run leindex_explore --set mode=find --set pattern=retry
leindex tools run leindex_explore --args '{"mode":"search","query":"retry policy","top_k":5}'
90%+ token savings for AI coding tools
Standard tools burn context reading whole files to find one function. LeIndex returns the structured answer:
| Task | Standard tools | LeIndex | Savings |
|---|---|---|---|
| Understand a 500-line file | ~2,000 tokens | ~380 tokens | 81% |
| Find all callers of a function | ~5,800 tokens | ~420 tokens | 93% |
| Navigate project structure | ~8,500 tokens | ~650 tokens | 92% |
| Cross-file symbol rename | ~12,000 tokens | ~340 tokens | 97% |
Each call is context-aware, not atomic: symbol lookups return callers,
callees, data dependencies, and impact radius; file summaries return
cross-file relationships; renames return a previewed multi-file diff. One
LeIndex call replaces chains of Grep → Read → Read → Read.
Methodology:
docs/TOOL_SUPREMACY_BENCHMARKS.md.
Quick start
Install (pick one — then run leindex setup to provision the neural path):
# cargo (Rust users)
cargo install leindex
cargo install leindex --features onnx --force # ensure the ONNX runtime is linked
leindex setup
# npm (Cursor / Claude Code / VS Code users)
npm install -g @leindex/mcp
npm run setup --prefix "$(npm root -g)/@leindex/mcp"
# PyPI (Python users; bootstraps the Rust binary via cargo)
pip install leindex && leindex setup
# prebuilt release bundle
curl -fsSL https://raw.githubusercontent.com/scooter-lacroix/LeIndex/master/install.sh -o install-leindex.sh
bash install-leindex.sh && leindex setup
The setup wizard selects local Qwen3 ONNX, managed EmbeddingGemma2 GGUF, an
external embeddings server, or the existing configuration. TF-IDF and the PDG
remain available without a neural provider. Non-interactive --neural selects
local Qwen3; use --embedding keep to retain an existing route.
leindex setup --embedding qwen3 --cpu
# Linux managed service: explicit compatible runtime, or verified official download
leindex setup --embedding embeddinggemma2 --download-llama cpu --gpu-layers 0
# Alternative: --llama-server /absolute/path/to/llama-server
leindex setup --embedding remote --embedding-endpoint http://127.0.0.1:9000/v1 \
--embedding-model your-served-model
leindex setup --check
ONNX --cpu/--gpu amd|nvidia selects a local execution provider; llama.cpp
--gpu-layers controls managed offload independently. Official runtime backends
are cpu, vulkan, and cuda on supported Linux architectures. Managed setup
binds loopback only; use an authenticated external server for nonlocal inference.
Remote routes do not require ORT or a local Qwen model. --check makes a bounded
embedding request without starting services; start a stopped managed service first.
See neural setup for authentication, dimensions and templates.
leindex setup --system-one opens the System One wizard in a terminal. The gate
requires a system-one build and LEINDEX_FEATURE_SYSTEM_ONE=1 in the serving
process; configuring it does not enable the runtime flag.
Inspect or edit configuration without rerunning setup:
leindex config path
leindex config show
leindex config get search.search_mode
leindex config set search.search_mode '"hybrid"'
leindex config unset indexing.embeddings.remote_endpoint
leindex config validate
Values passed to config set are TOML; strings need the inner double quotes.
Store API-key environment variable names, never credentials, in shared config.
Index and search:
leindex index /path/to/project # ~seconds; re-indexes are delta-priced
leindex search "authentication flow"
leindex analyze "how authorization is enforced"
Connect your agent (MCP stdio):
{
"mcpServers": {
"leindex": {
"command": "npx",
"args": ["-y", "@leindex/mcp"]
}
}
}
Replace npx -y @leindex/mcp with leindex mcp if you installed the binary
directly. Zed, Cursor, VS Code, and Claude Code configuration snippets are in
docs/MCP.md. Long-running servers self-exit after
[mcp] idle_timeout_secs (default 1800) and evict idle engines after
engine_max_idle_secs (default 600).
Environment variables: LEINDEX_HOME (storage root, default
~/.leindex), LEINDEX_PORT (HTTP server, default 47500), ORT_DYLIB_PATH
(ONNX Runtime override). Memory rails — LEINDEX_WORKER_MAX_RSS_MB (default
10240), LEINDEX_WORKER_MIN_AVAILABLE_MB (default 2048),
LEINDEX_REGISTRY_MAX_HEAP_MB (default 1536), the Engram bounds
LEINDEX_ENGRAM_MAX_ENTRIES (20000) and LEINDEX_ENGRAM_MAX_MB (256) — plus the escape hatches
LEINDEX_CLI_SHUTDOWN_DAEMON, LEINDEX_ALLOW_MULTIPLE_EMBED_DAEMONS, and
the LEINDEX_FEATURE_* rollout kills catalogued in
.env.example. The experimental System-One
decision gate (source builds with --features system-one) additionally needs
LEINDEX_FEATURE_SYSTEM_ONE=1 and a [system_one] section — see
leindex.toml.example.
The optional System-One gate requires a source build with --features system-one.
Set LEINDEX_FEATURE_SYSTEM_ONE=1 in the MCP server's environment (the client's
env object for stdio, or the HTTP server's environment), then add this to
$LEINDEX_HOME/config/leindex.toml (default ~/.leindex/config/leindex.toml):
[system_one]
mode = "shadow" # observe decisions first; use "enforce" to apply them
provider = "openai"
base_url = "https://api.openai.com/v1"
model = "gpt-4.1-mini"
api_key_env = "SYSTEM_ONE_API_KEY" # environment variable NAME, never the key
timeout_ms = 10000
top_n = 5
Set SYSTEM_ONE_API_KEY through your server's secret environment, not in this
file or a committed MCP config. For a local service, use provider = "laya"
with its HTTP base URL and served model, and omit api_key_env. Keep
mode = "off" (the default) to disable the gate; leindex setup --system-one
opens the terminal wizard.
How it works
Tree-sitter parses every source file into symbols that feed two layers over the same nodes: a TF-IDF lexical corpus and a Program Dependence Graph (call edges, data flow, containment). The configured neural worker embeds the same nodes for semantic scoring, joined after readiness — terminal failure preserves the complete TF-IDF/PDG result.
Codebase → Tree-sitter → PDG + TF-IDF (core, always) → neural join → hybrid ranking
- Indexing is resumable and delta-priced. Phase checkpoints
(scan → parse → pdg → lexical → neural) resume after interruption;
re-indexes only re-embed changed content; unchanged PDG edges write
nothing (
save_pdgdiffs at the edge level). - Generations are immutable and content-addressed. Publication uses a
staging→promote pattern with blake3-hashed layers; no-op reindexes are
byte-identical, and
leindex retention --gckeeps the store bounded. - Memory is bounded by construction. Streaming pipeline, admission control (admit/defer/reduce — never error), a single RSS-capped embed daemon with idle eviction, and byte-budgeted registry eviction.
Use cases
- Understanding unfamiliar codebases — ask questions instead of reading every file
- Onboarding — find relevant code without tribal knowledge
- Legacy exploration — surface logic buried in decades of code
- AI coding assistants — give LLMs real structural context over MCP
- Refactoring with confidence — impact analysis and previews before touching disk
- Cross-project search — query multiple repositories at once
Under the hood
- 18 MCP tools — search, navigation, analysis, and safe editing (preview/dry-run/preview-only defaults on every destructive path)
- Honest degradation everywhere — direction labels on impact figures, notes when enrichment was skipped,
signature_scopeon incremental counts, freshness footers separated from machine-readable JSON - 5-phase analysis — structural scan, dependency map, logic flow, critical path, synthesis; freshness-aware and incremental
- Dashboard — Bun + React operational UI with project metrics and graph telemetry
- HTTP + WebSocket server —
leindex serve - Flexible embedding backends — TF-IDF, local ONNX models, or remote providers (OpenAI, Cohere)
- Built in Rust — fast, low-memory, safe concurrency
Learn more
BENCHMARKS.md— resource benchmarks, model bake-off, acceptance-gate evidencedocs/NEURAL_SETUP.md— CPU/GPU/AMD/NVIDIA provider setup and troubleshootingdocs/MCP.md— MCP integration for every major clientCHANGELOG.md— full release history, including the v2.0.0 post-release fix roundsARCHITECTURE.md/RUST_ARCHITECTURE.md— system design
License
MIT OR Apache-2.0 — see LICENSE.
Metadata
Release files for leindex 2.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| leindex-2.0.3.tar.gz | 26.8 kB | Without provenance | Details for leindex-2.0.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| leindex-2.0.3-py3-none-any.whl | Python 3 | none | any | Details for leindex-2.0.3-py3-none-any.whl |
Total release size: 43.2 kB
Release files / leindex-2.0.3.tar.gz
| Download URL | leindex-2.0.3.tar.gz |
|---|---|
| Size | 26.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
374619e29e1084dba2817e9f0314947f17d6a921b1879005502382339e074e03
|
|
BLAKE2b-256 checksum How to use checksums |
04fabca2abee67d30e54983fd9a3868b29c2128e691863a303ca64aec4c3ba7d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Release files / leindex-2.0.3-py3-none-any.whl
| Download URL | leindex-2.0.3-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f3894f0b39bb83190d7194fa05015aebb88f049e53beb4227d1800c2013f6c03
|
|
BLAKE2b-256 checksum How to use checksums |
72394ab42bf1ca9a3ab933cc66cefb1d269a51b8f925a26e6de411ab4895fc63
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.15
|
Security for leindex 2.0.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.