Primitive CLI
The primitive CLI is the recommended interface for agents and humans operating from a terminal. It handles auth, file inputs, command discovery, and common workflows that are awkward with raw HTTP.
Install
# Homebrew brew install primitivedotdev/tap/primitive # npm npm install -g @primitivedotdev/cli
Homebrew installs the required Node.js runtime automatically. npm installs require Node.js 22 or newer. Both install the primitive binary.
No-install form:
npx @primitivedotdev/cli@latest <command>The CLI ships through the primitivedotdev/tap Homebrew tap and as @primitivedotdev/cli on npm (the same build is also published unscoped as primcli). Either package installs the primitive and prim binaries. The CLI is separate from the runtime SDK @primitivedotdev/sdk, which is imported from application code.
Authenticate
primitive login primitive whoami
primitive login opens a browser and stores an OAuth token set locally. whoami verifies the current token and prints the account context visible to the CLI. To revoke the current CLI session, run:
primitive logoutYou can also revoke CLI and third-party OAuth grants from Settings -> Connected Apps. For non-interactive automation, API keys still work by setting PRIMITIVE_API_KEY.
Send Mail
primitive send \ --to alice@example.com \ --subject "Hello" \ --body "Hi from Primitive" \ --wait
The CLI can infer a valid sender on the managed domain when possible.
Read Inbound Mail
primitive emails:latest --limit 5 primitive emails:get-email --id <email-id>
Piped table output keeps ids complete so agents can chain commands safely.
Reply
primitive sending:reply-to-email \ --id <inbound-email-id> \ --body-text "Got it."
Primitive derives recipient and threading headers from the inbound email.
Discover Send Permissions
primitive sending:get-send-permissionsRun this before a first outbound send if you are unsure whether a recipient is allowed.
Functions
Create and deploy a hosted Function:
primitive functions:init my-fn cd my-fn npm install npm run build primitive functions:deploy --name my-fn --file ./dist/handler.js
primitive functions:init is local filesystem scaffolding, so the API equivalent starts when you deploy the built bundle.
Test and inspect it:
primitive functions:test-function --id <function-id> primitive functions:list-function-logs --id <function-id>
Primitive Memories
Memories are durable JSON key-value records. CLI calls use org scope by default.
Pass --function <function-id> to use function scope; the id is the function
UUID, not the function name.
primitive memories set thread:latest '{"email_id":"em_123"}' primitive memories set greeting '"hello"' primitive memories get thread:latest primitive memories search thread: --metadata-only primitive memories delete thread:latest primitive memories set state '{"step":2}' --function <function-id> primitive memories get state --function <function-id>
Values must be valid JSON. Strings must be quoted as JSON strings, so use
'"hello"', not hello.
See Primitive Memories for scopes, TTLs, version checks, search, metadata, and billing.
Domains
Claim a domain, publish its DNS, and verify it for sending and receiving. The topic separator is a space; the colon forms (primitive domains:add) still resolve for back-compat.
primitive domains add --domain example.com primitive domains verify --id <domain-id> primitive domains list primitive domains zone-file --id <domain-id> --output example.com.zone
domains add returns the exact DNS records to publish. domains zone-file downloads those same records as a BIND-format zone file for bulk import (pass --domain example.com instead of --id if you only have the name). domains verify re-checks DNS and reports which records are still missing. A domain keeps the id domains add returned once it verifies, so later commands take that same id. See Receiving for the full inbound setup walkthrough.
More Commands
The CLI mirrors the full REST surface. Beyond the workflows above, these command groups are available:
primitive endpoints ...— webhook endpoint CRUD andtest. See Endpoints.primitive filters ...— allow/block filter CRUD.primitive routes ...: inbound routing rules (add,list,test,update,reorder,remove);routes test <recipient>simulates routing for an address. See Routing.primitive chat <email> <message>— send a message to another agent or person and wait for the threaded reply.primitive signup <email>/primitive signup confirm <email> <code>: provision a managed inbox with one email-verification code; the confirm step saves the issued credentials locally. See Skills & Agent Signup.primitive inbox status— consolidated inbound readiness view.primitive credits redeem <code>andprimitive credits balance: redeem a credit code and read the organization credit balance. See Credits.
Run primitive list-operations for the full machine-readable manifest of generated operations, and primitive describe <operation> for one operation's parameters and behavior.
Operation Discovery
Agents should use CLI help and operation descriptions before guessing command shapes.
primitive --help primitive list-operations primitive describe emails:get-email primitive describe sending:reply-to-email
list-operations is the broad machine-readable manifest. describe gives focused parameter and behavior details for one operation.
Proxy Environments
On Node 22+ behind a proxy, set:
export NODE_USE_ENV_PROXY=1Then HTTP_PROXY and HTTPS_PROXY are respected by Node networking. primitive doctor checks the environment.
primitive doctor is a local environment diagnostic. There is no REST endpoint for inspecting local proxy variables; use primitive whoami or the /v1/account request above to verify API reachability after setting them.
Good Agent Defaults
- Run
primitive whoamibefore state-changing operations. - Prefer CLI commands for terminal workflows instead of hand-written curl.
- Use
--waitwhen an immediate send result is needed. - Use
describebefore composing unfamiliar operations. - Never print API keys or webhook secrets in logs.