Skip to main content

grep, but semantic, for your Claude Code conversation history. Local-first, hybrid BM25+vector retrieval.

Project description

claudegrep

grep, but semantic, for your Claude Code conversation history. Local-first, private, fast.

Every Claude Code session vanishes the moment you close it. claudegrep indexes your ~/.claude/projects/ JSONL files into a single SQLite database and gives you a fast CLI (recall) to find any past turn — hybrid BM25 + vector search with optional cross-encoder reranking.

$ recall search "sqlite vec hybrid"
1. 2026-04-29  claude-recall  score=-18.4
   how should we store the chunk vectors — sqlite-vec or lancedb?
   [assistant] for <10M vectors sqlite-vec wins on ops simplicity…

2. 2026-04-22  gstack         score=-14.1
   …

Status

Week 5 / 6recall serve is live: a local FastAPI + HTMX web UI at http://127.0.0.1:7777 with hybrid search, inline filters, session viewer, and one-click "copy turn" to clipboard. v0.3.0 ships it. See PLAN.md.

Install

# CLI only (~120 MB with embedder model)
uv tool install claudegrep
# or:
pipx install claudegrep

# CLI + local web UI
uv tool install 'claudegrep[serve]'

# first run
recall index
recall search "your query"
recall serve              # opens http://127.0.0.1:7777

Dev install:

git clone https://github.com/lbbstarry/claudegrep
cd claudegrep
uv sync
uv run recall index

Commands

Command What it does
recall index Scan ~/.claude/projects/ and index + embed new/changed sessions (incremental via mtime + sha256). --no-embed for BM25-only.
recall search <q> Hybrid BM25 + vector search by default. --mode bm25|vector|hybrid, --rerank, --limit N, --project NAME. Inline filters: project:foo since:7d role:user tool:Bash.
recall show <session> Render a session as Markdown. Accepts an 8+ char prefix; use --turn N to view one turn.
recall inject <chunk> Copy a chunk's text to your clipboard so you can paste it into a new Claude session.
recall export <session> -o file.md Export a session to disk as Markdown.
recall watch Re-index in the background as JSONL files change (debounced; uses polling on WSL2).
recall serve Local web UI on 127.0.0.1:7777 (FastAPI + HTMX). Requires [serve] extras.
recall stats Index size, vector count, DB path.
python -m claude_recall.eval.run Run the labeled eval set, print Recall@10 / MRR / nDCG@10, write benchmarks/eval_results.md.

Coming in Week 6+:

  • bge-m3 + query expansion (planned biggest single eval bump)
  • Pro tier: encrypted cross-machine sync, voyage-3-lite embedder
  • v1.0 + Product Hunt launch

Architecture

~/.claude/projects/*.jsonl
    │
    ▼
parsers/claude_code.py    typed Message records
    │
    ▼
ingest/chunker.py         per-turn chunks (one user msg + following assistant)
    │
    ▼
embed/local.py            sentence-transformers (bge-small-zh) + disk cache
    │
    ▼
store/                    SQLite + FTS5 + sqlite-vec (vec0 virtual table)
    │
    ▼
search/                   bm25 · vector (KNN) · hybrid (RRF) · rerank (cross-encoder)
    │
    ▼
cli.py                    Typer app

Why per-turn chunks? Per-message loses Q-A pairing; sliding-window inflates the index 3-5×. A turn averages ~1.2k tokens — perfect for bge-m3's 8k context, no truncation needed.

Why SQLite + FTS5 + (later) sqlite-vec? Single file, zero ops, ships with the wheel, hybrid search is a JOIN away. Beats Chroma at this scale.

Eval

51 hand-labeled (query, relevant_chunk_id) pairs from real developer sessions in tests/fixtures/queries.jsonl. Index size: 6,593 chunks across 127 sessions / 6 projects. Reproduce with python -m claude_recall.eval.run.

Method Recall@10 MRR nDCG@10 p95 ms
BM25 (FTS5) 0.216 0.125 0.148 2
Vector (bge-small-zh-v1.5, 512d) 0.353 0.175 0.217 13
Hybrid (RRF) 0.392 0.175 0.228 16
Hybrid + rerank (bge-reranker-base) 0.471 0.230 0.289 214

Hybrid + rerank gives +118% Recall@10 and +95% nDCG@10 over BM25. Reranker latency is dominated by CPU cross-encoder inference; GPU or bge-reranker-v2-m3-onnx will reduce it. Numbers are CPU-only on a WSL2 Ryzen laptop.

Why the absolute numbers look modest: the eval queries are deliberately short (median 5 chars) and developer-domain-specific, e.g. prefab, figma示例. That is the realistic distribution for "I vaguely remember talking about this last month" — and the gap between methods, not the absolute floor, is what matters. Query expansion and bge-m3 (8k context, multilingual) are next.

Roadmap

  • Week 1 — Typer CLI, SQLite + FTS5, incremental ingest, BM25 search
  • Week 2 — bge-small-zh embeddings, sqlite-vec, RRF hybrid, reranker, 51-query eval
  • Week 3show/inject/export, watch daemon, filter DSL, --rerank flag
  • Week 4 — v0.2 on PyPI, eval blog post drafts (EN + ZH)
  • Week 5recall serve (FastAPI + HTMX local UI), v0.3
  • Week 6 — v1.0, Pro tier (cloud sync, Voyage embedder), Product Hunt

Privacy

Everything stays on your machine. The index is a single SQLite file under your OS's user data dir (~/.local/share/claude-recall/recall.db on Linux). No network calls are made by the OSS build.

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claudegrep-0.3.0.tar.gz (166.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claudegrep-0.3.0-py3-none-any.whl (33.4 kB view details)

Uploaded Python 3

File details

Details for the file claudegrep-0.3.0.tar.gz.

File metadata

  • Download URL: claudegrep-0.3.0.tar.gz
  • Upload date:
  • Size: 166.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for claudegrep-0.3.0.tar.gz
Algorithm Hash digest
SHA256 505f37c0f56251dcf4f2e32bb6310c776de6de3735031a40d7aa07482c08b335
MD5 6a5f0bc6bc3fabeb44357f71b72e98d1
BLAKE2b-256 6b8c3b9299ad7a9aabe1bd87aa24a334a7f5b3424d7aac3abbebdd1b15a2425b

See more details on using hashes here.

File details

Details for the file claudegrep-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: claudegrep-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 33.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for claudegrep-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 565302643c744d1bd1475dd556656d64188a64ddaf3d61b0bd9e82f6dbd36f14
MD5 433849292b4b5fd3ec3b734a57601c47
BLAKE2b-256 382ba6f94dcc2328ebac81c87bf7fee51d0ae0686d77145024e96423a66a6c6e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page