Clients (where Houston runs)
Houston runs in six places. All of them share one agent core, so tools, permissions, and skills behave the same everywhere.
| Client | Start it with | Good for |
|---|---|---|
| Desktop app | the app | everyday work, with diffs, previews, and panels |
| Interactive terminal | houston -i | a chat that lives in your terminal |
| Headless | houston -p "<prompt>" | scripts and CI |
| Standalone CLI | houston (Node script) | headless Linux servers |
| GitHub Action | houston-code/houston/action | answering mentions, reviews, fixing CI |
| Editor integration | houston --acp | editors that support ACP agents |
Desktop-only surfaces. The sidebar, the Preview panel, the integrated terminal and Files panel, rendered diagrams, and the tools that need a browser engine (view_localhost and render_mockup). Spawned sessions run in every client, but only the desktop app lists them in a sidebar.
Desktop app
The full GUI:
- a chat sidebar and diffs
- a right-hand dock with a Background tasks list of background commands (stop them, read their output, see which port each one holds) and the live Preview
- Settings
Chat status. Each chat in the sidebar has a status dot:
| Dot | Means |
|---|---|
| amber | it's waiting on you (an approval, a question, a plan to review) |
| grey pulse | it's working |
| red | its last run failed |
| blue | it has a reply you haven't seen |
- Read and unread. A chat's ⋯ menu (or ⌥U / Alt+U) marks it unread or read. The filter menu marks every chat read, or sorts the ones that want attention first.
- Picking up where you left off. A reply's hover actions include Mark unread from here, and reopening an unread chat lands on a "New" divider above the first reply you haven't seen.
- Back where you were after a restart. Houston reopens the chat that was open when you quit. If that chat was deleted, or its folder or worktree is gone, it opens a new chat in your last folder instead.
- Seeing what's waiting at a glance. A collapsed group's header, the collapsed sidebar, and the app icon count what's waiting (the Dock badge on macOS, a dot on the Windows taskbar button; turn it off under Settings, Notifications). A "N need you" pill in the title bar opens the next chat waiting on you, and clicking a desktop notification opens the chat it's about.
Interactive terminal
houston -i keeps a chat open in your terminal.
- The conversation streams live, and you answer approvals and questions inline.
- Slash commands switch settings mid-session.
--continuereopens this folder's most recent chat at launch;--resume <id>reopens a specific one.
See "The terminal composer" for how to type, paste, and edit a message.
Headless
houston -p "<prompt>" runs one prompt, writes the result to stdout, and exits. Each model round's text is written once that round has finished.
- Read-only by default. Add
--full-autoto let it edit files and run commands. - Machine-readable output. Add
--jsonfor one JSON line per event.
Nobody is there to answer, so a headless run handles prompts itself:
- Approvals.
--on-approval <allow|deny|fail>decides what a gated tool call gets. The default isdeny(allowunder--full-auto).failalso exits non-zero, so a script can tell the run hit a permission wall. - Questions. The agent isn't offered
ask_user. It is told no user is available, makes the call itself, and states its assumptions in the final answer. - Shell network. Under
--full-auto, shell commands reach the network through the egress allowlist from the start. Under ask or auto-edit, approving a shell command with--on-approval allowis a plain "Allow", so the command runs without network. Pass--allow-shell-networkto let shell commands reach the network for the run under any policy (see "Shell sandbox and network").
Prompt from stdin
-p -reads the prompt from stdin.- So does
-pwith no value when input is piped in:cat task.md | houston -p --json. - The standalone CLI also reads a piped prompt with no
-pat all.
Per-run settings
These apply to one run and never change your saved settings. A bad value exits with code 2 before anything runs.
| Flag | Effect |
|---|---|
--effort <off|low|medium|high|xhigh> | reasoning effort |
--max-turns <n> | caps the model steps (a hard cap that never auto-extends) |
--max-cost <usd> | the agent wraps up once the run's estimated cost reaches this (a soft ceiling: the step in flight still finishes) |
--verify <command> | runs this command when the agent stops after editing files, and sends a failure back for a bounded fix-up pass (needs a policy that can edit, such as --full-auto) |
--no-memory | runs without the memories saved in earlier sessions (a headless run reads memories but never saves them) |
Resuming a chat
--continue (this folder's most recent chat) or --resume <id> runs on that chat's own model and reasoning effort, unless --provider, --model, or --effort says otherwise.
The approval mode always comes from the flags (read-only unless --full-auto), never from the chat. A chat you use in full auto can't loosen an unattended run.
Automation flags
--allowed-tools <list>/--disallowed-tools <list>restrict the run's tools. Each entry is a tool name (read_file), a name ending in*(mcp__github__*), or a name with a permission-rule pattern (run_shell(git *)).- Tools out of scope aren't offered, and a call out of scope is refused under every policy,
full-autoincluded. - Disallowed wins over allowed.
- The scope only narrows: an allowed call still needs whatever approval the policy and rules require.
- Tools out of scope aren't offered, and a call out of scope is refused under every policy,
--append-system-prompt <text|@file>adds instructions for the run in their own marked section of the system prompt.--output-schema <file|json>makes the final answer a JSON value matching that JSON Schema. Houston checks it and gives the agent one round to correct a miss.--mcp-config <file>adds MCP servers for this run only: themcpServersshape of.houston/settings.json, at most 10. Their tools are namedmcp__run-<id>__<tool>.--input-format stream-json(with--json) reads one{"type":"user","content":"..."}line per turn from stdin. Each turn starts after the previous one finishes, until end of input.
--json output
Lines arrive in this order:
- Init:
{"type":"system","subtype":"init", "schemaVersion", "houstonVersion", "cwd", "providerId", "model", "approvalPolicy", "onApproval", "inputFormat", "tools"?, ...} - Session: a
sessionline, when the run is saved. - Events: one JSON line per agent event.
- Result: a summary (one per turn with stream-json input):
{"type":"result", "schemaVersion", "status", "stopReason", "limitReason"?, "turns", "costUsd", "inputTokens", "outputTokens", "durationMs", "finalText", "receipt"?, "structured_output"?, "schemaErrors"?, "error"?}
In the result line:
statusissuccess,limit,stalled,approval_denied,error,schema_invalid,input_error, orverify_failed.finalTextis the agent's closing answer (the text after its last tool call).receiptis Houston's record of what the run actually ran (see "What actually ran"), present when it ran checks or changed files.structured_outputis the answer parsed against--output-schema.
Every line is described by docs/schemas/headless-events.schema.json in the repository.
Exit codes
| Code | Meaning |
|---|---|
| 0 | the agent finished on its own |
| 1 | an error or aborted run, a stalled agent, or a call refused under --on-approval fail |
| 2 | a usage error (a bad flag value, an unreadable flag file, or an empty prompt on stdin; nothing ran), or a bad stream-json input line |
| 3 | the run hit a budget before finishing (its step cap or the model's output limit) |
| 4 | the final answer still didn't match --output-schema after the corrective round |
| 5 | the agent finished, but the last --verify check it ran still failed (its fix-up passes ran out) |
Standalone CLI
The same -p, -i, and --acp clients as one self-contained Node script, with no desktop app and no browser engine.
- Runs on headless Linux servers.
- API keys come from environment variables.
GitHub Action
houston-code/houston/action runs the standalone CLI in GitHub Actions, on your own runners, with your own model key from a repository secret. There is no Houston service.
It has three modes:
respondanswers an@houstonmention from someone with write access, as a reply.reviewposts one review comment on a same-repository pull request, fromreview_changes.fix-cifixes a failed workflow run, pushes the fix to a newhouston/branch, and opens a pull request.
For safety, the action verifies the downloaded CLI's signature first, gives the model only read access to GitHub and no web access, and does all posting and pushing itself. Inputs, example workflows, and the security model are in action/README.md in the Houston repository.
Editor integration
houston --acp speaks the Agent Client Protocol (ACP) on stdio, so an editor that supports ACP agents can run Houston without a Houston extension.
Set it up: point the editor's agent setting at the houston command with the --acp argument (the desktop binary takes the same flag).
The editor's folder becomes the workspace. Its chat panel shows Houston's replies, reasoning, tool calls (with diffs for edits), the todo list as a plan, and context and cost as usage.
- Modes are the approval policies: Plan, Ask, Auto-edit, Full auto. A new session starts in your default policy, and the editor's mode picker switches it for the rest of the session, a running prompt included.
- Approvals appear as the editor's permission prompt: Allow (this call), Always allow (saves a permission rule, as in the app), Deny, or Always deny. Dismissing the prompt denies the call. The sandbox and your permission rules apply exactly as in the other clients, and file reads, writes, and commands go through Houston's own tools, not the editor's.
- Plans from Plan mode arrive as a permission prompt too: accept with edits applied automatically, accept approving each edit, or keep planning. Accepting moves the session's mode.
- Questions (
ask_user) and an MCP server's input requests show as a form when the editor supports ACP forms. Without forms, a question is answered "use your best judgment" and an MCP request is declined, as in headless mode, so a run never hangs. - Sessions are Houston conversations. The editor can list and reopen them, and they also show up in the desktop app and in
houston -i --resume <id>. MCP servers the editor passes join your own for that session (asrun-acp-<name>) and are never saved to your settings. - Credentials resolve as in the CLI: environment variables, then saved keys. With no provider set up, the editor gets an "authentication required" error; an editor that can open a terminal is offered to run
houston -i, which walks you through adding one. - Output and trust. Stdout carries protocol messages only; diagnostics go to stderr and the log file. A folder that isn't trusted yet gets none of its project's allow rules, hooks, or MCP servers, as in headless mode. Trust it from the desktop app or
houston -i.