ai-memory v0.8.0

ai-memory CLI Reference

Complete reference for every subcommand, flag, and environment variable the ai-memory binary exposes.

ai-memory [GLOBAL_OPTIONS] <COMMAND> [COMMAND_OPTIONS]

Run ai-memory <command> --help for the authoritative flag list generated by clap. This document is kept in sync with the source (the Command enum in src/daemon_runtime.rs; 87 top-level subcommands in the default build, 89 under --features sal — SSOT: EXPECTED_CLI_SUBCOMMANDS_DEFAULT / _SAL in src/lib.rs) and supplements --help with examples and context.

Global flags

Flag Type Default Description
--db <PATH> path ai-memory.db SQLite database path. Honours AI_MEMORY_DB env var.
--json bool false Emit machine-parseable JSON on stdout.
--agent-id <ID> string synthesized NHI default Stamps metadata.agent_id. Honours AI_MEMORY_AGENT_ID env var.
--db-passphrase-file <PATH> path v0.6.0.0+. Root-readable file holding the SQLCipher passphrase. Only meaningful on --features sqlcipher builds. Exports AI_MEMORY_DB_PASSPHRASE for the process.

Environment variables

Variable Purpose
AI_MEMORY_DB Override default database path.
AI_MEMORY_AGENT_ID Default metadata.agent_id for memories written by this process.
AI_MEMORY_DB_PASSPHRASE SQLCipher passphrase (set via --db-passphrase-file or by operator).
AI_MEMORY_NO_CONFIG=1 Skip loading ~/.config/ai-memory/config.toml. Used by tests.
AI_MEMORY_ANONYMIZE=1 Suppress hostname/PID from fallback agent_id generation.
AI_MEMORY_AUTONOMOUS_HOOKS=1 Enable post-store LLM hooks (v0.6.0.0). Overrides config.
AI_MEMORY_BOOT_ENABLED Enable/disable session-boot context. Set to 0 to disable. Overrides config.
AI_MEMORY_AUDIT_DIR Override directory for the security audit trail. Default: ~/.local/state/ai-memory/audit/.
AI_MEMORY_LOG_DIR Override directory for operational logs. Default: ~/.local/state/ai-memory/logs/.
AI_MEMORY_REQUIRE_API_KEY=1 Hard-require api_key on every daemon bind, including loopback (#1458). Use when fronting the daemon with a reverse proxy / --network=host container / socat forward, where the loopback host string the daemon sees does not reflect off-host reachability. Default off (keyless loopback permitted with a warning; keyless non-loopback already refused).
AI_MEMORY_EMBED_BACKEND #1598 — embedding backend selector: ollama (default), any #1067 vendor alias (openrouter, openai, gemini, …), or openai-compatible (self-hosted TEI/vLLM/llama.cpp server). Precedence: env > [embeddings] section > legacy flat > compiled default.
AI_MEMORY_EMBED_BASE_URL #1598 — embedding endpoint base URL. Required for openai-compatible; vendor default applies for named aliases.
AI_MEMORY_EMBED_MODEL #1598 — embedding model id (e.g. google/gemini-embedding-2). Dim resolves from KNOWN_EMBEDDING_DIMS; set [embeddings].dim for models outside the table.
AI_MEMORY_EMBED_API_KEY #1598 — secret. Bearer key for API embedding backends; highest-precedence layer over the per-vendor alias env, [embeddings].api_key_env, and [embeddings].api_key_file (0400 enforced).
RUST_LOG Tracing filter, e.g. RUST_LOG=ai_memory=debug. (Standard Rust ecosystem env, not product-specific.)

Resolution precedence for any setting: CLI flag > AI_MEMORY_* env var > config file > compiled default.

Core memory operations

store

Create or upsert a memory. Upsert key is (title, namespace). Tier never downgrades.

Flag Type Default Notes
--tier/-t enum mid short/mid/long.
--namespace/-n string git-remote or dir name  
--title/-T string required  
--content/-c string required Pass - to read stdin.
--tags comma-list ""  
--priority/-p int 1–10 5  
--confidence float 0.0–1.0 1.0  
--source/-S string cli One of the canonical VALID_SOURCES (src/validate.rs): user, nhi, claude (deprecated), hook, api, cli, import, consolidation, system, chaos, notify.
--expires-at RFC3339 Overrides tier default.
--ttl-secs int Overrides tier default.
--scope enum private Task 1.5 visibility. private/team/unit/org/collective.
--kind enum observation v0.7.0 F2.3 (#1427) Form-6 memory kind: observation, reflection, persona, concept, entity, claim, relation, event, conversation, decision.
--citations JSON Form-4 provenance: JSON array of {uri, accessed_at, hash?, span?}.
--source-uri string Form-4 source pointer; uri: / doc: / file: schemes.
--source-span JSON Form-4 byte-range pin: {start, end}.
--entity-id string QW-2 persona binding; required with --kind persona.
--sign bool false #626 Layer-3 — sign the write with the resolved agent’s local Ed25519 keypair so the stored row is attested (attest_level = "agent_attested") rather than merely claimed. Requires a <agent_id>.priv under the key directory (AI_MEMORY_KEY_DIR or the platform default) and a matching bound public key (ai-memory agents bind-key). Without --sign the write is claimed unless AI_MEMORY_REQUIRE_AGENT_ATTESTATION is set (which then rejects the unsigned write).
ai-memory store --title "Q2 roadmap" \
  --content "Aligned on microservices cut-over by July" \
  --tier long --namespace planning --tags strategic,quarterly

# Attested write: sign with the agent's bound Ed25519 keypair (#626 Layer-3).
ai-memory store --title "Prod incident postmortem" \
  --content "Root cause: connection-pool exhaustion under retry storm" \
  --tier long --namespace incidents --agent-id ai:claude-opus-4.7 --sign

recall

Semantic + keyword hybrid recall. Mutates the database: increments access_count, raises expires_at to MAX(current expires_at, now + per-tier-extend_secs) (extension FLOOR — an access can never move an expiry earlier; issue #1596, superseding the #830 replacement contract), auto-promotes mid→long at 5 accesses.

Flag Type Default Notes
<context> positional required Natural-language query.
--namespace/-n string  
--limit int 10 Capped at 50.
--tags comma-list  
--since/--until RFC3339  
--tier/-T enum config keyword/semantic/smart/autonomous.
--as-agent string Task 1.5 scope-aware recall.
--budget-tokens int Task 1.11 context-budget.
--context-tokens comma-list v0.6.0.0 conversation bias; 70/30 fusion.
--session-default bool false v0.7.0 (#518) — splice [agents.defaults.recall_scope] defaults for unset filters.
--include-archived bool false v0.7.0 WT-1-E — also return archived atomisation sources.
--has-citations bool false v0.7.0 Form 4 (#757) — only memories with a non-empty citations array.
--source-uri-prefix string v0.7.0 Form 4 (#757) — only memories whose source_uri starts with this prefix.
--kind / --kinds comma-list v0.7.x Form 6 (#759) — Batman-taxonomy kind filter (concept,entity,claim, …; all or omit = no filter).
ai-memory recall "what deployment pattern did we agree on" \
  --tier semantic --namespace planning --limit 5

Read-only FTS5 keyword search. Does not mutate the database.

Flag Type Default Notes
<query> positional required AND semantics.
--namespace/-n string  
--tier/-t enum  
--limit int 20 (The MCP memory_search tool caps at 200; the CLI passes the limit through.)
--since/--until RFC3339  
--tags comma-list  
--agent-id string Exact metadata.agent_id match.
--as-agent string Scope-aware filter.
--include-archived bool false v0.7.0 WT-1-E — include archived atomisation sources.
ai-memory search "kubernetes rollout" --tier long --limit 10

list, get, update, delete

Standard CRUD.

ai-memory list --namespace planning --tier long --limit 50
ai-memory get abc123
ai-memory update abc123 --title "Renamed" --priority 8
ai-memory delete abc123

list supports the same filters as search. get accepts a UUID or unique prefix. update omits any flag you don’t pass. delete archives first when archive_on_gc=true (default).

ai-memory promote abc123                    # bump to long tier
ai-memory promote abc123 --to-namespace org # Task 1.7 clone-to-ancestor
ai-memory forget --namespace scratch --tier short
ai-memory link src-id dst-id --relation supersedes

Relations (nine at v0.8.0; was six at v0.7.0): related_to (default), supersedes, contradicts, derived_from, reflects_on, derives_from, decomposes_into, depends_on, advances (the last three are the v0.8.0 Pillar-2 typed-cognition Goal/Plan/Step relations, #1709). Canonical enum in src/models/link.rs::MemoryLinkRelation (COUNT = 9).

forget safety rail (Round-2 F11): when --namespace is omitted and --pattern or --tier is set, the delete is global-scope and refuses to run without --confirm-global.

Lifecycle

consolidate

Merge multiple memories into a single summary memory. Sources deleted (archived); new memory carries derived_from links.

ai-memory consolidate "id1,id2,id3" \
  --title "Consolidated Q2 planning" \
  --summary "Consensus notes across three sessions" \
  --namespace planning

Min 2, max 100 source ids.

auto-consolidate

Automatic batch consolidation of similar short-tier memories. Identifies clusters via Jaccard similarity, then merges each cluster into a single mid-tier consolidated memory (sources archived, derived_from links preserved). Pairs with curator for autonomous mode.

Flag Type Default Notes
--namespace/-n string Restrict scan to one namespace.
--short-only bool false Only consolidate short-tier candidates.
--min-count usize 3 Skip clusters below this size.
--dry-run bool false Report only — no archive, no merge.
ai-memory auto-consolidate --namespace planning --min-count 5 --dry-run

Cluster threshold: CONSOLIDATE_JACCARD_THRESHOLD = 0.55. Cluster ceiling: CONSOLIDATE_MAX_CLUSTER_SIZE = 8 (per src/autonomy.rs).

resolve

Mark one memory as superseding another (adds supersedes link + archives loser).

ai-memory resolve winner-id loser-id

gc, stats, namespaces

ai-memory gc                      # immediate garbage collection
ai-memory stats                   # counts by tier/namespace, DB size
ai-memory namespaces              # list every namespace + count

export, import

ai-memory export > backup.json
ai-memory import < backup.json                # restamps agent_id
ai-memory import --trust-source < trusted.json # preserves agent_id

--trust-source is only safe when the source is your own backup or a fully-trusted peer. Without it, metadata.imported_from_agent_id records the original claim.

Integration surfaces

mcp

Run as an MCP tool server over stdio (JSON-RPC 2.0). --profile full advertises 101 entries (100 callable memory tools + the always-on memory_capabilities bootstrap; see issue #862 for the disambiguation). Default --profile core ships 7 tools + the bootstrap. Plus 2 prompts (recall-first, memory-workflow).

ai-memory mcp --tier semantic

See docs/API_REFERENCE.md and the MCP section of USER_GUIDE.md.

serve

Axum-based HTTP daemon on port 9077. There is no --tier flag (tier comes from config.toml, #703) and no --api-key flag (the API key comes from the api_key field in config.toml).

Flag Type Default Notes
--host string 127.0.0.1  
--port u16 9077  
--tls-cert/--tls-key path Enable HTTPS. rustls, no OpenSSL.
--mtls-allowlist path SHA-256 cert-fingerprint allowlist (requires --tls-cert).
--shutdown-grace-secs u64 30 SIGINT grace period.
--quorum-writes usize 0 v0.7 federation: W (peer acks required). 0 = federation off.
--quorum-peers comma-list Peer base URLs; each must expose POST /api/v1/sync/push.
--quorum-timeout-ms u64 2000 Quorum-ack deadline; after it the write returns 503 quorum_not_met. Default assumes same-DC peers; cross-region (WAN) meshes need 5000-10000 (the do-1461 reference deployment uses 8000 — see docs/federation.md, #1565).
--quorum-client-cert/--quorum-client-key path mTLS client pair for outbound quorum fanout.
--quorum-ca-cert path CA for verifying quorum peers.
--catchup-interval-secs u64 30 Federation catch-up loop cadence.
--federation-identity string Identity this node presents to peers (also AI_MEMORY_FED_IDENTITY).
--store-url URL SAL backend selector (postgres://… under --features sal-postgres).
ai-memory serve --host 0.0.0.0 --port 9077 \
  --tls-cert /etc/ai-memory/cert.pem \
  --tls-key /etc/ai-memory/key.pem

sync, sync-daemon

ai-memory sync /path/to/remote.db --direction merge --dry-run
ai-memory sync-daemon \
  --peers http://peer-a:9077,http://peer-b:9077 \
  --interval 30 --batch-size 500

sync flags: --direction pull|push|merge (default merge), --trust-source, --dry-run. sync-daemon flags: --peers (comma-list), --interval (seconds, default 2), --batch-size (default 500), --api-key (X-API-Key presented to peers), plus the mTLS options --client-cert / --client-key. --insecure-skip-server-verify is documented as DANGEROUS.

Mining & archives

mine

Import memories from Claude, ChatGPT, or Slack exports.

ai-memory mine ./claude-export --format claude --min-messages 3

--format: claude / chatgpt / slack. --dry-run previews.

archive

ai-memory archive list --limit 100
ai-memory archive restore abc123
ai-memory archive purge --older-than-days 30
ai-memory archive stats

Governance & agents

ai-memory agents list
ai-memory agents register \
  --agent-id ai:claude@prod \
  --agent-type ai:claude-opus-4.7 \
  --capabilities recall,search,store

ai-memory pending list --status pending
ai-memory pending approve pending-id
ai-memory pending reject pending-id

--agent-type accepts: human, system, ai:claude-opus-4.6, ai:claude-opus-4.7, ai:codex-5.4, ai:grok-4.2, or any ai:<name> form (e.g., ai:gpt-5, ai:gemini-2.5).

agents also exposes bind-key / revoke-key — bind (or revoke) an agent’s Ed25519 public key for #626 Layer-3 store-path attestation (pairs with ai-memory store --sign).

Backup & restore (v0.6.0.0)

ai-memory backup --to /var/backups/ai-memory --keep 48
ai-memory restore --from /var/backups/ai-memory

backup uses SQLite VACUUM INTO (hot-backup safe) and writes a sha256 manifest. restore verifies the manifest before replacing the DB; use --skip-verify only for forensic recoveries.

Autonomy (v0.6.1)

curator

Flag Type Default Notes
--once bool Single sweep + JSON report.
--daemon bool Loop until SIGINT/SIGTERM.
--interval-secs u64 3600 Daemon cadence; clamped to [60, 86400].
--max-ops usize 100 Hard cap on LLM calls per cycle.
--dry-run bool No DB writes.
--include-namespace repeatable Restrict to listed namespaces.
--exclude-namespace repeatable Skip listed namespaces.
--json bool Machine-parseable report.
--rollback <id> string Reverse one rollback-log entry.
--rollback-last <N> usize Reverse the N most recent.
# Once with JSON report
ai-memory curator --once --max-ops 50 --json

# Daemon mode
ai-memory curator --daemon --interval-secs 1800

# Reverse the last 5 autonomous actions
ai-memory curator --rollback-last 5

See docs/RUNBOOK-curator-soak.md for the week-long soak procedure.

Session-boot, install, wrap, logs, audit, bench, doctor (v0.6.3.1)

These seven subcommands land in v0.6.3.1.

boot

Universal session-boot CLI primitive. Read-only, fast (no embedder, no daemon). Always emits a 5-field diagnostic manifest (version, db_path + schema_version + memory count, tier with embedder/reranker/llm, latency, namespace + loaded count) so the agent and the human always see what loaded and why.

Flag Type Default Notes
--namespace string inferred from --working-dir Override the auto-namespace.
--limit int 10 Clamped to 1..=50.
--budget-tokens int 4096 Optional context-budget cap (0 = unlimited).
--format enum text text / json / toon.
--no-header bool false Suppress the manifest header. NOT recommended for production hooks (silent failure becomes indistinguishable from “no memories yet”).
--quiet bool false Exit 0 silently when DB unavailable.
--cwd <PATH> path . Override the working-directory inference for auto-namespace.

AI_MEMORY_BOOT_ENABLED=0 is the highest-precedence privacy opt-out (silent exit 0). boot exits 0 in every state — never wedges an agent’s first turn.

ai-memory boot --limit 3
ai-memory boot --namespace planning --format json --quiet
AI_MEMORY_BOOT_ENABLED=0 ai-memory boot   # privacy opt-out: silent exit 0

See the [boot] config block in docs/ADMIN_GUIDE.md for enabled / redact_titles settings.

install <agent>

Multi-target config-file installer. 10 targets: claude-code, openclaw, cursor, cline, continue, windsurf, claude-desktop, codex, grok-cli, gemini-cli.

Flag Type Default Notes
--apply bool false Write changes. Without it, runs in dry-run mode and emits a unified diff to stdout.
--dry-run bool true Default mode — preview only. Conflicts with --apply.
--uninstall bool false Remove the managed marker block precisely. Combine with --apply to actually delete.
--config <PATH> path per-target canonical Override discovery for targets where the canonical path can’t be auto-detected.
--binary <PATH> path resolved on PATH Override the resolved ai-memory binary path.
--hook <KIND> enum Also install the named hook (claude-code only today).
--force bool false Overwrite an existing managed block.

Behaviours:

ai-memory install claude-code               # preview the diff
ai-memory install claude-code --apply       # actually write
ai-memory install claude-code --uninstall --apply

wrap <agent>

Cross-platform Rust replacement for shell-wrapper recipes. Spawns the named CLI with ai-memory boot context delivered via the appropriate strategy.

Strategy Behaviour Default for
SystemFlag --system <msg> (or whatever the target accepts) codex / codex-cli, gemini
SystemEnv env-var injection ollama
MessageFile tempfile + --message-file <path> aider
Auto per-agent lookup table (selector)
Flag Type Default Notes
--system-flag <FLAG> string per-agent Override the system-message flag. Mutually exclusive with --system-env and --message-file-flag.
--system-env <NAME> string per-agent Override the system-message env var.
--message-file-flag <FLAG> string per-agent Override the message-file flag.
--no-boot bool false Skip the ai-memory boot call entirely.
--limit int 10 Boot row limit (clamped [1, 50]).
--budget-tokens int 4096 Boot token budget.
trailing <args>... Forwarded to the wrapped agent after --.

Fall-through is --system. Same binary on macOS / Linux / Windows / Docker / Kubernetes. Exit code is propagated.

ai-memory wrap codex -- "draft a release note"
ai-memory wrap aider -- src/main.rs

logs

Operator CLI for the operational logging facility (default-OFF; opt-in via [logging] enabled = true). Subcommands:

Subcommand Notes
tail [--follow] Stream the active log file. --follow-interval-ms (default 1000) sets the poll rate. --lines <N> (default 50) sets the initial buffer.
cat Concatenate rotated log files in order.
archive zstd-compress files past their retention window.
purge --before <date> Delete log files older than <date> (RFC3339). Emits an audit-gap warning.

Global filters (apply to tail / cat): --since, --until, --level, --namespace, --actor, --action-filter, --format text|json, --log-dir <PATH>.

Path resolution precedence: --log-dir flag > AI_MEMORY_LOG_DIR env > config.toml > platform default. See docs/ADMIN_GUIDE.md for the [logging] block and platform default paths.

ai-memory logs tail --follow --level warn
ai-memory logs archive
ai-memory logs purge --before 2026-01-01

audit

Operator CLI for the security audit trail (default-OFF; opt-in via [audit] enabled = true). Three subcommands:

Subcommand Behaviour Exit codes
verify Walks the hash chain, confirms every prev_hash matches the prior line’s self_hash. 0 on integrity, 2 on tamper detection.
tail [--lines N] Prints the most recent N events. Default 50. Filters: --actor, --namespace, --action, --format text|json. 0
path Prints the resolved audit log path. 0

Global flag: --audit-dir <PATH> (overrides AI_MEMORY_AUDIT_DIR env).

Path precedence: --audit-dir flag > AI_MEMORY_AUDIT_DIR env > config.toml > platform default. Append-only at the OS level where supported (chattr +a on Linux, fs_chflags UF_APPEND on macOS/BSD).

ai-memory audit verify          # exits 0 on integrity, 2 on tamper
ai-memory audit tail --lines 50
ai-memory audit path

See docs/ADMIN_GUIDE.md [audit] block + compliance presets.

bench

In-process performance harness against an ephemeral SQLite database (operator’s main DB is never touched). Reports per-operation p50/p95/p99 against the budgets in PERFORMANCE.md. Used by .github/workflows/bench.yml on every PR; exits non-zero when any operation’s measured p95 exceeds its target by more than 10%.

Flag Type Default Notes
--iterations usize bench::DEFAULT_ITERATIONS Sample size, clamped to [1, 100_000].
--warmup usize bench::DEFAULT_WARMUP Warmup iterations, clamped to [0, 10_000].
--json bool false Emit a single JSON document instead of the table.
--baseline <PATH> string Compare against a saved --json baseline; flag regressions.
--regression-threshold <PCT> f64 bench::DEFAULT_REGRESSION_THRESHOLD_PCT Growth threshold for regression flagging (clamped [0.0, 1000.0]).
--history <PATH> path Append the run as one JSONL row to a history file (rolling p95 trend).
--scale <ROWS> usize #1579 B8: seed a scratch corpus of <ROWS> rows first and gate against the PERFORMANCE.md §”Corpus-scale budgets” table (clamped [1, 1_000_000]).
ai-memory bench
ai-memory bench --json --history ./bench/history.jsonl
ai-memory bench --baseline ./bench/baseline-v0.6.3.json
ai-memory bench --scale 10000

Operations covered by src/bench.rs: memory_store (no embedding), memory_search (FTS5), memory_recall (hot, depth=1), memory_kg_query (depth 1 / 3 / 5), memory_kg_timeline. Embedder-bound operations and federation paths are deferred to Stream E follow-ups — see the *[advisory]* rows in PERFORMANCE.md.

doctor

10-section health dashboard (v0.7.x post-#1146/#1598): Storage / Index / Recall / Governance / Sync / Webhook / Capabilities / Reflection Health / LLM Reachability (#1146) / Embeddings Reachability (#1598). Each section is severity-tagged.

Flag Type Default Notes
--remote <URL> string Query a remote daemon’s HTTP API instead of the local DB.
--json bool false Emit JSON instead of the human-readable dashboard.
--fail-on-warn bool false Exit 1 on warnings (default behaviour: exit 0 on warnings).
--tokens bool false v0.6.4-004 — per-tool / per-family / per-profile cl100k_base token-cost report instead of the health report.
--profile <PROFILE> string core With --tokens: evaluate cost under this hypothetical profile (same vocabulary as mcp --profile).
--raw-table bool false Dump the full per-tool size table as JSON. Implies --tokens.
--hooks bool false v0.7-G3 — hook-executor backpressure report (loaded hooks.toml shape + metric placeholders).

Exit codes: 0 healthy, 1 warning (only when --fail-on-warn), 2 critical.

ai-memory doctor
ai-memory doctor --json | jq '.sections[] | select(.severity != "ok")'
ai-memory doctor --remote https://memory.prod.example.com

LLM Reachability (#1146) section. Resolves the canonical LLM configuration via AppConfig::resolve_llm (the same path used by MCP, HTTP daemon, atomise, curator, boot banner) and probes the endpoint:

7-bucket severity partition: INFO = 200 OK; WARN = 401/403 auth failure, 429 rate-limited, 5xx vendor outage; CRIT = 4xx-other (likely wrong base_url), network/DNS/TLS error. Surfaces the resolved provenance facts (backend, model, base_url, config_source, key_source). See docs/CONFIG_SCHEMA.md for the full resolver contract.

Embeddings Reachability (#1598) section. The embeddings sibling of the LLM section. Resolves the canonical embeddings configuration via AppConfig::resolve_embeddings (the same ladder the MCP stdio init + daemon build_embedder consume) and probes:

Same severity mapping (INFO 2xx; WARN 401/403/429/5xx; CRIT other 4xx / network / DNS) plus the full provenance facts (backend, model, base_url, config_source, key_source — never the key itself). When no operator embeddings configuration exists anywhere (fresh install), the section is INFO without probing — the tier preset governs. Additionally fires the operator GPU-policy WARN when the resolved backend is ollama on a host with no detectable NVIDIA GPU (nvidia-smi -L): operator policy runs local Ollama embeddings only on GPU-equipped nodes; CPU-only nodes should use an API backend (see the enterprise reference architectures).

config migrate (v0.7.x #1146)

One-shot rewrite of legacy v1 ~/.config/ai-memory/config.toml (flat fields: llm_model, ollama_url, embed_url, embedding_model, cross_encoder, default_namespace, archive_on_gc, archive_max_days, max_memory_mb, auto_tag_model) into the v2 sectioned shape ([llm], [llm.auto_tag], [embeddings], [reranker], [storage]). Idempotent — running against a v2 file is a no-op INFO log.

Flag Type Default Notes
--dry-run bool false Print the diff to stderr, no writes.
--also-clean-claude-json bool false Additionally remove mcpServers.<*>.env blocks from ~/.claude.json whose command resolves to ai-memory. Opt-in — operator verifies the new config.toml works first.

Exit codes: 0 success or already-v2; 1 dry-run (informational); 2 file not found at ~/.config/ai-memory/config.toml; 3 parse error (invalid TOML); 4 write error.

ai-memory config migrate              # write <file>.bak.<ts> + rewrite
ai-memory config migrate --dry-run    # preview diff, no writes
ai-memory config migrate \
    --also-clean-claude-json          # also strip MCP env block

The migrator never lowers security posture or removes secrets. Inline [llm].api_key = "<literal>" in the source file is REJECTED at v0.7.x parse time — operators must use api_key_env or api_key_file instead. See docs/CONFIG_SCHEMA.md for the secret-handling discipline.

v0.7 feature-gated commands

migrate (--features sal)

One-shot bidirectional migration between SAL backends.

Flag Type Default Notes
--from <URL> string required sqlite:///path.db or postgres://… (needs sal-postgres).
--to <URL> string required Same shapes.
--batch usize 1000 (MIGRATE_BATCH_DEFAULT) Page-size hint, retained for API compatibility — the current migrator reads one page capped at MAX_ROWS (1,000,000) and refuses loudly past it (see src/migrate.rs).
--namespace string Restrict to one namespace.
--dry-run bool Report only, no writes.
--json bool Machine-parseable report.
ai-memory migrate \
  --from sqlite:///var/lib/ai-memory/ai-memory.db \
  --to postgres://ai_memory:pass@pg:5432/ai_memory \
  --dry-run

v0.7.0 net-new CLI subcommands

These subcommands joined the CLI surface between v0.6.4 and v0.7.0 HEAD c9472c1. Source files in src/cli/ (and src/cli/commands/ for the WT-1/QW/Form additions).

atomise — Form 2 / WT-1-C decomposition

Decomposes a long memory into 2-10 atomic propositions. Backs the memory_atomise MCP tool. See docs/atomisation.md.

calibrate confidence — Form 5 sweep (#758)

Per-source baseline calibration: ai-memory calibrate confidence --from-shadow reads confidence_shadow_observations and emits per-(namespace, source) baselines. Backs memory_calibrate_confidence. See docs/confidence-calibration.md.

export-reflections — QW-1 file-backed export

Walks the reflection-chain and writes Markdown to ~/.ai-memory/reflections/<ns>/<id>.md by default. Pair with auto_export_reflections_to_filesystem = true for hands-off operation.

persona — QW-2 persona-as-artifact

Build a persona from observation-kind memories for a given entity. Backs memory_persona / memory_persona_generate.

offload — QW-3 context offload

Move a large blob out of the agent context window. Pairs with the background offload_ttl_sweep worker.

expand — LLM query expansion (#1443)

Expand a free-text query into semantic reformulations via the configured LLM. Closes the three-surface-parity gap: the same expansion primitive backs the MCP memory_expand_query tool, the HTTP POST /api/v1/expand_query route, and this CLI subcommand — the expanded-terms set is byte-equal across all three because they share one code path (crate::mcp::handle_expand_query).

ai-memory expand "neural nets"          # human-readable summary
ai-memory expand --json "neural nets"   # {query, expanded_terms, elapsed_ms, key_source}
Flag Notes
<QUERY> Positional free-text query to expand.
--json Emit the raw JSON envelope on stdout (harness consumption). The no-LLM error envelope also lands on stdout under --json.

Exit codes. 0 success; 2 no LLM backend configured (503-equivalent — the expansion primitive is unreachable); 3 an LLM backend is configured but the call failed (502-equivalent — upstream error).

No-Ollama operation. Query expansion is LLM-backend-agnostic (post-#1067). An entirely Ollama-free configuration drives expansion against a cloud backend — e.g. AI_MEMORY_LLM_BACKEND=openrouter plus AI_MEMORY_LLM_API_KEY (or the OPENROUTER_API_KEY fallback). This is the no-Ollama path the v0.7.0 LongMemEval reproduction exercised; the in-process one-shot lets benchmarks/longmemeval/harness.py inject LLM query-expansion without standing up an MCP stdio server or HTTP daemon per call. The key_source field in the envelope echoes which precedence layer supplied the key (env / config / none) for harness observability.

reembed — vector-space migration (#1598)

Re-embeds the corpus under the currently-resolved embedding backend/model (AppConfig::resolve_embeddings — the same #1598 ladder the daemon’s build_embedder consumes). This is the operator tool for switching embedding models: vectors from different models (or different dims) are not comparable, so after changing [embeddings].model / AI_MEMORY_EMBED_MODEL the existing corpus must be re-embedded into the new vector space.

ai-memory reembed --dry-run                 # plan only, no writes
ai-memory reembed                            # re-embed every row
ai-memory reembed --namespace prod --json    # scope to one namespace
ai-memory reembed --batch 50                 # smaller batches
Flag Notes
--namespace <ns> Restrict the re-embed to a single namespace.
--dry-run Print {total_rows, rows_missing_embeddings, target_model, target_dim, backend} and exit without writing.
--batch <n> Rows per embedding batch (defaults to the resolved backfill_batch).
--json Emit the machine-parseable summary envelope on stdout.

A live run replaces all vectors (not just missing ones). Rows whose batch fails are retried per-row (#1595 resilience); rows that still fail (“poison rows”) are skipped with a WARN naming the row id, and the run continues — a single un-embeddable row never aborts the migration. The run ends with a summary (JSON under --json).

Pair with ai-memory doctor (section “Embeddings Reachability (#1598)”) to verify the target backend is reachable and authenticated before a long re-embed run.

reown — re-stamp metadata.agent_id ownership (#1720 B2)

Rewrites the metadata.agent_id owner stamp on every memory in a namespace to <agent_id>. This is the operational tool to establish durable ownership before turning on enforced-multi-agent scope=private reads (#1720): the owner-keyed visibility filter (A) drops rows owned by a different agent, so an operator who enables it against a namespace of legacy / foreign-owned rows would lock themselves out of their own data. reown claims the namespace first.

ai-memory reown --namespace prod --to alice --dry-run   # count, no writes
ai-memory reown --namespace prod --to alice             # re-own owned rows
ai-memory reown --namespace prod --to alice --claim-unowned --json
Flag Notes
--namespace <ns> The namespace whose memories are re-owned. EXACT match — the subtree is NOT included.
--to <agent_id> The new owner stamped onto metadata.agent_id. Validated against the wire agent_id shape; a malformed value is rejected before any write.
--dry-run Count the matched rows and print the plan WITHOUT writing.
--claim-unowned ALSO re-own rows with an absent / empty metadata.agent_id (the legacy “owned by nobody” class). Without it, only rows with an existing owner are rewritten.
--json Emit the machine-readable {matched, rewritten, dry_run} report instead of the human summary.

Only metadata.agent_id is touched (a single-key json_set on sqlite / jsonb_set on postgres); every other metadata key is preserved and the agent_id_idx generated column auto-reprojects the new owner. Both sqlite + postgres. See the §”Agent Identity” durable-stamp posture in CLAUDE.md for why this precedes enabling enforced reads.

identity — Ed25519 keypair management (H-track)

Subcommand Notes
ai-memory identity generate --agent-id <id> Create a keypair under ~/.config/ai-memory/keys/<agent_id>.{pub,priv} (0644/0600). Refuses on an existing id; --force opts into rotation.
ai-memory identity import --agent-id <id> --pub <path> [--priv <path>] Import a keypair (or public-only handle) written by another tool.
ai-memory identity list List enrolled keypairs (never loads private keys).
ai-memory identity export-pub --agent-id <id> Print the base64 public key.

Global flag: --key-dir <PATH> overrides the key storage directory (default: platform config dir; AI_MEMORY_KEY_DIR env honoured).

verify-signed-events-chain — V-4 closeout verifier

Walks the signed_events cross-row hash chain end-to-end. Supports --since N (skip the first N rows) and --format text|json. See docs/signed-events-v4.md.

schema-init — postgres + AGE bootstrap (--features sal)

Idempotent schema bootstrap for a fresh SAL store by URL (--store-url <URL>; flags: --json, --embedding-dim, default 384). Enumerates the resulting catalog (tables, views, functions, indices, extensions, schema_version); on Postgres with Apache AGE installed it also bootstraps the memory_graph projection — without AGE the recursive-CTE fallback stays in place automatically. See docs/postgres-age-guide.md.

governance subcommands

Subcommand Notes
ai-memory governance migrate-to-permissions Dry-run by default; --apply to commit the v0.6.x governance → v0.7 permissions migration. Idempotent.
ai-memory governance install-defaults Install the operator-signed seed rules R001..R004.
ai-memory governance check-action Evaluate an action against the live permissions/rules engine (CLI mirror of memory_check_agent_action).

rules subcommand (7th-form, #691)

CRUD over the governance_rules table consulted by check_agent_action. Mutation verbs (add / enable / disable / remove) require the operator’s Ed25519 keypair on disk at <key-dir>/operator.priv (mode 0600); without it they refuse with governance.no_operator_key. Read verbs (list / check) are unprivileged. Global flag: --key-dir <PATH>.

Subcommand Notes
ai-memory rules keygen Generate the operator keypair used to sign rules.
ai-memory rules sign-seed --key <path> Sign the seed R001-R004 governance rules with the operator key (rules ship unsigned + disabled by design; sign-seed is the first-time operator-attestation step).
ai-memory rules add … Add a signed rule (flags include --decision, default refuse, and --namespace, default the global sentinel).
ai-memory rules list List the active rule corpus (CLI equivalent of memory_rule_list).
ai-memory rules check … Evaluate a hypothetical action against the corpus.
ai-memory rules enable / disable / remove … Toggle or delete a rule (operator-signed).

export-forensic-bundle / verify-forensic-bundle — L2-5

Deterministic in-process POSIX-ustar tar with byte-identical mod timestamps. Operator-signed when an operator keypair is present. See docs/forensic-export.md.

FX-12 / FX-C3 MCP↔CLI parity subcommands (v0.7.0)

Each is a thin CLI surface over the same substrate handler as its MCP twin (byte-equal envelopes; --json for the raw envelope):

Subcommand MCP twin Notes
kg-query memory_kg_query Outbound KG traversal from a source memory (≤ 5 hops).
find-paths memory_find_paths Enumerate KG paths between two memories (BFS, max_depth ≤ 7, default 4).
kg-invalidate memory_kg_invalidate Set valid_until on a link (non-destructive supersession).
kg-timeline memory_kg_timeline Ordered link timeline anchored at a source memory.
recall-observations memory_recall_observations List rows from the recall-consumption ledger (#886).
check-duplicate memory_check_duplicate Pre-write near-duplicate check (cosine over stored embeddings; requires semantic tier+).
replay memory_replay Reconstruct the transcript chain that produced a memory.
reflect memory_reflect Synthesize a reflection over source memories (CLI dispatcher runs unsigned / no LLM dedup — use MCP/HTTP for those).
subscribe / unsubscribe / list-subscriptions memory_subscribe / memory_unsubscribe / memory_list_subscriptions Webhook subscription CRUD.
subscription-replay / subscription-dlq-list memory_subscription_replay / memory_subscription_dlq_list Webhook DLQ replay + inspection.
notify / inbox memory_notify / memory_inbox Agent-to-agent inbox send / read.
ingest-multistep memory_ingest_multistep Form 3 multi-step ingest (CLI passes no LLM handler; tier-locked advisory on every tier).
entity-register / entity-get-by-alias memory_entity_register / memory_entity_get_by_alias Entity registry.
dependents-of-invalidated memory_dependents_of_invalidated Memories citing invalidated KG edges.
reflection-origin memory_reflection_origin Walk a reflection back to its origin chain.
quota-status memory_quota_status K8 per-agent quota row.

recover-previous-session — #1389 L2

Fail-safe recovery of agent context from a host’s per-turn transcript file after an ungraceful session end (SIGKILL, tmux lockup, host crash). Designed for SessionStart-hook chaining after ai-memory boot; the in-session counterpart is the memory_recover_previous_session MCP surface.

Additional v0.7.0 subcommands

Subcommand Notes
deref <ref_id> QW-3 — dereference a previously-offloaded blob; refuses tampered rows (SHA-256 mismatch). Pairs with offload.
share #1095 — copy a memory into _shared/<from>→<to>/ (same primitive as memory_share / POST /api/v1/share).
skill <register\|list\|get\|resource\|export\|promote\|compose> Cluster E API-2 (#767) — CLI parity for the 7 memory_skill_* MCP tools.
namespace <set-standard\|get-standard\|clear-standard\|batman-policy> #800 — operator CRUD for the per-namespace standard policy pointer.
verify-reflection-chain <memory_id> L1-3 — walk reflects_on edges to depth 0, verify each Ed25519 signature, emit a chain-integrity report. Distinct from verify-signed-events-chain and audit verify.

Additional v0.8.0 subcommands

Subcommand Notes
undo-edit <id> [--dry-run] #1727 — CLI-ONLY (no MCP tool / HTTP route, by deliberate security design) NON-DESTRUCTIVE undo of an in-place edit. Re-applies the archive_reason='in_place_edit' (#1725) snapshot to the live row via the in-place update path — NO raw DELETE, so ON DELETE CASCADE children survive. Routes through the backend-blind MemoryStore::undo_in_place_edit trait so SQLite + Postgres behave identically.
verify-audit-trail [--since <RFC3339>] [--json] §22 Policy-Engine PE-8 (#697 / EPIC #1709) — verify the append-only signed_events V-4 cross-row hash chain end-to-end and surface any gaps for operator review. --since scopes by timestamp (chain still verified across the boundary). Exit 0 if intact + no gaps, 1 on any break/gap. Distinct from verify-signed-events-chain (V-4 closeout #698) and audit verify (JSONL audit log).

Shell, completions, man

ai-memory shell                              # interactive REPL
ai-memory completions bash > ~/.bash_completion.d/ai-memory
ai-memory completions zsh  > ~/.zsh/completions/_ai-memory
ai-memory man | man -l -

Agent identity (NHI)

Every memory stamps metadata.agent_id. Resolution order:

  1. Explicit --agent-id CLI flag.
  2. AI_MEMORY_AGENT_ID env var.
  3. (MCP only) initialize.clientInfo.nameai:<client>@<host> (durable, pid-free since #1720).
  4. host:<hostname> (durable host-scoped default, pid-free since #1720).
  5. anonymous:pid-<pid>-<uuid8> (no hostname).

Validation: ^[A-Za-z0-9_\-:@./]{1,128}$. Once stored, preserved across update / upsert / import / sync / consolidate.

For production deployments, always set --agent-id or AI_MEMORY_AGENT_ID to an opaque identity. The default fallback exposes the hostname (the host:<hostname> form is durable + pid-free since #1720).

The ladder above is the write-path identity stamped into metadata.agent_id. The MCP read tools that enforce per-row scope=private ownership (memory_session_start, memory_list, memory_search, memory_recall) resolve their visibility caller separately: AI_MEMORY_AGENT_ID if set, else None (trust-all). The pid-synthesized clientInfo id is not used there — it embeds the live PID and could never match a prior process’s metadata.agent_id. Set AI_MEMORY_AGENT_ID to filter cross-agent private rows out of read results (#1468 / #1469); leave it unset for single-tenant trust-all reads.

Tiers & TTL at a glance

Tier TTL Typical use
short 6 hours Session context, scratch.
mid 7 days Normal memories (default).
long permanent Important records.

Accessing a memory extends TTL (short +1 h, mid +1 d). At 5 accesses, mid auto-promotes to long.

See also