Skip to content

Releases: cashcon57/recall

v2.1.0 — Namespace filtering

Choose a tag to compare

@cashcon57 cashcon57 released this 14 Apr 20:16

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_memory accepts optional namespace (alphanumeric, hyphens, underscores, dots; max 128 chars).
  • retrieve_memory accepts optional namespace filter. Unnamespaced memories are NOT returned when a namespace filter is active.
  • list_memories accepts optional namespace filter. Output now shows [ns: ...] for namespaced memories.
  • Test infrastructure — vitest + MockAdapter runs against the shared tools.ts layer using the RecallAdapter abstraction. 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

Choose a tag to compare

@cashcon57 cashcon57 released this 14 Apr 19:59

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

  • RecallAdapter interface — 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, /health endpoint
  • Codex CLI supportexamples/AGENTS.md template, .mcp.json examples 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_memories tool
  • 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

Choose a tag to compare

@cashcon57 cashcon57 released this 14 Apr 01:14

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_memory on 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

Choose a tag to compare

@cashcon57 cashcon57 released this 12 Apr 17:34

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

Choose a tag to compare

@cashcon57 cashcon57 released this 12 Apr 02:18

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

Choose a tag to compare

@cashcon57 cashcon57 released this 12 Apr 01:30

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:

  1. Trust state in `~/.claude.json` didn't stick
  2. Env var not set in the launch shell
  3. `.mcp.json` missing, malformed, or in wrong directory
  4. Missing `"type": "http"` field
  5. 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

Choose a tag to compare

@cashcon57 cashcon57 released this 12 Apr 01:15

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 tail from 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_memory Vectorize error handling — orphan vectors on Vectorize failure are reported cleanly instead of throwing.
  • clear_memories per-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_memories hard 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_memory documented 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.json author field filled in, engines: { node: ">=20" } added.
  • Deleted stragglers: PORT_FIXES_PROMPT.md and examples/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

v1.0.0 — Recall first public release

Choose a tag to compare

@cashcon57 cashcon57 released this 11 Apr 23:09

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.