Searchable memory for AI coding-agent sessions (Claude/Gemini/Codex) — FTS5 + vector hybrid search
Project description
convo-recall
Searchable memory for your coding-agent conversations — across sessions, across projects, across Claude Code™, Codex™, and Gemini™.
Coding agents are stateless by design. convo-recall makes them stateful by infrastructure: every conversation lands in one local SQLite index, searchable by keyword and semantic meaning, and auto-fed back into the agent's context on every prompt.
recall search "how did we fix the auth middleware"
recall search "approaches we tried for the chunking problem" --recent
recall search "deployment config" --all-projects
recall search "the prompt that worked" --agent gemini
Key features
- One memory across every agent. Claude Code™, Codex™, and Gemini™ sessions all land in the same SQLite DB. Claude™ can find what Codex did yesterday.
- Verbatim, source-traceable. Full transcripts indexed — not LLM summaries. Every hit links back to the originating session and timestamp.
- Hybrid FTS + vector search. SQLite FTS5 (porter stemming) fused with semantic recall (BAAI/bge-large-en-v1.5, 1024-dim, running locally on MPS/CPU) via Reciprocal Rank Fusion.
- Cross-project recall. Auto-scopes to the current repo by default;
--all-projectsfor global search. - Zero-upkeep ingest. Response-completion hooks index every turn within ~50 ms — no daemons to babysit.
- Auto-context injection. A pre-prompt hook runs
recall searchon every substantive prompt and feeds the top hits to the agent, so it actually knows what you've already worked on. - Local-only, secrets redacted. Everything stays on your machine. OpenAI/Anthropic/GitHub/AWS/JWT/Slack token shapes are stripped on the way in. No cloud, no telemetry.
Runs on macOS or Linux. Python 3.11–3.14. Works with any subset of Claude Code™, Codex™, or Gemini™ CLI.
Install
Pick one path. Both install with hybrid FTS + vector search (the [embeddings] extra) and both end with recall install running the full interactive wizard.
A — From the public Git repo (no clone):
pipx install 'convo-recall[embeddings] @ git+https://github.com/AhedAdwan/convo-recall.git'
recall install
B — From a local clone (use this if you want to edit the source):
git clone https://github.com/AhedAdwan/convo-recall.git
cd convo-recall
pipx install -e '.[embeddings]'
recall install
recall install runs an interactive wizard that walks through every decision (response-completion ingest hooks, embed sidecar, pre-prompt search hooks, initial ingest) — each prompt prints what happens if you answer yes vs. no.
The wizard kicks off the initial ingest + embed-backfill in a detached background process so it returns control immediately. Watch progress with recall stats (one-shot tqdm bar at the top while the job is active) or tail -f ~/Library/Logs/convo-recall-wizard-backfill.log.
The embedding model (BAAI/bge-large-en-v1.5, ~1.3 GB) downloads on first use. Long texts are chunked with a 450-token sliding window (50-token overlap) and mean-pooled — no silent truncation at 512 tokens.
Uninstall
recall uninstall # removes hooks + sidecar (DB + config preserved)
pipx uninstall convo-recall # removes the package itself
Order matters — recall uninstall first, otherwise the bundled hook script can't be located and entries get left dangling in each agent's settings file.
Full purge (also drops the indexed DB, logs, runtime cruft):
recall uninstall --purge-data
pipx uninstall convo-recall
Settings backups (~/.claude/settings.json.bak.*, etc.) and the BGE model cache (~/.cache/huggingface/hub/models--BAAI--bge-large-en-v1.5/) are always preserved — clean up manually if you want them gone.
Schedulers
recall install picks one of four schedulers automatically — used to supervise the embed sidecar. Since v0.3.5, the response-completion ingest hook handles ingestion, so the scheduler tier matters mainly for keeping the embedding service warm.
| Scheduler | Detected when | Survives reboot | Notes |
|---|---|---|---|
launchd |
macOS | yes | ~/Library/LaunchAgents plists. Default on Darwin. |
systemd |
Linux + systemctl --user is-system-running succeeds |
yes (with linger) | User-mode .service units. Run loginctl enable-linger $USER to keep the sidecar alive after logout. |
cron |
Linux + crontab available, no usable systemd-user |
yes | @reboot lines tagged # convo-recall:*. Tagged-line filtering on uninstall preserves your other crontab entries. |
polling |
always | NO | Last-resort fallback: Popen child. Dies at logout/reboot. |
recall uninstall walks every scheduler, so a host that switched OS gets clean teardown.
Usage
# Search (auto-scopes to current project)
recall search "sqlite vector search"
recall search "chunking strategy" --recent # bias toward recent conversations
recall search "embedding model" --all-projects # search every project
recall search "the failing test" --agent codex # filter to one agent
recall search "bug fix" -n 20
# Recent conversation tail
recall tail # last 30 messages of the latest session in this project
recall tail 50 --all-projects # latest session across all projects
# Maintenance
recall ingest # manual ingest trigger
recall ingest --agent gemini # one agent only
recall stats # DB statistics, per-agent counts
recall doctor # health check + per-agent hook state
# One-time backfills (run after upgrading)
recall embed-backfill # embed any un-embedded messages
recall chunk-backfill # re-embed long messages with chunked mean-pooling
recall backfill-clean # re-clean content + rebuild FTS index
recall backfill-redact # apply secret redaction to existing rows
recall tool-error-backfill # index tool error blocks from existing sessions
Project identity
Every project is identified by:
project_id=sha1(realpath(cwd))[:12]— collision-free, deterministic, hyphen-vs-slash safe. Symlinked paths that resolve to the same target collapse to one id.display_name= basename of the nearest ancestor containing a project-root marker (.git,package.json,Cargo.toml,pyproject.toml,go.mod, …). Falls back to the basename ofrealpath(cwd).
Search and tail accept --project <display_name> and resolve to the right project_id (exact match first, LIKE fallback with a multi-match warning). recall forget --project X requires an exact display_name match — no fallback.
Cross-machine limitation: project identity is path-based. The same repo at ~/work/repo on machine A and /srv/repo on machine B has different project_ids. If you sync the DB across machines, the same logical project appears twice — search across both with recall search foo --project repo (display_name match).
Hooks
convo-recall ships two shell hooks that auto-detect each CLI's payload shape and work across all three:
conversation-memory.sh(pre-prompt) — runsrecall search "$prompt" -n 3 --jsonon every substantive user turn (≥12 chars, not pure interjections like "yes" / "ok" / "hmm") and injects the top hits into the agent's context. Trivial prompts are no-ops. Opt out withCONVO_RECALL_HOOK_AUTO_SEARCH=off.conversation-ingest.sh(response-completion) — fires on Claude™Stop/ Codex™Stop/ Gemini™AfterAgent, spawnsrecall ingestdetached. Throttled to one ingest per 5 s via a lock file. Opt out withCONVO_RECALL_INGEST_HOOK=off.
recall install wires both into every detected CLI. To wire later or selectively:
recall install-hooks # both kinds, all detected CLIs
recall install-hooks --kind ingest # ingest only
recall install-hooks --kind memory # search only
recall install-hooks --agent claude # one CLI
recall doctor # show per-agent wired/NOT-wired state
recall uninstall-hooks # remove only convo-recall blocks
Every operation backs up the original settings file with a .bak.<timestamp> suffix.
Custom instructions
The pre-prompt hook also reads two optional files and prepends them to injected context (each capped at 2 KB):
- Global:
~/.config/convo-recall/instructions.md - Per-project:
.recall-instructions.mdin cwd
Order: global → per-project → prior-context → static reminder.
Continuous ingest
Since v0.3.5, ingestion runs entirely off response-completion hooks. conversation-ingest.sh fires on each CLI's end-of-turn event:
| CLI | Event | Per-turn? |
|---|---|---|
| Claude Code™ | Stop |
✅ yes |
| Gemini™ CLI | AfterAgent |
✅ yes (default-on since v0.26.0) |
| Codex™ CLI | Stop |
⚠ session-end only — Codex hook system limitation |
Codex™ caveats: Codex hooks are experimental and gated behind [features] codex_hooks = true in ~/.codex/config.toml. recall install writes the flag automatically when safely mergeable; skips with a warning when the file is invalid TOML or when running on Windows.
Scheduler-tier watchers (launchd / systemd .path units / cron) are no longer installed by default — the response-completion hook makes them redundant. The watcher install code remains in the codebase for users with bespoke flows; re-enable by uncommenting the _ask block in _wizard.py.
Privacy
convo-recall ingests your conversation history verbatim into a local SQLite DB. To reduce the chance that secrets pasted into chats end up indexed, ingestion runs a secret redaction pass that replaces well-known credential token shapes with stable placeholders before they reach the FTS / vector index.
| Shape | Placeholder |
|---|---|
OpenAI keys (sk-…) |
«REDACTED-OPENAI-KEY» |
Anthropic keys (sk-ant-…) |
«REDACTED-ANTHROPIC-KEY» |
GitHub tokens (ghp_/gho_/ghs_/ghu_/ghr_) |
«REDACTED-GITHUB-TOKEN» |
AWS access keys (AKIA…) |
«REDACTED-AWS-KEY» |
JWTs (eyJ….….…) |
«REDACTED-JWT» |
Slack tokens (xoxb-/xoxp-/…) |
«REDACTED-SLACK-TOKEN» |
Redaction is on by default. Set CONVO_RECALL_REDACT=off to disable (e.g. for security-research workflows where you want raw content). For a DB that pre-dates redaction:
recall doctor --scan-secrets # count what's already indexed
recall backfill-redact # re-apply redaction + rebuild FTS
The DB and its WAL/SHM sidecars are chmod-0600; the parent directory is chmod-0700.
Environment variables
| Variable | Default | Description |
|---|---|---|
CONVO_RECALL_DB |
~/.local/share/convo-recall/conversations.db |
SQLite database path |
CONVO_RECALL_PROJECTS |
~/.claude/projects |
Claude Code™ projects directory |
CONVO_RECALL_GEMINI_TMP |
~/.gemini/tmp |
Gemini™ CLI session root |
CONVO_RECALL_CODEX_SESSIONS |
~/.codex/sessions |
Codex™ rollout root |
CONVO_RECALL_CONFIG |
~/.local/share/convo-recall/config.json |
Enabled-agents config file |
CONVO_RECALL_SOCK |
~/.local/share/convo-recall/embed.sock |
Embedding sidecar socket path |
CONVO_RECALL_REDACT |
on | Set to off to disable secret redaction during ingest |
Embedding sidecar protocol
The sidecar exposes HTTP over a Unix socket. Bring your own embedding service by pointing CONVO_RECALL_SOCK at a socket that implements:
POST /embed
Body: {"text": "...", "mode": "query"|"document"}
Response: {"vector": [...N floats...], "dim": N, "protocol": 1}
GET /healthz
Response: {"model": "...", "dim": N, "device": "...", "protocol": 1}
The bundled sidecar uses 1024-dim vectors. If your service uses a different dimension, run recall embed-backfill after switching.
License
Fair Source. convo-recall is licensed under the Functional Source License v1.1, Apache 2.0 Future License (SPDX: FSL-1.1-Apache-2.0) — the same Fair Source license used by Sentry, Codecov, Liquibase, GitButler, and Keygen. After two years, each released version converts automatically to the Apache License, Version 2.0.
In addition, all use is subject to the convo-recall Acceptable Use Policy, which is a perpetual ethical-use rider that survives the Apache 2.0 conversion.
What you may do — for free, with no further permission
- Use convo-recall internally at any company, including a for-profit company — engineers can run it on their machines while building their own products.
- Modify, fork, redistribute the source under these same terms.
- Use it for personal projects, hobby work, non-commercial education, non-commercial research.
- Provide professional services to a licensee that is itself using convo-recall in compliance with these terms.
- After the two-year conversion, use it under Apache 2.0 (still subject to the AUP).
What the FSL does not permit — needs a commercial license from the author
- A Competing Use: making convo-recall available to others as a commercial product or service that substitutes for, or offers substantially similar functionality to, convo-recall itself. Hosting convo-recall as a SaaS, reselling it as the product, or offering managed convo-recall is a Competing Use.
If your use case falls outside the FSL — e.g., you want to bundle convo-recall in a commercial product, host it as a managed service, or remove the AUP rider — email the author to discuss commercial licensing terms.
What the AUP forbids — under all licenses, perpetually
Notwithstanding any license grant (including the post-conversion Apache 2.0), convo-recall may not be used in or for:
- Any government institution at any level (except public schools / universities for teaching and academic research).
- Any military, defense, weapons, intelligence, or armed-conflict purpose — including reconnaissance, targeting, autonomous-weapons systems, command-and-control, or any training, deployment, or evaluation thereof.
- Any mass-surveillance, social-credit, or biometric-identification system operated against a general population without specific informed consent.
Full FSL text in LICENSE. AUP details in ACCEPTABLE_USE.md. Third-party dependency attributions in NOTICE. Contributor terms in CLA.md.
Trademarks
Claude™ and Claude Code™ are trademarks of Anthropic, PBC. Codex™ is a trademark of OpenAI OpCo, LLC. Gemini™ is a trademark of Google LLC. All other trademarks are the property of their respective owners. convo-recall is an independent open project and is NOT affiliated with, endorsed by, sponsored by, or otherwise associated with Anthropic, OpenAI, or Google. References to these CLIs identify the third-party tools whose session files convo-recall reads — they do not imply endorsement.
Disclaimer
convo-recall is provided as-is, without warranty of any kind. The codebase ships with 360+ tests and several end-to-end sandbox runs, but your environment is not our environment.
Before installing on a workstation you care about: read SECURITY.md, run a sandbox first (tests/sandbox-*.sh spin up disposable Docker environments that exercise install / search / uninstall), and do your own due diligence on the source (~3K lines of Python).
You run convo-recall at your own risk. See LICENSE § No Liability for binding terms.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file convo_recall-0.4.0.tar.gz.
File metadata
- Download URL: convo_recall-0.4.0.tar.gz
- Upload date:
- Size: 272.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f0ccac02f2f24e084b7507db259cc5a6b3b4de9d8f813b1ed65ebe64f8e71c81
|
|
| MD5 |
939e189f5853401f3de626a8aeccbb34
|
|
| BLAKE2b-256 |
d5570dbce36e3144c82d1146a40b0bfa2e47ad47f0a8fdfa85d11dac30aa54f9
|
Provenance
The following attestation bundles were made for convo_recall-0.4.0.tar.gz:
Publisher:
publish.yml on AhedAdwan/convo-recall
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
convo_recall-0.4.0.tar.gz -
Subject digest:
f0ccac02f2f24e084b7507db259cc5a6b3b4de9d8f813b1ed65ebe64f8e71c81 - Sigstore transparency entry: 1437218146
- Sigstore integration time:
-
Permalink:
AhedAdwan/convo-recall@ae59d2e184a9c4f317865162dd4ea0e1e64cce49 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AhedAdwan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ae59d2e184a9c4f317865162dd4ea0e1e64cce49 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file convo_recall-0.4.0-py3-none-any.whl.
File metadata
- Download URL: convo_recall-0.4.0-py3-none-any.whl
- Upload date:
- Size: 119.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f3ab10aec5ef9090c925c91ebab8df7d15aaeada4758bf5334c67a51b81010e
|
|
| MD5 |
ba52f4145afeb7dcfc143f3901ca4de2
|
|
| BLAKE2b-256 |
fbb800af644329b7b3cdde0752521798ee47492bd7063781333d26ca1f4f414d
|
Provenance
The following attestation bundles were made for convo_recall-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on AhedAdwan/convo-recall
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
convo_recall-0.4.0-py3-none-any.whl -
Subject digest:
8f3ab10aec5ef9090c925c91ebab8df7d15aaeada4758bf5334c67a51b81010e - Sigstore transparency entry: 1437218148
- Sigstore integration time:
-
Permalink:
AhedAdwan/convo-recall@ae59d2e184a9c4f317865162dd4ea0e1e64cce49 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AhedAdwan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ae59d2e184a9c4f317865162dd4ea0e1e64cce49 -
Trigger Event:
workflow_dispatch
-
Statement type: