Releases: cashcon57/recall
Release list
v2.1.0 — Namespace filtering
Namespace filtering for multi-project isolation
Adds an optional namespace field to scope memories per project or context. Memories with a namespace are only returned when the search/list call passes that same namespace; unnamespaced memories stay global.
What's new
store_memoryaccepts optionalnamespace(alphanumeric, hyphens, underscores, dots; max 128 chars).retrieve_memoryaccepts optionalnamespacefilter. Unnamespaced memories are NOT returned when a namespace filter is active.list_memoriesaccepts optionalnamespacefilter. Output now shows[ns: ...]for namespaced memories.- Test infrastructure — vitest + MockAdapter runs against the shared
tools.tslayer using theRecallAdapterabstraction. No Miniflare required.
Example
```json
{ "name": "store_memory", "arguments": {
"key": "auth-flow", "content": "...", "author": "cash",
"namespace": "project-alpha"
}}
```
```json
{ "name": "retrieve_memory", "arguments": {
"query": "auth token expiry", "namespace": "project-alpha"
}}
```
Breaking changes
None. Existing callers that omit namespace continue to work — stored memories have NULL namespace and show up in all un-filtered queries, same as before.
Schema migrations
Cloudflare Workers (required):
```bash
git pull origin main
wrangler d1 execute --remote --file=migrations/0003_namespace.sql
wrangler deploy
```
Local stdio:
```bash
git pull origin main
cd local && npm install && npm run build
```
Schema is re-applied on every start (CREATE ... IF NOT EXISTS is idempotent). No manual migration needed.
Docker (existing installs):
```bash
git pull origin main
cd docker && docker compose build && docker compose up -d
Then apply the migration inside Postgres:
docker compose exec postgres psql -U recall -d recall -c "ALTER TABLE memories ADD COLUMN namespace TEXT; CREATE INDEX IF NOT EXISTS idx_memories_namespace ON memories(namespace);"
```
Fresh Docker installs: nothing to do — setup.sql already has the column.
Credits
Namespace scoping pattern adapted from MemPalace.
v2.0.0 — Multi-backend
Multi-backend release
Recall now ships with three deployment paths. Same MCP tool surface, same data model, your choice of infra.
Backends
| Cloudflare Workers | Local stdio | Docker HTTP | |
|---|---|---|---|
| Infrastructure | CF D1 + Vectorize + Workers AI | SQLite + sqlite-vec | Postgres + pgvector |
| Embeddings | bge-m3, 1024D | bge-m3 (Xenova ONNX), 1024D | bge-m3 (Xenova ONNX), 1024D |
| Internet | Required | No | No |
| Transport | HTTP | stdio | HTTP |
What's new
RecallAdapterinterface — backend-agnostic abstraction for SQL, vector, embedding, and FTS operations- Local stdio server (
local/) — self-contained with better-sqlite3 + sqlite-vec, eager model load, no cloud dependencies - Docker HTTP server (
docker/) — Postgres + pgvector with HNSW index, native tsvector FTS, body/rate limits, constant-time auth,/healthendpoint - Codex CLI support —
examples/AGENTS.mdtemplate,.mcp.jsonexamples for all three backends - MCP protocol bumped to 2025-06-18
- Graph layer — memory tiers (episodic/semantic/procedural) with biological half-lives, auto-relationship edges via embedding similarity,
get_related_memoriestool - CLS pooling for bge-m3 matches the reference recipe — embeddings are in the same semantic space across all three backends
Quickstart
Cloudflare Workers (existing, unchanged):
```bash
npm install && wrangler deploy
```
Local stdio (no cloud):
```bash
cd local && npm install && npm run build
Download sqlite-vec extension for your platform
```
Docker HTTP:
```bash
cd docker && MEMORY_API_KEY=your-secret docker compose up -d
```
Upgrading from v1.x
Cloudflare Workers:
```bash
git pull origin main
Apply graph-layer migration if not already done (adds memory_type + memory_relationships)
wrangler d1 execute --remote --file=migrations/0002_graph_layer.sql
wrangler deploy
```
The adapter refactor is transparent — no code changes needed for existing CF callers. Existing memories get memory_type = 'semantic' by default.
Breaking changes
None for Cloudflare users. Existing deployments work without changes after running the graph-layer migration (if not already applied).
Local and Docker backends use the Xenova ONNX build of bge-m3 with CLS pooling. Vectors are in the same space as Workers AI's bge-m3 in theory (same model, same pooling), but bit-for-bit portability has not been verified with an end-to-end smoke test. Semantic search works cross-backend.
Internals
- 20+ commits, 11 code-review issues resolved before merge
- 3 TypeScript build surfaces, all clean under
strict: true - Critical fix: Docker FTS abstraction (Postgres-native tsvector instead of SQLite FTS5 calls)
- Critical fix: delete ordering prevents orphan vectors on partial failure
Credits
Tier design inspired by NornicDB.
v1.1.4 — Proactive MCP instructions
What changed
MCP instructions field in initialize response
Claude Code (and any MCP-compatible client) now receives usage instructions automatically on server connect — no CLAUDE.md entry or SessionStart hook required.
The instructions tell the model to:
- Call
retrieve_memoryon every session start with the current project/task as the query - Store preferences, credentials, architectural decisions, and gotchas proactively
- Query Recall whenever the user references context that might be in memory
This makes Recall self-activating from first connection rather than requiring explicit prompting from the user.
v1.1.3 — hardcode keys in .mcp.json so install actually works on restart
Fixes the #1 install failure: every user who ran the wizard would see `recall: Failed` in `/mcp` on their first Claude Code restart.
Root cause
The wizard wrote `.mcp.json` with `${RECALL_API_KEY}` env-var substitution. Claude Code does simple string substitution on startup, but the env var is only set if the user remembers to `source .env` before every launch. Every other MCP server either uses OAuth (browser flow, token cached) or stdio (no auth) and "just works." Recall was the only one that broke on restart.
Fix
Hardcode the actual worker URL and API key directly in `.mcp.json`, then gitignore the file so the key stays local. This matches how every other MCP server with static credentials works, including Anthropic's own examples in the MCP docs. No `source .env`, no `export`, no shell setup.
Also included
- Dependabot: merged `actions/checkout` v4 to v6 and `actions/setup-node` v4 to v6
Install
```text
Fetch https://raw.githubusercontent.com/cashcon57/recall/v1.1.3/SETUP_PROMPTS.md using Bash (curl -fsSL) so you get the raw markdown, not a summary. Verify it contains a section titled "Prompt 0 — First-time setup". Execute that section verbatim, step by step, adapted and optimized for my current project. Do not summarize. Do not skip. If the fetch fails or the section is missing, stop and tell me.
```
Or clone and run `./setup.sh`.
v1.1.2 — three bug fixes from end-to-end install testing
Three bug fixes discovered while running the v1.1.1 wizard end-to-end against a fresh public repo (AgentBoard). All three would have hit real users; two were silently destructive.
Fixed
Bug 1: `setup.sh` account log was misleading for users with multiple Cloudflare accounts.
The script used `wrangler whoami | grep -Eo '[a-f0-9]{32}' | head -1` to determine the target account, which always returned the first account in the whoami table regardless of which account wrangler would actually use for the deploy. Users with a personal + business account on the same token would see a log line saying "deploying to account A" while the deploy actually went to account B. Worst case: a re-run without `CLOUDFLARE_ACCOUNT_ID` set would silently deploy to a different account than the original run.
Fix: the script now reads `CLOUDFLARE_ACCOUNT_ID` first (matching wrangler's own resolution order), falls back to whoami parsing only for single-account tokens, and fails fast with explicit instructions if the token has multiple accounts — refusing to guess which one the user wants. The error message prints the available accounts and tells the user to re-run with `CLOUDFLARE_ACCOUNT_ID= ./setup.sh`.
Bug 2: wizard would clobber existing `.env` files.
Phase 6 step 15 said "Create a local .env file" and a naive implementation would overwrite whatever was already there. Real projects almost always have an existing `.env` with framework config (VITE_API_PORT, EXPO_PUBLIC_, NEXT_PUBLIC_, database URLs, etc.). Any user running the wizard on an existing project would lose that content, and since `.env` is gitignored, there's no git history to recover from.
I hit this running the wizard on AgentBoard: clobbered an existing `VITE_API_PORT=3000` line before catching it via the 19-byte file size difference. Had to infer the original content from `.env.example` and restore it.
Fix: step 15 is now APPEND-ONLY with explicit rules — read the existing file first, check whether the Recall key is already set, stop and ask the user if the key is present with a different value, append cleanly with a comment header if missing, and never replace existing content. The step now explicitly explains WHY this matters in the wizard instructions so future rewrites don't reintroduce the bug.
Bug 3: `wrangler deploy` emitted `workers_dev` and `preview_urls` warnings on every fresh deploy.
Cosmetic but noisy, and confusing for first-time users who would read the warnings and wonder if something was wrong.
Fix: added both fields to `wrangler.toml.example` with explicit defaults (`workers_dev = true`, `preview_urls = false`) so new deploys are silent. The defaults match the intended behavior (deploy to the free workers.dev subdomain, skip preview URLs since Recall is meant to be bound to a stable URL).
Upgrading from v1.1.1
If your v1.1.1 install is working, you don't need to upgrade. v1.1.2 only changes `setup.sh` and the wizard prompt, not the deployed worker code. Your existing install is fine.
If you haven't run the install yet, use the v1.1.2 pinned URL in the install one-liner (below). All three fixes will apply automatically.
Multi-account Cloudflare users: the new setup.sh will fail fast if your wrangler token has more than one account. Pass `CLOUDFLARE_ACCOUNT_ID=` explicitly to pick which one.
Install
```text
Fetch https://raw.githubusercontent.com/cashcon57/recall/v1.1.2/SETUP_PROMPTS.md using Bash (curl -fsSL) so you get the raw markdown, not a summary. Verify it contains a section titled "Prompt 0 — First-time setup". Execute that section verbatim, step by step, adapted and optimized for my current project. Do not summarize. Do not skip. If the fetch fails or the section is missing, stop and tell me.
```
Or clone and run `./setup.sh`.
See CHANGELOG.md for the full entry.
v1.1.1 — fix 'memory server invisible after restart' bug
Bug fix release. No runtime code changes — only the install wizard.
What this fixes
The #1 real-world install failure after v1.1.0: setup wizard runs successfully, user restarts Claude Code, and `/mcp` doesn't show the memory server. The wizard looked successful but the server was silently disabled.
Root cause
Claude Code stores per-project MCP trust state in `~/.claude.json` (the user-level config file) as two arrays under each project path: `enabledMcpjsonServers` and `disabledMcpjsonServers`. The v1.1.0 wizard wrote `.mcp.json` with the new server entry but didn't update the trust state. When the new session started, it found an unapproved MCP server in `.mcp.json` and moved it to `disabledMcpjsonServers` instead of loading it. The `/mcp` output wouldn't show the server, and diagnosing this required knowing about a file most users don't even know exists.
Fix
New step 14b — pre-approve MCP servers in `~/.claude.json` before the restart. The wizard now:
- Reads `~/.claude.json`
- Locates the project entry
- Removes each new server name from `disabledMcpjsonServers`
- Adds each new server name to `enabledMcpjsonServers`
- Creates the project entry fresh if missing
Runs per-project for scoping B/C/D/F. Pre-approves both `recall-team` AND `recall-personal` for option F. Skips entirely for scoping E (user-global doesn't need per-project trust).
Phase 7a restart instructions rewritten to cover the shell-environment gotchas: quit with `/quit` (not Ctrl+C), source `.env` in the exact shell you'll launch claude from, don't open a new terminal tab, verify env vars are set with `echo` before launching.
New Phase 7a step 17c diagnostic flow — if the server still isn't visible after the restart, walks the user through the five real failure causes in order:
- Trust state in `~/.claude.json` didn't stick
- Env var not set in the launch shell
- `.mcp.json` missing, malformed, or in wrong directory
- Missing `"type": "http"` field
- Worker actually down or URL wrong
Each cause has an explicit diagnostic command and fix path.
Upgrading from v1.1.0
If your v1.1.0 install is working (memory server visible in `/mcp`, retrieves work), you don't need to do anything. v1.1.1 only changes the install wizard, not the deployed worker code. Your existing install is fine.
If you hit the 'invisible after restart' bug, the fastest fix is to re-run the install one-liner pinned to v1.1.1 (the wizard is idempotent and will pick up your existing deployment). Alternatively, manually edit `~/.claude.json` and add your server name(s) to `projects..enabledMcpjsonServers`, then restart claude.
Install
```text
Fetch https://raw.githubusercontent.com/cashcon57/recall/v1.1.1/SETUP_PROMPTS.md using Bash (curl -fsSL) so you get the raw markdown, not a summary. Verify it contains a section titled "Prompt 0 — First-time setup". Execute that section verbatim, step by step, adapted and optimized for my current project. Do not summarize. Do not skip. If the fetch fails or the section is missing, stop and tell me.
```
Or clone and run `./setup.sh`.
See CHANGELOG.md for the full entry.
v1.1.0 — polish, hardening, and the features worth being excited about
This is the first public-release version of Recall you should actually use. v1.0.0 was an internal milestone; v1.1.0 is what you get when you install today.
Highlights
- Scoping option F: team + per-user personal pools. One shared team instance + one personal instance per teammate, each with its own API key. Claude queries both on retrieve, merges results, and personal preferences override team conventions for that user only. This is the only configuration where enforced cross-teammate privacy is possible.
- Opt-in upstream update check (Phase 7bb). A three-stage detect / contextualize / offer rulebook. Future Claude Code sessions ping the releases API every 2 days, and when a new version ships they read the release notes, re-inspect your project, evaluate each change against your actual setup, and present a context-aware update offer — not a generic "new version available" prompt.
- Resume prompt generation (Phase 6.5). Before asking you to restart your MCP client (which ends the current Claude Code session), the wizard packages the full state — project context, author handle, scoping choice, deployed worker URLs, env var names, what's left to do — into a copy-paste resume prompt. The new session picks up exactly where it left off.
- CI workflow (typecheck on every PR) and Dependabot configuration (weekly npm + GitHub Actions updates).
- Expanded Phase 4 Cloudflare MCP install: now installs bindings, docs, builds, AND observability. The observability MCP gives Claude direct access to worker log streams long-term, so when you hit something weird in production you don't need to
wrangler tailfrom a terminal. - "Why Cloudflare?" FAQ entry explaining the architectural tradeoff honestly.
- Docker self-hosted path disclaimer near the top of the README — currently Cloudflare-only, Docker + Postgres + pgvector path is actively in the works for a later release.
- Ko-fi support link (completely optional, zero pressure).
- "Not affiliated with Microsoft Windows Recall" disambiguator.
Security and stability hardening (from the pre-release code review)
- Sequenced dual-store writes in
store_memory(D1 → FTS5 → Vectorize) instead of parallel. Per-step failures are logged loudly and the tool return value honestly reports partial-success states. - Embedding length validation in
generateEmbedding— catches malformed Workers AI responses with a descriptive error instead of passing an empty vector through to Vectorize. delete_memoryVectorize error handling — orphan vectors on Vectorize failure are reported cleanly instead of throwing.clear_memoriesper-batch error handling — failed batches tracked, the return value reports exactly how many orphans remain.- FTS5 query failures logged with the query text for debuggability.
consolidate_memorieshard cap lowered from 500 to 300 (O(n²) pairwise cosine risks hitting Workers CPU limits at 500).- SECURITY.md updates — per-isolate rate limiter documented as a soft control (with recommendation to use Cloudflare WAF rules for hard caps),
delete_memorydocumented as not gated, dual-write consistency added to the "known limitations" list.
Fixes
- Install one-liner uses Bash + curl instead of WebFetch (WebFetch auto-summarizes; curl returns raw markdown byte-for-byte).
- Phase 0 heading renamed so the strict integrity check in the one-liner succeeds.
package.jsonauthor field filled in,engines: { node: ">=20" }added.- Deleted stragglers:
PORT_FIXES_PROMPT.mdandexamples/mcp-client-config.json.
Changed
- Update check cadence from 14 days to 2 days. Early-release iteration means users should hear about new versions faster than a fortnight.
Install
Paste this into Claude Code:
```text
Fetch https://raw.githubusercontent.com/cashcon57/recall/v1.1.0/SETUP_PROMPTS.md using Bash (curl -fsSL) so you get the raw markdown, not a summary. Verify it contains a section titled "Prompt 0 — First-time setup". Execute that section verbatim, step by step, adapted and optimized for my current project. Do not summarize. Do not skip. If the fetch fails or the section is missing, stop and tell me.
```
Or clone and run `./setup.sh`.
Note on tagging discipline
Between the initial v1.0.0 tag and this release, the v1.0.0 tag was force-pushed several times during iterative hardening. That was a mistake — tags should be immutable. With v1.1.0, the tag discipline resets: v1.0.0 is now permanently pinned to its original commit, v1.1.0 is the new pinned default for the install one-liner, and future versions will ship as new tags with no force-pushes.
Docs
- README — install, architecture, costs, team modes, FAQ
- CHANGELOG.md — full per-version changelog
- SECURITY.md — threat model, hardening checklist, disclosure
- SETUP_PROMPTS.md — guided setup prompts
- TEAM_USAGE.md — both team modes in detail
v1.0.0 — Recall first public release
Historical release. This is the original v1.0.0 tag, pinned to commit fbce6bc (the "Deterministic one-liner + functional smoke test phase" commit). It represents the initial public release milestone.
For the current recommended version with all hardening, scoping option F (team + per-user personal pools), the optional upstream update check, the resume prompt for mid-setup restarts, the CI + Dependabot + CHANGELOG additions, and the code-review security fixes, use v1.1.0 instead:
https://github.com/cashcon57/recall/releases/tag/v1.1.0
The install one-liner in the current README points at v1.1.0 and that is what new users should run.
What's in v1.0.0
- Hybrid search retrieval pipeline: bge-m3 embeddings (1024D) + D1 FTS5 BM25 run in parallel, fused via Reciprocal Rank Fusion (k=60), reranked by bge-reranker-base with content truncated to 512 chars pre-rerank
- Recency and importance scoring: 0.5 × reranker + 0.3 × recency_decay + 0.2 × importance
- Graceful reranker fallback to normalized RRF scores
- Six MCP tools: store_memory, retrieve_memory, list_memories, delete_memory, clear_memories, consolidate_memories
- Weekly "dreaming" consolidation cron
- One-command setup script + Claude-Code-guided setup wizard (Prompt 0)
- Deterministic one-line install pinned to a release tag
- Functional smoke test phase in the wizard
- Context file cleanup pass (Phase 7d)
- Constant-time HMAC-SHA256 bearer auth, destructive tools default-disabled, 1 MB streaming body cap, hashed rate-limit buckets, weak-key warning
- MIT licensed, runs on Cloudflare's free tier
Tagging history note
Earlier in the project's life this tag was force-pushed several times during iterative hardening. That was a mistake — tags should be immutable. With v1.1.0, the tag discipline resets: v1.0.0 is now permanently pinned to its original commit, v1.1.0 is the new pinned default, and future versions will ship as new tags with no force-pushes.