CLI reference
garage command groups, flags, and environment variables.
The garage CLI is the canonical shell client for the API. Every command also
accepts --json for machine-readable output; JSON is the default when
stdout is not a TTY.
Global flags
Recognised anywhere in argv (before or after the subcommand):
| Flag | Description |
|---|---|
--repo <name> |
Override the active repo for this invocation |
--json |
Machine-readable JSON on stdout, events as NDJSON on stderr |
| Env var | Description |
|---|---|
GARAGE_API_KEY |
Overrides the stored auth.json key (takes precedence) |
GARAGE_SERVER_URL |
API base URL (default: https://api.thegarage.sh) |
GARAGE_REPO |
Default repo if no --repo is passed |
GARAGE_ANON_ID |
Overrides the stored anonymous repo identifier |
Repo names are bare — the server resolves them against your active org.
There is no per-command org override; switch the active org with
garage org switch <slug>.
garage init
Authenticate the CLI, set up your active org, and optionally link the current directory to a garage repo. An organization is auto-created at signup. Idempotent — re-running surfaces current state without destructive changes.
garage init
garage init --no-link
Behavior:
- no auth → device-flow login
- active org set → report it
- no active org yet → activate the account’s oldest org
- inside a git repo → offer to write
.garage/config.json(--no-linkskips)
garage whoami
Print the active authentication, organization, and resolved repo context. Exits 0 even when unauthenticated so agents can use it as a probe.
garage whoami
garage auth
| Subcommand | Purpose |
|---|---|
garage auth login |
Start the device-authorization flow and store a grg_ API key |
garage auth logout |
Delete the stored credential and revoke the key |
garage auth token |
Print the active API key (or --header for curl) |
garage auth status |
Show which credential is active (env vs file) |
Bare garage auth is a back-compat alias for garage auth login.
# Print the active key for scripting
export GARAGE_API_KEY=$(garage auth token)
# Or use it directly with curl against the oRPC endpoint
curl -X POST -H "$(garage auth token --header)" \
https://api.thegarage.sh/api/rpc/health/ping
garage org
An organization is auto-created when you sign up — its name is derived from
your display name or email (renamable later). Org slugs are opaque,
server-minted handles (org-…): copy them from garage org list, don’t
invent them.
| Subcommand | Purpose |
|---|---|
garage org list |
List organizations you belong to |
garage org current |
Print the active organization |
garage org switch <slug> |
Switch the active organization (slug from list) |
garage org create [--name] |
Create an organization (slug is server-minted) |
garage org delete <slug> |
Delete an organization you own |
garage repos
| Subcommand | Purpose |
|---|---|
garage repos create |
Create a new repo |
garage repos import |
Import a repo from GitHub |
garage repos get |
Show a repo |
garage repos list |
List repos in the current org |
garage repos delete |
Delete a repo |
garage repos list
garage repos create hello-world --description "..." --default-branch main
garage repos import site --from https://github.com/acme/site.git
garage repos delete hello-world --yes
For ephemeral, no-auth repos, see garage anon.
garage anon
Manage anonymous, ephemeral repos that don’t require authentication.
Identity is a local anonId stored in ~/.config/garage/anon.json (or set
via GARAGE_ANON_ID). Anon repos are owned by that anonId and expire
after the TTL chosen at creation time.
| Subcommand | Purpose |
|---|---|
garage anon create |
Create an ephemeral anonymous repo |
garage anon list |
List anon repos owned by this anonId |
garage anon get |
Show details of an anon repo |
garage anon clone |
Clone an anon repo (mints a read token + wires git credentials) |
garage anon share |
Share an anon repo with a human or an agent |
garage anon delete |
Delete an anon repo |
garage anon whoami |
Print the local anonId and its source (env vs store) |
garage anon create --ttl 6h
garage anon list
garage anon clone <name> /tmp/scratch
garage anon share <name> --role write --expires 2h
garage anon delete <name> --yes
garage anon share mirrors garage share for anonymous
repos: it mints an owner-scoped share token and prints a clone URL that
works with bare git — no account, no garage CLI on the recipient side. A
share can never outlive the repo (the TTL is clamped to the repo’s remaining
lifetime), and garage anon delete <name> is the kill switch for every
share. --link creates a secure invite instead (see
garage invites), clamped to the repo’s expiry; manage
those with garage anon invites list / garage anon invites revoke <id>
(anon invites belong to your local anonId, not a logged-in session).
garage git
Read and clone git content via the API — no shell-out needed for log,
show, ls, branch, tag, compare, or diff.
| Subcommand | Purpose |
|---|---|
garage git clone |
Clone a repo (mints a token + wires the credential helper) |
garage git log |
List commits |
garage git show |
Show a blob by oid or ref:path |
garage git ls |
List tree entries |
garage git branch |
List, create, or delete branches |
garage git tag |
List, create, or delete tags |
garage git compare |
Compare two refs |
garage git diff |
Diff two refs |
garage git clone hello-world
garage git log hello-world --oneline -n 20
garage git ls hello-world src/ -r
garage git clone and garage anon clone read the repo’s API-returned
storage remote, mint a short-lived token, and install local credentials for
the clone.
garage link / garage unlink
Write or remove .garage/config.json in the current directory so
subsequent commands resolve the repo automatically.
# Auto-detect from `origin` when inside a clone, or pass an explicit name
garage link
garage link --repo hello-world
garage unlink
The link file records the bare repo name. That name resolves against your
active org, so switching orgs re-points the link; if the repo does not exist
in the new active org, repo and git commands surface REPO_NOT_FOUND.
garage tokens
| Subcommand | Purpose |
|---|---|
garage tokens mint |
Mint a scoped repo token (--scope read or write) |
garage tokens list |
List repo tokens (shares included) |
garage tokens revoke |
Revoke a repo token by id |
garage tokens mint hello-world --scope write --op agent
garage tokens list hello-world
garage tokens revoke hello-world <id>
You can always revoke tokens you minted yourself (so the revoke command
printed by garage share works for every sharer); revoking anyone else’s
tokens requires repo admin.
--op selects the TTL cap and must be one of refs, object, merge,
seed, clone, agent, or share. Use agent for general write tokens;
share is the long-lived tier behind garage share. Git
credential-helper requests derive push/fetch scope through the API’s
tokens.mintForGitRemote path.
Repo tokens are for git remote operations. Use API keys from garage keys
when calling the RPC API or SDK.
garage share
One command to onboard a single human or agent to one specific repo — without org membership, accounts, or short-lived git-wire tokens. A share is a long-lived, repo-scoped, revocable token embedded in a clone URL: whoever holds the link has the granted access (bearer semantics).
garage share my-api --role write --expires 7d
Every share prints:
- a clone URL that works with bare
git clone(the credential is percent-encoded into the URL — treat the whole URL as a secret), - the
.garage/config.jsonlink snippet for the recipient’s clone, - a paste-ready onboarding block that reads the same for a human or an agent
(
--out FILEwrites it to a file), and - the exact
garage tokens revoke …command that kills the share.
| Flag | Purpose |
|---|---|
--role read|write |
Access level → token scope (default read) |
--expires <duration> |
Share lifetime, e.g. 24h, 7d (default 7d, clamped) |
--link |
Mint a secure invite link instead (see below) |
--out <file> |
Write the onboarding instructions to a file |
--print |
Dry run — show the plan without minting anything |
Inside a linked directory garage share needs no name; manage shares with
garage tokens list / garage tokens revoke.
Secure invite links (--link)
garage share --link prints an unguessable https://thegarage.sh/invites/<id>
capability URL instead of a credential-bearing clone URL — safe to paste in
chat, because the invite id is the only secret in the link:
garage share my-api --role read --link
Opening the invite renders the onboarding instructions; a fresh,
short-lived git credential is minted only on an explicit Reveal action
(never on a bare GET, so link previews can’t consume it). Agents can fetch
the same invite as raw markdown at /invites/<id>.md?reveal=1. Invites are
revocable (garage invites revoke <id>), expiring, and policy-bounded
(maxReveals); garage stores only a hash of the invite id and never stores
a live credential.
garage invites
Manage the secure invite links created by garage share --link.
| Subcommand | Purpose |
|---|---|
garage invites list |
List share invite links you created |
garage invites revoke |
Revoke an invite (stops future reveals) |
garage invites list
garage invites revoke <id>
Invites created by garage anon share --link belong to your local anonId
rather than a logged-in session — manage those with
garage anon invites list / garage anon invites revoke <id>.
Revoking an invite stops future reveals immediately; credentials already
revealed stay valid until their short TTL expires (revoke those with
garage tokens revoke). Treat every invite URL like a password.
garage keys
Create, list, and delete additional API keys for CI, API, and SDK consumers. Scopes are repeatable.
| Subcommand | Purpose |
|---|---|
garage keys create |
Create a new API key |
garage keys list |
List API keys |
garage keys delete |
Delete an API key |
garage keys create ci --scope repos:read --scope tokens:mint
garage keys list
garage keys delete <id> --yes
Available scopes: repos:read, repos:write, tokens:read,
tokens:mint, tokens:revoke, orgs:read, orgs:write, members:read,
members:write, keys:read, keys:write, agents:invoke.
garage members
Members commands administer the active org. Switch the administered org with
garage org switch <slug>.
| Subcommand | Purpose |
|---|---|
garage members list |
List members |
garage members invitations |
List pending invitations |
garage members invite |
Invite a member |
garage members remove |
Remove a member |
garage members set-role |
Change a member role |
garage members accept |
Accept an invitation |
garage members cancel |
Cancel an invitation |
garage doctor
Check the CLI’s local configuration: auth store, file permissions, server reachability, and the git credential helper.
garage doctor
garage git config-credential-helper
Install or remove the git credential helper for garage remotes. garage git clone wires credentials for the clone automatically; this command is useful
when you manage remotes yourself.
garage git config-credential-helper --global
garage git config-credential-helper --global --uninstall
Agent discovery endpoints
The docs site exposes canonical bytes for coding agents alongside the rendered pages:
| Endpoint | Content |
|---|---|
/skill.md |
Canonical garage SKILL.md for agent skill stores |
/llms.txt |
Plain-text index of every docs page |
https://thegarage.sh/docs/<slug>.md |
Raw markdown for any docs page (append .md) |
See /docs/agents for the install-the-skill walkthrough.