High-speed, local-model codebase indexer with a live-updating knowledge graph.
graphindex scans a repository, parses it with tree-sitter, builds a knowledge
graph of files and symbols, embeds every node with Qwen3-Embedding-0.6B and
summarizes/tags it with LFM2.5-1.2B-Instruct — all running locally via
an embedded llama.cpp runtime (llama-cpp-python, auto-installed). A
React WebUI renders the graph node-by-node as it is built, and an Ask the
codebase feature answers natural-language questions with grounded, cited
sources.
Everything works offline with no models too, thanks to a deterministic fallback backend — so the full pipeline, UI and tests run anywhere.
Search
- Regex, semantic (vector), fuzzy (typo-tolerant), plain-text
- Filter syntax:
path:lang:ext:kind:scope:branch: - Case-sensitivity toggle, directory/branch scoping
Code intelligence (tree-sitter AST)
- Go-to-definition, find-all-references
- Call hierarchy (callers/callees), inheritance mapping
- Type/kind disambiguation of same-named symbols
- Languages: Python, JavaScript, TypeScript/TSX, Go, Java, Rust (extensible)
Knowledge graph
- Files, classes, functions, methods, interfaces, imports, externals
- Edges: contains, defines, calls, imports, inherits, references, similar
- Live node-by-node streaming with a colour state machine (see below)
Ask the codebase (RAG)
- LFM2.5 rewrites the question → embedding retrieval → reads source on disk →
grounded answer with
[ref N]citations mapping to file + line + node id - Available in the WebUI, CLI (
graphindex ask) and MCP (ask_codebase)
extended_ask — multi-agent deep investigation
- A local orchestrator built to let a coding agent understand a codebase while spending the fewest possible tokens (it does the reading; the main agent gets one compact, cited answer).
- Up to 2 keyword rounds × 4 queries, then up to 3 parallel search agents per round for up to 10 rounds. Each agent reads index data structures (callers/callees/inheritance/refs) and requests specific source ranges, then the lead synthesizes a grounded answer.
- Reports token-saving stats (nodes inspected, source ranges read, distilled
vs full-file size). WebUI "Deep ask" tab (live), CLI
graphindex extended-ask, MCPextended_ask. - Each indexed function stores its full parameter setup and a search string (the canonical embedding input) alongside its summary.
Analysis
- Dead-code detection, duplicate/near-duplicate detection
- Language breakdown, internal+external dependency graph
- Index health metrics (speed, errors, unresolved refs)
- Automated pruning of deleted files; incremental watcher
Interfaces
- CLI (
graphindex …), Flask REST + WebSocket API, MCP server (stdio) - Respects
.gitignoreand a custom.graphignore(full gitignore semantics incl.!negation); commit-aware (records the git SHA)
| State | Colour | Meaning |
|---|---|---|
| discovered | gray | file/symbol found |
| parsed | yellow | AST parsed |
| embedded | blue | vector stored |
| summarized | green | summarized/tagged |
| hub | red | high-degree node |
| unresolved | orange | unresolved reference / external |
| warning | purple outline | duplicate / dead-code flag |
scanner/ repo walk + .gitignore/.graphignore
parsing/ tree-sitter AST -> symbols (calls, bases, imports)
graph/ node/edge model, builder, resolver (def/refs/calls/inherit/types)
chunking/ symbol -> embedding text
engine/ embedded llama.cpp: autoinstall, GGUF download, in-process + server
embedding/ Qwen3-Embedding-0.6B | HF InferenceClient | deterministic fallback
summarize/ LFM2.5-1.2B-Instruct | HF InferenceClient | heuristic fallback
storage/ SQLite (graph+meta+FTS) + FAISS (numpy fallback) vector store
search/ regex / semantic / fuzzy / filtered / scoped
analysis/ dead code, duplicates, languages, dependencies, health, prune
qa/ grounded ask-the-codebase RAG
pipeline/ orchestrator (10-step) + event bus (node-by-node streaming)
watcher/ incremental re-index on file changes
api/ Flask + SocketIO server, REST routes, MCP server
frontend/ React + react-force-graph-2d live graph UI
- Scan repo → 2. Respect
.gitignore/.graphignore→ 3. Parse (tree-sitter) → 4. Build graph nodes+edges → 5. Chunk symbol content → 6. Embed (Qwen3) → 7. Summarize/tag (LFM2.5) → 8. Store (SQLite + FAISS) → 9. Stream to WebUI node-by-node → 10. Incremental watcher for updates.
graphindex is a normal Python package with a graphindex console-script entry
point. The base install gives you the full CLI, WebUI and pipeline — it uses
the deterministic fallback backend for embeddings + summaries so it runs
anywhere, with zero model downloads.
# 1) Create a venv (Python 3.10-3.12 recommended; 3.13+ may lack tree-sitter
# wheels for some grammars).
python -m venv .venv
# Windows:
.venv\Scripts\activate
# Linux / macOS:
source .venv/bin/activate
# 2) Install graphindex itself
pip install graphindex # from PyPI
# or, from a clone of this repo:
# pip install -e .
# 3) (Optional) Real local LLM + fast vector search
# Uses the prebuilt CPU wheel of llama.cpp — no C++ toolchain needed.
# On Windows / Linux / macOS use the abetlen extra-index-url; the PyPI
# sdist of llama-cpp-python needs a compiler.
pip install --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu \
"graphindex[llama,faiss]"
# Everything at once:
# pip install --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu \
# "graphindex[all]"After install, graphindex is on your PATH — open any cmd / PowerShell /
bash, cd into a repo, and run:
graphindex setup . # one-time: download GGUF models (~1.2 GB total)
graphindex index . # build the index (streams live progress)
graphindex serve . --watch # WebUI at http://localhost:8000
graphindex ask . "what does the bump function do"graphindex setup <repo> auto-installs the llama.cpp runtime (when missing)
and downloads the GGUF models (Qwen/Qwen3-Embedding-0.6B-GGUF,
LiquidAI/LFM2.5-1.2B-Instruct-GGUF) to ~/.cache/graphindex/models.
auto(default) — use the real llama.cpp models when present, else fallbackllamacpp— force the embedded Qwen3 + LFM2.5 modelshf— usehuggingface_hubInferenceClient(remote provider or a local OpenAI-compatible endpoint viaGRAPHINDEX_HF_ENDPOINT)fallback— deterministic, dependency-free embeddings + heuristic summaries
# Build the index (streams progress)
graphindex index /path/to/repo
# Search
graphindex search "lang:python kind:function auth token" --semantic --fuzzy
graphindex search "^make_.*" --regex
# Ask the codebase (grounded, cited)
graphindex ask "How are inheritance edges resolved across files?" /path/to/repo
# Stats / maintenance
graphindex stats /path/to/repo
graphindex prune /path/to/repo
# Live WebUI + API (open http://localhost:8000)
graphindex serve /path/to/repo --watch
# MCP server (stdio) for agents/IDEs
graphindex mcp /path/to/repocd frontend && npm install && npm run build # served by `graphindex serve`
# or: npm run dev (proxies /api + /socket.io to :8000)GET /graph · GET /node/<id> · GET /search · POST /ask · GET /stats
· GET /health · POST /index · POST /prune · GET /config
WebSocket channel index_event streams node_add / node_update /
edge_add / phase / stats / done.
pip install pytest && pytest # 31 tests (fast, fallback backend)Embedding/summarization speed depends on the llama.cpp build. The generic CPU
wheel is portable but slow for large files; for production use a BLAS/AVX or
CUDA/Metal llama-cpp-python build (or the hf backend) for a large speedup.
The deterministic fallback backend is always instant.
| Var | Default | Effect |
|---|---|---|
GRAPHINDEX_LOG_LEVEL |
INFO |
Root Python logging level. |
GRAPHINDEX_ACCESS_LOG |
off | Set 1 to re-enable the per-request access log from Werkzeug/Engine.IO/Socket.IO that graphindex serve silences by default. |
GRAPHINDEX_LLAMA_LOG |
error |
Verbosity of the embedded llama.cpp C logs: silent | error | warn | info | debug. |
GRAPHINDEX_LLAMA_LOG_SUPPRESS |
1 |
When 1, well-known benign warnings (e.g. llama_context: n_ctx_seq (2048) < n_ctx_train (32768) -- the full capacity of the model will not be utilized) are dropped and any identical message is printed at most once per process. Set to 0 to see every occurrence. |