indexkit¶
Local-first semantic and hybrid search
A bin/indexkit CLI that chunks and embeds a corpus with ollama and indexes it
with turbovec (a quantized vector index). Optional --hybrid retrieval
fuses vectors with SQLite FTS5/BM25. The default Ollama endpoint is localhost
and needs no API key; a configured remote endpoint receives submitted text.
indexkit is notes-first but corpus-agnostic: loaders are pluggable, so the same
engine can index Markdown notes, code, or any text corpus. Named indexes persist
across sessions for fast repeat queries.
Install¶
The CLI is published on PyPI and works on its own, with no plugin host:
Install it as a plugin when you also want the bundled skill, so an agent knows when to reach for semantic retrieval:
Requirements¶
-
ollamarunning locally with an embedding model: -
SQLite compiled with FTS5 for optional
--hybridqueries. Semantic-only retrieval remains available when FTS5 is absent. uv— only for the plugin venv bootstrap. Apip installneeds nothing beyond Python 3.10+.
Claude Code and GitHub Copilot CLI both create the venv automatically on session
start (the plugin's SessionStart hook) into ${CLAUDE_PLUGIN_DATA}/venv.
APM does not deploy hooks, so on APM — or wherever --check reports a
missing venv — install the package and the plugin launcher will find it on
PATH:
When --check reports stale, bootstrap instead: the launcher prefers an
existing venv over PATH, so a packaged install would be shadowed by the stale
one. Rebuild it from a clone:
export CONTEXT_KIT_DATA="$HOME/.local/share/context-kit"
bash plugins/indexkit/scripts/bootstrap.sh
export PATH="$PWD/plugins/indexkit/bin:$PATH"
Usage¶
indexkit index <path> --name notes # build/update (incremental)
indexkit query "your question" --name notes --k 8
indexkit query "your question" --name notes --k 8 --hybrid
indexkit status --name notes # counts, model, dim
indexkit list # known indexes
indexkit remove --name notes --yes # permanent, non-interactive removal
Each named index is persisted under ${CONTEXT_KIT_DATA}/indexes/<name>/ (or
${CLAUDE_PLUGIN_DATA} inside Claude Code), so queries are fast and survive across
sessions.
Index lifecycle¶
Index names remain backward-compatible with earlier releases: any non-empty
single path component except . or .. is accepted, including names with
spaces or more than 80 characters. Path separators (/ and \) and NUL are
rejected. The same containment validation protects index, query, status,
and remove.
indexkit remove --name NAME --yes permanently removes exactly one named index and
never prompts. It refuses to run without --yes, fails clearly for missing
indexes, and refuses while that index is in use. Indexing, querying, status
inspection, and removal share a per-index process lock. Once locked, removal
moves the selected index out of the active namespace before non-recursively
unlinking its flat artifact files. Other indexes remain untouched; any
incomplete cleanup reports the quarantined artifact location.
Hybrid retrieval and scoping¶
--hybrid retrieves a deeper semantic and lexical candidate set, then applies
deterministic reciprocal-rank fusion. It preserves vector similarity, BM25,
per-source ranks, fused rank/score, and source offsets in JSON output:
This helps exact names and intent reinforce one another without pretending their
raw scores are directly comparable. If FTS5 is unavailable, --hybrid fails
clearly; it never silently degrades to semantic-only results.
indexkit query accepts an --allowlist of candidate documents (from a file, or -
for stdin). The allowlist scopes both semantic and lexical candidates:
# Feed Obsidian backlinks into a semantic query
obsidian backlinks file="Project X" | indexkit query "open risks" --name notes --allowlist -
This is the bridge the obsidian plugin drives. After either query
mode surfaces a candidate, use the returned offsets plus rg or Read to pin the
exact evidence.
Configuration¶
Set via Claude userConfig or the portable environment variables:
| Variable | Purpose | Default | Claude fallback |
|---|---|---|---|
CONTEXT_KIT_DATA |
venv and index storage | — | CLAUDE_PLUGIN_DATA |
CONTEXT_KIT_EMBED_MODEL |
ollama embedding model | nomic-embed-text |
CLAUDE_PLUGIN_OPTION_EMBED_MODEL |
CONTEXT_KIT_OLLAMA_HOST |
ollama base URL | http://localhost:11434 |
CLAUDE_PLUGIN_OPTION_OLLAMA_HOST |
The pre-rename PRODUCTIVITY_SKILLS_* names still resolve as a deprecated alias
(CONTEXT_KIT_* → PRODUCTIVITY_SKILLS_* → Claude fallback).
At a glance¶
| Category | retrieval |
| Provides | bin/indexkit CLI, a skill, a bootstrap hook |
| Engine | ollama embeddings + turbovec vectors + optional SQLite FTS5/BM25 RRF |
| Dependencies | ollama + an embedding model; uv for the plugin bootstrap only; SQLite FTS5 for --hybrid |
| License | MIT |