# Introduction

> Install the primitives CLI, global options, the master key, environment variables and output.

Source: https://useprimitives.com/docs/cli

The `primitives` CLI runs the engine on your machine and manages the groups and primitives in a local data directory. It's a single binary with no runtime dependencies.

| Command | What it does |
| --- | --- |
| [`primitives dev`](/docs/cli/dev) | Serve the REST API and MCP on `localhost:7777` |
| [`primitives mcp`](/docs/cli/mcp) | Serve one group over MCP stdio, for clients that launch a process |
| [`primitives group`](/docs/cli/group) | Create, list, inspect and destroy groups |
| [`primitives primitive`](/docs/cli/primitive) | Create, list, snapshot, restore, fork, pause, rename and delete primitives |

The CLI works on local data only. To manage cloud groups, use the dashboard, the [REST API](/docs/api) or an [SDK](/docs/sdk).

## Installation

Install the prebuilt binary for macOS or Linux (x64 and arm64):

```bash
curl -fsSL https://useprimitives.com/install.sh | sh
```

The script downloads the latest release from `releases.useprimitives.com`, verifies its SHA-256 checksum and installs `primitives` to `~/.primitives/bin`. If that directory isn't on your `PATH`, it prints the line to add.

| Variable | Description |
| --- | --- |
| `PRIMITIVES_VERSION` | Pin a release, for example `v0.2.0`. Defaults to the latest |
| `PRIMITIVES_INSTALL_DIR` | Install somewhere other than `~/.primitives/bin` |
| `PRIMITIVES_DOWNLOAD_URL` | Download from another host. Defaults to `https://releases.useprimitives.com/primitives` |

On other platforms, or to build from source, use a Rust toolchain:

```bash
git clone https://github.com/useprimitives/primitives
cd primitives
cargo install --path crates/primitives-cli
```

Check the install:

```bash
primitives --version
```

```text
primitives 0.2.0
```

## Upgrading

Run the install script again. It replaces the binary in place and leaves your data directory alone.

## Global options

Every command takes these:

| Option | Environment | Default | Description |
| --- | --- | --- | --- |
| `--data <DIR>` | `PRIMITIVES_DATA` | `.primitives` | Data directory holding groups. Relative to the current directory |
| `-h`, `--help` | | | Print help for any command or subcommand |
| `-V`, `--version` | | | Print the version |

Pass `--data` with an absolute path whenever something else starts the CLI for you, such as an MCP client, so it always finds the same data.

## Master key

Vault secrets are encrypted at rest with a master key. The CLI looks for it in this order:

1. `PRIMITIVES_MASTER_KEY`, base64 or hex. Use this on servers, in CI and in containers.
2. Your OS keychain: macOS Keychain, Windows Credential Manager or Secret Service on Linux. A key is generated and stored there on first use, one per data directory.
3. `<data>/.master-key`, created with `0600` permissions, when no keychain is available.

Losing the key means losing access to the secrets in that data directory. Every other primitive is unaffected.

## Environment variables

| Variable | Used by | Description |
| --- | --- | --- |
| `PRIMITIVES_DATA` | every command | Same as `--data` |
| `PRIMITIVES_MASTER_KEY` | every command | Master key for vault secrets. See [above](#master-key) |
| `PRIMITIVES_PORT` | `dev` | Same as `--port` |
| `PRIMITIVES_SIGNED_URL_BASE` | `dev` | Same as `--signed-url-base` |
| `PRIMITIVES_IDLE_TIMEOUT` | `dev` | Same as `--idle-timeout` |
| `PRIMITIVES_IDLE_SWEEP_INTERVAL` | `dev` | Same as `--idle-sweep-interval` |
| `PRIMITIVES_MAX_LOADED_GROUPS` | `dev` | Same as `--max-loaded-groups` |
| `PRIMITIVES_EMBEDDINGS_URL` | `dev`, `mcp` | An OpenAI-compatible embeddings endpoint for memory recall. See [Memory](/docs/primitives/memory) |
| `PRIMITIVES_EMBEDDINGS_KEY` | `dev`, `mcp` | API key for the embeddings endpoint |
| `PRIMITIVES_EMBEDDINGS_MODEL` | `dev`, `mcp` | Embeddings model. Defaults to `text-embedding-3-small` |
| `RUST_LOG` | every command | Log filter for stderr, such as `debug`. Defaults to `info` |

## Output

Commands that return data print pretty JSON on stdout, so they pipe straight into `jq`:

```bash
primitives primitive list --group agent-42 | jq -r '.[] | "\(.id)  \(.type)  \(.name)"'
```

Logs, confirmations such as `deleted <id>`, and errors go to stderr. A failed command exits with status `1`:

```text
Error: "unknown primitive type \"blob\"; use db, fs, queue, memory, vault, kv or storage"
```

## Help

Every command and subcommand has `--help`:

```bash
primitives --help
primitives primitive fork --help
```
