---
name: cognee-cli
description: Use when the user wants to drive cognee from the terminal with cognee-cli — remember/recall/forget/improve memory commands, managing datasets and config, or database migrations.
---

# Use the cognee CLI

`cognee-cli` ships with the package (entry point in `cognee/cli/_cognee.py`;
each command lives in `cognee/cli/commands/`). Every command has
`--help` for its flags, but only a few (`demo`, `memify`, `eval`, `serve`,
`push`, `upgrade`, `downgrade`, `stamp`, and `search` with one CODE example)
include usage examples — for the memory commands use the examples
in this file. Needs `LLM_API_KEY` configured, same as the SDK.

## Core flow

The memory commands are the primary surface as of cognee 1.x:

```bash
cognee-cli remember "Your text here"         # also accepts file paths / URLs
cognee-cli remember ./docs --dataset-name my_project
cognee-cli recall "Your question"            # query the graph
cognee-cli recall "keyword" --query-type CHUNKS
cognee-cli forget --all                      # wipe local state
```

`remember` is ingest + graph build in one step (`add` + `cognify` under the
hood); `--background`/`-b` runs the cognify stage in the background, and
`--dry-run` estimates LLM tokens/cost without ingesting. `recall` takes
`--datasets`/`-d`, `--top-k`/`-k` (default 10), and `--session-id`/`-s`.

`forget` targets `--dataset`, `--dataset-id`, `--data-id` (needs a dataset), or
`--everything`/`--all` — one unified command replacing the older `delete` and
empty-dataset paths. `--memory-only` (with a dataset) drops the graph and
vectors but keeps the raw files, so the data can be rebuilt.

> **`forget --all` does not ask for confirmation.** It deletes every dataset
> immediately, even on a non-interactive stdin. The legacy `delete --all`
> prompts `Delete ALL data from cognee? [y/N]` first, so switching to `forget`
> silently drops that safety net — script it with care.

`--query-type` accepts 10 of the SDK's 20 `SearchType` values — the list in
`cognee/cli/config.py:SEARCH_TYPE_CHOICES`: HYBRID_COMPLETION, GRAPH_COMPLETION,
RAG_COMPLETION, CHUNKS, CHUNKS_LEXICAL, SUMMARIES, CODE, CYPHER, GRAPH_REPORT,
SKILLS. The rest (TEMPORAL, TRIPLET_COMPLETION, GRAPH_COMPLETION_COT,
AGENTIC_COMPLETION, NATURAL_LANGUAGE, …) are SDK-only, e.g.
`cognee.recall(q, query_type=SearchType.TEMPORAL)`.

When `--query-type` is omitted the CLI uses `HYBRID_COMPLETION`
(`DEFAULT_SEARCH_TYPE`), whereas the SDK's `cognee.recall()` auto-routes
between search types. `--top-k` defaults to 10 on the CLI and 15 in the SDK.

## Session memory and enrichment

Session entries are currently written from the SDK — `cognee.remember(...,
session_id="chat_1")` — not the CLI (`cognee-cli remember` has no session
flag). The CLI side of session memory is reading and bridging:

```bash
cognee-cli recall "question" -s chat_1       # session cache first: without -d/-t
                                             # this searches the session directly
cognee-cli sessions get                      # retrieve session Q&A history
cognee-cli improve -d my_project -s chat_1   # bridge session content into the graph
cognee-cli improve -d my_project             # enrich/index the graph (no session)
cognee-cli feedback ...                      # attach feedback to results
```

`improve` also takes `--node-name`, `--feedback-alpha` (learning rate in
(0, 1]; default `IMPROVE_FEEDBACK_ALPHA`, 0.1), `--build-global-context-index`,
`--build-truth-subspace` (both opt-in stages; the truth subspace needs
`-s`), and `--background`/`-b`. It prints one line per stage — name, status
(`completed` / `already_completed` / `skipped` / `errored`) and the skip
reason (e.g. `no_session_ids`, `lock_held`, `triplet_embedding_disabled`).
`remember`/`improve` build their graphs through `cognify()`, so cognify-level
settings (e.g. `CONTRADICTION_DETECTION=true`) apply to them too.

## Legacy / lower-level commands

`add`, `cognify`, `search`, `memify`, and `delete` still ship and are what the
memory commands call underneath. Use them only to drive a single stage in
isolation; prefer `remember`/`recall`/`forget`/`improve` otherwise.

```bash
cognee-cli add "text" && cognee-cli cognify  # what `remember` does in one step
cognee-cli search "question"                 # `recall` minus routing/scope/session sources
cognee-cli memify -d my_project              # custom extraction/enrichment tasks
cognee-cli delete --all                      # superseded by `forget --all`
```

## Management

```bash
cognee-cli datasets list                     # dataset operations
cognee-cli config get [key] [--show-secrets] # view one/all settings (API keys masked by default)
cognee-cli config set <key> <value>          # set + persist to ./.env in the cwd
cognee-cli config unset <key>                # reset a key to its default (also persisted)
cognee-cli -ui                               # launch API server + UI (see cognee-server skill)
cognee-cli serve --url http://localhost:8000 # connect CLI/SDK to a running instance
```

## Database migrations

cognee has two migration chains: the relational schema (Alembic, in
`cognee/alembic/`) and the graph/vector data chain (slugs registered in
`cognee/modules/migrations/registry.py`). Both run automatically — at API
server startup and on the first write (`remember`, `add`, `cognify`,
`improve`, …) in an SDK/CLI process — unless `ENABLE_AUTO_MIGRATIONS=false`.
So you rarely need these commands; they are for inspecting state, disabled
auto-migration, and rollbacks. There is no `migrate` command.

```bash
cognee-cli current                    # stamped revision per database (per dataset
                                      # with access control on)
cognee-cli history                    # the data-migration chain, newest first
cognee-cli upgrade                    # relational to head, then data chain to head
cognee-cli upgrade <slug>             # data chain up to and including <slug>
cognee-cli upgrade --alembic <rev>    # pin the relational (Alembic) target
cognee-cli downgrade <slug|base>      # REWRITES DATA; revision is required,
                                      # prompts unless --force; --dataset <uuid>
                                      # (repeatable) limits it
cognee-cli stamp <head|base|slug>     # set the stored revision WITHOUT running
                                      # anything; prompts unless --force;
                                      # --dataset <uuid> (repeatable) limits it
```

The positional revision is always a **data-chain slug**; the relational
target goes through `--alembic`. `downgrade` leaves the relational schema
alone unless you pass `--alembic`. `upgrade` runs even when
`ENABLE_AUTO_MIGRATIONS=false`. `--alembic-path` (or `COGNEE_ALEMBIC_PATH`)
points at a custom Alembic scripts directory.

## Gotchas

- The CLI initializes cognee lazily; the first command in a fresh environment
  is slow (DB + model setup), later ones are fast.
- `remember` (and `add`) without `--dataset-name` targets the default dataset
  `main_dataset`; `recall`/`search` operate across your accessible datasets
  unless a dataset is given.
- `forget` refuses to run bare — pass `--dataset`, `--dataset-id`, `--data-id`
  (with a dataset), or `--everything`/`--all`.
- Session commands (`recall -s`, `sessions get`, `improve -s`) require
  `CACHING=true` (the default) — with it off, session reads return nothing and
  SDK session writes raise. To cut read latency and token cost while keeping
  session memory, `cognee-cli config set AUTO_FEEDBACK false` — by default
  cognee makes one structured-output LLM call per answered query to self-tune
  its memory.
- `memify` requires one of the arguments -d/--dataset-name --dataset-id
- `config set`/`config unset` write to the `.env` file in whatever directory
  you run the command from (creating it if missing). `config reset` (reset
  *all* keys) is still not implemented.
- **Which `.env` actually wins is not always the cwd one.** At import, cognee
  calls `dotenv.load_dotenv(override=True)`, which resolves relative to the
  *cognee package location*, not your working directory. In a source/editable
  checkout (`uv pip install -e .`) a `.env` at the repo root therefore shadows
  the `.env` in the directory you ran from — and because `override=True`, it
  also beats variables you `export`ed. Symptom: `config set` appears to do
  nothing, or the CLI connects to a backend you thought you had overridden.
  To test against different settings, move the repo `.env` aside, or set
  values programmatically after import (`cognee.config.set_*`). (Under
  `python -c` the cwd `.env` does win, because dotenv falls back to the cwd
  when `__main__` has no `__file__` — which is why the same command can
  behave differently as a script vs. `-c`.)
