CLI
Command reference
Every command, every option, one example each. Taken from the installed CLI, so engram <command> --help says the same thing at the terminal.
Global options
These work on engram itself and on every command. Both positions are valid, so engram --json status and engram status --json do the same thing, and the one on the command wins.
| Option | Meaning |
|---|---|
--profile, -p | Config profile to use. Default default. |
--json | Emit JSON on stdout for scripting, and nothing else on stdout. |
--version | Show the installed version and exit. Needs no profile. |
--help | Show help at any level, including for a sub-subcommand. |
Wherever an argument or option is a document base, it accepts the base's id or its exact name.
engram --version
engram --json corpora list
engram login
Store an API key in a profile, after checking that it actually works.
| Option | Meaning |
|---|---|
--api-key | API key, starting with ek_. Prompted for, hidden, if omitted. |
--api-url | Control-plane base URL. Default https://api.engramdynamics.org. |
--api-version | API contract for this profile: legacy (default), 1, or auto to take the newest the server advertises. |
--insecure | Allow a plain http --api-url. Only for a control plane on this machine. |
engram login --api-key <your key> --api-url https://api.engramdynamics.org
See Login, profiles and environment for precedence, the config file location and the https rule.
engram status
Platform health and the profile in use, or one document base's progress. Takes one optional argument: the document base.
With no argument it reports the profile, URL, API version, which credential it found and where, API reachability, the region the platform runs in with its egress guidance, the live serving state, and how many document bases the key can see. It exits 1 when the API is unreachable or the credential is refused.
The credentials row reads key configured (env), or wherever the key came from, and none configured when there is none. It answers "do I have a credential", not "does it work": that is the api row and the exit code. When the API cannot be reached, the api row names the host that did not answer, which is the useful half of a connection failure.
The region and egress rows come from the public platform info and are best-effort, so an older control plane simply does not print them and engram status never fails because of it. They answer "which region should my bucket be in", which engram sources add s3 --help sends you here for.
With a document base it reports the base's status and onboarding step, its documents grouped by lifecycle, the latest sync run with its counters, and the latest job with progress and an estimate.
engram status
engram status "Support KB"
engram status "Support KB" --json
engram profiles
List the configured profiles and where the config file lives. Each row is the profile name, its URL, its API version and the first characters of its key. The stored secret is never printed in full.
engram profiles
engram corpora
Document bases: list, create, show, delete.
| Subcommand | Arguments and options | Does |
|---|---|---|
list | Every document base on the account, with id, name, status, onboarding step, document count and creation time. | |
create | --name, -n (required) | Create an empty document base. |
show | CORPUS (required) | One base in full: identity, status, readiness counts and the results of its last onboarding run. |
delete | CORPUS (required), --yes | Delete a document base and everything in it. Needs a key with the admin scope. |
engram corpora list
engram corpora create --name "Support KB"
engram corpora show "Support KB"
engram corpora delete "Support KB" --yes
delete is the one command that takes documents away, so it asks before it acts: at a terminal it wants the confirmation, and in a script, where there is nobody to ask, it refuses without --yes. It calls DELETE /v1/corpora/{id}.
engram docs
Documents inside a document base.
| Subcommand | Arguments and options | Does |
|---|---|---|
list | CORPUS or --corpus/-c (one of them), --limit/-l, --offset, --verbose | List documents: filename, size, status and description. --verbose adds the document id, cart id, content hash and per-stage errors. |
upsert | --corpus/-c and --path (required), then exactly one of --file/-f or --text/-t, plus --verbose | Create or replace one document by path. |
engram docs list shows the four things a listing gets read for: which file, how big, whether it is being served, and what it says. --verbose prints every field, one document per block, which is the view a support conversation wants. --json is the full API response and neither flag changes it. docs upsert hides the sectioning fields the platform fills in unless you ask for them the same way.
--path is the document's identity: upserting the same path twice replaces the document rather than adding a second one. --text - reads the content from stdin. Content that is not valid UTF-8, such as a PDF, is sent as binary automatically with no flag to set.
engram docs list "Support KB" --limit 20
engram docs list --corpus "Support KB" --verbose
engram docs upsert --corpus "Support KB" --path notes/q3.md --file ./q3.md
./generate.py | engram docs upsert --corpus "Support KB" --path notes/q3.md --text -
Use engram push for a folder: it skips what has not changed, which upsert cannot.
engram push
Upload a folder, a single file, or an s3:// prefix to a document base, sending only what changed. Takes one argument, the path or S3 URL.
| Option | Default | Meaning |
|---|---|---|
--corpus, -c | required | Document base id or name. |
--delete | off | Mirror mode: also remove documents no longer in the source. |
--onboard / --no-onboard | --onboard | Build cartridges after the upload, or register and stop. |
--include | Only push paths matching this glob. Repeatable. | |
--exclude | Skip paths matching this glob. Repeatable, and it beats --include. | |
--concurrency | 8 | Parallel uploads, 1 to 64. |
--dry-run | off | Show what would be uploaded and change nothing. |
--watch | off | Stay open and push again every time the folder changes. Ctrl-C to stop. |
--debounce | 2 | Seconds of quiet before a watched change is pushed. Raise it to group more into one push. |
--verbose | off | Name the files behind each counter: Google shortcut files that hold no text, and everything .engramignore skipped. |
--wait / --no-wait | --wait | Watch the sync run to a terminal state before returning. |
--timeout | 3600 | Seconds to watch the sync run before giving up watching it. |
--region | AWS region for an s3:// source. Ignored for local paths. |
engram push ./docs --corpus "Support KB"
engram push ./docs --corpus "Support KB" --include '*.pdf' --dry-run
engram push ./docs --corpus "Support KB" --delete
engram push s3://acme-docs/reports --corpus "Support KB" --region us-east-1
engram push ./docs --corpus "Support KB" --watch
A .engramignore file at the top of the folder keeps paths out for good, in gitignore syntax, so they never need an --exclude. The summary counts what it kept out on a skipped (.engramignore) row, so a rule matching more than you meant looks different from an empty folder. Full behaviour on Push a folder.
engram keys
Workspace API keys.
| Subcommand | Arguments and options | Does |
|---|---|---|
list | --verbose | Every key with its id, name, scopes, last use and status — active, expired or revoked. --verbose adds the prefix and the full creation, expiry and revocation timestamps. The secret is never retrievable after creation. |
create | --name/-n and --scope/-s (required, repeatable), --expires | Create a key and print the secret. This is the only time it is shown. |
revoke | KEY_ID or --key/-k (one of them) | Revoke a key immediately. |
Scopes are ingest, query and admin. --expires takes an ISO-8601 timestamp.
engram keys create --name ci --scope ingest --scope query --expires 2026-12-31T00:00:00Z
engram keys list
engram keys revoke k-3f10ab
engram mcp
Print the config block for the hosted MCP server, filled in with the profile's URL and API key. There is no subcommand and no document base to name: one block reaches every base the key can see, and the assistant picks one per call.
This shape needs CLI 0.3.0 or later, and --client needs 0.3.1. Earlier releases ran a server on your machine instead, which the hosted server replaces.
--client/-c prints the block in the shape that client reads, because every client spells a remote server differently and the wrong spelling connects to nothing without saying so. The choices are claude-code (the default), claude-desktop, cursor, windsurf, vscode, gemini-cli and cline. Claude Desktop gets the mcp-remote bridge, in its Windows form when you run the command on Windows, because it cannot reach a remote server on its own.
--profile/-p prints the block for another environment. The JSON goes to stdout and the hints to stderr, which name the file the block belongs in, so redirecting the command still gives you a clean file.
engram mcp
engram mcp --client claude-desktop
engram mcp --client vscode > .vscode/mcp.json
engram mcp --profile uat > mcp.json
The block contains a live API key, so treat the file you paste it into like a password. Full setup on MCP quick start.
engram connections
The Google Drive and SharePoint accounts linked to the workspace, and the folders inside them. Linking an account happens in the app, because the consent screen needs a browser; everything after that is here.
| Subcommand | Arguments and options | Does |
|---|---|---|
list | Every linked account, with the connection id the other commands take. | |
browse | CONNECTION_ID (required), --parent | List one level and print the folder ids. --parent drills into one of them. |
engram connections list
engram connections browse conn-123
engram connections browse conn-123 --parent 1AbCdEf_gHiJkLmNoPqRsTuV
See Connected folders from the terminal.
engram sources
Buckets and connected folders a document base pulls from, and the IAM setup for the buckets. An S3 bucket is set up here rather than in the app, from registration through the template to removal. Every subcommand takes --corpus/-c, except setup --bucket, which builds a role before any source exists and uses --corpus only to fill in the command it prints. The ones that act on one source take --source/-s, which is optional when the base has exactly one.
| Subcommand | Options | Does |
|---|---|---|
add s3 | --bucket/-b and --role-arn (required), --external-id, --prefix, --region, --mode, --every, --kms-key-arn, --inventory-bucket with --inventory-prefix, --allow-cross-region | Register a bucket with the role you applied and the external id it trusts. A role that does not work yet leaves the source waiting for access. |
add google-drive | --connection and --folder (required), --mode, --every | Register a Drive folder to pull from, through an account linked in the app. |
add sharepoint | --connection (required), then --library or --site, --mode, --every | Register a SharePoint library or one folder inside it. --site on its own takes that site's default library. |
list | The buckets and connected folders this base pulls from. | |
update | --source, --mode, --every, --role-arn, --external-id | Change a registered source in place. A new role ARN or external id is access-checked as it saves, and the verdict comes back with the receipt. |
validate | --source | Re-check the grant, list a page, and report how many of those objects are ingestible. |
setup | --bucket/-b with --prefix, --kms-key-arn, --inventory-bucket, --inventory-prefix and --external-id; or --source for a registered bucket; --format/-f | Print the IAM role to create in your account, as cloudformation (default) or terraform. With --bucket no source is needed, and the external id, the role name and the add s3 command to run next print on stderr. |
remove | --source | Stop pulling. Documents already ingested are left alone. |
--mode is additive (add and update only) or mirror (also delete, and only ever documents this source delivered). --every re-walks the source on a timer, minimum 15 minutes; it takes a duration such as 15m, 1h or 1d, or plain minutes, and omitting it leaves the source manual or event-driven. setup is for S3 only, because a connected folder has no role to create. Plain setup output is the template and nothing else, so it pipes straight into a file. The template-first S3 flow needs CLI 0.2.1 or later: that is the release with setup --bucket and the --external-id and inventory options on add s3. pip install -U engram-dynamics upgrades.
engram sources setup --bucket acme-docs --prefix reports --corpus "Support KB" > engram_role.yaml
engram sources add s3 --corpus "Support KB" --bucket acme-docs --prefix reports \
--external-id <external id> --role-arn <role ARN> --every 60
engram sources validate --corpus "Support KB"
engram sources update --corpus "Support KB" --every 6h --mode mirror
engram sources add google-drive --corpus Sales --connection conn-123 \
--folder 1AbCdEf_gHiJkLmNoPqRsTuV --every 1h
The mode and the schedule change later with sources update, along with the role ARN and the external id, so a wrong ARN is a one-line repair rather than a delete and a re-registration. The bucket and the prefix are fixed at registration: pointing at another folder is another source.
See Amazon S3 buckets and Connected folders from the terminal.
engram sync
Pull from a registered source now, without waiting for its schedule. It returns as soon as the run is open unless you ask it to wait; the run keeps going either way.
| Command | Options | Does |
|---|---|---|
sync | --corpus/-c, --source/-s, --wait, --timeout (default 3600) | Start a pull now. |
sync runs | --corpus/-c (required), --limit/-l (default 20) | The sync history: what ran, when, and how it ended. |
engram sync --corpus "Support KB" --wait
engram sync runs --corpus "Support KB" --limit 5
A run counts what it did: added, updated, unchanged, skipped, removed and failed, with the skipped objects broken down by reason in skipped_reasons, so a folder full of images explains itself. The five reasons are on What gets skipped.