个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Ask the index, get the line — local knowledge index for AI agents
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Ask the index, get the line. Your docs, live inventories and code, indexed for your AI agent — one binary. It stops digging through folders: it asks, and gets back small, sourced passages over MCP, a resident daemon or the CLI.
status tells the agent how fresh the index is.status they can trust.v3 is a ground-up rewrite: a retrieval core plus a code graph (symbols, callers, change impact, doc ↔ code links — docs/v3/CODEGRAPH.md).
cosine + α · bm25 / bm25_max. Identifier-like queries get a higher α.
With the built-in hash embedder, α is raised so BM25 leads.A 100-question golden set (exact-identifier and natural-language questions from a real private workspace, kept out of the repo) gates every change.
| Configuration | MRR | hit@1 | hit@5 | missed |
|---|---|---|---|---|
| Hybrid, qwen3-embedding 0.6b, tuned prompt template | 0.795 [0.739–0.848] | 71 % | 92 % | 8 |
| Same, generic prompt template | 0.754 | 67 % | 88 % | 12 |
| Built-in embedder, fully offline (128-d) | ≈ 0.51 |
Hybrid score fusion beat reciprocal rank fusion on that set. Details and history: docs/ROADMAP.md.
One binary, no runtime dependency. Source and releases live at
github.com/kerbart/ctxq. The one-liner
downloads a SHA-256-verified archive from GitHub Releases (ctxq.dev mirrors
them), installs it to ~/.local/bin, and puts ctxq on this shell's PATH.
Linux x86_64 is musl-static (Alpine and glibc distros). Linux arm64 and macOS
ship from the same command.
curl -fsSL https://ctxq.dev/install.sh | sh && . "$HOME/.ctxq/env"
# same installer: https://raw.githubusercontent.com/kerbart/ctxq/main/install.sh
Then, from a project:
ctxq setup
ctxq search "how do I deploy the api?"
Windows: use WSL. CTXQ_BINDIR changes the destination. Project page:
https://ctxq.dev.
From source:
cargo install --git https://github.com/kerbart/ctxq.git --locked
# or: cargo build --release # target/release/ctxq
# optional embedded ONNX model: cargo build --release --features onnx-embeddings
Cutting a release: bump version in Cargo.toml, commit, then
scripts/release.sh vX.Y.Z (tags and pushes; .github/workflows/release.yml
does the rest). ci.yml runs cargo test --release on every push.
cd my-workspace
ctxq setup # 1. index + register ctxq in your agents
ctxq search "how do I deploy the api?" # 2. ask it yourself
That is all. Your CLIs (Claude Code, Copilot, Codex, Grok, Gemini) and
any editor already configured in the repo now list ctxq among their tools —
restart them once. ctxq setup --interactive asks two questions, one line
each: the embedding provider, then which CLIs get the server.
ctxq setup --embed ollama writes that provider into ctxq.toml before
indexing (qwen3-embedding:0.6b on http://localhost:11434). An empty answer
keeps the current one. --embeddings still overrides a single run and does
not save. You never start the MCP server yourself: the CLI launches
ctxq mcp in the background and talks to it over stdin/stdout.
One index per workspace root (the directory you ran ctxq setup in).
It sits outside the tree, at ~/.cache/ctxq/<name>-<hash>/docs.db (or
<root>/.ctxq/ if you passed --in-repo). ctxq doctor prints the path.
ctxq setup --force-home indexes all of $HOME. That is a different
index from a project inside it:
ctxq setup --force-home # index A: ~/.cache/ctxq/<you>-…/docs.db
cd ~/engie && ctxq setup # index B: ~/.cache/ctxq/engie-…/docs.db
Two indexes. They do not merge. Searching from ~/engie uses B; searching
from $HOME uses A (which also contains the engie files as a subset).
Markdown, office, PDF and code are indexed; .git, archives, secrets and
gitignored files are skipped.
ctxq setup registers the CLIs it finds. Claude Code gets .mcp.json.
Copilot gets ~/.copilot/mcp-config.json. Codex and Grok get a project
file (.codex/config.toml, .grok/config.toml) and a user file
(~/.codex/config.toml, ~/.grok/config.toml). Copilot, Codex and Grok
follow the directory you launch them from: their user entry has no
--path, so one repo does not steal the others. Restart the CLI, then
check its MCP list. Do not run ctxq inside the Codex shell: its bwrap
sandbox cannot launch it; the MCP tools are the path that works.
search keeps the index warm in a background daemon it starts on first use
(milliseconds per query afterwards; docs re-sync every 60s). --no-daemon
searches in-process.
Filters: --tag legal --type pdf --since 2026-01-01 --path docs/, --json for
scripts. ctxq sync refreshes the index after big changes (the daemon
also re-syncs periodically).
For real semantic search, put a ctxq.toml at the workspace root (or
point $CTXQ_CONFIG at one) and pick an embedding server:
# A local or LAN server — no credentials
[embed]
backend = "ollama"
urls = ["http://gpu-box:11434", "http://localhost:11434"] # tried in order
model = "qwen3-embedding:0.6b"
# An API with a key — OpenAI or any compatible server (LM Studio, vLLM, TEI…)
[embed]
backend = "openai"
urls = ["https://api.openai.com"]
model = "text-embedding-3-small"
api_key_env = "OPENAI_API_KEY" # the NAME of a variable, not the key
export OPENAI_API_KEY="sk-..." # shell profile or secret manager
The key never goes in the file: ctxq.toml can be committed, the key
stays in your environment and is sent as Authorization: Bearer to the
embedding server only. Same pattern for Qdrant, federated peers
(api_key_env) and the daemon's HTTP API (http_token_env).
| Kind | How |
|---|---|
| Markdown | sections by H2/H3 with breadcrumbs; front matter (title, summary, tags, date, source_type) becomes metadata and filters |
| Office / PDF | .docx, .pptx (with speaker notes), .xlsx (one row = one passage), .pdf → markdown, in-process |
| Inventories | [[scan.source]]: any command's output, or built-in docker, systemd, ports, projects, scripts collectors; tables indexed row by row |
| Code | Rust, TypeScript/JavaScript, Python, Go, Java, Kotlin, C#: symbols, signatures, doc comments, callers/callees, bodies, change impact, doc ↔ code links ([code] enabled) |
Discovery honours roots (in priority order), .ctxqignore,
.gitignore, size limits, and skips third-party clones (own_remotes).
The binary is generic; ctxq.toml is what turns it into your knowledge base.
Nothing about a machine lives in the code — you describe the environment with
[[scan.source]] blocks, and every scan regenerates those inventories into
[scan] output_dir (default .ctxq/generated, always indexed even though
hidden). A few sources make ctxq the live memory of a host; any shell command
becomes a dated, searchable document.
[scan]
output_dir = ".ctxq/generated"
lang = "en" # prose language of the generated docs: en | fr
[[scan.source]] # built-in collectors — no CLI needed
name = "containers"
kind = "docker" # also: systemd, ports, projects, scripts
[[scan.source]]
name = "projects"
kind = "projects" # each sub-dir + its entry document
dir = "~"
entry_files = ["README.md", "AGENTS.md", "CLAUDE.md"]
[[scan.source]] # any command → a document agents can search
name = "domains"
title = "Public hostnames → local port"
format = "markdown" # "markdown" (as is) or "code" (fenced)
command = ["sh", "-c", "yq -r '.ingress[] | ...' ~/.cloudflared/config.yml"]
Then shape what gets walked for the role you want: roots (what to index),
exclude_top (top-level dirs of a root to skip — note it matches top level
only, so a bulky tree moved under a sub-folder needs an exclude_globs
entry), exclude_dir_names, extensions, and max_file_bytes. A home server,
a monorepo and a research corpus are the same binary with three different
ctxq.toml. See the fully-commented ctxq.example.toml.
| MCP tool | Use it for |
|---|---|
inventory(kind, filter) | exact rows: "which port / container / domain" |
search(query, tags, source_types, since, path_prefixes, max_chars) | ranked passages with metadata |
context(query, scope, max_tokens, page) | docs and code together, within a token budget |
map(prefix, depth) | one-line summary per document — read the map, open only what you need |
annotate(path, summary, tags) | leave what you learned for the next agent |
status() | freshness, store, sources, quarantined and lost files |
code_symbol(name) | signature, doc and body of a symbol |
code_callers / code_callees(name, depth) | who calls it, what it calls |
code_path(from, to) | shortest call chain between two symbols |
code_impact(diff | base, head) | changed symbols → transitive callers → docs that mention them |
code_sync(paths) | re-extract changed files now |
The same operations exist as CLI commands (search, context, explore,
changes, inventory, map, status, annotate) and, for docs, on the
daemon's HTTP API.
Optional — search starts it on demand. Run it yourself to expose the HTTP
API (federation, other tools) or to keep it up permanently:
ctxq daemon --http 127.0.0.1:7700
ctxq daemon --stop
A warm query costs a few milliseconds plus the query embedding (cached,
persistently). The daemon can re-sync and re-scan periodically ([daemon]).
[store]
backend = "qdrant" # default "local" (SQLite, exact)
url = "http://localhost:6333"
collection = "my-docs"
[[store.federate]] # read-only bases queried with every search
backend = "peer" # another ctxq daemon (POST /search)
url = "http://other-host:7700"
name = "team-docs"
weight = 0.8
ctxq store push uploads existing vectors without re-embedding.
Precedence: command-line flags > CTXQ_* environment > ctxq.toml
(or .ctxq.toml, or $CTXQ_CONFIG) > defaults. Every key is
documented in ctxq.example.toml.
bench/eval_docs.py replays a golden question set (recall@k, MRR, bootstrap
confidence interval) against one or several engines; nothing changes the
ranking without passing it.
MIT — see LICENSE.