RememberStackremember.dev/docs

CLI

This page describes the remember CLI (v0.17.2), installed by pip install remember.

The remember command stores documents, asks the memory questions and connects coding agents. It comes with the remember Python package:

pip install remember
remember --version

It needs Python 3.12 or newer. uv tool install remember installs it as a standalone tool; uvx remember … runs it without installing.

Commands at a glance

GroupCommandWhat it does
MemoryingestUpload one file.
queryAsk a question, or run SQL queries and saved queries.
operationsList or run assured operations by name.
documentsList documents, or delete one from the memory.
AgentsmcpServe the memory to a coding agent over MCP.
setupWrite MCP configuration for your coding agents.
doctorCheck installation, credentials, connectivity and agent configuration.
Not servedconnectorsTalks to routes no deployment serves yet.
Engine operatorsopsPipeline repair inside the engine container.

remember with no command prints help and exits with status 2. remember <command> --help prints that command's flags.

How the CLI finds your deployment

Every command that talks to a deployment (ingest, query, operations, documents, mcp, connectors, doctor) accepts the same three flags:

FlagMeaning
--api-url URLThe deployment address.
--api-key KEYThe API key. A bare key or a full Bearer … value.
--project PROJECTWhich project to use, by id or name, when the key covers several.

Put flags after the subcommand: remember query sql --api-url … "SELECT 1".

Each setting is resolved on its own. First match wins:

Setting1. Flag2. Environment3. Credential file4. Otherwise
Key--api-keyREMEMBER_API_KEYkeyno key
Address--api-urlREMEMBER_API_URLapi_urlhttp://127.0.0.1:8000
Project--projectREMEMBER_PROJECTdefault_projectnone

The Python SDK resolves the same settings the same way (Python SDK).

A key read from the credential file is only sent to the address stored beside it. If --api-url or REMEMBER_API_URL names another address, the command exits with status 2 and asks for the key explicitly, with --api-key or REMEMBER_API_KEY. A key you pass explicitly is sent wherever you point it.

export REMEMBER_API_URL=http://localhost:8000
export REMEMBER_API_KEY=<the key your engine accepts, if any>
remember query "Who owns the billing migration?"

Output

Commands print their results to standard output: JSON for memory commands. Warnings and errors go to standard error, so you can pipe the output into jq safely.

Exit codes

CodeMeaning
0Success.
1The request failed (network, HTTP error, rejected key), the credential file is unusable, or a check in doctor failed.
2Usage error: unknown command or flag, missing argument, or an argument the CLI could not parse (for example --parameters that is not a JSON array). Also a stored key refused for the address you named.

Memory commands

remember ingest

remember ingest FILE [--mime MIME] [--title TITLE]
                     [--source-kind KIND --source-ref REF]
                     [--source-modified-at ISO8601]
                     [--versioning-mode {snapshot,living}]
                     [--source-version-ref REF]
                     [--api-url URL] [--api-key KEY] [--project PROJECT]

Uploads one file and prints the new version as JSON:

{"deployment_id":"…","doc_id":"…","version_id":"…","content_hash":"…","created":true,"mime":"text/markdown","title":"…","versioning_mode":"snapshot"}

created is false when these exact bytes are already stored for the same document; nothing is processed again.

FlagDefaultMeaning
FILErequiredPath of the file to upload.
--mimefrom the file's extension (.md is text/markdown, .pdf is application/pdf; the full table is in Ingest files), else application/octet-streamMedia type. The engine processes only types it has a converter for; see File formats and converters.
--titlenoneHuman title.
--source-kind, --source-refnoneThe document's stable identity. Give both or neither. Re-ingesting with the same pair makes a new version of the same document.
--source-modified-atnoneWhen the source last changed, as an ISO 8601 timestamp with a UTC offset of zero, for example 2026-09-21T14:00:00+00:00. Needs --source-kind/--source-ref.
--versioning-modesnapshotsnapshot or living; living needs --source-kind/--source-ref. See Updating a source.
--source-version-refnoneThe source system's revision label. Needs --source-kind/--source-ref.

Exit status 2 when the source arguments break these rules or the timestamp is not UTC; 1 when the file cannot be read or the upload fails.

remember ingest notes/2026-09-18-billing-sync.md \
  --title "Billing sync, 18 September" \
  --source-kind meeting-notes --source-ref billing-sync/2026-09-18

It prints the IngestedVersion as one JSON line. When the file's conversion is parked waiting for a conversion route, the line has "parked":"no_route" and the command also prints a warning to stderr that names the release step (remember ops resume-no-route); the exit status stays 0, because the file is stored. See File formats and converters.

Ingest returns before processing ends. To wait, use the SDK's wait_for_readiness or the MCP pipeline_readiness tool; the CLI has no readiness command. See Wait until a document is queryable.

remember documents

remember documents list [--limit N] [--cursor CURSOR]
                        [--status {ingesting,converting,structuring,ready,failed}]
                        [--api-url URL] [--api-key KEY] [--project PROJECT]
remember documents search [QUERY] [--family FAMILY]... [--author NAME_OR_ADDRESS]...
                          [--recipient NAME_OR_ADDRESS]...
                          [--created-from T] [--created-to T]
                          [--modified-from T] [--modified-to T]
                          [--language LANG] [--thread-ref REF] [--doc-id DOC_ID]...
                          [--versions {current,all}] [--limit N] [--cursor CURSOR]
                          [--api-url URL] [--api-key KEY] [--project PROJECT]
remember documents delete DOC_ID [--api-url URL] [--api-key KEY] [--project PROJECT]

list prints one page of documents as JSON, newest document first, in the shape of DocumentPage. Pass the page's cursor to --cursor to read the next page; cursor is null on the last page. --limit is 1 to 200 (default 50). --status keeps only documents whose newest version has that status.

remember documents list --status failed | jq -r '.documents[] | "\(.doc_id) \(.title)"'

search finds documents by name, metadata and text and prints a DocumentSearchPage as JSON. Repeat --family, --author, --recipient and --doc-id to list several; any listed value matches. Dates are ISO 8601 with a timezone, for example 2025-01-01T00:00:00+00:00. With a QUERY the results are ranked and there is no next page; without one they are newest ingested first and --cursor reads the next page. --limit is 1 to 200 (default 20). See POST /documents/search.

remember documents search "q3 sales" --family spreadsheet | jq -r '.documents[] | "\(.doc_id) \(.file_name)"'
remember documents search --author alice@acme.com --created-from 2025-01-01T00:00:00+00:00

delete removes one document, every version of it, from the memory and prints what changed:

{"doc_id":"…","deleted_at":"2026-09-23T10:41:07.318000Z","claims_retired":12,"relations_closed":2,"observations_closed":1}

Its claims stop counting as evidence, and facts that only it supported are closed with a recorded retraction. The claims and the stored original stay as history. Deleting needs a write credential. Deleting a document that does not exist, or is already deleted, prints error: API 404: document_not_found and exits with status 1. See DELETE /documents/{doc_id}.

remember documents delete a1f3e0b4-1c2d-5e6f-8a9b-0c1d2e3f4a5b

remember query

remember query "QUESTION" [--combined]
remember query text "QUESTION" [--combined]
remember query sql STATEMENT [--parameters JSON] [--max-rows N]
remember query explain-sql STATEMENT [--parameters JSON]
remember query space [--pattern GLOB] [--include-examples]
remember query search-space QUERY [--k N]
remember query list-saved [--namespace NS] [--status STATUS]
remember query describe-saved NAMESPACE NAME [--version N]
remember query run-saved NAMESPACE NAME [--version N] [--parameters JSON] [--max-rows N]
remember query adjacent-chunks CHUNK_ID [--window {1,2}]

Every subcommand also takes --api-url, --api-key and --project.

Asking a question

remember query "QUESTION" is short for remember query text "QUESTION". It runs the facts_context operation and prints the result envelope as indented JSON. With --combined it runs combined_context instead and prints both the facts and what sources said.

remember query "Who owns the billing migration?"
remember query --combined "Why did the cutover move to October?"

Note

The shorthand applies only when no argument after query is exactly a subcommand name (text, sql, explain-sql, space, search-space, list-saved, describe-saved, run-saved, adjacent-chunks). To ask a one-word question such as "space", write remember query text space.

For other operation arguments (time, entity_ids, k), use remember operations run.

SQL queries

SQL queries run over the query space (memory_v1): prepared, read-only views and functions. The engine parses every statement and validates it against the query space before it runs; anything outside it is rejected. Output is the QueryResult/v1 JSON object. See Query space memory_v1.

SubcommandArgumentsWhat it prints
sqlSTATEMENT; --parameters (JSON array of positional values for $1, $2, …); --max-rows (integer, 0 or more)The result rows and their provenance.
explain-sqlSTATEMENT; --parametersThe plan, without running the statement.
space--pattern (shell-style filter over view names); --include-examplesThe views, functions, comments and limits.
search-spaceQUERY; --k (default 10; the engine accepts 1–25)Matching entries of the query space's own documentation, never your data.
list-saved--namespace; --statusSaved queries. Without --status, active versions only.
describe-savedNAMESPACE NAME; --versionOne saved query's SQL, parameters and columns.
run-savedNAMESPACE NAME; --version; --parameters; --max-rowsThe result of one active saved query.

NAMESPACE and NAME must match ^[a-z][a-z0-9_]*$. A malformed --parameters value exits with status 2.

remember query sql \
  "SELECT predicate, count(*) AS n FROM facts_current GROUP BY 1 ORDER BY 2 DESC LIMIT \$1" \
  --parameters '[10]'

adjacent-chunks

Prints the passages immediately before and after one chunk, in document order. --window is 1 (default) or 2.

remember query adjacent-chunks 6f1c2d0e-… --window 2

remember operations

remember operations list [--api-url URL] [--api-key KEY] [--project PROJECT]
remember operations run NAME [--arg KEY=VALUE]... [--api-url URL] [--api-key KEY] [--project PROJECT]

list prints one JSON descriptor per line for the four assured operations, with each one's input schema.

run runs one operation. Each --arg is KEY=VALUE; the value is parsed as JSON when it can be, otherwise kept as a string. The result prints as one line of JSON.

remember operations run facts_context \
  --arg query="billing migration owner" \
  --arg 'time={"mode":"history"}' \
  --arg k=25

An --arg without = exits with status 2. Operation names and arguments are in Assured operations.

Agent commands

remember mcp

remember mcp [--read-only] [--api-url URL] [--api-key KEY] [--project PROJECT]
remember mcp --transport http [--bind HOST:PORT] [--read-only] [--api-url URL]

Runs an MCP server for a coding agent. By default it speaks on standard input and output and finds the deployment the same way as every other command. --transport http serves the same tools over HTTP at http://127.0.0.1:8765/mcp instead (--bind picks another loopback address or port). --read-only removes the tools that change memory, ingest and delete_document.

You rarely start it yourself; remember setup writes the agent configuration that starts it. The two transports, the tools, their parameters and the errors are in MCP tools.

remember setup

remember setup [--self-hosted] [--api-url URL] [--api-key KEY] [--mcp-url URL]
               [--agent {cursor,claude,codex,agy,all}] [--dir DIR] [--dry-run]

Writes each coding agent's MCP entry for Remember.

FlagDefaultMeaning
--self-hostedConfigure for an engine at --api-url, default http://127.0.0.1:8000.
--api-urlnoneThe engine address. It implies --self-hosted and is written into stdio entries as REMEMBER_API_URL.
--api-keynoneWith --self-hosted: the engine's key, stored in the credential file and never written into agent configuration.
--mcp-urlnoneThe URL of your own remember mcp --transport http server. It implies --self-hosted. Agents that accept a URL entry connect to it; the others get a stdio entry.
--agentallWhich agent to configure. agy is Antigravity; claude means Claude Code and Claude Desktop.
--dircurrent directoryThe project directory for project-level configuration.
--dry-runoffPrint the entries it would write; write nothing.

What it does, in order:

  1. Finds the launcher. It prefers an installed remember binary; when that binary lives in a virtual environment or a cache, or when there is none, it uses uvx remember mcp. Paths are resolved to absolute paths so an editor started from a desktop launcher finds them. With neither remember nor uvx on PATH it exits with status 1.
  2. Chooses the agents. With --agent all it configures what it finds: Cursor if .cursor/ exists in the directory, Antigravity if .agents/ exists, Codex if .codex/ exists or codex is installed, Claude Code if claude is on PATH, Claude Desktop if its configuration file or directory exists (or, on macOS, the app is installed). If it finds none, it configures Cursor and Antigravity.
  3. For a self-hosted engine, stores the engine address and key in the credential file (see the warning below).
  4. Writes one entry per agent. For a self-hosted engine the entry starts remember mcp with REMEMBER_API_URL. With --mcp-url, Cursor, Claude Code and Codex get a URL entry instead; Claude Desktop and Antigravity keep the stdio entry. A key, if any, is never written: a URL entry refers to the REMEMBER_API_KEY variable, which you set in the agent's environment.

Claude Code and Codex count as accepting URL entries only when their installed command line supports them: claude mcp add --help must list --transport, and codex mcp add --help must list --bearer-token-env-var. Otherwise they get the stdio entry, which works everywhere.

The exact files and their content are listed in MCP tools: configuration that remember setup writes.

Existing configuration files must be valid JSON or TOML and must not be symbolic links; otherwise that agent is not configured and the command exits with status 1. A failure in one agent does not stop the others. Running the command again with the same flags leaves the files unchanged.

remember setup --self-hosted --agent cursor --dry-run

remember doctor

remember doctor [--api-url URL] [--api-key KEY] [--project PROJECT]

Checks your setup and prints one line per check:

  1. remember or uvx is on PATH.
  2. The credential file: whether it is readable, and what it holds.
  3. The deployment: GET /deployment with a 5-second timeout, resolved and authenticated exactly as every other command.
  4. Agent configuration in the current directory: .cursor/mcp.json, .agents/mcp_config.json, .codex/config.toml, and Claude Desktop's configuration file. For each it checks the file parses and contains a remember server. For a stdio entry it checks the command exists and is executable; for a URL entry it prints the URL.

[✓] is a pass, [-] is informational, [!] is a failure. Exit status 1 when any check fails.

remember connectors

remember connectors list
remember connectors add KIND --name NAME [--config KEY=VALUE]... [--credential-ref REF]
remember connectors pause CONNECTOR_ID
remember connectors status CONNECTOR_ID

These commands call /connectors routes that no deployment serves today. Every one fails with API 404 and exit status 1. Connectors are listed in What is not built yet.

Self-hosted operations: remember ops

remember ops repairs and inspects a self-hosted engine's pipeline. It runs inside the engine container, which enables it by setting REMEMBERSTACK_INTERNAL_OPS=1. Elsewhere, including a remember installed from PyPI, it prints an error and exits with status 1, and the help output does not list it.

docker compose exec api \
  remember ops inspect --deployment "$REMEMBERSTACK_SELFHOST_DEPLOYMENT_ID"

--deployment is the engine's deployment id (REMEMBERSTACK_SELFHOST_DEPLOYMENT_ID).

SubcommandFlagsWhat it doesOutput
inspect--deployment IDA bounded report of the pipeline: work in progress, dead letters, projections and freshness.JSON
cost-export--deployment ID, --cursor CURSOR, --limit N (default 100)One page of the cost export, which holds no document content. Exit 2 when --deployment does not match the engine or the cursor is invalid.JSON
resume-no-route--deployment IDReleases documents that were parked because no converter handled their media type, once a route now covers them.{"released": [...]}
replayPROCESSING_ID, --deployment ID, --attempts N (default 1), --lane {steady,backfill}, --not-before ISO8601Reopens one dead-lettered work item with N more attempts.JSON
graph-catalog ensurenoneChecks the database's graph metadata and repairs it when needed.{"ready", "changed", "problems_before", "problems_after", "definitions"}

When and why to use each: Operating the pipeline.

Engine container commands

The engine image ghcr.io/writeitai/remember-stack has its own entry point, python -m rememberstack.profiles.selfhost. compose.yaml runs each process with one of these commands; you use them when you write your own orchestration.

CommandWhat it runs
setupApplies database migrations and prepares the deployment. Runs once; the other services start after it succeeds.
apiThe HTTP API. Listens on REMEMBERSTACK_SELFHOST_API_HOST (default 0.0.0.0) and REMEMBERSTACK_SELFHOST_API_PORT (default 8000). This is the image's default command.
worker --stage STAGEOne pipeline worker. STAGE is one of convert, structure, chunk, embed_chunk, extract_claims, ground_claims, normalize_relations, adjudicate_observations, adjudicate_supersession, embed_claim, reconcile, label_relation. Run one process per stage.
project --plane p3Builds the filesystem view snapshot once. In compose.yaml it belongs to the operations profile.
mounts --root PATH [--raw-root PATH] [--artifacts-root PATH]Publishes the latest snapshot under a local directory.

The pipeline stages are explained in The pipeline and readiness; configuration in Configuration; snapshots and mounts in Filesystem views.

Credential file

remember setup --self-hosted stores the engine address and key in credentials.json. The CLI and the Python SDK both read it, after flags (or arguments) and environment variables.

Location, first match wins:

  1. REMEMBER_CONFIG_DIR
  2. $XDG_CONFIG_HOME/remember/
  3. ~/.config/remember/

Protection:

  • The directory is created with mode 0700 and the file with mode 0600. The file is written to a temporary name, synced and renamed, so a crash leaves either the old file or the new one.
  • The CLI refuses to read a file that is a symbolic link or that group or other users can read, and exits with status 1. Fix it with chmod 600 ~/.config/remember/credentials.json.
  • Commands that change the file take a lock (.lock in the same directory).

Format, version 2, for a self-hosted engine:

{
  "version": 2,
  "api_url": "http://127.0.0.1:8000",
  "key": "<the engine's key, or null>",
  "issuer": null,
  "key_id": null,
  "expires_at": null,
  "default_project": null
}

A file in any other shape is refused. remember setup --self-hosted replaces it.

Environment variables

VariableUsed byMeaning
REMEMBER_API_URLmemory commandsDeployment address.
REMEMBER_API_KEYmemory commandsAPI key, ahead of the credential file.
REMEMBER_PROJECTmemory commandsProject id or name for a key that covers several projects.
REMEMBER_CONFIG_DIRallCredential file directory.
XDG_CONFIG_HOMEallBase for the default credential directory.
REMEMBERSTACK_INTERNAL_OPS, REMEMBER_INTERNAL_OPSopsEnables remember ops. The engine image sets it.
REMEMBERSTACK_MCP_INGEST_ROOTS, REMEMBERSTACK_MCP_PATH_READ_MAX_BYTESmcpPath ingest; see MCP tools.
APPDATA (Windows), XDG_CONFIG_HOME (Linux)setup, doctorWhere Claude Desktop's configuration lives.

Names are not case-sensitive. All client variables are in Configuration variables.