Stasho CLI
The Stasho CLI runs the agent API calls as terminal commands, for people and for agents that have a shell. It works with an agent key that you, the owner, create in the dashboard under Settings. It only reaches uploaded sites, the same as the key does.
Prompt for your agent
Copy this into Claude Code, Cursor or any agent that can run shell commands.
Read https://docs.stasho.xyz/reference/cli.md and follow it to manage my Stasho sites.
Run stasho with npx @stasho/cli. My agent key (stasho_ak_…) is in the STASHO_AGENT_KEY
environment variable: never ask me to paste it in chat, and never write it into a file, code or
a commit. For a key created with My agent signs, the signing key is in STASHO_SIGNING_KEY or
saved by a prior stasho login on this machine. After every create and publish, tell me the url (it changes per version) and offer a
custom domain for a stable address. Read every error to me, and stop on exit codes 2 and 3 when
the message names something I must do. Ask me before every delete and domain remove, and pass
--yes only after I say yes.Install
npx @stasho/cli --help
# or
npm i -g @stasho/cliIt needs Node 22 or later. The examples below use the installed stasho command; with npx, write npx @stasho/cli in its place.
Log in
stasho loginlogin generates a signing key the first time and keeps it on every later run, including after a failed login. It prints the key's public half and its address:
Signing public key: 0x04…
Signing address: 0x…Then it asks for your agent key (stasho_ak_…), or reads it from STASHO_AGENT_KEY without asking. Without a terminal it reads one line from stdin, and exits 1 when stdin is empty or closed: set STASHO_AGENT_KEY, or run stasho login in a terminal. A STASHO_SIGNING_KEY that does not parse stops login with exit 1 and saves nothing. There are two kinds of agent key:
- My agent signs. You create the key in the dashboard (Settings > Authorizations > Create key), choose My agent signs and paste the public signing key. The CLI signs the site records itself.
- An ordinary key. You create the key as usual. Stasho's delegate writes the site records and the CLI signs nothing.
The credentials are saved in $XDG_CONFIG_HOME/stasho/credentials.json, or ~/.config/stasho/credentials.json when that is not set. The file is mode 0600 in a 0700 directory. In CI, skip the file and set STASHO_AGENT_KEY (and STASHO_SIGNING_KEY for a My agent signs key); both override the file. stasho logout deletes the file.
Commands
Every command takes --json, which prints one JSON object on stdout. Progress lines go to stderr, so stdout stays parseable in a pipe. publish, domain and delete take --site <id> (the site's projectId), or read STASHO_SITE_ID when the flag is absent; site takes the id as its argument. An empty --site is refused rather than falling back to STASHO_SITE_ID, and a command refuses any argument it does not take, before it sends a request or asks a question.
Create a site
stasho create ./dist --name "Launch page"Zips the directory (index.html at its root) and creates a site. Prints projectId, deploymentId, url, cid and name. The url is the gateway URL of this version and changes with every version; a custom domain is the stable address. This is the create call, scope create.
create and publish leave .git out and refuse a folder with a .env or .env.* file at any depth, naming the file so you can move it out; every other dotfile, .well-known included, is published.
If create exits 3 saying the site was created but its first version was not recorded, publish to the site id it names instead of creating again.
Publish a new version
stasho publish ./dist --site <id>Prints deploymentId, url, cid and domains. This is the publish call, scope publish.
List sites
stasho sitesPrints one line per site: its id, its latest version's status and its url. This is the list call, scope publish, all-sites key only.
Read a site
stasho site <id>Prints the site's projectId, url, latest version status and each domain with its status. This is the read call, scope publish.
Attach a custom domain
stasho domain add www.example.com --site <id>Prints the DNS records to set, one per line. This is the attach call, scope domains.
A host must be a hostname like www.example.com. The CLI lowercases it and drops a trailing dot, and refuses anything else before sending a request.
Check a domain's DNS
stasho domain check www.example.com --site <id>Prints ok, or one missing: line per record that is wrong, each with its meaning. This is the check call, scope domains. It exits 0 and lists what is missing until the DNS is right, so read its output rather than its exit code.
Detach a domain
stasho domain remove www.example.com --site <id>Detaches the domain. On a terminal the CLI asks [y/N]; without one it refuses and needs --yes. This is the detach call, scope domains.
Delete a site
stasho delete --site <id>Deletes the site, with the same [y/N] question on a terminal and --yes otherwise. This is the delete call, scope delete.
Signing
On a My agent signs key, create, domain add, domain remove and delete each answer with a message to sign. The CLI checks the message before it signs: that it is to be signed by the key it expects, that it writes exactly one site record (the one you named, for domain and delete; a new site has no id to name yet), and that the text it signs is the hash of that message. Any mismatch stops with exit code 2 and nothing is signed. The CLI checks which site a signature writes; it does not judge the record's contents.
Your agent signs its own site records. Stasho still publishes the files and marks versions live, as it does from the dashboard, and gains no new permission over your sites.
The loop itself is described in Sign your own records.
Exit codes
| code | meaning |
|---|---|
0 | done |
1 | usage, credentials or a refused input (including a destructive command without a yes) |
2 | the CLI refused to sign: the message did not match |
3 | the server refused: the message says what to change |
4 | the server or the network is unavailable: retry later |
Environment
| variable | use |
|---|---|
STASHO_AGENT_KEY | your agent key; overrides the credentials file |
STASHO_SIGNING_KEY | your signing private key; overrides the credentials file |
STASHO_SITE_ID | the site used when --site is not given |
STASHO_API_URL | overrides the API base URL (--api does too) |
XDG_CONFIG_HOME | where the credentials directory lives |
Never pass a key as an argument: it would show in ps, shell history and CI logs.
Limits
The CLI is subject to the same limits as the key; see the Limits table.