Menu

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:

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, --region flags (or profile defaults) determine which resources commands target. Bare slugs like web-1 expand to projects/my-app/virtual-machines/web-1.
  • Operations — VM create/delete/resize return operations/…. Use --wait or metalhost ops wait to block until done.
  • Output-o json for scripting, -o yaml for manifests, -q for names only.
  • Manifestsmetalhost vm apply -f vm.yaml for declarative VMs. See CLI → VMs (YAML).

Install

macOS and Linux:

curl -fsSL https://metalhost.net/install-cli.sh | bash
metalhost version

Downloads the latest release from GitHub, verifies the checksum when available, and installs to /usr/local/bin or ~/.local/bin. Set INSTALL_DIR or VERSION to override. Windows binaries and manual installs: GitHub Releases. Build from source: go install github.com/AES-Services/metalhost-cli/cmd/metalhost@latest.

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:

  1. Paste an existing API key — mint one in the dashboard under Developers → API keys.
  2. Log in with email + password — exchanges credentials for a session token.
  3. Sign up — creates a new account + organization; sends a verification email.
  4. 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.

FlagWhat it does
--config PATHPath to the CLI config file.
--profile NAMESwitch profile for this command (default: active profile).
--endpoint URLOverride the API endpoint.
-o, --format FMTtable (default), json, or yaml.
-q, --quietPrint only resource names — handy for piping into scripts.
--project NAMEProject scope for this command (overrides the profile default).
--org NAMEOrganization scope (overrides the profile default).
--region NAMERegion / datacenter scope (overrides the profile default).
--waitFor commands that return an operation, block until it finishes and print the final operation.
--wait-timeout DURMax 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).

CommandWhat it does
get KINDList resources of a kind in the active scope.
get KIND NAMEGet one resource by name.
describe KIND NAMEFull detail for a single resource.
delete KIND NAME [--yes]Delete a resource (prompts unless --yes).
apply -f FILECreate/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.

CommandWhat it does
profile listList configured profiles.
profile create NAMECreate a new profile.
profile use NAMESwitch the active profile.
profile set NAME --key=valueUpdate fields on a profile.
profile delete NAMERemove a profile.

auth

CommandWhat it does
auth whoamiShow the caller identity + default project + accessible orgs.
auth login --email ADDREmail/password login (prompts for the password).
auth login --oidc PROVIDERBrowser SSO via an OIDC provider (e.g. google, github).
auth login --api-keyStore the key from METALHOST_API_KEY in the active profile.

project

CommandWhat it does
project listList projects you can access (auto-scoped to your orgs).
project get NAMEGet a project.
project create NAME --org ORG --display-name "..."Create a project.
project update NAME ...Update display name / labels / annotations.
project delete NAMEDelete a project (must be empty).

iam

API keys, members, sessions, MFA, invites. Common commands are in CLI → IAM. Full command list:

CommandWhat it does
iam keys list|create|revoke|rotateAPI key lifecycle.
iam members list|invite|update-role|removeOrg membership.
iam sessions list|revoke|logoutSession management.
iam mfa enroll|verify|revokeTOTP MFA.
iam invites list|accept|revoke|minePending invites.
iam password change|forgot|resetPassword flows.
iam import-github-ssh-keysBulk-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).

CommandWhat it does
ops listList recent operations.
ops get NAMEGet one operation.
ops wait NAMEBlock 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