# CLI reference

Source: https://pushary.com/docs/agents/reference/cli
Last updated: 2026-10-24

> Every command and flag in the Pushary CLI, from setup and doctor to mode, clean and daemon, with one working example for each command.

The Pushary CLI connects your AI agents to your phone. It installs the hooks that hold risky tool calls for your approval, pairs the Pushary phone app, and checks that everything works. Run it with `npx` to get the latest version with nothing to install first. It is published on npm as [`pushary`](https://www.npmjs.com/package/pushary), and the same build as `@pushary/agent-hooks`.

What changed in each release is in the [CLI changelog](/docs/agents/reference/cli-changelog).

```bash
npx pushary@latest <command>
```

On Windows PowerShell, type `npx.cmd pushary@latest <command>`. Setup also installs the CLI globally, so `pushary <command>` works after your first setup. The CLI needs Node.js 20.17+, 22.13+, 23.5+ or 24+. Run `npx pushary@latest --help` for the list, or `npx pushary@latest <command> --help` for one command.

## Commands [#commands]

| Command                       | What it does                                                                               |
| ----------------------------- | ------------------------------------------------------------------------------------------ |
| [`setup`](#setup)             | Set up your agents with Pushary and pair your phone                                        |
| [`login`](#login)             | Sign in from this terminal through your browser, no key to copy                            |
| [`pair`](#pair)               | Pair a phone without running setup again. Also answers to `connect`                        |
| [`status`](#status)           | Show which key is in use, whether pushary.com accepts it, and what can receive an approval |
| [`doctor`](#doctor)           | Check every configured agent, the connection and a test push                               |
| [`sign-out`](#sign-out)       | Remove the key this machine stores. Also answers to `logout`                               |
| [`mode`](#mode)               | Choose where approval requests appear                                                      |
| [`wait`](#wait)               | Show or set how long approvals wait for your phone                                         |
| [`suggestions`](#suggestions) | List rules mined from your own approvals, and accept one                                   |
| [`stats`](#stats)             | Count the approval moments your agents hit while Pushary was not connected                 |
| [`disconnect`](#disconnect)   | Turn off Pushary for one agent                                                             |
| [`clean`](#clean)             | Remove Pushary from this machine                                                           |
| [`upgrade`](#upgrade)         | Update the globally installed hooks                                                        |
| [`claude`](#claude)           | Run Claude Code through Pushary so your phone can reach it even when idle                  |
| [`daemon`](#daemon)           | Keep this machine reachable so your phone can start a new session                          |
| [`cowork`](#cowork)           | Show the setup for Claude Desktop and Cowork with the Pushary connector                    |
| [`bell`](#bell)               | Ring a free local bell when an agent finishes or needs you. No account or network          |
| [`transcripts`](#transcripts) | Show or re-trust the keys this machine encrypts transcripts to                             |

`pushary hook` also exists. It is the PreToolUse hook the installed agents run, reading the tool call on stdin and writing the verdict on stdout. You do not run it by hand.

## Set up and connect [#set-up-and-connect]

### setup [#setup]

Sets up Claude Code, Codex, Gemini CLI, Hermes, Cursor, VS Code, OpenCode, fx or another [supported agent](/docs/agents/supported-agents), then pairs your phone and sends a test question.

```bash
npx pushary@latest setup
```

| Flag                      | What it does                                                                                                                                                                   |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--agents <list>`         | Set up only these agents, comma separated, such as `--agents claude_code,codex`. `auto` sets up every agent it finds without asking. `none` saves the key and sets up no agent |
| `--agents cowork`         | Show the Claude Desktop and Cowork connector setup without installing CLI hooks                                                                                                |
| `--key <pk_xxx.xxx>`      | Use this API key instead of pairing or signing in. The key shows in your process list                                                                                          |
| `--key-stdin`             | Read the key from the first line of stdin, so it never appears in argv or shell history. Use this in CI                                                                        |
| `--yes`, `-y`             | Accept every default and ask nothing. Implies `--agents auto` unless you pass `--agents`                                                                                       |
| `--connect app`           | Pair the Pushary phone app, with no key to paste. This is the default on a machine with no key. Typed on a machine that has a key, it pairs anyway and mints a new key         |
| `--connect none`          | Skip pairing a phone. Same as `--skip-phone`                                                                                                                                   |
| `--skip-phone`            | Skip pairing a phone                                                                                                                                                           |
| `--control auto\|on\|off` | Manage starting sessions from your phone automatically (default), require it, or turn off its background service                                                               |
| `--transcripts on\|off`   | Turn encrypted transcript sync on or off for this machine                                                                                                                      |
| `--take-over-hooks`       | Replace hooks the Pushary Mac app owns with the CLI's. Without it, the app's wiring is kept                                                                                    |
| `--verify roundtrip`      | Send a real question and wait for you to answer it. The default when someone is at the terminal                                                                                |
| `--verify push`           | Only prove a notification was delivered. Automatic when nobody is at the terminal                                                                                              |
| `--verify none`           | Skip the final check                                                                                                                                                           |
| `--dry-run`               | Print what would be written and change nothing                                                                                                                                 |
| `--json`                  | Print one machine-readable object instead of the report                                                                                                                        |

Agent ids for `--agents`: `claude_code`, `codex`, `gemini_cli`, `hermes`, `cursor`, `vscode`, `opencode`, `fx`, `cline`, `qwen_code`, `codebuddy`, `qoder`, `droid`, `devin`, `antigravity_cli`, `custom`.

On a machine that already has a key, a plain `setup` names the account behind that key, asks `Continue as @workspace?` at a terminal, and pairs the app if you answer No. To pair the phone app on such a machine directly, run `npx pushary@latest setup --connect app`.

Setup without a terminal on stdin takes the defaults instead of waiting for a keypress. In CI with no key it stops with "No API key, and setup does not pair in CI." Pass the key on stdin:

```bash
npx pushary@latest setup --key-stdin --agents claude_code --yes < key.txt
```

### login [#login]

Signs in from this terminal. The terminal prints a code, your browser approves it, and the key arrives sealed to this machine. Like setup, it saves the transcript sync choice: `PUSHARY_TRANSCRIPTS` when set, else this machine's saved choice, else on. `transcripts off` turns it off.

```bash
npx pushary@latest login
```

| Flag           | What it does                                                        |
| -------------- | ------------------------------------------------------------------- |
| `--with-token` | Read a key from stdin instead, for a machine with no browser nearby |
| `--no-browser` | Print the link instead of opening a browser                         |
| `--force`      | Replace a key this machine already has                              |
| `--json`       | Print the result as one object                                      |

### pair [#pair]

Pairs a phone without running setup again. `--app` pairs the Pushary phone app. Without it, or with `--browser`, you approve in a browser tab. Also answers to `connect`.

```bash
npx pushary@latest pair --app
```

### status [#status]

Shows one screen: which key is in use, whether pushary.com accepts it, and what can receive an approval. `--json` prints it as one object, and `--devices` also lists the machines registered to your site.

```bash
npx pushary@latest status --devices
```

### doctor [#doctor]

Checks each configured agent, confirms the MCP server is reachable, discovers the tools, and sends a real test push to your phone. At a terminal it then offers a synthetic question and answer round trip.

```bash
npx pushary@latest doctor
```

| Flag                                                  | What it does                                                                            |
| ----------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `--roundtrip`                                         | Always send a synthetic question and report the answer. It does not test agent hooks    |
| `--no-push`                                           | Run every check without waking a device                                                 |
| `--json`                                              | Print every check as one object. Skips the test push unless you also pass `--roundtrip` |
| `--bundle`                                            | Write a redacted diagnostics file to attach to a support thread                         |
| `--activation claude_code --activation-target <path>` | Read the recorded evidence for one scratch file. Sends no test question                 |

The test push is also skipped when stdout is not a terminal. See [Troubleshooting](/docs/agents/reference/troubleshooting) for what each failed check means.

### sign-out [#sign-out]

Removes the key this machine stores and says what it does not remove. `--revoke` also revokes the key on pushary.com, so it stops working everywhere, but only a key this CLI created when you signed in with `login`, `setup` or the pairing QR. A key you passed with `--key` or `login --with-token`, the Mac app's key, a different key in an `export PUSHARY_API_KEY=...` line, and a key saved before the CLI began recording which keys it created are removed here and not revoked, because the Mac app or another machine may still use them. sign-out says which keys it revoked and which it only removed. `--json` prints the result as one object. Also answers to `logout`.

```bash
npx pushary@latest sign-out --revoke
```

## Approvals [#approvals]

### mode [#mode]

Chooses where approval requests appear for the whole site.

```bash
npx pushary@latest mode push_only --for 30m
```

| Mode            | Label      | What happens                                                                                                                                                                                                                            |
| --------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `push_first`    | When away  | Ask your phone only when you are away, or when Pushary cannot tell you are at the agent's machine. While you are there, the decision stays with the agent or the Mac app. An agent with no prompt of its own asks your phone every time |
| `push_only`     | Always     | Ask your phone for each approval, even while you are there, then apply your policy's timeout action                                                                                                                                     |
| `notify_only`   | Alert only | Alert your phone that approval is needed, then decide in the agent's own prompt. `updates-only` works too                                                                                                                               |
| `terminal_only` | In agent   | No approval alert. The agent's own prompt decides                                                                                                                                                                                       |

With `--for <n>m` or `--for <n>h`, the mode is a temporary override of up to 24 hours. Without `--for`, it changes your site's default mode until you change it again. `mode status` shows the current override, and `mode clear` goes back to your per-tool rules. See [Permission policies](/docs/agents/policies) for how modes and rules interact.

<Callout type="warn">
  Changing the mode, the wait window or a suggestion needs a full-access key: create a new key with **Create Key** at [pushary.com/dashboard/agent/settings](https://pushary.com/dashboard/agent/settings). Keys that Pushary creates for your computer when you set it up run approvals and notifications, not account settings. With one of those, the command says so and tells you where to change it instead: the mode in the Pushary app or on the dashboard at [pushary.com/dashboard/agent/policies](https://pushary.com/dashboard/agent/policies), the wait window and suggestions on the dashboard at the same address. A temporary mode from `--for` ends on its own, when you pick a mode in the Pushary app, or with `mode clear` and a full-access key. An edit on Policies does not end it.
</Callout>

### wait [#wait]

Shows or sets the push window: how many seconds When away waits for your phone before it hands the decision back to the agent's prompt. Takes `0` to `300`, `status` for the whole ladder, or `clear` to reset it to 20 seconds.

```bash
npx pushary@latest wait 45
```

### suggestions [#suggestions]

Lists the rules Pushary mined from your own approvals. `accept <id>` turns one into an always-allow rule.

```bash
npx pushary@latest suggestions accept <id>
```

### stats [#stats]

Counts the approval moments your agents hit in the last 7 days while Pushary was not connected, by tool. It reads a local count and needs no key.

```bash
npx pushary@latest stats
```

## Agents and machines [#agents-and-machines]

### disconnect [#disconnect]

Turns off Pushary for one agent and leaves the others alone. Takes one of `claude`, `codex`, `gemini`, `cursor`, `opencode`, `qwen`, `codebuddy`, `qoder`, `droid`, `devin`, `antigravity` or `fx`. Setup ids such as `claude_code` and `gemini_cli` work too. If the Pushary Mac app is installed, it leaves that agent off until you connect it again.

```bash
npx pushary@latest disconnect codex
```

### clean [#clean]

Removes Pushary from this machine.

```bash
npx pushary@latest clean --dry-run      # list what would go, change nothing
npx pushary@latest clean                # remove what the CLI set up
npx pushary@latest clean --everything   # and what the Mac app set up
```

| Flag           | What it does                                                                        |
| -------------- | ----------------------------------------------------------------------------------- |
| `--dry-run`    | Print every file it would change and every command it would run. Nothing is written |
| `--yes`, `-y`  | Skip the confirmation. Needed in a non-interactive shell                            |
| `--everything` | Also revoke the key this CLI created, and remove what the Pushary Mac app set up    |

A plain `clean` removes what the CLI set up: its hooks, MCP entries, skills and plugins in every agent, the key export in your shell profile, the background service, and `~/.pushary`. If the Mac app is installed, `clean` leaves the app's setup alone so the app keeps working, and tells you so at the end. If you already deleted the app, `clean` removes what it left behind.

`--everything` removes both. Before it removes the CLI's key from this computer, it revokes it on pushary.com, but only a key this CLI created when you signed in with `login`, `setup` or the pairing QR. Any other key in `~/.pushary/config.json` or in an `export PUSHARY_API_KEY=...` line in your shell profile is removed and not revoked: the Mac app's key, a key you passed with `--key`, and a key saved before the CLI began recording which keys it created. The Mac app or another machine may still use it, so revoke it in your agent settings if nothing does. A key that is only in the `PUSHARY_API_KEY` environment variable is left alone, because Pushary did not write it. It says whether each key was revoked or only removed. If pushary.com cannot be reached, the clean still finishes and tells you where to revoke the key yourself. With `--dry-run` it only lists the keys it would revoke.

On a Mac, `--everything` quits the app first, because a running app writes its setup back, and then also removes:

* the app's keychain items, including keys still waiting to be revoked
* its preferences, caches and saved window state
* the editor extension it installs in Cursor and VS Code
* the Pushary skill's registration in `~/.agents`

The app itself stays installed. Drag `Pushary.app` to the Trash to finish.

If anything could not be removed, `clean` says what and exits with a non-zero code. Fix it and run `clean` again. If it keeps failing, send the output to [business@pushary.com](mailto:business@pushary.com).

#### Start over with a different account [#start-over-with-a-different-account]

To make this machine behave like one that never had Pushary:

1. Run `npx pushary@latest clean --everything`.
2. Run `unset PUSHARY_API_KEY`, or open a new terminal. `clean` cannot change the terminal it runs in, and `setup` reuses a key it finds there.
3. Drag `Pushary.app` to the Trash.
4. Sign out at pushary.com in your browser. The app and `pushary login` both sign in through your browser, so they would pick the old account back up.
5. Install the app again, or run `setup`.

What `clean` does not touch:

* Your agents' own folders, such as `~/.claude` and `~/.codex`. Only the Pushary entries inside them are removed, including from Claude Code's backups of `~/.claude.json`.
* Your Pushary account. A plain `clean` revokes no key, and other keys and devices you created stay listed in your agent settings until you revoke them there.
* Launch at login. macOS lets only the app itself remove that, so turn it off in the app first, or in System Settings > General > Login Items.

### upgrade [#upgrade]

Updates the globally installed hooks to the latest version, then refreshes every agent that is already set up: its hooks, the Pushary instructions in its instruction file and, for Claude Code, Codex, Gemini CLI, Cursor and VS Code, its Pushary server entry. It never adds an agent or instructions that are not already there, and it leaves a read-only instruction file as it is. Pushary also updates itself in the background once a day when an agent session starts, or when fx starts the Pushary server, within the same major version. `--auto=off` stops that, and `--auto=on` turns it back on.

```bash
npx pushary@latest upgrade
```

### claude [#claude]

Runs Claude Code through Pushary, so your phone can send it an instruction even when the agent is idle. Ctrl-] takes the terminal back. `--remote` starts it headless so you drive it from your phone, and `-p <prompt>` gives it a first prompt.

```bash
pushary claude --remote -p "start the refactor"
```

### daemon [#daemon]

Keeps this machine reachable so your phone can start a new agent session. `install` sets it up as a per-user service that restarts on login and on failure. `start`, `stop`, `restart`, `status` and `uninstall` control that service. A bare `pushary daemon` runs in the foreground for diagnostics.

```bash
pushary daemon install
```

### cowork [#cowork]

Shows how to set up Claude Desktop and Cowork with the Pushary connector. `--open` also opens the guide in your browser, `--instructions` prints standing instructions to paste into Cowork, `--skill` prints the Cowork `SKILL.md` to upload, and `--json` prints the steps as JSON.

```bash
npx pushary@latest cowork --instructions
```

### bell [#bell]

A separate, smaller tool. It rings a bell on this machine when Claude Code finishes or needs you. It needs no account, no key and no network, and it cannot reach your phone. Run it with no flags to turn it on. `--test` rings once, `--status` says whether it is on, and `--off` removes it.

```bash
npx pushary@latest bell --test
```

### transcripts [#transcripts]

`on` and `off` turn encrypted transcript sync on or off for this machine. With it on, your phone shows a session's conversation, not only its summary. Codex and Gemini sessions already running from your phone keep syncing until they end. `PUSHARY_TRANSCRIPTS` in an agent's environment overrides the saved choice, and Pushary for Mac has its own switch for the sessions it runs.

```bash
npx pushary@latest transcripts on
```

With no subcommand, or `status`, it shows whether sync is on and the keys this machine encrypts transcripts to, with their fingerprints. Sync stops if the phone key or the recovery key changes. Compare the fingerprint with the app under Settings, then accept the new keys with `trust --rotate`.

```bash
npx pushary@latest transcripts trust --rotate
```

## Environment variables [#environment-variables]

| Variable                                | What it does                                                                                                                                                                               |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PUSHARY_API_KEY`                       | Your API key. The CLI also saves the key to `~/.pushary/config.json`, so this is optional after setup. When both are set, the environment variable wins and the CLI warns that they differ |
| `PUSHARY_SUPPRESS_KEY_DRIFT_WARNING`    | Set to `1` to silence that warning when the difference is deliberate                                                                                                                       |
| `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY` | Commands you run with `pushary` honor your proxy settings                                                                                                                                  |
| `PUSHARY_RESPECT_PERMISSION_MODE`       | Set to `0` to gate tool calls in every Claude Code and Codex permission mode, including plan, auto and acceptEdits                                                                         |
| `PUSHARY_DEFER_BYPASS`                  | Set to `1` to leave calls in `bypassPermissions` mode to the agent too                                                                                                                     |

See [Get your API key](/docs/agents/api-key) for where a key comes from.

## Next steps [#next-steps]

<Cards>
  <Card title="Run the quickstart" description="Set up your agents and your phone with one command." href="/docs/agents/quickstart" />

  <Card title="Fix a problem" description="What to do when your phone does not buzz, the agent does not ask, or doctor reports a failure." href="/docs/agents/reference/troubleshooting" />
</Cards>