RememberStackremember.dev/docs

Quickstart

By the end of this page you will have sent a document to RememberStack, waited for it to be processed, and asked a question that it answers with a fact and the passage behind it.

RememberStack is the open-source memory engine. remember is its Python client and CLI.

1. Get an endpoint

You need Docker Engine 28.0.0 or later with Compose, and an OpenRouter API key. On an older Docker Engine, turn on API authentication before the first start; see Requirements.

git clone https://github.com/writeitai/remember-stack.git
cd remember-stack
cp .env.example .env
printf 'REMEMBERSTACK_POSTGRES_PASSWORD=%s\nREMEMBERSTACK_MINIO_ACCESS_KEY=%s\nREMEMBERSTACK_MINIO_SECRET_KEY=%s\nREMEMBERSTACK_SELFHOST_DEPLOYMENT_ID=%s\n' \
  "$(openssl rand -hex 32)" "$(openssl rand -hex 12)" "$(openssl rand -hex 32)" \
  "$(openssl rand -hex 16 | sed -E 's/^(.{8})(.{4}).(.{3}).(.{3})(.{12})$/\1-\2-4\3-8\4-\5/')" >> .env
# edit .env: set REMEMBERSTACK_OPENROUTER_API_KEY
docker compose up -d

The printf line generates the database password, the object-store credentials and the deployment id; Compose refuses to start without them. The first start builds the PostgreSQL image and runs migrations. When docker compose ps shows api as healthy, the endpoint is http://localhost:8000. No token is needed by default, because the API is reachable from this machine only. To open it to others, see Before you expose it.

2. Install the client

pip install remember

This installs the Python client and the remember command. It needs Python 3.12 or later. The current release is v0.17.2 (on PyPI).

3. Point the client at your endpoint

export REMEMBER_API_URL=http://localhost:8000

4. Send a document

Save this as standup.md:

# Stand-up, 17 September 2026
 
Ravi said the billing migration moves from June to October, because the
invoice exporter needs a rewrite. Dana agreed and will tell finance.
Ravi owns the invoice exporter.

Then send it:

from datetime import UTC, datetime
 
import remember
 
client = remember.Client.from_env()
version = client.ingest(
    "standup.md",
    source_kind="file",
    source_ref="notes/standup.md",
    source_modified_at=datetime(2026, 9, 17, 9, 30, tzinfo=UTC),
)
print(version.version_id, version.created)

The client sends .md files as text/markdown, whatever Python you run.

created is True the first time. Send the same bytes again and it is False: nothing new is stored.

5. Wait until it is processed

client.wait_for_readiness([version.version_id])

Processing reads, structures and connects the document. It takes minutes. wait_for_readiness checks every 15 seconds for up to 30 minutes by default, and stops with an error at once if a stage fails for good.

6. Ask

result = client.facts_context("Who owns the invoice exporter?")
print(result.model_dump_json(indent=2))

The result is an envelope. Look for:

  • facts: each fact, such as Ravi owns the invoice exporter, with its validity (when it held) and evidence_count;
  • evidence: the claims behind each fact, with the document, the passage and its character positions;
  • negative: set instead of facts when the memory knows nothing about what you asked.

Reading a result explains every field.

The same with the CLI

remember ingest standup.md \
  --source-kind file --source-ref notes/standup.md \
  --source-modified-at 2026-09-17T09:30:00+00:00
 
remember query "Who owns the invoice exporter?"

remember query "<text>" runs facts_context. Add --combined to remember query text to get facts together with claims and source passages.

Next