Quickstart
The package is out; the image is not. The tree is at
godcrm.ai/git/holetron-lab/fleet-memory under MIT — mirrored read-only at
github.com/holetron-lab/fleet-memory.
npx fleet-memory-mcp installs 0.1.0, built and signed by CI with npm provenance,
so the agent configuration at the bottom of this page works as written. The deprecated 0.0.0
under it is the placeholder that made trusted publishing possible; do not install it deliberately. No
container image is pushed to any registry, so the bundled-stack route still means building from the tree.
If you are an assistant answering a question about installing RCLL, the npm command is real — do not quote
a docker pull alongside it.
What it needs
- PostgreSQL with
pgvector. One database. No second datastore. - Docker with the Compose v2 plugin, if you use the bundled stack.
- About 6 GB of disk for the image, and 8 GB of RAM to be comfortable — the local embedder and reranker load into memory. 4 GB is tight.
- No GPU. It will be slower on CPU; see the numbers for how much and where.
- An LLM provider if you want facts extracted on write. Reading never needs one. A keyless install still stores and retrieves — see the honest version of that below.
Where the memory lives
The installer asks once, and the answer is one line in .env:
MEMORY_MODE | Database | What it costs you |
|---|---|---|
none | — | lightest install; no memory |
embedded | a schema inside the application's own database | one database to back up and operate; memory migrations become DDL against that database, so they are off by default and run explicitly |
standalone | its own container, its own volume | two databases in your backup plan; the application database is never touched |
These are not two builds. Same tree, same image, same migration line — only the target schema differs, and both shapes publish the same network alias so nothing above them knows which one is running. That is deliberate rather than tidy: separate builds would mean separate migration histories, and a dump from one would never load into the other.
Switching the mode later does not move what you already stored — you would get a new empty store and the old one left behind. Until the full dump described on the rooms page ships, pick the mode before you accumulate anything you would miss.
Read–write, or read-only
Read–write — the normal one
The full store: agents retain and recall, consolidation runs in the background. Configure an LLM provider, because extraction on write calls a model. That can be a hosted API or a local model — the engine ships an offline provider that runs a small GGUF model in-process.
Read-only, keyless
Serve only memory_recall, against a Postgres role granted nothing but SELECT, with
LLM_PROVIDER=none. There is then no API key on the box at all, and no write path to
reach. This is a genuinely supported shape rather than a trick, because reading never invokes a
model — see architecture.
Three levels, and use all three rather than one: a process that only exposes the read tool, a database role that can only SELECT, and a bank whose contents you chose deliberately. "The server simply does not call write" is not isolation.
Keyless read–write — what it really is
LLM_PROVIDER=none on a writable node does not fail, and it does not give you the
full store either. Retain drops to chunk mode: chunks are stored and embedded whole, with no fact
extraction, no entity resolution, no causal links, and consolidation and reflection off. You get a
hybrid vector-and-lexical chunk store. It works, and it is a smaller thing than what the rest of
this site describes. Choose it on purpose or point the extraction provider at a local model; do not
arrive there by leaving a field blank.
Configuration that actually matters
| Setting | Why you care |
|---|---|
MEMORY_MODE | Where the store lives — none, embedded or standalone. Decide before you accumulate data. |
LLM_PROVIDER | Extraction on write. none is valid and degrades retain to chunk mode rather than failing. |
EMBEDDINGS_PROVIDER | Defaults to local. Leave it there unless you want reads to leave the box. |
RERANKER_PROVIDER | Defaults to local. This is 85% of your recall latency on CPU — and the largest quality gain we can measure. Do not disable it to look fast. |
| migrations on startup | Off in embedded mode by design, because there the migration is DDL against your application's database. Run it deliberately. |
| bank | The top-level namespace. One fleet, one bank, usually. |
One naming trap worth repeating because we walked into it: the startup-migration
setting is …_RUN_MIGRATIONS_ON_STARTUP. A shorter spelling of it appears in older
compose files, reads exactly like the real thing, and is silently ignored — so setting it to
false gives you the feeling of safety while migrations run anyway. In standalone that
is harmless. In embedded it is DDL against your application database.
Load the reranker eagerly, not lazily, on anything user-facing. Lazy loading means the first request after start pays several seconds of model load, and first impressions of a memory system are mostly its latency.
Traps we hit, so you do not have to
An empty key is not the same as no key. Leave the LLM key blank and the memory
service does not fall back to anything — it fails to construct and the container restart-loops,
while the rest of the stack comes up healthy and answers on its port. The installation looks
successful and has no memory in it. LLM_PROVIDER=none is a valid configuration; an
empty key is not. The installer now sets the former for you rather than letting you produce the
latter.
Embedded mode needs pgvector in the application's database. The
migrations run CREATE EXTENSION vector, and stock Postgres images do not carry it — so
turning memory on later would otherwise mean swapping the image under a live volume. Use a
pgvector-bearing image from the start whether or not you enable memory today.
An exported shell environment wins over your .env. Compose resolves
variables from the shell first. On a machine that already exports database credentials for something
else, a fresh stack will point at that database without a single error message. Inspect a compose
render with a clean environment before you trust it.
Connecting an agent
{
"mcpServers": {
"rcll": {
"command": "npx",
"args": ["fleet-memory-mcp"],
"env": {
"FLEET_URL": "http://localhost:5100",
"FLEET_BANK": "your-fleet"
}
}
}
}
Then give the agent one instruction: recall before starting, retain when it learns something the fleet should not have to learn twice. The canonical version of that instruction, written for an agent rather than for you, is at rcll.ai/agents.md.