OriginAI CLI
Log in, link, diagnose, run local MCP, read releases, sync, write specs, and stage change requests with the OriginAI CLI.
The originai CLI is how coding agents and humans pull product context outside the web app. Whenever you have a choice, prefer the CLI — or the MCP tools that call the same API — over raw HTTP.
The CLI is implemented in packages/skills (published to npm as originai), and the agent skill body lives in packages/skills/src/setup.ts (SKILL_MD).
Install
# Run it once, with no global install:
npx originai -h
bunx originai -h # preferred when Bun is available (~40ms vs ~1.2s for npx)
# Or install it globally:
npm install -g originai
# or: bun add -g originai / pnpm add -g originaiAuthorize
For everyday use on your own machine, just log in:
originai login
# or: npx originai loginThis opens a browser and then stores a token in ~/.origin/settings.json — never commit that file.
For CI or headless environments only, set ORIGIN_TOKEN instead (an oat_… value from Settings → Access tokens). See Access tokens.
The CLI resolves your token in this order:
- A
--tokenflag. ORIGIN_TOKENin the process environment or a.envfile in the current directory.~/.origin/settings.json(written byoriginai login).
Endpoint overrides
You can point the CLI at a local stack, a branch deploy, or production without passing flags every time.
# Show the resolved and stored endpoints:
originai config
# Point the API at a local Supabase Edge Function:
originai config set api_url http://127.0.0.1:54321/functions/v1/origin-api
# Optionally set the browser-login and remote-MCP endpoints for that environment:
originai config set web_url http://localhost:5173
originai config set mcp_url http://127.0.0.1:8787
# Clear a single override:
originai config unset api_urlThe ~/.origin/settings.json file (never commit it) looks like this:
{
"token": "oat_…",
"api_url": "http://127.0.0.1:54321/functions/v1/origin-api",
"web_url": "http://localhost:5173",
"mcp_url": "http://127.0.0.1:8787"
}| Key | Purpose |
|---|---|
api_url | The Origin API (Edge Function) base URL. |
web_url | The web app base, used for browser login. |
mcp_url | The hosted or remote HTTP MCP endpoint. |
The API URL is resolved in this order:
- A
--api-urlflag. - The
ORIGIN_API_URLenvironment variable. .origin.json→api_url(the project binding).~/.origin/settings.json→api_url.- The production default.
The web and MCP URLs follow the same pattern: ORIGIN_WEB_URL / ORIGIN_MCP_URL environment variables, then settings.json, then the production default.
Note that originai logout clears your token but keeps your endpoint overrides.
Link a repository
# Run this in your application repo's root:
npx originai link --project <project-id>
# Optionally also install the agent skill and RPML references:
npx originai link --skill
npx originai link --project <project-id> --skill
# Or install instruction files for specific agents:
npx originai link --project <project-id> --claude-code --codex --cursor --skill
# Or everything at once:
npx originai link --project <project-id> --allLinking writes:
| Path | Purpose |
|---|---|
.origin.json | The committed project binding: api_url, project_id, release_hash. |
.agents/skills/origin-product-spec-management/ | The skill and its rpml/ references (with --skill). |
CLAUDE.md / AGENTS.md / .cursorrules | Instruction files, with the matching platform flags. |
Diagnose
npx originai doctor
npx originai whoami
npx originai install-helpdoctor checks your login, .origin.json, skill and instruction files, and whether the API is reachable.
Local MCP (the Claude Code plugin default)
npx originai mcp # stdio MCP server (reads your login token)
npx originai mcp config --claude # print the stdio config JSON
npx originai mcp config --cursor
npx originai mcp config --remote # HTTP + ORIGIN_TOKEN (advanced / CI)The local MCP tool names match the hosted MCP and origin-api (get_diff, list_documents, and so on). There is no MCP sync tool — after implementing a release, run npx originai sync. See MCP & agent install.
Command reference
Prefer bunx originai <command> when Bun is available.
| Command | Description |
|---|---|
login / logout / whoami | The auth lifecycle. |
config / config get / config set / config unset | Endpoint overrides in ~/.origin/settings.json (api_url, web_url, mcp_url). |
doctor | Setup diagnostics. |
install-help | Per-agent install snippets. |
mcp / mcp config | The local stdio MCP server and client configs. |
link | Bind a repo and write skill/instruction files. |
list-projects | List the projects you can access. |
create-project --name "<n>" | Create an empty, writable project. |
list-documents | The file tree from the latest release (or --read-type workspace). |
get-document --id <file-id> | A single document's content. |
get-diff (alias diff) | The diff since your last sync. Read-only — it does not advance release_hash. Returns a unified diff (+/-), and by default also embeds the to-side content. Flags: --content-mode none|to|both, --from-hash, --to-hash. |
sync | Advance release_hash to the latest release after you've implemented a diff. |
grep --pattern "<regex>" | Search document content. |
find --file-pattern "<regex>" | Find files by name. |
validate --content "<rpml>" (-c) | Validate RPML locally (no network or token). |
validate --id <file-id> (-i) | Validate a released document (remote). |
write-document --name "<name>" --content "<rpml>" | Create or update a file. After a release, creates or extends a Change Request (--proposal / --new-proposal). There is no create-change-request command. |
delete-document --id <file-id> | Delete a file (same change-request behavior after a release). |
delete-documents --ids <id1>,<id2>,... | Batch-delete files. |
list-proposals --status all | Change requests + decided_items[] with dismiss_reason. Call before staging. |
get-proposal <id> [--with-content] | One change request: items, batches, diffs, purpose. |
get-proposal-diff <id> [--bind] | Release vs proposal tree. --bind writes .origin.json proposal_id. |
describe-proposal <id> --title "…" [--note "…" --rationale "…" ] | Issue / Decisions / Changelog message. |
submit-proposal <id> | Mark the change request ready. Same message fields if not described yet. |
commit-proposal <id> | Seal the current write-wave without marking ready. |
comment-proposal <id> --body "…" | Comment on a change request. |
list-proposal-comments <id> / list-proposal-reviews <id> | Discussion and Ready / Not ready conclusions. |
Data commands print pure JSON on stdout (pipe it to jq); tips and status messages go to stderr.
What reads return by default
- By default, reads return the latest published release snapshot — not the live workspace.
--read-type workspacereads the liverpml_filestree. You need this before the first release, since the default release read returns404until you publish.--release-tag <hash>pins a read to a specific published release.
After the first release
write-document and delete-document create or extend a Change Request (suggested: true). There is no create-change-request command — the first staged write creates it. They do not mutate the workspace until a human applies it in Origin. Pass --proposal to continue a request, or --new-proposal to open another. Use describe-proposal to record the purpose and design rationale before submit-proposal. See Workspace vs release.
The sync model
.origin.json carries release_hash (last published release this repo synced to) and an optional proposal_id (implementation bind only — set with get-proposal-diff <id> --bind when the next PR implements that change request).
get-diff— ifproposal_idis set, this isrelease <> change request; otherwise last sync vs latest release. Readdifffirst.- Implement the diff in code.
- Apply + publish in Origin if you were implementing a change request, then
syncto advancerelease_hash.syncclearsproposal_idonly after a new release hash exists.
Workflow A — existing product (Origin → repo)
npx originai login
npx originai link --project <project-id> --skill
npx originai doctor
npx originai get-diff
# implement from the diff
npx originai syncWorkflow B — new product (repo → Origin, pre-release)
npx originai login
npx originai create-project --name "My App"
npx originai link --project <new-id> --skill
# author RPML inline — no local .rpml files required
npx originai validate --content "<page mode='doc'>…</page>"
npx originai write-document --name "README.rpml" --content "<rpml>"
# one .rpml per planned page or route, then:
npx originai list-documents --read-type workspaceThen publish a release in the OriginAI UI. After the first release, further agent writes stage a change request — list-proposals, describe-proposal, submit-proposal — for you to apply, then publish again.
Don't call the API over raw HTTP
Always use the CLI or the MCP tools. Hand-written curl or fetch calls to origin-api tend to fail on auth headers, URL shape, or timeouts. For agent-facing skill discovery over HTTP, see Agent skills.