Atlas CLI and REST
Run governed Atlas actions from a terminal with the atlas CLI, or call the same REST actions directly. Every call is scoped to the token holder's organisation. Writes always go through a proposal that a person confirms.
Release status
- MCP server: ready on staging. It publishes eleven governed tools; see the MCP server guide.
- CLI source: ready on the current staging source. Every command in the reference below exists in the current source.
- Downloadable CLI:
atlas-cli-v0.1.0-staging.3. This archive predates customer search and customer creation. Build from source to useatlas customer searchandatlas customer create …, or wait for the next archive. - Production: not claimed by this update. Point the CLI at
https://atlas.staging.forth.ai.
Quick start
shasum -a 256 -c SHA256SUMS
tar -xzf atlas-cli-<tag>-darwin-arm64.tar.gz
./atlas version
./atlas config set base-url https://atlas.staging.forth.ai
./atlas auth login
./atlas profile read <customer-id>
./atlas library search "warranty terms" --limit 5
atlas version prints the release tag and source SHA. Both must match manifest.json from the same release.
Installation
The private GitHub Release contains atlas-cli-<tag>-darwin-arm64.tar.gz, atlas-cli-<tag>-darwin-x64.tar.gz, manifest.json, and SHA256SUMS.
- Download the archive for your Mac plus
SHA256SUMSinto one directory. - Run
shasum -a 256 -c SHA256SUMS. Stop if any line is notOK; delete the files and download again. - Extract the archive and move
atlasto a directory onPATHthat only you can write to. - Run
atlas versionand compare the tag and source SHA withmanifest.json.
Linux and Windows are not supported by the archives. On those platforms, run from source and pass the token through ATLAS_ACCESS_TOKEN.
Configuration
atlas config set base-url https://atlas.staging.forth.ai
atlas config get base-url
atlas auth login # prompts for a token without echo, stores it in macOS Keychain
atlas auth status # shows which token source is active, never the token
atlas auth logout
| Setting | Resolution order | Storage |
|---|---|---|
| Base URL | --base-url, then ATLAS_BASE_URL, then the config file | XDG config file holding only base_url; directory mode 0700, file mode 0600 |
| Token | ATLAS_ACCESS_TOKEN, then macOS Keychain | Keychain entry keyed by the normalised base URL. No file, .env, or config fallback. |
Mint the token in the Atlas portal; the MCP guide shows the request. Remote base URLs must be HTTPS. HTTP is accepted for loopback only.
Command reference
Arguments in angle brackets are required. Every command below sends one REST request to the configured base URL and prints the response envelope as JSON.
| Command | Result | REST call |
|---|---|---|
atlas catalog | Approved action catalog. | GET /assistant/v1/catalog |
atlas profile read <customer-id> | Profile level, confirmed facts, cited evidence, missing requirements. | POST /assistant/v1/actions/crm.customer_profile.read |
atlas suggestions list <customer-id> | Profile-gap suggestions with explanations. | POST /assistant/v1/actions/crm.customer_profile_suggestions.list |
atlas customer search <query> [--limit N] | Customers matching a name, contact, or email. | POST /assistant/v1/actions/crm.customers.search |
atlas knowledge search <query> [--limit N] [--type T] [--source-id ID] | Ranked, cited passages from active organisation knowledge. | POST /assistant/v1/actions/ekb.knowledge.retrieve |
atlas library search <query> [--limit N] | Ranked, cited snippets from confirmed Knowledge Library documents. | POST /assistant/v1/actions/ekb.library.search |
atlas customer create propose <name> --idempotency-key <key> [--contact NAME] [--email EMAIL] [--country COUNTRY] [--industry INDUSTRY] [--customer-type TYPE] | Proposal to create a customer. Creates no customer. | POST /assistant/v1/actions/crm.customer_profile.create |
atlas customer create inspect <proposal-id> | The proposal, its intent, evidence, state, and expiry. | GET /assistant/v1/proposals/<id> |
atlas customer create confirm <proposal-id> --idempotency-key <key> | Creates the customer from the proposal. | POST /assistant/v1/proposals/<id>/confirm |
atlas customer create reject <proposal-id> --idempotency-key <key> | Closes the proposal without creating anything. | POST /assistant/v1/proposals/<id>/reject |
atlas task propose-gap <customer-id> <gap-code> <title> --idempotency-key <key> [--due-at <epoch-seconds>] [--assignee-email EMAIL] [--suggestion-id ID] | Proposal to create a profile-gap task. Creates no task. | POST /assistant/v1/actions/tasks.profile_gap_task.create |
atlas task inspect <proposal-id> | The proposal, its intent, evidence, state, and expiry. | GET /assistant/v1/proposals/<id> |
atlas task confirm <proposal-id> --idempotency-key <key> | Creates the task from the proposal. | POST /assistant/v1/proposals/<id>/confirm |
atlas task reject <proposal-id> --idempotency-key <key> | Closes the proposal without creating anything. | POST /assistant/v1/proposals/<id>/reject |
Local commands with no REST call: atlas version, atlas config set|get base-url, atlas auth login|status|logout.
Propose, confirm, reject
- Propose with a key you choose:
atlas customer create propose "Acme" --idempotency-key acme-1. The response isawaiting_confirmationand carriesconfirmation.id. - Inspect:
atlas customer create inspect <id>. Checkintended_*,evidence, andexpires_at. - Decide with a second key:
atlas customer create confirm <id> --idempotency-key acme-1-confirm, orreject. - Re-running a confirm with the same key returns the original result with
meta.repeated: trueand no second effect.
Proposals expire 15 minutes after creation. Confirming an expired or rejected proposal returns conflict. Task proposals follow the same steps with atlas task ….
REST without the CLI
Send the same requests from any HTTP client. Base URL: https://atlas.staging.forth.ai.
| Header | Value |
|---|---|
Authorization | Bearer <token> on every request. |
Content-Type | application/json on every POST. |
idempotency-key | Required on propose, confirm, and reject. Reuse the same key to retry safely. |
curl -sS https://atlas.staging.forth.ai/assistant/v1/actions/crm.customers.search \
-H "Authorization: Bearer $ATLAS_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"q":"Acme","limit":5}'
curl -sS https://atlas.staging.forth.ai/assistant/v1/actions/crm.customer_profile.create \
-H "Authorization: Bearer $ATLAS_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-H "idempotency-key: acme-1" \
-d '{"name":"Acme","country":"SG"}'
curl -sS -X POST https://atlas.staging.forth.ai/assistant/v1/proposals/<id>/confirm \
-H "Authorization: Bearer $ATLAS_ACCESS_TOKEN" \
-H "idempotency-key: acme-1-confirm"
Request bodies use the field names from the MCP tool inputs: customer_id, q, query, limit, type, source_id, name, contact, email, country, industry, customer_type, profile_gap_code, title, due_at, assignee_email, suggestion_id.
Response envelope (atlas.action.v1)
{
"schema_version": "atlas.action.v1",
"action": "crm.customer_profile.create",
"status": "awaiting_confirmation",
"request_id": "…",
"data": { "proposal": { "id": "…", "state": "pending", "expires_at": "…", "...": "…" } },
"confirmation": { "id": "…", "summary": "…", "expires_at": "…" },
"meta": { "catalog_version": "…", "principal_kind": "…", "idempotency_key": "acme-1", "repeated": false }
}
status is one of completed, awaiting_confirmation (HTTP 202), forbidden, rejected, conflict, retryable_failure, terminal_failure. Failures carry error.code and error.message instead of data.
Output and exit codes
stdout is the JSON envelope, one document per command. --pretty indents it. Diagnostics go to stderr. There is no generic --yes; confirmation is always a separate command.
| Exit | Envelope status |
|---|---|
| 0 | completed, including a repeated result. |
| 2 | Local usage or configuration error. No request was sent. |
| 3 | forbidden: missing, expired, or revoked token, or missing scope. |
| 4 | awaiting_confirmation: a proposal was created and needs confirm or reject. |
| 5 | rejected or conflict. |
| 6 | retryable_failure: retry with the same idempotency key. |
| 7 | terminal_failure or a response that does not match the envelope. |
Token handling
- Never pass a token as a command argument. Use
atlas auth loginorATLAS_ACCESS_TOKEN. The CLI never prints or logs it. - In CI and scripts, set
ATLAS_ACCESS_TOKENfrom the runner's secret store. It takes precedence over Keychain. - Mint tokens with only the scopes the job needs. Tokens live at most 30 days and can be revoked by an admin.
- Expiry and revocation are decided by the server. The CLI returns the envelope and exits 3.
No analytics, remote fonts, external scripts, or secret-bearing assets are included in this manual.
Troubleshooting
| Symptom | Fix |
|---|---|
Exit 3, authentication_required | Run atlas auth status to see which source is active. Mint a new token and log in again, or reset ATLAS_ACCESS_TOKEN. |
Exit 3, insufficient_scope | Mint a token that includes the scope in the error message. |
| Exit 2, unknown command | Run atlas version. The staging.3 archive lacks customer search and customer create. |
| Exit 5 on confirm | The proposal expired or was rejected, or the idempotency key was reused with different input. Propose again. |
| Exit 6 or unreachable endpoint | Check atlas config get base-url, then retry with the same idempotency key. |
| Checksum mismatch | Delete the archive and download the release again. Do not install. |
| Login unavailable on Linux or Windows | Persistent login is macOS only. Set ATLAS_ACCESS_TOKEN. |