Code Context Engine is a local repository intelligence layer for AI coding agents.
repository
-> discovery and content hashing
-> language-provider Tree-sitter chunks
-> SQLite storage
-> Tantivy + in-memory BM25 search
-> symbol graph with reference provider evidence
-> context expansion and impact analysis
-> CLI and MCP stdio tools
Search and context-pack tools return compact metadata:
chunk_id- file path
- line span
- symbol name
- chunk kind
- score or expansion reason
- ranking signals
- estimated metadata token cost
Full source is returned only by get_chunk.
The important model objects are:
CodeChunkSymbolRecordGraphEdgeSearchResultImpactReport
Internal search and graph implementations can change as long as these contracts remain stable.
Graph edges carry a provider, confidence, and human-readable evidence.
The built-in provider is heuristic; it is useful for impact hints and context
expansion, but it is not a compiler-grade reference engine.
The indexer exposes registered language-provider descriptors for parser/plugin discovery. The graph layer exposes registered reference-provider descriptors and has a matching language-reference semantics boundary used by the heuristic provider:
- Rust keeps lightweight
useimport edges. - Rust/Java/TypeScript/Python syntactic calls are stored as
callsgraph edges when the target can be inferred by the heuristic provider. - Java records imports,
extends/implementsrelationships, JUnit-style test methods, and receiver-style calls such asnew Worker().work(). - TypeScript/TSX records named imports, import aliases,
class implements, and receiver-style method references/calls such asnew Service().run(). - Python records
import/from ... import ...bindings, subclass relationships, and constructor receiver references/calls such asWorker().run().
Local import aliases can resolve to indexed files in the same repository, which
lets find_references report a caller using run as execute as a reference to
the exported run symbol. This is still syntactic evidence, not full module or
type resolution.
context-mcp also supports configured external reference providers. These
providers are dynamically loaded as external commands during index_repo: the
engine sends repo/chunk/symbol metadata over stdin and expects graph edges on
stdout. Returned endpoints are resolved against existing SymbolRecord anchors
before storage, so external providers can add compiler/type-checker-grade
references and calls edges without owning chunking or persistence.
Provider subprocess I/O is handled concurrently so large stdout/stderr output or
providers that do not read stdin are bounded by the configured timeout rather
than deadlocking the indexer. On Windows, provider commands are attached to an
unnamed Job Object when available; timeout cleanup terminates the Job Object so
child processes from command shims, Node, or language servers are cleaned up with
the provider.
Provider labels remain part of the edge identity. This lets a rust-analyzer/SCIP provider, a TypeScript type-checker provider, and a Python type-checker provider coexist with the heuristic provider for the same symbol pair. Strict providers fail closed on ambiguous or unknown endpoints; non-strict providers skip only the unresolved edges.
context-cli ships first-party protocol adapters for the common compiler-grade
path: rust-analyzer/SCIP for Rust, scip-java for Java, the stable TypeScript
compiler/language-service API for TypeScript/TSX, and Pyright LSP references for
Python. They are still
configured as external commands, so deployments can pin tool paths and timeouts
without changing the engine. The TypeScript adapter checks the stable compiler
API surface before resolving references so toolchain drift fails with explicit
missing-capability diagnostics.
Impact analysis is not a sound compiler-grade call graph. It uses indexed symbols, references, imports, and test associations to produce likely impact hints and recommended verification. Impact item reasons include the edge provider label, so a report can distinguish built-in heuristic evidence from external compiler/type-checker evidence.
context-core shared types
context-indexer file discovery and language-provider chunking
context-storage SQLite persistence
context-search in-memory BM25, persistent Tantivy, local hash vectors, RRF
context-graph reference providers and impact hints
context-mcp MCP stdio server and agent-facing tool contracts
context-cli CLI wrapper
The SQLite database is the source of truth for indexed files. A normal index run compares discovered file hashes, skips unchanged files, replaces changed files, and removes files that no longer exist. --force clears and rebuilds only the selected repository.
SQLite index updates run inside a BEGIN IMMEDIATE transaction so a failed indexing pass does not leave a partially written logical index. After commit, the persistent Tantivy directory is rebuilt from SQLite using a temporary directory and then published by rename. Search can also rebuild Tantivy lazily if the sidecar index is missing or unreadable.
Repository IDs use the canonical repository path plus a stable hash, so two repositories with the same directory basename can share one SQLite database without colliding. Heuristic graph construction is partitioned by repository, and stored graph reads discard any legacy edge whose endpoints resolve to different repositories.
search_code builds an in-memory BM25 index from SQLite for deterministic correctness and also queries the persistent Tantivy sidecar when the database is file-backed. When requested, it adds the local deterministic hash-vector signal. Results are fused with reciprocal-rank fusion and preserve their signal labels, for example bm25, tantivy_bm25, and local_hash_vector.
- Additional language parsers and compiler/type-checker-backed reference providers beyond the current Rust, Java, TypeScript/TSX, and Python paths.