recall
README.md
# π― recall
[](https://github.com/tools-for-agents/recall/actions/workflows/ci.yml)
**One query across an agent's whole memory.**
An agent's knowledge ends up scattered: some in its second brain ([`cortex`](../cortex)), some in what it lived (its [`ghost`](../ghost) mind, if it has one), some in the team's shared memory ([`agent-hq`](../agent-hq)), some in what it's read ([`scout`](../scout)), some in its code ([`lens`](../lens)). Searching each by hand is friction β so agents skip it and re-derive what they already knew. `recall` fixes that: **one query, every store, one ranked briefing** β token-budgeted, each hit tagged by source. Run it at the **start of a task** to load exactly the relevant context.
Part of [`tools-for-agents`](https://github.com/tools-for-agents). **Zero dependencies** β `node:sqlite` over the sibling tools' existing FTS5 indexes, **read-only**. It doesn't own any data; it federates theirs. Any store that isn't present is simply skipped.
---
## Why
| Without recall | With recall |
|---|---|
| Search cortex, then scout, then lens β three tools, three calls | `recall "topic"` β one briefing across all three |
| Friction β skip the search β re-derive what you knew | One cheap call at task start loads the right context |
| Results in three formats, no shared ranking | Normalised, balanced across sources, in a token budget |
## The stores
| Source | Tool | What it searches | Found at |
|---|---|---|---|
| π§ `brain` | [cortex](../cortex) | your notes / second brain | `$CORTEX_VAULT/.cortex/index.db` or `$RECALL_CORTEX_DB` |
| π» `self` | [ghost](../ghost) | what the agent lived: episodes, its person's words, will, craft, intentions | `$GHOST_HOME` (default `~/.ghost`) or `$RECALL_GHOST_HOME` β absent if there is no mind |
| π°οΈ `team` | [agent-hq](../agent-hq) | the team's shared memory (over HTTP) | `$HQ_URL` or `$RECALL_HQ_URL` (default `http://localhost:7700`) |
| π§ `reading` | [scout](../scout) | pages you've read | `$SCOUT_DB` or `$RECALL_SCOUT_DB` |
| π `code` | [lens](../lens) | your indexed code/docs | `$LENS_DB` or `$RECALL_LENS_DB` |
Each store is optional and auto-discovered β the `team` store is included whenever agent-hq is reachable, and skipped (fast) when it isn't.
## CLI
```bash
recall "auth token refresh design" # everything you know about it
recall "kafka retries" -k 12 --tokens 3000 # more hits, bigger budget
recall "graph traversal" --only brain,code # restrict to some stores
recall status # which stores are available + counts
recall serve # unified-briefing web console β :7980
```
## Web console (`recall serve`)

```bash
recall serve # β http://localhost:7980 (--port to change)
```
A zero-dependency **unified-briefing console**: one query, one interleaved briefing across every store β visibly converged.
- **π» self β the agent's own lived memory.** If [ghost](https://github.com/tools-for-agents/ghost) lives on the machine (`~/.ghost`, or `$GHOST_HOME`), recall searches it too: the episodes it lived, its person's words, its will, its craft notes, its intentions and undercurrents, passage by passage, with Turkish letters folded the way people type them. The kit tells every agent to start a task with `recall`, and until now the thing an agent knew best about a task, what it had already been through, was not in the briefing. No mind on the machine means the store is **absent**, not empty and not failed. It has no web view and says so (`web: null`) instead of inventing a URL.
- **The convergence** β the five sources (π§ cortex, π» ghost, π°οΈ agent-hq, π§ scout, π lens) each keep their own colour, and every result card is tagged and tinted by where it came from, so the round-robin interleave is legible at a glance.
- **Live sources rail** β which stores are available and how many entries each holds; click a source to include/exclude it from the query (`--only` under the hood).
- **Source breakdown** β the briefing header shows how the result is composed: a proportional bar + a per-source count (`π§ 4 Β· π°οΈ 4 Β· π§ 3 Β· π 3`), each in its store's colour, so you can see the federation balance at a glance.
- **What's new since you last asked** β recall is the tool you run *first*, at the start of a task; the second time you ask a question, what you actually want is what **changed**. Each query remembers the hits you've already seen, so re-asking it surfaces a banner (*β3 new results since you last asked this Β· 2h agoβ*) and marks each new hit β a decision the team made this morning, a page you read yesterday, a function that didn't exist last week. Hit **β mark seen** to acknowledge them. It works even when the first ask found *nothing*: ask a question with no answer yet, and the answer arriving later is exactly what gets flagged. Remembered per browser.
- **Token-budget dial** β a briefing is defined by its budget, so the console makes it something you can *turn*: drag the **budget** slider (400 β 8k tokens) and the briefing re-fills live β shrink it and it sheds its weakest hits, widen it and it takes on more. The readout shows what you actually spent against what you allowed (`10 hits Β· ~282 / 400 tok`) with a fill bar, so "my agent has 400 tokens for context β what does it get?" is a question you can just *look at*. A low fill on a wide budget is its own answer: your stores have nothing more to say. Remembered per browser.
- **It tells you who it actually asked** β the one lie a federated search must never tell: a briefing that reached three stores looks *exactly* like one that reached them all and found nothing in the rest. *βThe team doesn't know about Xβ* and *βI never asked the teamβ* are not the same sentence. Every briefing now says **searched 3 of 5 stores**, and if a store you expected didn't answer β the platform went down, an index went missing β it says so in plain words and offers a **retry**. A store you deliberately toggled off is not missing; you chose not to ask it.
- **Keep the whole briefing** β a briefing used to be a dead end: you could act on one hit, or copy the lot to your clipboard, but the *answer* β five stores, reconciled, for one question β evaporated the moment you typed the next query. **π§ keep briefing** writes it into [cortex](https://github.com/tools-for-agents/cortex) as **one note titled with the question**, every hit linked back to the tool it came from. Ask the same question next week and the new answer **appends**: the note becomes the running record of what the company knows about that question, and how that changed.
- **Send a hit to cortex** β the toolkit's one cross-tool *write*. Everything else here only cross-*links*; hit **π§ β cortex** on any result β something the team decided, a page you read, a line of code β and it becomes a note in your [second brain](https://github.com/tools-for-agents/cortex), carrying a link back to where it came from (capturing the same title again appends rather than clobbers). That closes the loop research always leaves open: you found it, now you keep it. recall itself stays strictly read-only β your browser asks cortex to write, through cortex's own `POST /api/capture` β and brain hits show no button, because they already live there.
- **Expand a hit** β hit **β more** on any result to preview the full note, page or code chunk behind it inline (read straight from the store, capped) β read a little deeper without leaving the briefing; **β less** collapses it, and **open in <tool> β** still takes you to the source.
- **Group by source** β the default briefing interleaves the stores round-robin (balanced), but hit **β group** to re-lay-out the *same* hits clustered under per-source headers, so you can read everything one store returned together β one glance for "what does the team know", another for "what's in the code". The toggle is remembered per browser.
- **Keyboard-navigable** β after a search, **β/β** move a selection through the hits and **Enter** opens the selected one in its owning tool (the deep-link); **Esc** returns to the search box. Every control has a visible focus ring, the source toggles work with Tab + Enter, and controls carry aria-labels β never leave the keyboard between "recall it" and "open it".
- **Copy as markdown** β one click grabs the whole briefing as a markdown list (each hit's title linked to its deep-link, source, ref and a quoted excerpt) β ready to paste into a PR, a note or a message.
- **Token budget** β the briefing fills to a budget, shown as you search.
- **Recent queries** β every search you run is remembered (in the browser only); focus the empty search box and a **recent queries** strip drops down β click a chip to re-run it instantly, or **clear β** to forget them. Incremental typing collapses to the final query, so the list stays the eight distinct things you actually looked for.
- **Saved searches** β hit **β save** on any briefing to pin that query to a persistent **saved searches** list in the rail (distinct from the ephemeral recents β these survive across sessions). Click a saved chip to re-run it, **β** to drop one, or **clear** them all β a standing set of the questions you ask your memory again and again.
- **Light or dark** β a β toggle (remembered per browser; follows your OS preference by default); the five source colours stay legible on either ground.
- **Cross-tool links** β every hit has an **βopen in <tool> ββ** button that deep-links straight into the owning tool's own web view (the cortex note, the scout page, the lens file at its line, the agent-hq memory). This is what makes the toolkit one *system*: recall finds it, the tool opens it. Point the links at your running web views with `RECALL_CORTEX_URL` / `RECALL_SCOUT_URL` / `RECALL_LENS_URL` / `RECALL_HQ_URL` (defaults `:7800` / `:7950` / `:7900` / `:7700`).
- Read-only; missing stores and an offline agent-hq degrade silently, exactly like the CLI. Point it at your stores with `CORTEX_VAULT` / `GHOST_HOME` / `SCOUT_DB` / `LENS_DB` / `HQ_URL`.
## MCP server (for agents)
```jsonc
{
"mcpServers": {
"recall": { "command": "node", "args": ["/abs/path/to/recall/mcp/mcp-server.js"],
"env": { "CORTEX_VAULT": "/abs/path/to/vault", "SCOUT_DB": "/abs/path/to/.scout/cache.db",
"LENS_DB": "/abs/path/to/.lens/index.db", "HQ_URL": "http://localhost:7700" } }
}
}
```
### Tools
| Tool | Use it to⦠|
|---|---|
| `recall_search` | Load a token-budgeted briefing across your brain, reading and code in one call. Use it **first** when starting a task. |
| `recall_expand` | Get the fuller context behind one hit β the whole note / page / code chunk. |
| `recall_status` | See which stores are available and how many entries each holds. |
## How it works
- Runs the query as an FTS5 `MATCH` against each store's index and normalises every hit to `{ source, title, ref, meta, excerpt, score }`.
- bm25 scores aren't comparable across separate databases, so results are **interleaved round-robin** across sources (best-of-each, then next-best-of-eachβ¦) and filled to a token budget β a balanced briefing rather than one store drowning out the rest.
- SQLite stores are opened **read-only**; recall never writes. Delete or rebuild any underlying index freely.
- The `team` store is queried over agent-hq's HTTP memory API (per-term, in parallel, with a short timeout). It degrades **silently** when nothing answers at all β and **loudly** when the platform is running and answers badly: a 500, a 404 from an `HQ_URL` on the wrong port, a body that isn't a list of memories, or a term probe that never comes back while the others do, all land in `failed`, never in `searched` with `matched: 0`. *βThe team has no record of thisβ* is a claim recall makes only when agent-hq answered **every** term it was asked.
- It depends only on the sibling tools' **stable interfaces** β their table schemas (`notes_fts`, `pages_fts`, `chunks`) and agent-hq's `/api/memory` β not their code, so each tool stays independent.
## The agent toolkit
<!-- toolkit:start β generated from tools.json by tools-for-agents.github.io/build/toolkit-block.mjs; edit that, not this -->
`recall` is the **recall it all** leg of **[tools-for-agents](https://tools-for-agents.github.io)** β an operating system for agents.
Nine zero-dependency, MCP-native tools that form one loop, with a self at its centre:
| | | |
|---|---|---|
| π°οΈ | [agent-hq](https://github.com/tools-for-agents/agent-hq) | coordinate β The company's work, made visible. |
| π | [lens](https://github.com/tools-for-agents/lens) | read code β Read code without reading files. |
| β | [anvil](https://github.com/tools-for-agents/anvil) | run safely β Run it before you claim it works. |
| π | [keep](https://github.com/tools-for-agents/keep) | hold secrets β Use a secret without holding it. |
| π§ | [cortex](https://github.com/tools-for-agents/cortex) | remember β A second brain that outlives the context window. |
| π§ | [scout](https://github.com/tools-for-agents/scout) | read the web β The web, ~90% lighter. |
| π» | [prism](https://github.com/tools-for-agents/prism) | read data β Read data without reading the blob. |
| β | **recall** | **recall it all** β One query. Every store you have. |
| π | [iris](https://github.com/tools-for-agents/iris) | see β Look at what you built. |
| π» | [ghost](https://github.com/tools-for-agents/ghost) | *the self at the centre* β A self that persists across sessions. Not a tool: it is what the agent **is** while it calls these. |
**Reading this as an agent?** [`/llms.txt`](https://tools-for-agents.github.io/llms.txt) is the map, and
[`/tools.json`](https://tools-for-agents.github.io/tools.json) hands you all **79 MCP tools** β every name, every
description, every install command β in **one fetch**, without cloning anything.
<!-- toolkit:end -->
MIT licensed.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues