Deploy, manage, and SSH into your VPS instances from the command line. Available for macOS, Linux, and Windows.
Get up and running in 3 commands:
# Install via Homebrew
brew install hostodo/tap/odo
# Login to your account
odo login
# List your instances and SSH in
odo list
odo ssh my-server
The recommended way to install the Hostodo CLI:
# Add the Hostodo tap and install
brew tap hostodo/tap
brew install hostodo/tap/odo
# Or install directly
brew install hostodo/tap/odo
Download binaries from the releases page. Available for macOS (Intel & Apple Silicon), Linux (amd64, arm64), and Windows (amd64).
# macOS (Apple Silicon)
curl -L https://github.com/hostodo/odo-cli/releases/latest/download/odo_Darwin_arm64.tar.gz | tar xz
sudo mv odo /usr/local/bin/
# Linux (amd64)
curl -L https://github.com/hostodo/odo-cli/releases/latest/download/odo_Linux_x86_64.tar.gz | tar xz
sudo mv odo /usr/local/bin/
# Debian / Ubuntu
wget https://github.com/hostodo/odo-cli/releases/latest/download/odo_Linux_x86_64.deb
sudo dpkg -i odo_Linux_x86_64.deb
# RHEL / CentOS / Fedora
wget https://github.com/hostodo/odo-cli/releases/latest/download/odo_Linux_x86_64.rpm
sudo rpm -i odo_Linux_x86_64.rpm
Requires Go 1.25 or higher:
git clone https://github.com/hostodo/odo-cli.git
cd odo-cli
make install
The CLI uses OAuth device flow for secure authentication. When you run odo login, a browser window opens where you authorize the CLI with your Hostodo account. Your tokens are securely stored in the OS keychain (macOS Keychain, Linux Secret Service). On systems without a keychain, a plain token file is stored at ~/.odo/token with strict 0600 permissions.
odo login
This opens your default browser to authorize the CLI. Once approved, you're authenticated and ready to go.
| Flag | Description |
|---|---|
--api-url | Use a custom API URL (default: https://api.hostodo.com) |
Clear stored credentials:
odo logout
Display information about the authenticated user:
odo whoami
View your active CLI sessions:
odo auth sessions
Security: Tokens are stored in the OS keychain, never in plain-text config files. The config file (~/.odo/config.json) only stores the API URL and device ID. File permissions are set to 0600 automatically.
List all your VPS instances. Aliases: ls, ps.
# Interactive TUI (default)
odo list
# JSON output for scripting
odo list --json
# Simple ASCII table
odo list --simple
# Detailed view with all info
odo list --details
| Flag | Description |
|---|---|
--json | Output as JSON |
--simple | Output as simple ASCII table |
--details | Show detailed information |
--limit | Max instances to fetch (default: 100) |
--offset | Offset for pagination (default: 0) |
The default interactive TUI supports keyboard navigation:
↑ / ↓ or j / k — Navigate through instancesEnter — View detailed instance informationq or Esc — QuitGet detailed information about a specific instance:
odo status my-server
odo status my-server --json
Displays basic info, network configuration, resource allocation (RAM, CPU, disk, bandwidth), plan details, billing information, and timestamps.
Example output:
Start a stopped instance. Waits up to 30 seconds for the instance to boot:
odo start my-server
Stop a running instance. Waits up to 60 seconds for graceful shutdown:
# Graceful shutdown
odo stop my-server
# Force immediate shutdown
odo stop my-server --force
Restart an instance. Waits up to 90 seconds:
# Graceful restart
odo restart my-server
# Force restart
odo restart my-server --force
| Flag | Applies To | Description |
|---|---|---|
-f, --force | stop, restart | Force immediate shutdown without graceful stop |
Connect to an instance via SSH using the system ssh binary. The SSH user is auto-detected from the OS template. If key-based auth fails and the instance has a default password, the CLI automatically retries using sshpass.
# SSH with auto-detected user
odo ssh my-server
# Specify a different user
odo ssh my-server --user ubuntu
# Pass extra flags to the ssh binary (after --)
odo ssh my-server -- -L 8080:localhost:8080
odo ssh my-server -- -A -v
| Flag | Description |
|---|---|
-u, --user | SSH user (default: auto-detected from OS template) |
New instances: Host keys for freshly deployed instances are accepted automatically (StrictHostKeyChecking=accept-new). Changed keys on known hosts are still rejected for security.
Password fallback: Requires sshpass to be installed. Install with brew install hudochenkov/sshpass/sshpass on macOS or sudo apt install sshpass on Linux. Skip this by adding an SSH key with odo keys add.
Rename an instance by updating its hostname:
odo rename my-server new-name
Wipe and reinstall the OS on an existing instance. Optionally specify a different OS template and SSH key. This is destructive — all data on the instance will be lost.
# Interactive — prompts for OS and SSH key
odo reinstall my-server
# Specify OS template
odo reinstall my-server --os "Debian 12"
# Specify OS and SSH key
odo reinstall my-server --os "Ubuntu 22.04" --ssh-key mykey
| Flag | Description |
|---|---|
--os | OS template name (skips OS prompt) |
--ssh-key | SSH key name to inject |
-y, --yes | Skip confirmation prompt |
Note: Reinstall is a long-running operation (stop + wipe + rebuild). The CLI waits up to 10 minutes for completion. The new root password is displayed on success.
All instance commands accept hostnames as the primary identifier. The CLI resolves hostnames using a three-step fallback:
my-server)my-s resolves to my-server if unique)ins::abc123)Tab completion for hostnames is available when shell completions are enabled.
Deploy a new VPS instance with an interactive wizard or by passing flags. Aliases: new, create.
Run odo deploy without flags for a guided experience. The wizard walks you through selecting an OS template, region, plan, hostname, and optional SSH key.
odo deploy
Skip prompts by passing flags:
# Deploy with specific options
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN
# Custom hostname
odo deploy --hostname my-server
# Apply a promo code
odo deploy --promo LETCLI
# Skip confirmation
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN --yes
# Fully scripted deploy with promo
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN --billing-cycle monthly --promo LETCLI --yes
# JSON output (requires --os, --region, --plan)
odo deploy --os "Ubuntu 22.04" --region DET01 --plan EPYC-2G1C32GN --json
| Flag | Description |
|---|---|
--os | OS template name (skips OS prompt) |
--region | Region name: DET01, LV01, TPA01 |
--plan | Plan name (e.g. EPYC-2G1C32GN) |
--hostname | Custom hostname (skips auto-generation) |
--ssh-key | SSH key name to use for authentication |
--billing-cycle | Billing cycle: monthly, annually, semiannually, biennially, triennially |
--promo | Promo code for a discount (e.g. LETCLI) |
-y, --yes | Skip confirmation prompt |
--json | JSON output (requires --os, --region, --plan) |
List your invoices with optional filtering. Alias: bills.
# List all invoices
odo invoices
# Show only unpaid invoices
odo invoices --status=unpaid
| Flag | Description |
|---|---|
--status | Filter by status (e.g., unpaid) |
Pay an invoice by its ID using your default payment method:
odo pay INV-12345
# Skip confirmation prompt
odo pay INV-12345 --yes
| Flag | Description |
|---|---|
-y, --yes | Skip confirmation prompt |
odo keys list
# Add key inline
odo keys add mykey "ssh-rsa AAAAB3NzaC1yc2EAAA... user@host"
# Add key from file
odo keys add mykey --file ~/.ssh/id_rsa.pub
| Flag | Description |
|---|---|
--file | Read public key from file |
Aliases: rm, delete.
odo keys remove mykey
Commands that display data support multiple output modes:
A keyboard-navigable, color-coded table that adapts to your terminal size. Use arrow keys or j/k to navigate, Enter to view details.
--json)Structured JSON output, perfect for scripting and piping to tools like jq:
# Get running instances as JSON
odo list --json | jq '.[] | select(.status == "running")'
--simple)Clean ASCII table for quick viewing or piping:
--details)Comprehensive, human-readable output per instance:
Configuration is stored at ~/.odo/config.json:
{
"api_url": "https://api.hostodo.com",
"device_id": "a1b2c3d4-..."
}
Access tokens are stored separately in the OS keychain. On systems without a keychain, a plain token file is stored at ~/.odo/token with 0600 permissions.
Permissions: Config file permissions are automatically set to 0600 (owner read/write only) and directory permissions to 0700.
| Variable | Description |
|---|---|
HOSTODO_API_URL | Override the default API URL (must be https://) |
HOME | Used to locate the config directory |
# Use a custom API endpoint
export HOSTODO_API_URL=https://custom-api.example.com
odo login
Generate completion scripts for your shell. This enables tab-completion for commands and hostnames.
# Bash
odo completion bash > /etc/bash_completion.d/odo
# Zsh
odo completion zsh > "${fpath[1]}/_odo"
# Fish
odo completion fish > ~/.config/fish/completions/odo.fish
All commands support these flags:
| Flag | Description |
|---|---|
--config | Config file path (default: $HOME/.odo/config.json) |
-h, --help | Show help for any command |
-v, --version | Show CLI version |