gzero-cli
v0.10.2
Published
GroundZero command-line interface: deploy UIs and APIs, manage env, domains, and billing.
Readme
╻
╭─╯ ╰─╮ GroundZero
│ │ Deploy UIs & APIs from your terminal or an AI agent.
╰─────╯ gzer0.appGroundZero CLI
Deploy UIs and APIs, manage env vars, domains, and billing, straight from your terminal or an AI agent.
Built on @gzero/sdk. Everything the dashboard does, scriptable, with a
device-code login and a config that plays nicely with CI.
Install
Requires Node.js 20+.
npm install -g gzero-cli
# or run without installing
npx gzero-cli --helpWorks on Linux, macOS, and Windows.
Quick start
One command gets you live. Run it in your project directory:
gzero login # device-code sign in via your browser (one time)
cd my-app
gzero deploy # publish to GitHub if needed, scan, create, and shipgzero deploy (short alias: g0 deploy) is context-aware and does the right
thing for where you are:
- Linked directory (a
.gzero/project.jsonfile exists): redeploys that project. - Git repo with a GitHub remote: scans, creates the project, and deploys.
- Local repo, not on GitHub yet: offers to create a GitHub repo on your account and push your code there first, then continues.
- Not a git repo: falls back to picking one of your GitHub repositories.
init vs deploy, in one line: init sets up and links, deploy ships. Use
gzero init to create and link a project without deploying yet.
gzero deploy # deploy a project and watch it go live
gzero status # check hosting mode, readiness, URL, and env varsRun gzero with no arguments (or gzero --help) to see the full command list.
Note GroundZero builds from GitHub, so your code has to live in a GitHub repo. The CLI can create that repo and push for you (reusing your GitHub sign-in, no extra tokens), so a purely local project can go live without leaving the terminal.
Static vs server-rendered (SSR)
When a scan detects a server-rendered app (Next, Nuxt, SvelteKit, ...), the CLI
asks how to host it: a static site (free preview, cheap to go live) or a
server-rendered app running a Node server (the all-in $9/mo plan: server,
custom domain, SSL). Switch anytime with gzero ssr enable / gzero ssr disable.
Sign in
gzero loginThis runs a device-code login (OAuth 2.0 device authorization):
- The CLI prints a short code and opens your browser to
/activate. - Sign in with GitHub (if you aren't already) and confirm the code.
- The CLI receives a long-lived API token and saves it locally.
The token is minted only after you approve in the browser, and it is never shown in the browser itself.
Where the token is stored
| OS | Path |
| ------- | -------------------------------------------------------------------- |
| Linux | $XDG_CONFIG_HOME/gzero/config.json or ~/.config/gzero/config.json |
| macOS | ~/.config/gzero/config.json |
| Windows | %APPDATA%\gzero\config.json |
gzero login prints the exact path after saving. The file is written with
0600 permissions on Unix.
Commands
| Command | Description |
| ------- | ----------- |
| gzero login | Device-code sign in; saves an API token |
| gzero logout | Revoke the current token and clear local config |
| gzero whoami | Show the signed-in account |
| gzero deploy [project] | Get the current project live: publish to GitHub if needed, scan, create, and deploy (or redeploy the linked/named project) |
| gzero init [repo] | Set up and link a project (from local code or a GitHub repo) without deploying |
| gzero github | Show which GitHub organizations GroundZero can see, and how to grant more access |
| gzero projects (alias ls) | List your projects |
| gzero status [project] | Active deploy, hosting mode, readiness, and env status |
| gzero logs [project] | Print the latest deploy's build log |
| gzero run "<cmd>" [project] | Run a one-off command inside the running container (like heroku run), e.g. gzero run "python manage.py createsuperuser --noinput" my-api |
| gzero open [project] | Open the project's live URL in your browser |
| gzero logs -f [project] | Follow the running deploy's build log until it finishes; with --runtime, follow the container's output until Ctrl-C |
| gzero deploys active | Every deploy in flight on your account, whoever started it, and what just finished |
| gzero deploys cancel [project] | Stop a deploy that is queued or still building (the last live release stays up) |
| gzero rollback [project] | Roll back to a previous successful deploy |
| gzero promote [project] | Promote a live deploy to production |
| gzero ssr enable [project] | Switch a web project to server-rendered hosting (paid) |
| gzero ssr disable [project] | Switch a server-rendered project back to static |
| gzero auto-deploy show [project] | Whether the project deploys on push, whether the GitHub App covers its repository, queued pushes, and what recent pushes did |
| gzero auto-deploy on [project] [--no-previews] | Deploy the default branch on every push, and pull requests as previews with a comment and a commit status |
| gzero auto-deploy off [project] | Stop deploying from GitHub |
| gzero github-app | Where the GroundZero GitHub App is installed for your account, and the link to install it |
| gzero egress show [project] | Show the outbound IP the project connects to the internet from, and whether it is stable |
| gzero egress pin [project] | Keep that outbound IP fixed so it can be added to an external service's IP allowlist |
| gzero egress unpin [project] | Let the project run anywhere again (its outbound IP may change) |
| gzero env list [project] | List env var keys |
| gzero env set <project> <key> <value> | Set an env var |
| gzero env rm <project> <key> | Delete an env var |
| gzero env import <project> <file> | Bulk-import vars from a .env file |
| gzero domains list [project] | List custom domains |
| gzero domains add <project> <host> | Attach a custom domain |
| gzero domains verify <project> <host> | Re-check DNS and verify a domain |
| gzero domains remove <project> <host> | Remove a custom domain |
| gzero billing | Show plan, usage, and available add-ons |
| gzero billing upgrade | Open Stripe checkout (subscribe) |
| gzero billing addon <id> | Open Stripe checkout for an add-on |
| gzero billing portal | Open the Stripe billing portal |
| gzero mcp | Print config to connect an AI agent to the hosted MCP |
deploy flags: -b, --branch <branch>, -e, --env <environment>,
-y, --yes (acknowledge readiness warnings), --no-follow (return immediately).
init flags: --repo <owner/repo>, --kind <web|api>, --path <dir>,
--product <ref>, -b, --branch <branch>, --render <static|ssr>, -y, --yes.
[project] accepts a project id, slug, or name. If omitted, the CLI uses your
only project or prompts you to pick one.
Connecting to a service that restricts access by IP
MongoDB Atlas, some payment providers, partner APIs and corporate VPN endpoints only accept connections from addresses you list in advance. Your app reaches the internet from the public IP of the machine it runs on, and that machine can change when the app is redeployed onto different hardware, so the address you allowlist today is not guaranteed to be the one it uses tomorrow.
Pin it first, then read it, then allowlist it:
gzero egress pin my-api # fix the address
gzero egress show my-api # read the address to allowlist◆ backend (my-api)
egress IP: 203.0.113.10
stable: yesgzero status shows the same address, and tells you when it is not yet stable.
If pin reports that the app is still running elsewhere, its address changes
once, on the next deploy. Deploy, then re-read gzero egress show and
allowlist the address it reports then.
Pinning limits which machines the app may run on, so use it only for projects that
actually talk to an allowlisted service. gzero egress unpin reverses it, at the
cost of the address no longer being guaranteed. Static sites have no outbound
container traffic, so this does not apply to them.
Monorepos
gzero init deploys one folder. Run it from inside the folder you want and the
CLI uses that folder automatically:
cd store/backend && gzero init --kind apiFrom the repo root, name the folder instead:
gzero init --kind api --path backendOne repo can back several services — a frontend web service and a backend
API service on the same product — because a project is identified by repo and
path.
Non-interactive use (agents, CI, scripts)
The setup prompts need a real terminal. When stdin isn't a TTY (or CI is set,
or you export GZERO_NON_INTERACTIVE=1), the CLI stops immediately and prints
the flag that answers the question, instead of hanging on a prompt that can't
render.
Answer everything up front:
gzero init --repo acme/store --kind api --path backend --product store…or commit a gzero.json next to your code (flags override it):
{
"repo": "acme/store",
"kind": "api",
"path": "backend",
"product": "store",
"branch": "main",
"render": "static"
}.gzero/config.json works the same way if you'd rather not add a file at the
repo root. Both are read by init and by the first-time deploy flow.
GitHub organization access
If a repository you can see on github.com is missing from the picker, its organization most likely hasn't approved the GroundZero OAuth app. Signing in again does not fix that — GitHub skips the consent screen when your token already has the scopes we ask for, and org approval is a separate record.
gzero github # lists orgs, flags the ones with no access, prints the grant URL
gzero github --open # …and opens it in your browser
gzero github --refresh # re-pull the repo list after grantingPayments open a Stripe-hosted URL in your browser; card details are never handled by the CLI.
Configuration
Precedence: command-line flags, then environment variables, then the saved config.
| Setting | Flag | Env var |
| ------------ | ---------------- | ---------------- |
| API base URL | --api-url <url> | GZERO_API_URL |
| API token | --token <token> | GZERO_TOKEN |
The default API URL is https://api.gzer0.app. For local development against a
dev server, point it at your local API:
GZERO_API_URL=http://localhost:3000 gzero loginGZERO_TOKEN is handy for CI and other headless callers.
Note Output is colorized when writing to a terminal. Set
NO_COLOR=1to disable colors, orFORCE_COLOR=1to keep them when piping.
Connect an AI agent (MCP)
The MCP server is hosted by GroundZero, so there is nothing extra to install:
gzero mcpIt prints a ready-to-paste client config pointing at https://mcp.gzer0.app/mcp.
Add it to your AI client (for example Cursor's ~/.cursor/mcp.json); on first
use the client opens a browser to sign in with GitHub. See @gzero/mcp
for details.
Examples
# Take a purely local project live: creates a GitHub repo, pushes, then deploys
cd my-app && gzero deploy
# Create and link a project from a specific repo without deploying
gzero init acme/my-app
# Host a server-rendered app on the Node runtime, then deploy it
gzero ssr enable my-app
gzero deploy my-app
# Deploy a specific branch to production and wait for it to go live
gzero deploy my-app --branch main --env production
# Import a whole .env file, then redeploy
gzero env import my-app .env.production
gzero deploy my-app
# Attach and verify a custom domain
gzero domains add my-app app.example.com
gzero domains verify my-app app.example.com
# Roll back the last bad deploy
gzero rollback my-app
# Queue a deploy in CI without streaming logs
GZERO_TOKEN=$CI_TOKEN gzero deploy my-app --yes --no-follow