CLI — Getting started
The metalhost CLI talks to the same HTTP API the dashboard
uses. Every command in this reference works against
api.metalhost.net with an API key — no port-forwarding, no
cluster access.
Topic guides
Per-resource command reference with examples:
- VMs — create flags, YAML manifests, lifecycle, snapshots
- Bare metal — browse, lease, power, ISO library
- Storage — disks and file shares
- Network & firewall
- Wallet & billing
- IAM, projects & orgs
- Webhooks
- Support
- Catalog, quotas & audit
How the CLI works
The CLI is a thin wrapper around the public API
(https://api.metalhost.net). It stores your API key and
defaults in a profile file, sends Connect-RPC requests
with Authorization: Bearer, and formats JSON responses as
tables or YAML.
- Scope —
--project,--org,--regionflags (or profile defaults) determine which resources commands target. Bare slugs likeweb-1expand toprojects/my-app/virtual-machines/web-1. - Operations — VM create/delete/resize return
operations/…. Use--waitormetalhost ops waitto block until done. - Output —
-o jsonfor scripting,-o yamlfor manifests,-qfor names only. - Manifests —
metalhost vm apply -f vm.yamlfor declarative VMs. See CLI → VMs (YAML).
Install
Current release: v1.1.2. Includes single-disk backups and automatic schedules, whole-VM capture and restore, and monitoring, alerts, and GitHub Actions.
On macOS or Linux, run this. It fetches the latest CLI from GitHub,
checks the checksum when GitHub published one, and copies the
metalhost binary onto your machine:
curl -fsSL https://metalhost.net/install-cli.sh | bash
When it works, you’ll see an install path and a version line. That
version line is the installer calling the binary by its full path —
it does not mean you can type metalhost
yet.
→ Installing metalhost v1.1.2 (darwin/arm64)
→ Checksum verified
→ Installed /Users/you/.local/bin/metalhost
→ metalhost 1.1.2 (…) Where it lands
The script writes to a directory it can write without sudo:
/usr/local/bin— if that folder is writable. This is already on PATH for most systems, sometalhost versionusually works in the same terminal.~/.local/bin— fallback when/usr/local/binis not writable. This is the usual case on macOS. That folder is not on PATH by default, so the next command iscommand not founduntil you add it.
Read the → Installed … line if you’re unsure which one you got.
If you see command not found
The binary is installed. Your current terminal just doesn’t search
that folder. curl | bash runs in a subprocess, so it
cannot change PATH in the shell you’re typing in. Add the install
directory for this session, then check:
export PATH="$HOME/.local/bin:$PATH"
metalhost version
You should see something like metalhost 1.1.2 (…). To
keep that in new terminal windows, append the same
export to your shell startup file and reload it:
# macOS default shell (zsh)
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Linux bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc Pin a version or pick a folder
Put VERSION or INSTALL_DIR on the
bash side of the pipe (the right-hand side). Prefixing
them on curl has no effect:
curl -fsSL https://metalhost.net/install-cli.sh | VERSION=v1.1.2 bash
curl -fsSL https://metalhost.net/install-cli.sh | INSTALL_DIR=~/.local/bin bash Windows, zip files, or Go
Download a pre-built binary from
GitHub Releases
(includes Windows). Or, if you have Go installed:
go install github.com/AES-Services/metalhost-cli/cmd/metalhost@latest
(installs to your Go bin directory, usually $(go env GOPATH)/bin).
First-run setup: metalhost init
Interactive wizard that walks you through authentication and writes a
profile to ~/.config/metalhost/config.yaml. After it
finishes, every other CLI command uses the saved profile — no flags
needed.
metalhost init The wizard asks how you want to authenticate:
- Paste an existing API key — mint one in the dashboard under Developers → API keys.
- Log in with email + password — exchanges credentials for a session token.
- Sign up — creates a new account + organization; sends a verification email.
- OIDC / browser SSO — delegates to
metalhost auth login --oidc <provider>.
Then it lists your projects (prompting to create one if you have none) and picks a default datacenter.
Global flags
These persistent flags work on every command.
| Flag | What it does |
|---|---|
--config PATH | Path to the CLI config file. |
--profile NAME | Switch profile for this command (default: active profile). |
--endpoint URL | Override the API endpoint. |
-o, --format FMT | table (default), json, or yaml. |
-q, --quiet | Print only resource names — handy for piping into scripts. |
--project NAME | Project scope for this command (overrides the profile default). |
--org NAME | Organization scope (overrides the profile default). |
--region NAME | Region / datacenter scope (overrides the profile default). |
--wait | For commands that return an operation, block until it finishes and print the final operation. |
--wait-timeout DUR | Max time to wait with --wait (default 10m; 0 = no limit). |
Unified verbs get · describe · delete · apply
Alongside the per-service command trees, the CLI exposes kubectl-style
verbs that work uniformly across resource kinds
(vm, ssh-key, disk,
file-share, network, baremetal,
webhook, project).
| Command | What it does |
|---|---|
get KIND | List resources of a kind in the active scope. |
get KIND NAME | Get one resource by name. |
describe KIND NAME | Full detail for a single resource. |
delete KIND NAME [--yes] | Delete a resource (prompts unless --yes). |
apply -f FILE | Create/update from a declarative YAML/JSON spec — pairs with get … -o yaml. |
# list, then fetch one
metalhost get vm
metalhost get disk --all -o json
metalhost describe vm web-1
# round-trip a resource through a file
metalhost get vm web-1 -o yaml > vm.yaml
metalhost apply -f vm.yaml profile
Manage CLI profiles. Each profile holds an API endpoint, API key, default project, organization, and default region.
| Command | What it does |
|---|---|
profile list | List configured profiles. |
profile create NAME | Create a new profile. |
profile use NAME | Switch the active profile. |
profile set NAME --key=value | Update fields on a profile. |
profile delete NAME | Remove a profile. |
auth
| Command | What it does |
|---|---|
auth whoami | Show the caller identity + default project + accessible orgs. |
auth login --email ADDR | Email/password login (prompts for the password). |
auth login --oidc PROVIDER | Browser SSO via an OIDC provider (e.g. google, github). |
auth login --api-key | Store the key from METALHOST_API_KEY in the active profile. |
project
| Command | What it does |
|---|---|
project list | List projects you can access (auto-scoped to your orgs). |
project get NAME | Get a project. |
project create NAME --org ORG --display-name "..." | Create a project. |
project update NAME ... | Update display name / labels / annotations. |
project delete NAME | Delete a project (must be empty). |
iam
API keys, members, sessions, MFA, invites. Common commands are in CLI → IAM. Full command list:
| Command | What it does |
|---|---|
iam keys list|create|revoke|rotate | API key lifecycle. |
iam members list|invite|update-role|remove | Org membership. |
iam sessions list|revoke|logout | Session management. |
iam mfa enroll|verify|revoke | TOTP MFA. |
iam invites list|accept|revoke|mine | Pending invites. |
iam password change|forgot|reset | Password flows. |
iam import-github-ssh-keys | Bulk-import GitHub keys. |
quota
metalhost quota — show current quota usage + limits for
the active project's organization. Details:
CLI → Catalog & quotas.
audit
metalhost audit search (alias audit list) —
search audit events. See
CLI → Catalog & quotas.
catalog
Datacenters, capacity, and pricing quotes — CLI → Catalog & quotas.
health
metalhost health — check API health and the served build
version.
ops aka operations
Most write RPCs return an operations/<uuid>. Track
progress here (or pass --wait to the original command).
| Command | What it does |
|---|---|
ops list | List recent operations. |
ops get NAME | Get one operation. |
ops wait NAME | Block until the operation finishes (success or error). |
support aka sup
Org-scoped tickets — full reference: CLI → Support.
Output formats
Every command supports -o table (default),
-o json, or -o yaml. JSON is the safest pipe
target — combine with jq for shell scripts:
# every VM's hostname + public IPv4
metalhost vm list -o json \
| jq -r '.items[] | [.hostname, .public_ipv4] | @tsv'
# create and wait for the operation in one shot
metalhost vm create ... --wait
# just the resource names, for scripting
metalhost get vm -q