CLI
Install, authenticate, control sessions, and run the external MCP server from the CLI.
The Happier CLI is the power-user client for:
- installing and updating Happier
- authenticating to one or more servers
- selecting a default server profile or targeting one command
- creating, listing, resuming, attaching to, and managing sessions
- running the external Happier MCP server
- inspecting Happier tools and action-driven workflows
Install
curl -fsSL https://happier.dev/install | bashPublic installer lanes:
stable:curl -fsSL https://happier.dev/install | bash->happierpreview:curl -fsSL https://happier.dev/install-preview | bash->hprevdev:curl -fsSL https://happier.dev/install-dev | bash->hdev
Windows (PowerShell):
irm https://happier.dev/install.ps1 | iexnpm fallback (power-user / Node workflow):
npm install -g @happier-dev/cliImportant:
- npm installs expose the npm dist-tags (
@latestand@next). - The rolling
devlane is installer-managed (install-dev/hdev), not a separate npm dist-tag.
Homebrew (coming soon)
Not published yet
The Homebrew formula is prepared but its tap is not public yet, so this command does not work today. Use the installer above until this notice is gone.
On macOS 13 (Ventura) or later and on Linux, the stable CLI will install from Happier's own tap:
brew install happier-dev/tap/happierThe formula installs the same signed release payload the installer does, into Homebrew's prefix,
and links happier onto your PATH. It has no brew services entry: the background service is
still set up by the CLI itself (happier setup, or happier service install).
Updates
How you update depends on how you installed the CLI:
- Installer install: run the lane-specific command (
happier,hprev, orhdev) withself check/self update(or rerun the matching installer endpoint). Installer installs keep the full CLI payload under~/.happier/cli/currentand refresh the selected lane shim for you. - Stable is
~/.happier/cli/current; preview/dev use~/.happier/cli-preview/currentand~/.happier/cli-dev/current. - npm install:
npm install -g @happier-dev/cli@latest(or@nextfor preview). npm does not currently expose a separate publicdevdist-tag. - Homebrew install (once published):
brew upgrade happier.happier self updaterecognises a Homebrew install and prints that command instead of replacing Homebrew's copy.
Using the desktop app with a CLI you installed yourself
In the current development build (unreleased), when the desktop app sets up this computer and finds
a happier it did not install (npm, Homebrew or a manual copy), it asks once, naming that CLI's
version and path:
- Let Happier manage it — the app installs its own CLI, puts it first on your
PATHfor new terminals, and moves the background service to it. Your old copy is left in place; Settings › This computer › Command line shows the command that removes it (for examplenpm uninstall -g @happier-dev/cliorbrew uninstall <formula>). The app never runs it for you. - Keep my own — the app installs nothing and adds nothing to your
PATH; the app, the background service and your terminal all use your CLI. Updating it stays with you (for examplenpm install -g @happier-dev/cli@latest). If it is too old for setup, the app says so and names that command instead of replacing it.
The answer applies to every Happier app on this computer. Change it any time in Settings › This computer › Command line. You are asked again only if the CLI you kept disappears or becomes too old for setup; if it disappears, the app asks before installing anything in its place.
On Windows, a happier on the system-wide Path (for example from a machine-wide Node.js install)
still runs first in new terminals after Let Happier manage it, because Windows puts the system
Path ahead of yours. Remove that copy with the command Settings shows.
The CLI can also show periodic update notices in TTY sessions; disable with:
HAPPIER_CLI_UPDATE_CHECK=0Full matrix (all apps/assets): Updates.
Set up a coding agent
The upcoming 0.2 setup flow offers installable agents from Happier's catalog when none is available. Choose one or Skip for now. Skipping completes the machine connection, but a computer with no agent is not coding-ready. Installing an agent only makes its CLI available; complete that agent's own authentication separately before starting a session.
Authenticate
happier auth loginhappier auth login asks whether to approve with a web browser or the mobile app.
The browser path prints its terminal-connect URL; the mobile path prints a QR code and deep link.
When using self-hosted servers, run login against the correct server profile (see below).
Recommended first-run flow:
- Choose the approval method available on the device where you already use Happier.
- If you already use Happier on another device, sign in with that same account.
- If you open a terminal-connect link while logged out, Happier routes you through sign in and then returns you to terminal approval automatically.
Notes:
- The CLI never needs your secret key directly. For device-key accounts, restore happens in the app (mobile/web UI).
- On enterprise/keyless deployments (mTLS or keyless OAuth), the same
happier auth loginflow works; the browser/app will use whatever the server advertises viaGET /v1/features. - Terminal connect is separate from account restore. In the app, use Scan QR to connect terminal only for terminal/daemon approval. To sign a phone into the same account, use Add your phone on an already-signed-in desktop/web app and Restore account on the phone.
- If the mobile QR/deep link does not include a server URL, your current server is probably loopback-only (
localhost/127.0.0.1). Configure the phone to a reachable server URL first, then retry.
Advanced:
- To also print optional “configure server” links (rarely needed):
happier auth login --print-configure-links - To stop waiting for approval after a fixed time instead of waiting indefinitely:
happier auth login --wait-timeout <seconds>. When the timeout expires, that request ends and cannot be approved. Rerunhappier auth loginto create a new request. Guided setup uses this so it can hand the terminal back.
User guide: Features → Device linking & restore
Remote machine pairing (SSH, automated)
If you want to run Happier on a remote machine (VPS, home server, dev box) but approve/authenticate it from a machine where you're already signed in:
happier auth pair-remote --ssh user@hostNotes:
- This orchestrates a claim-gated pairing flow over SSH (remote request → local approve → remote wait).
- Add
--jsonfor machine-readable output. - Add
--server ...or--server-url/--webapp-urlto choose the local relay profile/account used for approval. - If your selected relay is local-only (
localhost/127.0.0.1), interactive mode offers reachable addresses for this computer (Tailscale Serve, direct Tailscale IP, LAN IP) plus Custom. In scripts, pass the address the remote machine should use to reach this computer's relay:happier auth pair-remote --ssh user@host --server-url-for-remote https://relay.example.com. --remote-server-urlremains available as a legacy alias for--server-url-for-remote.- For remote Windows hosts, make sure the Happier CLI command is available in the SSH session. If the command is not named
happier, pass--remote-command hdevor the installed command name.
Pairing (JSON, manual / scripting)
Split the flow when you want full control (automation, custom SSH, etc):
# On the remote host (prints a request + publicKey)
happier auth request --json
# On a local machine that's already authenticated (approves the public key)
happier auth approve --public-key <publicKey> --json
# Back on the remote host (waits, claims, and writes credentials)
happier auth wait --public-key <publicKey> --jsonThis is terminal/CLI pairing, not the same flow as device restore inside the app.
Guided first run
happier setupOn a fresh interactive install, the installer continues directly into
happier setup. Run it yourself when the installer was unattended, you skipped
the guided step, or sign-in did not finish. Setup asks where your relay lives,
points this computer at it, and runs the sign-in. It leaves an already-finished
computer alone only when a relay is selected, the relay still accepts the stored
sign-in, and this machine is registered against it. Credentials the relay has
since rejected, or credentials with no registered machine behind them, are what
setup exists to repair, so they do not count as configured. When the selected
relay does not answer, nothing can be verified: setup keeps your relay choice
and stored sign-in exactly as they are, says it could not check them, and offers
retry or explicitly choosing another relay — an unreachable relay is never
treated as a rejected sign-in or a reason to sign in somewhere else.
The current 0.2 checkout has the refreshed setup presentation; it is not part
of the public 0.2.11 installer. Wide terminals place the planet beside the
setup choices, drawn in Braille dots. It rises into view, turns briefly and
comes to rest, then keeps breathing slowly; once you move the selection it
dims so the choices lead. Terminals that report a light background through
COLORFGBG get the light planet. On Windows the planet needs a host that can
draw Braille characters, such as Windows Terminal; the legacy console uses the
compact text layout. Use the arrow keys to select and Enter to continue;
letter shortcuts remain available. Narrow terminals use a compact text layout.
On a capable terminal, set HAPPIER_NO_ANIMATION=1 to keep the branded
output static. NO_COLOR
disables colour, while TERM=dumb and non-interactive output suppress cursor
animation and decorative art automatically.
On capable terminals, the corresponding installer introduces Happier with a static Braille planet and groups its work into Download, Verify, and Install. It retains detailed failure output and hands over to setup without repeating the welcome. Colours use your terminal's capabilities; its font and background remain yours.
The installer's automatic handoff to setup is best-effort: declining it or
leaving setup incomplete does not turn a successful binary installation into a
failed installation. An explicitly requested installer action, such as
--run setup, is different: that action is part of the command you asked for,
so its exit status is propagated. A non-zero result means the CLI was installed
but the requested setup action did not finish.
| Flag | Effect |
|---|---|
--cloud | Use Happier Cloud without being asked |
--relay <url> | Use a relay you already run |
--this-computer | Install a relay on this computer and use it |
--yes | Ask nothing, do everything that needs no answer, stop at the sign-in |
--non-interactive | Change nothing, and say what would be needed |
--yes and --non-interactive ask for opposite things, so they cannot be
combined.
--yes runs the steps that have an answer already: it points this computer at
the relay you named and, for --this-computer, installs the relay here. It then
stops, because signing in has to be approved on your phone or in a browser and
nothing on the command line can approve it for you. Setup names
happier auth login and exits non-zero — the binary installed, the guided setup
did not finish. It needs one of --cloud, --relay <url> or --this-computer:
your account lives on whichever relay is chosen, so setup will not choose one.
--non-interactive writes nothing at all. It is also how setup reads
HAPPIER_NONINTERACTIVE=1 and a run with no terminal, which is what installers
and CI set for a whole run — a machine that is only passing through does not
get an account created on it. Ask for the work explicitly with --yes.
Choosing to host the relay on this computer adds a reachability step, before and after the install: setup says whether Tailscale is running here, installed but stopped, or not installed at all, and what that means for your phone. Tailscale must be active on both devices, on the same tailnet, and the relay must actually be published with Tailscale Serve or listen on a reachable Tailscale address. Installation alone is not reachability. When Tailscale is absent, setup offers to set it up — opt-in, defaulting to no. On macOS and Windows it opens the download page; on Linux it prints the install docs and moves on.
For LAN access, the relay must listen on a non-loopback address and its port must
be allowed through the host firewall. localhost is local to the environment
where the relay runs: a loopback listener inside a VM is not reachable as the
host Mac or PC's localhost.
That install also creates a master secret in the relay's data directory the first time the relay starts, and says so once, there. It encrypts what the relay stores, is saved nowhere else, and cannot be regenerated — keep it with your backup of the relay's database.
When the relay ends up reachable from this computer only — no Tailscale, or a
loopback address — the sign-in step says so and signs in through this computer's
browser rather than offering the app. Terminal links deliberately drop an
address no other device can reach, so the phone would be left pointing at
whichever relay it already had. Only a sign-in that actually starts a new
request makes that choice: setup runs happier auth login either way, and when
your stored sign-in is still accepted it just repairs the machine registration
without opening a browser. Once the relay has an address your phone can reach,
happier auth login offers both routes again.
Setup finishes by checking for an installed coding agent. Finding none is a warning, not a failure — you can finish setup and install one afterwards.
Check and repair this machine
happier status reads the whole chain between you and a working session —
account, relay registration, automatic startup, CLI channel — and changes
nothing. happier doctor repair fixes what it can. Both are covered in
Check your setup, along with the
happier service commands that manage automatic startup.
Notifications from a script
Send a notification to your own devices from anywhere a shell runs — the end of a long build, a cron job, a deploy:
happier notify -p "Deployment complete!"
happier notify -p "Database connection restored" -t "Alert"-p is the message and -t an optional title.
Automations
Trigger a saved automation without opening the app:
happier automation run <automation-id> [--idempotency-key <key>] [--json]Pass --idempotency-key when the caller might retry — a repeated key will not
run the automation twice.
Plugins
happier plugins list [--json]This version of Happier does not support installing plugins; the command exists so that tooling asking about plugins gets a clean, empty answer rather than an unrecognised-command error. It always lists nothing.
Server profiles
Save and switch servers
happier server list
happier server current
happier server add --name company --server-url https://api.company.example --webapp-url https://app.company.example --use
happier server use company--use (and happier server use ...) sets the default server for future commands, so you can usually omit --server ... once it’s selected.
The selected server hosts the account and synchronized session state; coding agents still run on the machine that owns the session. Changing the default server selects that server's account context. It does not migrate an account, sessions, or settings from the previous server.
Target a server for one command
Use per-invocation targeting when you do not want to switch the default:
happier --server company auth login
happier --server personal daemon statusYou can also use URL flags:
happier --server-url https://api.company.example --webapp-url https://app.company.example auth login
happier --server-url https://api.company.example --webapp-url https://app.company.example auth pair-remote --ssh user@host --jsonhappier logout is deprecated and prints a notice saying so. Use
happier auth logout.
Daemon (background mode)
For always-on background sessions, remote control, and headless servers, see Daemon.
Attach to an existing session
If a supported session is already running, you can reattach to that same live session from a terminal:
happier attach
happier attach <session-id>This is the main “start in the app, continue in the terminal” workflow. In a supported TTY, happier attach opens an interactive picker of active sessions:
- local attachable sessions are selectable immediately
- active but non-attachable sessions stay visible but disabled with a reason
- remote-capable provider sessions are marked as remote; press
Pin the picker to run a reachability check before attaching
If the session is stopped, use happier resume instead.
Important notes:
- tmux and other terminal-host attach flows work only for sessions that are still owned by the current machine.
- You must target the same Happier account/server profile that owns the session.
Attach strategy depends on the provider and terminal host:
- Terminal-hosted sessions reconnect to their existing
tmux, zellij, or Herdr terminal. - OpenCode uses a provider-native attach flow for server-backed sessions.
For OpenCode, the supported reattach command is still happier attach <session-id>. Do not rely on a raw vendor opencode attach ... command as your normal Happier workflow.
Supported attach styles include:
- tmux-backed sessions on machines where tmux is enabled
- zellij- and Herdr-hosted sessions on supported macOS and Linux machines
- Windows Terminal or Console hosted sessions on Windows
- provider-native attach for supported provider sessions such as OpenCode
For the full workflow, see Features → Attach to a running session.
In current development builds, happier herdr opens Herdr from the terminal. Happier requires a stable Herdr release, version 0.9.2 or newer, for both the executable and the running server. If you are already inside a Herdr pane, use Herdr's pane controls instead of starting a nested client.
In current development builds, Herdr's saved Happier resume command retains the original local Happier home and relay profile. It also uses the session's release-channel command (happier, hprev, or hdev), rather than always invoking happier.
In current development builds, happier resume <session-id> can reopen a preserved local Herdr pane after its controller has stopped, including after a Herdr restart. Opening the pane starts its saved resume command; it is not confirmation that the Happier session has reconnected. Live or unverified controllers keep the existing admission checks. A session resumed in a foreground shell is borrowed: stopping Happier preserves that pane rather than assuming its former ownership.
If a shared controller survives the Herdr restart, attaching inside its restored
pane can rebind a verified native client to that same conversation with managed
status. Detach terminal then closes only the native client and preserves the
restored shell and pane. The saved release-channel command must be available in
the shell; otherwise invoke that CLI's attach <session-id> there yourself.
Cold restoration verifies the original Herdr namespace before starting it; it never substitutes another server with the same name. If a stopped server uses a custom socket whose saved namespace cannot be located, reopen that original server and retry. Attachment to an already-running custom socket remains supported.
Continue a session
happier resume attaches to a running, attachable session or resumes a stopped, vendor-resumable session.
Interactive selector
happier resumeIn a supported TTY, Happier shows running sessions you can attach to and stopped sessions you can resume in one picker.
Resume by id
happier resume <session-id>You can use a full session id or an unambiguous prefix.
Important behavior:
- resume is strict: if the provider resume fails, Happier errors instead of starting a fresh session
- active sessions use the existing attach flow; an attachment failure does not launch a second agent
- archived sessions cannot be continued
- for stopped sessions, the command restores the working directory before launching the agent again
For the full user guide and the meaning of “resumable”, see Features → Resume inactive sessions.
List sessions
Use:
happier session listThe default output is a table that includes session id, agent, recent activity, active state, resume state, title, and path.
Useful variants:
happier session list --resumable
happier session list --plain
happier session list --json--resumablefilters to sessions that can currently be resumed--plainrestores the older one-line output--jsonis for scripting
Session control (non-interactive)
The happier session ... command group is the non-interactive surface for creating and controlling sessions.
Deep reference: CLI sessions.
Create a session (scriptable)
happier session create --title "My session" --message "Hello"Optional targeting:
happier session create --path /path/to/repo --backend <backend-target-key> --tag <tag>--backend expects a backend target key (not a short name). Common forms:
# Built-in catalog agent
happier session create --backend "agent:<agent-id>"
# ACP backend target (e.g. opencode, gemini, etc)
happier session create --backend "acpBackend:<backend-id>"Send messages
happier session send <session-id> "ping"Wait for an agent response (useful for scripts; can time out if the agent is busy/offline):
happier session send <session-id> "ping" --wait --timeout 60Status, stop, archive
happier session status <session-id>
happier session history <session-id>
happier session wait <session-id> --timeout 60
happier session stop <session-id>
happier session archive <session-id>
happier session unarchive <session-id>Set title / model / permission mode
happier session set-title <session-id> "New title"
happier session set-model <session-id> <model-id>
happier session set-permission-mode <session-id> <mode>Prefer read_only, default, auto, or yolo for <mode>. Older aliases such as read-only, safe-yolo, workspace_write, acceptEdits, and bypassPermissions remain accepted. Use --json to script and see the compatible normalized permissionMode value.
Session id prefixes
Commands that accept <session-id-or-prefix> allow an unambiguous prefix of a full session id.
If the prefix matches multiple sessions, the command fails with candidates.
Approvals from CLI commands
Some actions can be configured as approval-gated on the CLI surface.
In that case, the CLI command does not execute immediately; it creates an approval request instead. Use the app’s Inbox to review/approve/deny and see the final execution result:
For advanced automation, approvals can also be decided through the generic action executor:
happier session actions execute <session-id> approval.request.decide --input-json '{"artifactId":"<id>","decision":"approve"}' --jsonAction catalog from the CLI
You can inspect and execute Happier actions directly:
happier session actions list
happier session actions describe <action-id>
happier session actions execute <session-id> <action-id> --input-json '<json>'Execution runs (review / plan / delegate / voice agent)
Execution runs are the structured “run” layer for multi-step flows in a session (for example: start a review run, then send follow-up messages, then stop).
happier session run list <session-id>
happier session run start <session-id> --intent <intent> --backend <backend-target-key> --permission-mode auto
happier session run send <session-id> <run-id> "message"
happier session run stop <session-id> <run-id>Execution-run permission input uses the same preferred read_only, default,
auto, and yolo vocabulary. Compatible responses and stored run state retain
the established read_only / workspace_write wire projection.
External MCP control surface
If you want an MCP host (editor/agent) to control Happier sessions and actions, run the external MCP server:
happier mcp servehappier mcp start is accepted as a compatibility alias, but serve is the canonical command name in the docs and CLI help.
Guide: Happier MCP (external)
Backend profiles
The CLI supports backend profiles for session starts and profile discovery:
happier profiles list
happier claude --profile deepseek
happier codex --profile openaiFor the full guide, see Features → Profiles.
Happier tools
The CLI also exposes the unified Happier tools surface directly.
Use it when you want to:
- inspect which built-in Happier tools are currently available
- inspect which custom MCP tools resolve in the current machine/workspace context
- call one of those tools directly from the terminal
List tools
happier tools listOptional:
happier tools list --directory /path/to/projectThis lists:
- built-in Happier tools
- custom MCP tools that resolve for the selected directory and machine
list does not require a session id.
Call a tool
happier tools call --session-id <session-id> --source happier --tool action_spec_search --args-json '{"query":"plan mode","limit":5}'Examples:
--source happier --tool review_start--source happier --tool subagents_plan_start--source happier --tool action_spec_get--source happier --tool action_options_resolve--source playwright --tool browser_navigate
Use the Happier built-in discovery tools when you do not know the exact action id or valid option values yet.
For the broader product model, see Happier tools & actions.
Multi-server reference
For full multi-server and multi-daemon guidance, see Features → Multi-server.