Reference / CLI
The Pantech CLI
Create and manage virtual machines, databases, Kubernetes clusters, volumes, snapshots, networks, static IPs, load balancers, security groups and webhooks from your terminal.
pantech drives your organization from the terminal, through the public API. It runs on macOS (Apple silicon and Intel) and Linux (x86-64 and arm64).
Install
$ curl -fsSL https://pantechdynamics.com/install | bash✓ Installed pantech v0.1.5 to ~/.pantech/bin/pantechThe script downloads the build for your machine, checks it against the release's checksums, installs it in ~/.pantech/bin and adds that to your PATH. Open a new terminal, or run the export line it prints, then check it worked:
$ pantech --versionpantech v0.1.5To install a particular version, pass it to the script: curl -fsSL https://pantechdynamics.com/install | bash -s -- v0.1.5.
Sign in
$ pantech auth loginOpened your browser to approve the CLI.Waiting for approval…✓ Signed in to Acme (read, write), profile "default".Your browser opens the console's Sign in the CLI page. Choose the access, Read and write or Read only, and when the key expires, then press Approve. The console creates an API key for the CLI, named after your machine, like CLI on mac-mini, and hands it to the CLI directly: it is never shown on screen. The tab then says you're signed in, and you can close it.
If the CLI can't open a browser, such as over SSH, pantech auth login --no-browser prints the link to open on another device instead.
As with any API key:
- You need to be an owner or admin of the organization.
- Two-factor authentication must be on for your account.
- You can revoke it any time under Organization → API keys.
The key is kept in your system's keychain: the macOS Keychain, or the Secret Service on Linux. On a machine without one, such as a server, it goes in ~/.config/pantech/credentials.json, readable only by you.
pantech auth status shows which organization and key the CLI is using. pantech auth logout forgets the key on this machine, then revokes it, so it stops working everywhere straight away. To forget it here but keep the key working until it expires, pass --keep-key. A key in PANTECH_API_KEY is never revoked: unset it yourself.
Without a browser
On a server or in CI, create a key in the console and give it to the CLI instead:
$ pantech auth login --with-token < key.txtOr store nothing, and set the key in the environment. It takes precedence over a stored key:
$ export PANTECH_API_KEY=PAN_…$ pantech vm listCreate your first machine
Find a plan and an image, add your SSH key, then create the machine:
$ pantech plans$ pantech images$ pantech ssh-keys add ~/.ssh/id_ed25519.pub✓ Added me@laptop (sshk_…).$ pantech vm create --name web-1 --plan starter --image ubuntu-24-04 --ssh-key me@laptopCreate web-1 (starter, ubuntu-24-04) for about NGN 17,000.00 a month? [y/N] y ✓ Ordered web-1 NGN 15,040.00 ✓ Payment taken 2s ✓ Provisioned 1:12web-1 is ready at 102.211.122.80Connect: pantech vm ssh web-1$ pantech vm ssh web-1The first payment is taken from your credit, or else your organization's default card. Images have no password login, so --ssh-key is required: it is how you log in. If you don't have a key, pantech ssh-keys add --name deploy > deploy_key generates a pair, registers the public half, and prints the private half once: save it, because it is never shown again.
To place the machine in a VPC subnet instead of giving it its own public address, pass --subnet. A standard machine gets your default security group unless you pass --security-group. --tags env=prod,team=web labels it.
SSH access
Port 22 is closed by default. pantech vm ssh asks the platform to open it to your address for 15 minutes, waits until it is open, then connects with your own ssh and keys. The port closes again after the 15 minutes; pass --revoke to close it as soon as your session ends, even if you end it with Ctrl+C.
If the platform won't open access (the machine shares its security group with another, or your key is read-only), the CLI says why and connects to the machine's address directly. That works if the security group already allows port 22 from you.
It logs in as the image's usual user (ubuntu, debian or rocky, otherwise root). Pass --user to choose another, and anything after -- goes to ssh:
$ pantech vm ssh web-1 --revoke$ pantech vm ssh web-1 -- -i ~/.ssh/deploy -L 8080:localhost:80Commands
| Command | What it does |
|---|---|
pantech auth login, logout, status | Sign in, sign out, and show who the CLI acts as |
pantech vm list, get | List your machines, or show one |
pantech vm create | Create a machine |
pantech vm start, stop, reboot | Change a machine's power state |
pantech vm delete | Delete a machine and its root disk |
pantech vm ssh | Open SSH access for 15 minutes and connect |
pantech vm orders list, get | Follow the payment and provisioning of new machines |
pantech vm private-network attach, detach | Give a standard VPS an interface on the private database network, or remove it |
pantech volumes list, get, create, attach, detach, delete | Block storage volumes |
pantech snapshots list, get, create, delete | Snapshots of a machine's root disk or of a volume |
pantech networks list, get, create, delete | VPC networks |
pantech networks subnets list, create, delete | A network's subnets |
pantech public-ips list, get, create, delete | Public IPs for machines in a VPC |
pantech public-ips attach, detach | Move a static IP to another machine, or take it off its machine and keep it |
pantech load-balancers list, get, create, update, delete | Load balancers: one port of a static IP spread across machines |
pantech security-groups list, get, create, delete | Security groups, the firewalls of standard machines |
pantech security-groups rules add, remove, set | Add or remove rules, or replace them all |
pantech ssh-keys list, add, delete | Manage the keys installed on new machines |
pantech plans, images, regions | The catalogue: what you can create, and what it costs |
pantech db | Managed databases (see below) |
pantech kubernetes | Managed Kubernetes clusters (see below) |
pantech webhooks list, get, create, update, delete | Webhooks: URLs Pantech sends events to |
pantech webhooks test, rotate-secret, event-types | Send a test event, replace the signing secret, or list the event types |
pantech webhooks deliveries list, get, redeliver | A webhook's deliveries, and sending one again |
pantech operations get, wait | Follow a change while it happens |
pantech mcp install, status, list-clients | Connect an AI app to Pantech (see below) |
pantech upgrade | Install the latest version of the CLI |
pantech api | Call any endpoint in the API directly |
Resources, subnets included, can be named by their name or their id. Most commands answer to shorter names too: pantech vm is also pantech instances, networks is vpc, security-groups is sg, public-ips is ips, load-balancers is lb, kubernetes is k8s, volumes is vol, list is ls, get is show and delete is rm. Every command explains itself with --help.
Changes like stop and delete are asynchronous: the CLI waits for them to finish and shows how they went. Pass --no-wait to get the operation's id straight away instead.
Networks, IPs and firewalls
A machine in a VPC has no public address of its own: create a network and a subnet, create the machine in the subnet, then point a public IP at it:
$ pantech networks create --name prod --cidr 10.0.0.0/16$ pantech networks subnets create prod --name web --cidr 10.0.1.0/24$ pantech networks subnets list prod$ pantech vm create --name web-1 --plan starter --image ubuntu-24-04 --ssh-key deploy --subnet web$ pantech public-ips create --network prod --vm web-1A standard machine is protected by its security group instead. A rule is written DIRECTION:PROTOCOL:PORTS:CIDR, with no ports for icmp and all. rules add and rules remove change some rules and keep the rest; a rule to remove must match one exactly, as pantech security-groups get lists it. rules set replaces every rule the group has, so list them all:
$ pantech security-groups create --name web --rule ingress:tcp:80:0.0.0.0/0 --rule ingress:tcp:443:0.0.0.0/0$ pantech security-groups rules add web --rule ingress:tcp:22:203.0.113.4/32$ pantech security-groups rules remove web --rule ingress:tcp:80:0.0.0.0/0$ pantech security-groups rules set web --rule ingress:tcp:443:0.0.0.0/0 --rule ingress:tcp:8000-8100:203.0.113.4/32add and remove read the rules and write them back, so run one change to a group at a time.
Static IPs
A static IP that points at one machine can move. attach points it at another machine in its VPC, keeping the same address; detach takes it off its machine and keeps it yours. create without --vm reserves one detached, to attach later:
$ pantech public-ips create --network prod$ pantech public-ips attach 102.211.122.80 --vm web-2$ pantech public-ips detach 102.211.122.80$ pantech public-ips listName an address by its IP or its id. list shows detached for an address held without a machine, and (applying) while a change has not reached it yet. A held address is billed whether it is attached or not; see static IPs. A machine a static IP points at cannot be deleted: detach the address, or delete it, first.
Load balancers
A load balancer needs a static IP reserved for load balancing. Name the subnet by its id:
$ pantech public-ips create --network prod --purpose load_balancer$ pantech load-balancers create --name web --public-ip 102.211.122.91 --subnet snet_… \ --port 443 --private-port 8443 --algorithm leastconn --target web-1,web-2$ pantech load-balancers update web --targets web-1,web-2,web-3$ pantech load-balancers list# In a standard zone, an appliance load balancer brings its own address:$ pantech load-balancers create --name app --zone af-abj-1 --port 80 --target web-1,web-2--allow limits which source ranges may connect (anywhere if you leave it out). update changes the name, --algorithm or the targets; --targets is the whole new set, and --no-targets removes them all. The address, subnet, ports and allowed ranges are fixed: to change them, create a new load balancer and delete the old one.
Volumes and snapshots
$ pantech api GET /disk-offerings$ pantech volumes create --name data --offering small-5gb --vm web-1 --mount-point /data$ pantech snapshots create --volume data --name nightly$ pantech snapshots create --vm web-1 --name before-upgradeA custom-size offering also needs --size, in GB. A volume attaches only to a running machine in its zone.
Anything else
For what the CLI has no command for yet (usage, snapshot schedules, firewall and port forwarding rules, and disk offerings), pantech api calls the API with your key and prints the answer. --data takes JSON, @file or @- for stdin, and -f adds a query parameter:
$ pantech api GET /usage/by-resource -f period=month$ pantech api POST /networks --data '{"name": "prod", "cidr": "10.0.0.0/16"}'Databases
pantech db manages managed databases:
| Command | What it does |
|---|---|
pantech db engines | The engines and versions you can create, and where |
pantech db list, get | List your databases, or show one and how to connect to it |
pantech db create | Create a database, and wait until it is running |
pantech db start, stop, delete | Change its power state, or delete it and its data |
pantech db access-rules add, remove, set | Allow or stop CIDRs, or replace the whole list |
pantech db security-groups set | Attach up to 5 security groups as sources of address ranges, or --none |
pantech db storage resize | Grow the data disk, online. It never shrinks |
pantech db snapshots list, get, create, delete | Crash-consistent snapshots of the data disk |
pantech db password set, reset | Set the admin password to one you choose, or have one generated |
pantech db orders list, get | Follow the payment and provisioning of new databases |
$ pantech db engines$ pantech db create --name orders-db --engine postgresql --version 18 --plan starter \ --zone af-abj-2 --subnet web --storage-gb 100$ pantech db storage resize orders-db --storage-gb 200$ pantech db snapshots create orders-db --name before-migration$ pantech db snapshots list orders-db--storage-gb sets the data disk's size at create: the plan's own size if you leave it out, otherwise a multiple of 10 GB up to 2,000 (today's limits). db storage resize grows it later without a restart. pantech db engines shows each zone's limits and price per GB, and both commands check the size against them before asking you anything, so a size the zone does not allow, or one that is not larger, is refused straight away. See storage and snapshots.
In af-abj-1, a standard VPS reaches a database through a private interface. Narrow its security group first (no inbound rule may cover 10.250.0.0/20, ICMP included; pantech regions shows each zone's range under PRIVATE NETWORK), then:
$ pantech vm private-network attach web-1$ pantech db access-rules add orders-db 10.250.4.23/32attach prints the VPS's new address and the command to allow it. access-rules add and remove change some ranges and keep the rest; access-rules set replaces the whole list. Connect a standard VPS to a database has every step, including the netplan file.
--admin-username names the admin login (dbadmin if you leave it out): 3 to 32 lowercase letters, digits or underscores, starting with a letter, and not a reserved name. The CLI checks it before sending.
A database password never goes on the command line. Without --password-stdin, one is generated and printed once, alone on stdout: save it there and then. With --password-stdin, the CLI reads the one you choose from a hidden prompt or a pipe. pantech db password reset prints a new one the same way.
Kubernetes
pantech kubernetes, or pantech k8s, manages managed Kubernetes clusters:
| Command | What it does |
|---|---|
pantech kubernetes versions | The versions you can create, by zone, and where 3 control nodes are offered |
pantech kubernetes list, get | List your clusters, or show one: its nodes, endpoint, allow-list and the upgrades on offer |
pantech kubernetes create | Create a cluster, and wait until it is running |
pantech kubernetes configure | Change the worker count, turn autoscaling on or off, or set who reaches the API server |
pantech kubernetes upgrade | Move to one of the cluster's available upgrades |
pantech kubernetes start, stop, delete | Change its power state, or delete it |
pantech kubernetes kubeconfig | Download the cluster's kubeconfig |
pantech kubernetes resize, network, endpoint-access | Move every node to another plan; change the pod network (CNI, address ranges); choose where the API server is reachable (public, private, dual) |
pantech kubernetes nodes, workloads | The cluster's nodes, and its services and pods, read live from the cluster (-A adds the kube-* namespaces) |
pantech kubernetes apply -f, manifests | Apply a YAML manifest (server-side apply, -f - for stdin); export what you run as YAML |
pantech kubernetes expose, sync-routing | Route a public port of the cluster's address to a service; reconcile the routes with what the cluster exposes |
pantech kubernetes node-pools, addons | Node pools (workers with their own plan, labels and taints) and managed add-ons (metrics-server, csi-driver, ingress-controller) |
$ pantech kubernetes versions --zone af-abj-2$ pantech kubernetes create --name prod --zone af-abj-2 --version 1.31.2 \ --subnet snet_… --node-plan s-2vcpu-4gb --workers 2 --api-allow 203.0.113.0/24$ pantech kubernetes kubeconfig prod -o ~/.kube/prod.yaml$ KUBECONFIG=~/.kube/prod.yaml kubectl get nodes$ pantech kubernetes configure prod --autoscale 2:5$ pantech kubernetes upgrade prod --version 1.32.0$ pantech kubernetes apply prod -f app.yaml$ pantech kubernetes workloads prod$ pantech kubernetes expose prod web --port 80Give create a fixed --workers count, or --autoscale MIN:MAX for the autoscaler to manage. --control-nodes 3 asks for a highly available control plane where the zone offers it. Every node is billed as a machine of --node-plan, so create, and configure when it adds workers, ask first.
configure takes --workers N, --autoscale MIN:MAX or --no-autoscale, and --api-allow with the whole new list of ranges, or --api-allow-any to let any address reach the API server again. Limiting API server access works in a VPC zone only.
A kubeconfig grants cluster-admin: treat it like a password. kubeconfig writes it to the file you give with -o, readable only by you, or to stdout only if you pass --stdout; without either it refuses.
AI apps
pantech mcp sets up an AI app to use Pantech's MCP server. It writes the app's config file for you, keeps any other servers in it, and saves the old file as <file>.bak.
$ pantech mcp install cursor$ pantech mcp install claude-code --local$ pantech mcp install vscode --print$ pantech mcp list-clients$ pantech mcp statusinstall <client>takesclaude-code,claude,cursor,vscode,windsurf,codex,gemini,chatgptorgrok. For Claude Code and Gemini CLI it runs their ownmcp addcommand when they are installed. Forclaudeit prints the connector steps, or with--localwrites Claude Desktop'sclaude_desktop_config.json. Forchatgptandgrokit prints instructions only, and they take no--local.- It connects to the hosted server,
https://mcp.pantechdynamics.com/mcp, by default;--urluses another. The app asks you to approve it in the browser the first time. --localrunspantech-mcp stdioon your machine instead, which uses the key you signed in with. The config gets the full path topantech-mcp, so apps started outside your shell find it. Ifpantech-mcpis not on yourPATH, it warns you.--printshows the config and changes nothing.list-clientslists the ids.statusshows the hosted URL, whetherpantech-mcpis installed, and which apps already have Pantech.
Scripts and CI
Every command takes:
--json: print the API's own JSON instead of a table.--quiet: print only ids, one per line.--yes: don't ask before deleting something or spending money. Without a terminal to ask in, the CLI refuses to do either unless you pass it.
$ pantech vm list --quiet | xargs -n1 pantech vm stop --yesEvery change carries an Idempotency-Key, and the CLI retries network errors, rate limits and server errors with the same one, so a retried change never happens twice.
The exit code says how a command ended:
| Code | Meaning |
|---|---|
0 | Done |
1 | Anything else went wrong |
2 | The command was used wrongly |
3 | Not signed in, or the key was refused or lacks the access |
4 | Not found |
5 | A change finished, but failed |
pantech vm ssh exits with ssh's own code, and a command you stop with Ctrl+C exits with 130.
More than one organization
Profiles keep separate sign-ins. Sign in to each under a name, then pick one per command with --profile, or for a whole session with PANTECH_PROFILE:
$ pantech --profile acme auth login$ pantech --profile acme vm listUpdate and uninstall
To update, run pantech upgrade. It downloads the latest version, checks it against the release's checksums, and installs it in place of the one you have. Pass a version to install that one instead, or --check to only see what the latest is:
$ pantech upgrade$ pantech upgrade --check$ pantech upgrade v0.1.5At most once a day, the CLI also says when a newer version is out. It stays quiet with --json or --quiet, in CI, and when its output is not a terminal; set PANTECH_NO_UPDATE_NOTIFIER=1 to turn it off. Versions before v0.1.5 have no upgrade: run the install command again instead.
To uninstall, sign out first, which revokes the key and removes it from your keychain, then remove the CLI and its settings:
$ pantech auth logout$ rm -rf ~/.pantech ~/.config/pantechThen delete the # Pantech CLI lines the installer added to your shell's startup file (~/.zshrc, ~/.bash_profile, ~/.bashrc or fish's config.fish).