receipt binary. The in-repo developer CLI is a different program with different verbs — see The developer CLI.
Conventions that apply everywhere
Scripts should parse the
--json forms rather than the text output. setup --json and login --json also suppress the Step 1 of 2 progress lines; connect status and connect <provider> still print them when a fresh sign-in happens first.Entry points and help
--version and -V are recognised only as the sole argument. receipt tools --help, receipt mcp --help and receipt workspace --help never print help either — their handlers are matched before the help check, so each runs its default subcommand or fails with a not-signed-in error instead. The parsing rules give the dispatch order and the exact messages.
Session: setup, login, logout, doctor
login takes an optional positional target, so receipt login local and receipt login --target local are the same. doctor does not: a positional there is ignored, and only --target counts. logout reads no flags at all — it always acts on whichever session is active.
logout with nothing to remove still exits 0, and so does login --no-login, which prints receipt login: skipped (disabled by setup flag). doctor exits 1 when its ok is false or the endpoint cannot be resolved. Full behaviour: Sign in and Diagnosing your setup.
Workspaces
current is the default subcommand. Every one of these requires a saved session — there is no environment fallback — and each <workspace> selector matches case-insensitively on id, slug or name.
use is the only command you run to replace the session’s token; current, list and identity also mint one, but only when the workspace saved in the session no longer exists. Anything else in the list is receipt workspace supports list, current, create, rename, use, and delete. See Switching workspaces.
Tools
Output is always JSON:
ok, the result fields, and a workspace object naming the workspace the session is bound to. A provider-side failure on an aggregate call comes back as a normal MCP result carrying isError, so ok: true means the gateway answered, not that the provider succeeded. Anything other than the three subcommands fails with receipt tools supports list, describe, and call.
Identity here resolves the saved session first, and falls back to RECEIPT_CONNECT_TOKEN with a gateway and organization id from the environment. That is the opposite order from the automation surface below. See Calling tools and wiring MCP clients.
MCP clients
status is the default subcommand and codex the default client. Identity is resolved before the subcommand runs, so config, status, install and remove all need a saved session; only serve accepts an environment token. install, status and remove support Codex only — anything else gets receipt mcp install/status/remove currently supports codex; use 'receipt mcp config --client generic' for other clients.
Every generated config is checked before it is written: it is refused with refusing to install an MCP client config containing the Receipt session token or refusing to install an MCP client config containing credential material rather than emitting a credential. install backs up the existing Codex config first and restores it if the client command fails. Unknown subcommands give receipt mcp supports config, install, status, remove, and serve.
serve is the stdio bridge: one JSON-RPC message per stdin line, forwarded to the gateway’s aggregate MCP endpoint with the session token, one response per line. It reads the session once at start, so restart the client after receipt workspace use.
Connections
Once you pick a connector, onboarding hands off to the same code as
receipt connect <connector-id>, so the <connector-id> flags apply to the interactive flow too.
These commands reuse the session saved by setup, and if the gateway rejects that token they print Saved Receipt session was rejected by the gateway; signing in again., sign in once and retry. They never read RECEIPT_CONNECT_TOKEN.
Endings you will see: receipt connect: <provider> connection '<name>' is ready for server jobs., Timed out waiting for <provider> connection., receipt connect status: no server-side connections configured, receipt connect disconnect: removed <provider>:<name> or … no <provider>:<name> connection found. Bare disconnect targets aws:default, so pass --provider unless that is what you meant.
Pick a connector by id (
receipt connect gcp) rather than by number in the menu. A numbered pick returns the display label, and only labels that also happen to be a connector alias resolve; the rest fail with unsupported Receipt Connect onboarding choice: <Label>. receipt connect relay is gone entirely and always fails.Automation surface
RECEIPT_CONNECT_TOKEN is unset — and then only if the gateway is the same host the session belongs to. Setting the token without a gateway variable fails with Receipt Connect gateway is unavailable; run 'receipt setup' or set RECEIPT_CONNECT_TOKEN even when a session exists.
list prints Current connections: with one <provider>:<name> <status> line each, or Current connections: none; --json gives ok and connections. tools and call print the gateway’s JSON verbatim. Validation happens before any request: receipt connect tools requires a connection id or provider:name, receipt connect call requires --path beginning with /, receipt connect call is read-only and supports GET only, --json must contain valid JSON, --json must contain a JSON object. There is no sign-in retry on this path.
Import and observe
clauden or claude-code; anything else fails with import source is required. Supported sources: clauden, claude-code, or observe source is required. Supported sources: clauden, claude-code for observe. observe is import with following forced on. Service actions are clauden only — observe claude-code supports live file tailing only; use observe clauden install for proxy service install.
Both always emit JSON and ignore
--json as a switch: ok, source, importId, stream, sourcePath, mode, follow, storage, an optional cloud object, and counts. Service actions return ok, action, platform, label, serviceFile, dataDir, eventLog, mode and, when the service was started, active.
Exit codes in practice
0 and 1 are the whole vocabulary. A device-login failure, a rate limit, a rejected token, a validation error and a failing doctor all exit 1 with the message on stderr. Commands that do nothing still succeed: receipt logout with no session, receipt login --no-login, and receipt mcp remove codex when the entry was already absent.
A code you did not expect did not come from the CLI. The one you are likely to meet is 137 on macOS with no output: the operating system killed the binary before it ran, almost always because that copy is quarantined — read it as a broken copy rather than a CLI error, and reinstall with the published installer. Exit codes and the environment variables that steer all of the above are collected in Environment and exit codes; the message-by-message fixes, that one included, are in CLI troubleshooting.
Next step: look up an environment variable or an exit code.