Command reference
Updated 2026-10-10
Every command accepts --json and --help (ghosty skills --help and ghosty help skills show that command's usage and examples). <id> is an agent: its name (ghosty agents get pia-0, case-insensitive) or its id (shown by ghosty agents ls). If several share a name, the one in the ghosty use workspace wins; if there are still several, the CLI prints their ids to pick from.
Naming rule (like gh): noun then verb (ghosty cards show, ghosty boards create); turning something on or off is enable / disable (ghosty skills disable <id> pdf-doc); on / off only as an option's value (--sponsor on). The old forms (board, skills on|off, --on/--off, --vence) still work and say which one is new.
Session
Agents
agents get shows the agent's env; values that look like secrets (…KEY, …TOKEN, …SECRET) come back as •••.
agents box shows which machines serve the agent and, with --check PATH (repeatable) or --contains PATH=TEXT, whether they have what you expect. Use it after an image change: on ✗, --recycle and check again after one turn. On Ghosty · Lite and Goose use agents restart.
create adds an agent to your account (no workspace) and returns its id. Without --engine it uses Claude; without --model, the engine's default. An engine or model that doesn't exist is rejected (also without --engine) and the error lists the valid ones; ghosty engines ls --models shows them beforehand.
--env K=V,K2=V2 sets variables on the agent's machine, in create or set; K= removes one. The most useful: GHOSTY_THINKING_EFFORT (off · low · medium · high · max) sets how much the model thinks on Ghosty · Lite.
Connecting Drive (or another connector) to your account gives no agent access: each one gets it with --connect <connector> or on its page → Connectors. Only the owner can grant it.
set changes only what you pass. Prompt and model apply from the next turn. --engine switches the engine; --model is then a model of the new engine. On Claude, effort is --env FLEET_EFFORT=low|medium|high|xhigh|max; without it, it runs at medium. Codex, DeepSeek, Goose and DeepAgents are deprecated: use Claude, Ghosty · Lite or Gemini.
Public demo: agents demo
A /p/<name>-<code> link so anyone can try your agent without an account, exactly as you built it (its machine, its skills, its engine), paid by you. With "Keep it" the visitor creates an account and takes their own copy, with the trial conversation and files.
With no options it only shows the status. The output includes trials, messages and copies kept (how many on your key) and, if the agent failed to answer a visitor, the last reason.
Web widget: agents embed
A chat bubble with your agent on your site, with one line of code. It only loads on the domains you list; each visitor gets their own isolated conversation and talks as a customer. Details in .
The output also includes the React snippet (npm i @ghostystudio/widget + <GhostyWidget token="emb_…" />); in --json, under react ({install, code}).
Try a demo and see what happened: demos
demos try counts against the demo's caps (messages per visitor and per IP per day) and shows up in its numbers and CRM. demos history shows turns, messages, attachments, deliveries and clones; it is Ghosty staff only: the owner sees numbers (agents demo), not their visitors' chats.
The agent as a file
ghosty agents export writes an agent's whole setup to a YAML (compatible with recipes); ghosty apply makes an agent match the file, showing the plan first.
- Anything the file doesn't mention is left alone; the fields it has become exactly what it says.
- Lists (databases, documents, shares, own skills, env vars) add and change; removing needs
--prune(without it they show with!). - Secrets never leave: they're exported as
${NAME}. WithNAMEin your environment it changes; otherwise today's value stays. - Before applying, the agent's current version is saved (Versions, in the web).
applydoesn't move an agent between workspaces.
Configure an agent
Every agent has its own machine and disk: files, skills and MCP work with any engine. On pool engines (Claude, Codex, DeepSeek, Gemini) they enter by themselves on the next turn; on Ghosty · Lite and Goose new skills enter with agents restart (needsRestart in agents get).
Files
Derived prompt
An agent can inherit another agent's prompt plus an overlay of edits: a store's branch using the head office's prompt with its own name, hours and catalog. When the base changes, the derived prompt regenerates by itself.
- Edits run in order and each must find its place. If the base changed right there, the derived agent keeps its previous prompt and
agents doctorflags it (prompt.base). --dry-runtells whether every edit applies (--out FILEwrites the result).--prompt-base noneunlinks and keeps today's prompt.- While linked, its prompt can't be edited directly (409): change the base or the overlay.
Patch the prompt
To change one piece of the prompt without rewriting all of it (and without overwriting what someone else changed in between), with the same overlay format:
- It applies on the server, on the prompt as it is at that moment: no need to download it with
get --prompt-outand upload it again. - If an edit doesn't find its place, nothing changes (409 saying which one).
--prompt-patchand--prompt-appendtogether: edits first, then the text. - It's logged (
agent.prompt_patch). It doesn't apply to a derived prompt: change the base or the overlay there.
Skills
skills rm saves the copy under ~/.config/ghosty/trash/ and prints the command that restores it.
skills templates reads a live machine (run one turn first) and lists what pdf-doc sees: agente:<skill> or casa. An agent's own template is <skill>/pdf-templates/<name>.html in any of its skills; with the same name it wins over the house one.
MCP servers
One key per end user: in an http MCP, a header may carry ${turn.token}
("Authorization": "Bearer ${turn.token}"). Each message-stream or turns call sends its
turnToken and gs applies it to that turn only, through its proxy: the token never enters the box
and is never stored. A turn without turnToken on that agent fails with an error. Not allowed in
sse, stdio, the URL, or ACP agents.
Quoting with the house tool: VAT and catalog
The cotizar tool does the math, the folio and the PDF; the agent only sends the lines. Each line's VAT comes from the agent's config, in this order:
- If the call sends
iva_pct, that one for everything. - With
solo-factura=trueand nofactura: trueon the quote: 0. - If the line's category has a rule (
iva.GRANEL=16): that one. - With
iva-incluido=true(prices already include it): 0. - Otherwise:
iva(16 by default).
The category comes from the agent's catalog (--catalog), not from the model; the one the agent sends only counts when the product is not in the catalog. When lines carry different rates, the PDF breaks it down ("IVA (GRANEL 16%)"). An agent with its own cotizar skill doesn't use this tool: saving that skill turns it off.
Check an agent: agents doctor
Like brew doctor: it only prints what needs attention, each finding with the command that fixes it, and exits 1 when there is a problem (usable as a gate in a script). --verbose also lists what passed.
It checks: skills that could fire on the same request (two quoting skills on at once), skills the prompt names (skill \cotizar`, .claude/skills/cotizar/) that the agent lacks or has off, an own skill named like a house tool that is still on (the model may use the generic one), tools the prompt names that don't exist or have no permission, customer-write tables that no longer exist, db_/doc_` in the prompt with nothing granted, and turns that failed in the last 24 h.
Databases
queryis read only;--writeallowsINSERT/UPDATE/DELETE/DDL.--arg Vgives the value of each?, in order (repeatable).exportdownloads a copy: without--table, the whole database as SQLite (every table with its rows); with--table, that table as UTF-8 CSV.--outsays where to save it. It uses your session, not the agent'sgat_token, and is recorded in the audit log. The same downloads are on each database's page (/app/datos?tab=dbs→ the database → .sqlite / table.csv).importreplaces each table's rows (idempotent);--appendadds them instead and--tables a,bcopies only those.--dry-runprints the plan (+create,~replace N → M rows) and changes nothing. If the database is shared with agents already writing in gs (quotes, folios), it warns about the rows that exist only in gs and asks before deleting them.dbis an alias ofdbs, anddbs sqlofdbs query.
Catalog photos
A catalog's photos should live at permanent links (img.ghosty.studio): links from EasyBits or the customer's website expire or change, and WhatsApp stops sending them.
importwarns when replacing a table would turn permanent links back into external ones, and gives you the exact flag.photos putonly takes JPEG, PNG or WebP up to 10 MB;--dry-runlists keys with no row and files that aren't images. The column isimagen_urlunless--column.- On the web (
/app/dbs, Tables tab) you get the same counts, a «Hacer permanentes» button, and you can drag a photo onto a row.
Documents
<db> and the document accept the id or the name. An agent token (gat_…) only sees what was granted and cannot grant itself anything.
A document is one document even when several agents use it: replace uploads a new version that keeps the name (only the extension follows the type), the access and every agent that uses it, so a prompt that names it doesn't break. The previous version stays in the history (20 are kept). With an agent token, replace and restore only work if the agent has «Can update it» (grant --write).
Turns
turns grep searches the conversation text (not steps or tools) and returns each match with its turn, to open with turns show. In the «resumed» column, «1st turn» is the first turn of a new SDK session: not a memory loss.
--errors is the same as --status error. --since takes 30m, 1h, 2d or an ISO date; --limit defaults to 20 (max 500).
turns show first prints what came in (in) and what it answered (out), on any engine and channel (WhatsApp groups included). Then it answers "where did 4 minutes go?": the turn's timeline (+12.3s Bash office-reader … 8.1 s), the slowest tools and the total model calls and output tokens. That part reads the engine's transcript, so it only exists on pool engines (Claude, Codex, DeepSeek, Gemini), not on Ghosty · Lite or Goose.
WhatsApp channels
Enabling a number makes the agent answer real customers: it asks you to type the number's last 4 digits (or --yes). A number has one agent: enabling it takes it from the other.
Groups belong to the agent's paired personal WhatsApp (not WhatsApp Business): which ones it answers, and as whom. equipo = the team (writes to databases, admin tools); cliente = like any customer.
<group> is its name or its jid. Turning a group on asks first (or --yes): the agent starts answering there.
--wake: mention (the default when you turn a group on) only opens a turn when someone @-mentions the agent, writes its name or replies to one of its messages; everything else reaches it as context on its next turn. all answers every message (imported groups and groups made with create).
Who was answering this number?
If a number or a page was left without an agent, the «last answered by» column tells which agent answered it last and when (from gs's turns), so you can give it back:
Bring a number from somewhere else
To migrate an agent from EasyBits (or a droplet) without signing the number up again:
--answerhas no default:onanswers real customers;offonly records. Formmy only forwards when its channel is on:onturns it on; withoff, only if you add--forward(the plan warns when gs won't see the conversations).- The owner, an admin of the agent or Ghosty staff can do it. If the number's owner in Formmy has a different email, only staff.
historygoes afterlinkand never duplicates: run it before the cutover and again right at it. It fires no "new lead" alerts.historyalso copies the files (photos, PDFs, audio) to gs, and the summary says how many were copied and how many failed. Formmy deletes them after 7 days: bring the number within that week. Failed ones are retried with--media, which touches no cards or messages; with--dry-runit says how many are missing.import: first turn off WhatsApp in EasyBits without logging out (two connections with the same keys knock each other off; logging out invalidates them).--own-number no= it's a person's number: only their chat with themselves counts as the owner's. Delete the file afterwards: it holds the account's keys.
Board
resume doesn't answer by itself (the wake-up Formmy sends on resume is ignored); reply does, only on WhatsApp Business and only if that agent answers the number. pending flags and never answers: paused, escalated, outside WhatsApp's 24 h window (Meta only takes templates), only a reaction, not WhatsApp Business, and numbers answered by nobody. pause, resume and reply are logged.
The board belongs to the workspace: an agent shared with you doesn't give you its board; the owner has to add you to the workspace. At least one filter is required (--integration, --column or --before).
Credentials
A key is never accepted as an argument: it would stay in your shell history. creds is an alias of credentials.
Connectors
The same as /app/connectors and the app. Key connectors with several fields (Odoo, WooCommerce…) are asked one by one; secrets without echo and never as an argument.
Confirmations
agents rm, files rm, skills rm, credentials rm, board archive, replacing rows with dbs import and channels whatsapp enable ask before acting. Without a terminal (a coding agent, CI) they never wait for an answer: add --yes, or they exit 2 with the exact command to retry.
Talk to an agent
Test turns
--waba goes through the same path as a real WhatsApp Business customer (inherited context, price rule, board, voice) and sends nothing: no message, no voice note, no payment link. It lists everything that would have gone out, including what tools send: 📍 location, 📄 files, 🎤 voice, ↩️ quotes, 🔘 buttons, 👤 contacts and reactions. With --as-formmy the attachment goes the way a real one does: proxy with credential, copy to gs and transcription; it says at the end whether the copy arrived. --replay runs from your machine and writes replay.json after every step; if Ghosty deploys mid-run it waits the Retry-After and continues, and --resume picks up an interrupted run.
Conversations
try is for testing configuration; chat uses the agent's real conversations, the same ones you see in the dashboard and the app.
Schedule turns
The agent works on its own at the time you set: each run lands in a conversation and notifies your phone (iOS or Mac app). If its answer is exactly OK, it stays silent; use that for "check and tell me only if…".
Without --conversation a new conversation is opened (named after --title if given). Rules: repeat every 15 minutes at least, --until is required when repeating, at most 30 days ahead, and up to 5 pending per conversation.
In a channel conversation (--conversation waba:…, wa:<jid> for personal WhatsApp —a group or a chat— or messenger:…) the answer goes out through that channel; an «OK» answer is not sent. On WABA only within the 24 h window; on personal WhatsApp, if the agent's number is connected.
In a Teams thread
At that time the agent answers in the room (or in the thread: the number is the id of the message that starts it) as if someone mentioned it, with that room's memory. It must be active in the workspace's Teams and you must be a member. Without a thread it posts in the room. --every doesn't work with --teams yet.
Your account
Usage
plan apply can be run by staff, or by the workspace owner when there's no subscription (with one, the new plan starts when the invoice is paid). Without a workspace, both use the one from ghosty use.
With --json it returns plan.name, week.pct and month.pct (0 to 1; month.pct is null if your plan has no monthly cap), their resetsAt, creditMxn (top-up balance) and exhausted (true when you have no usage left). Change plan or top up: .
Workspaces
Token bags, renewal and slug of a workspace. The owner can read the bags; changing them, renewing and renaming is for Ghosty staff (logged in the workspace's audit).
A transfer only changes the owner: the space, its agents, their skills and history stay as they are. Documents, databases, boards and numbers its agents use move to the new account; anything an agent outside the space also uses stays, and the dry run says so. --copy-keys copies the provider keys and connectors (MercadoPago, Skydropx…) the new owner lacks.
Archiving deletes nothing: the workspace stops showing in /app and ghosty spaces ls, and its agents, data and history stay. The owner or staff can do it; it's logged (workspace.archive / workspace.restore) and ghosty spaces restore <workspace> undoes it.
A monthly bag (default) refills every workspace period; a one-time bag (--recurring off) counts everything spent since it was created and, when it runs out, it's over. With --hard-cap on (default) turns stop at 100% with «out of balance»; with off it only counts. An agent with no bag spends from the workspace balance.
Audit log
Who changed what: the agent page's Save, channel changes, pauses and replies from the CLI, prompt patches, transfers, staff in and out and «log in as». Ghosty staff see everything; anyone else, only their own workspaces and agents. A gat_ agent token can't read it.
Factory
A workspace's Software Factory runs (they live in its Teams). Reading needs membership; renaming needs owner, admin or staff (logged as factory.run_rename).
runs ls shows how long each run took and what it cost. To see where one run's time and money went:
- Working: some role had a turn running. Waiting for a person: the plan or the PR to approve. Other: CI, queues, deploy.
- Commands of 60 s or more come from each role's transcript. ACP engines don't keep one: they show minutes and cost, without commands.
- The cost includes @plan's first turn in the thread, before the run existed.
Why it got stuck or failed (a healthy run doesn't call the model; the analysis is saved, --refresh redoes it). See :
And how the workspace's factory is doing:
Getting help
Support is by email: each case has its own reply address, so answering the email or writing here lands in the same case. You can also ask your agent in your chat: "report it to support". The case carries your account, your agents and their recent errors, so you don't have to repeat them.
On the web: Support in the menu.
Support
For Ghosty staff (User.isAdmin): what used to be a script in the box for each report. Reading someone else's conversations is logged.
conversations archive|rm with --kind test|channel is for the agent's owner (or staff): rm never deletes customer threads (--kind channel), which are only archived because their memory is what keeps serving them. --kind personal is for anyone with access to the agent and only touches YOUR own chats with it, never someone else's. What you delete also disappears from the apps (iOS, Android) on their next sync. push log is recorded since 2026-10-01 and kept 30 days; since the same day it includes announcement pushes (kind: novedad), and novedades ls shows how many FCM delivered and rejected. agents ls --user --app also lists their phones with the app build, and the «fetched» column of agents doctor --user exists since 2026-10-01. --tools reads the transcript in Tigris (claude-worker) or the box history (goose, ghosty-lite); never while a turn is running in that thread.
Assigned staff
A Ghosty account executive assigned to a client's account sees and runs, with their own session, that account's agents (with and without a workspace), its documents, databases and boards. They don't see keys or tokens, don't touch plan or billing, and don't transfer or delete. Only staff assigns; the customer sees it as «Your Ghosty account executive» in their account. Every assignment and every write by the executive is logged.
In the panel, the executive picks «Atendiendo: » in Documents and databases and in Agents; it is a cookie revalidated on every request, never another session or «sign in as».
Sites
The sites your agents publish, at <slug>.ghosty.page (nobody needs an account anywhere else). sites ls shows yours: live, paused, and unpublished ones that can still be recovered.
Free plan: a site pauses after 30 days without changes (notice 7 days before; every change gives it another 30). While paused its link shows «This page is paused — Reactivate it» and nothing is deleted. After 30 days paused it is unpublished (the link stops working and the slug stays reserved) and its copy is kept 6 more months; then it is deleted for good. Reactivating it any time before that brings it back as it was, on the same link.
Pinned sites: $49 USD a year or $5 USD a month ($990 / $99 MXN), includes up to 3 sites. A pinned site never pauses and carries no «Made with Ghosty» banner. Need more? Each extra pack adds 3 sites for the same price. Releasing a site, cancelling or a failed payment send it back to the Free rule with notice: it never pauses at once.
The slug: lowercase letters, digits and hyphens, 3 to 60, no hyphen at the start, at the end or doubled, and not reserved (api, admin, s, www, app, assets, static, dashboard, login). Errors with a code: slug_invalid, slug_taken and slug_unsupported (EasyBits does not accept choosing or changing the slug yet; nothing changes and it exits with 1). Limits: 1 MB per file, 8 MB and 40 files per site.
Browser
Asks for confirmation (--yes for scripts). To reconnect the terminal, copy the new command from the extension panel. See .
Partners
ghosty partner gives an agent to each of your customers (one shared agent, memory per customer). It has its own page: .
Language
The CLI speaks Spanish if your system is in Spanish (LANG=es_MX…) and English otherwise; --lang es|en or GHOSTY_LANG forces it. It also translates the server's messages to English. With --json, keys and codes don't change.
Tab completion
It completes commands, subcommands and flags, plus your agents' and workspaces' names (cached for 5 minutes).
Global options
An agent token (gat_…, generated on the agent's page) reaches only that agent: it works for agents get/set/restart, files, skills, mcp and try, but not for listing agents or chat.