Semantic search over dated markdown journals, scoped to your cwd. Finds "that thing we decided three weeks ago" when you don't remember the exact words to grep.
npm install -g @skybluejacket/recall
cd your-project
recall '{"intent":"init"}' # scaffold memory/journal/
recall '{"intent":"search","query":"why we switched providers"}' # ranked hitsShips with sensible defaults for local embeddings via oMLX on Apple Silicon. Point at a different provider by dropping a config in ~/.config/recall/config.jsonc.
Grep finds exact strings. recall finds the idea.
When you ask "did we hit this error before?" or "what did I decide about the auth flow?", you rarely remember the exact phrasing of your old notes. recall runs your question against a semantic index of your journal entries and returns ranked pointers — with line numbers — so your agent can read just the relevant section instead of the whole file.
- Scope is cwd. Always.
./memory/journal/is the whole world — no walking up, no walking down. - Two-step flow.
recallreturns pointers (path+lines). Your agent reads those lines for the real content. - Incremental.
searchsilently reindexes changed files.reindex full:truerebuilds from scratch.
recall '{"intent":"init"}' # scaffold memory/journal/ + .recall/
recall '{"intent":"search","query":"..."}' # ranked semantic hits
recall '{"intent":"status"}' # index state, provider, counts
recall '{"intent":"reindex"}' # incremental refresh
recall '{"intent":"reindex","full":true}' # rebuild from scratchSearch output:
{
"ok": true,
"hits": [
{
"path": "/abs/path/memory/journal/2026-03-12.md",
"lines": [14, 38],
"heading": "Auth flow decision",
"snippet": "Decided to drop OAuth because...",
"score": 0.87
}
],
"provider": "omlx",
"model": "Qwen3-Embedding-4B-4bit-DWQ"
}Request knobs: limit (default 5, max 20), min_score (default 0), full (reindex only). No path-override field exists. Run from the repo whose memory you want.
./memory/journal/YYYY-MM-DD.md indexed
./memory/core/*.md optional, hand-curated, never indexed
./.recall/index.db SQLite index
./.recall/config.jsonc optional scope overrides
Writing journals well. The chunker splits on ## (H2) headings, then by paragraph. A wall of text with no headings chunks as one giant blob and retrieves worse. Write the why, not just the what — past-you writing for future-you.
Three layers, later wins:
~/.config/recall/config.jsonc(+~/.config/recall/.envfor secrets)./.recall/config.jsonc(scope-local, no secrets)- CLI request fields for that single call
Defaults:
| Field | Value |
|---|---|
| provider | omlx |
| model | Qwen3-Embedding-4B-4bit-DWQ |
| dimensions | 2560 |
| oMLX base URL | http://localhost:8000 |
| OpenRouter base URL | https://openrouter.ai/api/v1 |
When provider, model, or dimensions change, the next call raises PROVIDER_MISMATCH. Resolve with {"intent":"reindex","full":true}.
An OCO skill is included at skill/SKILL.md.
mkdir -p ~/.config/oco/skills/recall
cp skill/SKILL.md ~/.config/oco/skills/recall/SKILL.mdgit clone https://github.com/AidenGeunGeun/recall.git
cd recall && npm install && npm run buildMIT
