Skip to content

Core concepts

Five minutes here makes every other page shorter. CodeNavi has a small number of ideas that everything else — the MCP tools, the web UI, the CLI — is built on.

Codebases

One CodeNavi server indexes many repositories. Each is a codebase with a name (laravel, billing, …). Every search can be scoped three ways:

  • per call — codebase="laravel" on any tool,
  • per endpoint — point a client at /mcp/laravel and everything it does is scoped,
  • per server default — default_codebase in settings. When it is set, every tool treats an empty codebase= as that codebase. Without it, the index-backed searches cover every codebase, and the tools that work on one codebase at a time (read_file, grep_search, list_directory, the call-graph and notes tools) refuse an unscoped call on a multi-codebase server and list the names — they never guess.

list_codebases shows what's indexed. A single-repo install usually has one codebase named default, and you never think about this again.

Chunks

CodeNavi never indexes whole files. Source files are split into chunks along structural boundaries — a function, a class, a method — using AST parsing for 15 languages, with dedicated splitters for SQL, templates, and config, and heading-aware splitting for docs. A chunk is the unit of everything downstream: it's what gets embedded, searched, ranked, cited, and security-scanned. Results always carry the chunk's file:line range, so an answer is a place in your code, not a paraphrase.

Every chunk is tagged with a source type — code, doc, or web (crawled pages, if you enable the crawler) — and results show the tag, so you always know what kind of evidence you're looking at.

The index

Each chunk is embedded by Buric-E4B, CodeNavi's code-specialized embedding model, and stored in a local vector database on your disk. Two properties matter day to day:

  • Incremental by default. After the first full index, a reindex touches only changed files — seconds, not minutes. Wire it to a git hook or let your agent call reindex_incremental when results look stale.
  • Never blocks search. Rebuilds happen in a shadow copy and swap in atomically; queries keep answering the whole time, and every result reports index freshness.

The search pipeline

A query flows: embed → vector search → cross-encoder rerank → bounded top-N. The reranker re-reads the query against each candidate chunk and reorders by actual relevance, and the response is cut to a token budget — a ranked, decision-ready list, not a haystack.

One thing to internalize: scores are relative, not calibrated confidence.1 The top hit of one search can score 0.15 and be exactly right. Judge by order and by gaps between scores, never by absolute level — and tell your agent the same (the bundled agent rules already do).

The call graph

Indexing also builds a relations sidecar: which symbol calls which, per codebase. This is what answers the questions embeddings can't:

  • find_callers — who actually calls this function (real call sites, multi-hop),
  • impact_analysis — blast radius of changing a symbol, with heavily-connected hub symbols flagged by centrality,
  • diff_impact — what a concrete diff touches downstream,
  • graph_neighborhood — a bounded caller/callee sub-graph, rendered interactively in the Graph screen.

Semantic search finds what code means; the call graph knows how code connects. Change-safety questions belong to the graph.

The Docs Wiki

Search retrieves fragments; the Wiki compiles knowledge. An LLM synthesizes standing pages across your indexed documentation — architecture overviews, runbooks, onboarding notes — each claim carrying a source locator back to the underlying document, with staleness tracking when sources change. Compilation is explicit and consent-gated: nothing is sent to a remote model unless you configured one and confirmed. Each compiled page is then checked: a package, file path or code symbol it names must appear in the page's source documents or exist in the indexed code. Any name that does not is marked (unverified) on the page and listed in a warning above the sources, so an agent reading the page knows not to trust it.

The security scanner

Every chunk passes one scanner before it enters the index. Secret-like values (API keys, tokens, DSNs, private keys) are redacted at indexing time — they never appear in results, chat context, or logs. Files that look malicious are quarantined and never indexed; merely suspicious chunks are indexed but flagged, and the retrieval gate keeps them out of results until you allowlist them with an audit reason. Managed from the Security screen.

The local boundary

The default deployment is fully local: indexing, embedding, search, reranking, and the call graph all run on your hardware, with zero telemetry. Two features can use an LLM — chat and the Wiki — and both default to local providers (Ollama, vLLM, LM Studio, or any OpenAI-compatible endpoint). Cloud providers are an explicit opt-in with a warning before anything leaves the box, and even then receive ranked chunks, not whole files.

Which tool answers which question

You're asking Reach for
"How does password reset work here?" semantic_search
"Where is DB_HOST used, exactly?" grep_search
"Where is UserAuth defined?" symbol_search
"What breaks if I change this?" impact_analysis, find_callers
"What does this diff touch?" diff_impact
"Give me the lay of the land" codebase_overview
"Summarize our deployment docs" chat, wiki_page

The full tool list is in the API reference; the rules your agent should follow are in Rules for your agent.


  1. Vendor change reference CN-396. ↩