Running it
From a source checkout: pnpm dev <command>.
From the installed app:
alias inboxminder='"/Applications/InboxMinder.app/Contents/Resources/runtime/bin/node" "/Applications/InboxMinder.app/Contents/Resources/runtime/cli/dist/cli.js"'
Put that line in ~/.zshrc to keep it. inboxminder --help lists every command; inboxminder <command> --help the options.
Global option, placed before the command: --profile <name> runs against an isolated profile. INBOXMINDER_PROFILE=<name> does the same for scripts and is how the agent's plist selects its profile.
Conventions:
- Secrets are never passed as arguments.
set-keyandlicense activateprompt, or read from stdin with--stdin. - Every read command takes
--json. A failure is one{"error": …}object with a non-zero exit. classifyanddraftare previews: they create nothing and label nothing.
Setup and lifecycle
| Command | What it does |
|---|---|
init | Interactive setup: provider, model, keys to the Keychain, knowledge sources, Gmail client, then an offer to go live. Keeps Keychain secrets if a config already exists |
init --answers-stdin [--force] | Non-interactive: a JSON answers document on stdin writes config.toml (secrets excluded; store them with set-key --stdin). --force overwrites an existing file |
set-key <name> [--stdin] | Store or rotate a secret: anthropic, openai, google, openai-compatible, notion, linear, slack, gmail-client-id, gmail-client-secret, license, or any MCP secret name. Restart the agent afterwards (agent install) so it picks up the new value |
auth | Browser OAuth flow for Gmail. Safe to repeat; re-run it when the menu bar says Gmail needs re-authorization |
index [--source <name>] [--full] | Pull sources and (re)build the local index. Incremental by default; --source limits to one connector (files, llmstxt, github, notion, linear, slack, sent, notes, answers); --full refetches everything but still skips re-embedding unchanged content |
up | Go live: authorize Gmail if needed, build the index, install the agent. Idempotent |
watch | Run the agent in the foreground (what the launchd agent runs) |
agent install | Render the launchd plist and (re)start the agent. Also the way to restart it after a settings or key change |
agent uninstall | Remove the launchd agent. Data and config stay |
agent status | Installed, running, pid, last tick, paused; warns when stalled |
agent pause / agent resume | Stop and restart watching without unloading the agent. Mail arriving while paused is handled on resume (unless paused beyond about a week, when Gmail expires the cursor) |
license activate [key] [--stdin] | Bind this Mac to a license key and store it in the Keychain |
license status [--json] | Licensed, grace days left, expiry; or why not |
license deactivate | Free the seat for another Mac |
profiles | List the default profile and every one under the data dir's profiles/, with agent state |
Previews
| Command | What it does |
|---|---|
classify <messageId> | The verdict for one message: reply-worthy, category, urgent. Labels nothing |
draft <messageId> | Verdict plus the draft it would write, plus docs-gap and ticket verdicts when those features are on. Creates nothing |
The message id is the long hex string in a Gmail message URL after #inbox/, or in Show original. draft is the tuning loop: change an instruction, a note or a source, re-run, compare.
Configuration surfaces
| Command | What it does |
|---|---|
config get-sources | The connectors section as JSON |
config set-sources --stdin | Replace the connectors section from a JSON document on stdin. Every other key in the file is preserved |
config get-settings | The curated behavior settings (what Preferences shows) as JSON |
config set-settings --stdin | Merge a settings document into config.toml. Restart the agent to apply |
Provider, model, embedding dimensions, repoPath, teamId and the [mcp] section are hand edits in the file by design. See Configuration.
Reading what it did
| Command | What it does |
|---|---|
drafts list [--limit N] | Recent drafts, newest first (max 500) |
drafts show <id> | One draft with the passages and sent emails it drew on |
knowledge docs [--source X] | Indexed documents (sent mail is under voice) |
knowledge passages <docKey> | Every passage of one document, in order |
knowledge search --stdin [--limit N] | What a draft would retrieve for a question read from stdin (max 20) |
knowledge exclude <docKeys...> | Stop using documents (or sent emails) in drafts; survives re-indexing |
knowledge include <docKeys...> | Use excluded documents again (each returns on its next index pull) |
voice list | Every indexed sent email, newest first, with skipped ones and their reasons |
voice audit [--limit N] | Dry run: which recent sent emails look automated, and why. Writes nothing |
notes list / notes get <slug> | Your notes |
notes save --stdin | Save a note (markdown on stdin; the first heading is the title) and index it at once |
notes delete <slug> | Delete a note and remove it from the index |
written list | Docs pages, suggested answers and Linear tickets the app produced |
stats [--days N] | Day-by-day counts: labeled, drafts, urgent, handled (max 366 days) |
linear status / linear teams / linear members | Is a Linear key connected and as whom; the teams; workspace members for hand-off labels |
polish --stdin | Polish text you wrote: in on stdin, out on stdout. --json wraps it |
Examples
# preview a draft for one message, creating nothing inboxminder draft 18c2f4a9e1b07d3c # what would a draft find for this question? echo "how long do refunds take?" | inboxminder knowledge search --stdin # polish the clipboard in your tone pbpaste | inboxminder polish --stdin | pbcopy # the last hundred log lines, for support tail -n 100 ~/.inboxminder/logs/watch.log | pbcopy # a second mailbox, fully separate inboxminder --profile support init inboxminder --profile support up