CLI
Last updated
terminus is how you build on Terminus from your own machine, the way Git works with GitHub: sign in, bring a creation down, run it, push its draft — then publish it on the web. It needs Node.js 22.16 or newer, and nothing else.
On this page⌄
Install#
npm install -g @terminus-ai/cli
terminus helpterminus help <command> shows a command's options and examples. One-off runs work too: npx @terminus-ai/cli status.
Sign in#
terminus login # approve this computer in the browser
terminus login --no-browser # print the sign-in link instead of opening it
terminus account # who you are, with your notifications and creations
terminus notifications # what is waiting for you
terminus logout # revoke this computer's sessionSigning in gives this device a session that lasts seven days, kept at ~/.terminus/session.json and readable only by you. System Settings → General → Devices on the web lists every device and can revoke any of them. The link --no-browser prints is opened on the same computer.
Signed out, terminus account says so and exits with status 3 — the check a script or a coding agent makes before anything else. A coding agent cannot approve a sign-in: when it sees 3, it asks you to run terminus login.
There are no API keys. For automation — a script, a coding agent in a container — set TERMINUS_TOKEN to a session token; it takes precedence over the saved login, and it expires and is revoked like any other session.
The development loop#
It works like Git and GitHub. A creation is made on the web — Creations → New creation — which gives it its address, the way a new repository gets its URL. It has one draft online, shared by the editor and every working copy; its id in terminus.json says which creation a folder belongs to, and Git stays your local history. Publishing happens on the web too, from the creation's page: the CLI never publishes.
terminus clone @you/my-app # a working copy of a creation
terminus remote add @you/my-app # or connect the folder you are in
terminus dev # run it on this machine
terminus status # this folder vs. the draft vs. the live release
terminus pull # bring in what changed in the draft
terminus push # replace the draft with this folder; then publish on the web- A push replaces the draft with this folder: the files that differ, and the ones the folder no longer has. A draft keeps no history — whatever it held is gone, and push says so when that included saves in the web editor, or a collaborator's push, that this folder never pulled. A push that changes nothing says
Everything up to date. terminus diffshows how this folder differs from the draft now — exactly what a push would change — andterminus loglists the creation's releases.pullbrings in what changed in the draft since this folder last matched it, file by file: a file only the draft changed is taken, one only you changed is kept, and one both changed stops the pull before anything is written, naming it.pull --forcetakes the draft's files;pushsends yours..gitignoredecides what counts as source, and.terminusignoreleaves out more. Secrets,node_modules/and local dev data are never uploaded, whatever the ignore files say.- For an app,
pushalso runs the build and attaches it to the draft it pushed. A later source change leaves that build stale until the next push. - The
versioninterminus.jsonnames the next release. A push whose version is already released, or below the live one, says so and names the version to use.
What they print
$ terminus status
@you/my-app · draft r4
Up to date with the draft.
Changes not pushed:
modified: src/main.js
Live: 0.1.0 (2026-09-20T10:12:00Z)
$ terminus push
Pushed @you/my-app to its draft (r5): 1 source file and 1 build file changed; 2.1 KB uploaded.
build current, ready to publish · 3 files, 48 KB
publish https://www.terminus.build/os?open=creation:…- A creation with no folder yet
terminus clone <address>— into a folder that does not exist or is empty. An empty creation arrives started from a template;--templatepicks an app's, or a service's language (Rust unless named).- Code already in a folder
terminus remote add <address>, thenterminus status.- Nothing made on the web yet
terminus init <kind> [<dir>]scaffolds the package; make the creation on the web, thenterminus remote add. In a folder cloned from an empty creation,terminus init <kind> .fills it in and keeps its link.- The draft moved
terminus pullto keep what changed there, thenterminus push. A push alone replaces it.- A pushed change was wrong
- Fix it in the folder and push again: a draft keeps no history to go back to, so earlier work lives in your own Git.
- Build: stale in status
terminus pushagain: it builds.
terminus dev#
What it runs depends on the package:
- An app
- Serves
dist/on port 8868 against local test data, as Alan — or as several people with--members— and runs the app's server here. Its declared services reach the real ones, billed to you, except a hosted service of yours run beside it with--service. See Apps. - An agent
- Opens a chat page to talk to it and watch its tools, or runs one turn or one trigger for a script. Needs you signed in. See Agents.
- A service
- A hosted one, in any of its languages, is built and run here as Terminus runs it — a fresh copy per call, its secrets from
.env.local— behind itsdev/test page, or a page with a form per operation when it has none;--callmakes one call from the terminal. An external one's page calls its endpoint through Terminus. No marketplace charges. See Services.
Its options, and the kind each is for:
- --members 3, --members alice,bob
- Apps: run as several people at once, each on a port of their own from 8868 up.
- --profiles people.json
- Apps: names, bios and avatars for those people.
- --guest
- Apps: add a port after the people's for someone who is not signed in, as a guest of an app open to guests. Signing in there picks one of the people.
- --fresh
- Apps: start from empty local data.
- --service ../my-service
- Apps and hosted services: run a hosted service's folder beside it, answering its calls to that service as Terminus does; repeat it for more.
@you/my-service=../my-servicenames the service when the folder'sterminus.jsonhas noid. Needs a CLI newer than 0.0.4. - --call <operation>
- Hosted services: build, make one call, print the answer and exit — non-zero when the service refused or failed.
--input '<json>'is a JSON operation's input;--file <path>the bytes for one that takes a file, with--query '<json>'for its query. Needs a CLI newer than 0.0.4. - --port 5000
- Serve here; with
--members, the others follow. - --remote
- Apps: your local build against your real account on Terminus. Agents: the conversation on Terminus itself, after pushing the folder to its draft.
- --prompt "…"
- Agents: send one message, print the reply, exit.
--resume <id>continues a given conversation. - --trigger <name>
- Agents: fire one declared trigger now;
--payload file.jsonis what it carries. - --json
- With
--promptor--trigger: every event as one line of JSON. With--call: the answer as JSON. - --model <model>
- Agents: run on another model than the default.
- --no-open
- Agents and services: do not open the browser.
Every dev server listens on this computer only. terminus data handles an app's local data as the files people download — one simulated person's (--member bob; Alan by default), or one space's:
- data export <file>
- Write one person's local data as their
data.sqlite;--space <id>writes that space's file. - data import <file>
- Start one person's local data from a file — a
data.sqlitedownloaded from the desktop included — at the file's own data version.--forcereplaces what is there, keeping a backup. - data inspect
- Summarize one person's local data.
- data migrate --check <file>
- Run your pending migrations on a copy of the file, never the file itself: rows added, changed and removed per table, and
.out/migrations/report.json. See Migrations.
When terminus dev starts, it runs pending migrations on every person's and every space's local data, as Terminus does.
All commands#
Account
- login
- Sign in to Terminus in your browser.
- logout
- Sign out and revoke this device's session.
- account
- Your account's station.
- notifications
- Check your notifications.
Explore
- search
- Search the catalog.
Developing
- init
- Create a new app, agent, service, or skill.
- clone
- Copy a creation into a new folder.
- fork
- Fork an open-source app or agent, or a free skill, and clone it.
- remote
- Show or change the creation a folder is connected to.
- dev
- Run a package on this machine.
- build
- Build an app's browser bundle, or a hosted service's component.
- validate
- Check a package for problems before pushing.
- status
- Compare your working copy with its draft and live release.
- diff
- Show your changes, or compare two releases.
- pull
- Bring the draft's changes into your working copy.
- push
- Upload your working copy to its online draft.
- log
- Show a creation's releases.
- logs
- Show a published app's recent logs.
- data
- Export, import and inspect local app data files, and rehearse migrations.
- service
- Inspect services, test operations, and run jobs.
- secrets
- An app's or a service's secrets: list, set, delete. A value is read at a hidden prompt or from stdin.
- settings
- A service's settings: list, set, unset. Values its code reads by name, read back whole; see Settings.
Install Skills
- skills
- Install and use skills in Claude Code or Codex.
- skills install
- Add a skill to Claude Code or Codex.
- skills list
- List the skills you have installed.
- skills update
- Update the skills you have installed.
- skills uninstall
- Remove an installed skill.
- skills use
- Load a skill's instructions for your coding agent.
- skills fetch
- Download a skill's files to the local cache.
- skills files
- List a skill's files.
- skills file
- Print one of a skill's files.
Management
- creations
- Manage your published creations.
- drafts
- Manage your drafts.
Your published apps
- apps
- List apps, check access and use their tools.
- mcp
- Serve your apps' tools to coding agents over MCP.
- inspect
- Show a published app's runtime state.
Releases
- outdated
- Check a creation's dependencies for newer releases.
Your apps, for coding agents#
Your coding agent can use the apps you have installed, and the Terminus desktop itself, as you let it in System Settings → App access, under Coding agents: Off, Read only, or Read and write, and Send for tools that reach other people, in your own data and the shared spaces you choose. The CLI never gives itself access.
terminus mcp is an MCP server on stdin and stdout. Add it to your agent once:
claude mcp add terminus -- terminus mcp
codex mcp add terminus -- terminus mcpIt serves each tool you allow as <app>__<tool> — notes__search_notes, notes__digest — describing what it may change; where you allowed shared spaces, a tool takes a space. A change in Settings applies at the agent's next look at its tools, and every call is checked again. It signs in as you (terminus login, or TERMINUS_TOKEN); --dev serves the app terminus dev is running in this folder instead.
With the Terminus desktop open on the same computer, signed in to the same account, it also serves what runs there. For the apps you allow, that is their window commands and each one's whats_open and open; an app that is not open is opened out of sight for the call, and when one has more than one window open, its tools take a window. As the Terminus row in App access allows, it is also the desktop's own tools, as desktop__<tool>: desktop__list_windows, desktop__screenshot, desktop__open_app, desktop__focus_window and desktop__close_window. Your agent is told whenever the list changes — the desktop opening or quitting included — and everything else keeps working without the desktop.
terminus apps does the same from a terminal or a script:
terminus apps # your installed apps
terminus apps notes # its tools, and what is allowed
terminus apps notes search_notes --query "launch" # call one
terminus apps notes create_note --args '{"value":{"title":"Hi"}}' --space <id> --jsonA tool's arguments come from its schema: page_id becomes --page-id. A refused call exits 77 and says to ask you in Settings. --invocation <uuid> keeps a call's identity across retries, so an uncertain answer never runs a tool twice; --status <uuid> reads what became of it.
Versions and releases#
Every creation versions the same way: MAJOR.MINOR.PATCH, starting at 0.0.1 — in terminus.json, a skill's included. You choose the version when you publish on the web, with a note that annotates the release like a commit message; each release must be above the last, and a version is never reused for different content.
terminus log @publisher/app # its releases and their notes
terminus diff @publisher/app # the latest release against the one before
terminus diff @publisher/app --from 1.0.0 --to 1.2.0 # any two, by version or release number
terminus fork @publisher/app # your own copy on Terminus, cloned hereterminus fork makes the fork on Terminus, the way GitHub's Fork does — a draft at @you/<slug> (an app or agent stays open source like its original) — then clones it; --version forks an earlier release, --slug names yours, and --no-clone stops after the fork. Only open-source apps and agents fork, and free skills that aren't restricted; each account has one fork of a creation: forking again answers with yours. A fork that costs credits is made on the creation's page on the web, where you see the price and agree to it; the CLI prints both and stops.
Someone else's open-source creation also clones read-only: terminus clone @publisher/app brings its latest release down, and terminus pull brings newer ones. It never pushes.
terminus outdated @you/my-app # each dependency's pinned version against its latestterminus outdated reads a published creation's dependencies — the services, skills and agents its release names — and says for each whether it is up to date, how far behind it is, or that its address no longer resolves. Dependencies are recorded when a release is published.
Scripting#
Most commands take --json. With it, a failure prints one JSON object to stderr — {"error":{"code":…,"message":…}} — so a script or an agent can branch on the code instead of parsing prose. When Terminus refused the request, the object also carries its status, Terminus's own api_code — price_confirmation_required, say — and any details. terminus dev --prompt … --json is the exception that streams: one JSON object per line, one per event.
Reads, and any request carrying an idempotency key, are retried when Terminus is briefly unavailable; other writes are sent once. Options are checked strictly: a typo such as --limt fails before anything is sent.
Exit codes
- 0
- Success.
- 1
- Anything else that failed: an API error, an invalid package. Code
error. - 2
- Bad usage: an unknown command or option, a missing argument. Code
usage. - 3
- Not signed in, or the session expired or was revoked. Code
auth. - 69
- Terminus unreachable: a connection failure, a timeout, or a 502, 503 or 504. Code
unavailable. - 75
- Rate limited; the message says when to retry. Code
rate_limited. - 77
- Not allowed: Terminus answered
forbiddenorgrant_required, or a closed skill's content was asked for. Codeforbidden.
Environment
- TERMINUS_TOKEN
- A session token to use instead of the saved login.
For your coding agent
https://www.terminus.build/