Hetzner Cloud
Use this skill for Hetzner Cloud VPS inventory, provisioning, network and volume
inspection, cost estimates, and snapshot lifecycle work.
Default Workflow
- Start read-only: list servers, locations, server types, images, prices,
volumes, and networks.
- Use
plan for natural-language requests before building any write request.
- Treat
hetzner_cloud.cjs as the API wrapper. Do not handcraft Hetzner Cloud
API URLs, JSON bodies, tiers, or secret refs from memory.
- For prompt/user testing, stop after
plan or after helper http-request
payload generation. Do not call helper run or the built-in http_request
tool.
- For real user requests that need live Hetzner API data, use helper
run.
The helper constructs the request, sends it through the HybridClaw gateway,
and the gateway injects bearerSecretName: "HETZNER_API_TOKEN" server-side.
Do not rewrite that secret reference into secretHeaders, preflight it,
inspect it, or ask the model for the token.
- Use
http-request only when you need to inspect the generated gateway
payload or when the active runtime cannot give the helper gateway access.
- If a live helper
run or http_request call returns 401 or 403, stop after
that first
failure. Do not retry, do not fan out to more endpoints, and ask the operator
to set or verify HETZNER_API_TOKEN.
- Require an explicit operator grant before any changing action, including
delete, upgrade, downgrade, buy/create, restore, attach, detach, snapshot,
network, or volume mutation. Pass
--operator-grant only after that grant.
- Use
--project acme for project-scoped inventory and provisioning. The
helper converts it to project=acme label selectors or labels where the
Hetzner API supports them.
- Never paste, print, or inspect
HETZNER_API_TOKEN; the gateway injects it
server-side with bearerSecretName: "HETZNER_API_TOKEN".
- Do not repeat the same read call unless the previous result was ambiguous or
stale. For a named resize, one
list-servers --project <project> --name <name> call is enough to resolve the server id.
See references/operator-setup.md for operator
setup, token scope, autonomy defaults, and cost-reporting expectations.
Command Contract
Run the helper:
node skills/hetzner-cloud/hetzner_cloud.cjs --help
Plan a request without contacting Hetzner:
node skills/hetzner-cloud/hetzner_cloud.cjs --format json plan "Create a demo VPS in Falkenstein until Monday"
Run live read requests:
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-servers --project acme
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-server-types
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-locations
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-prices --project acme
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-volumes --project acme
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-networks --project acme
Run guarded live write requests:
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run create-server \
--name acme-demo --server-type cax11 --image ubuntu-24.04 --location fsn1 \
--project acme --label ttl=2026-05-18 --operator-grant
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run create-snapshot \
--project acme --server-id 123456 --description "pre-deploy" --operator-grant
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run restore-snapshot \
--server-id 123456 --snapshot-id 987654 --operator-grant
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run attach-network \
--server-id 123456 --network-id 555 --ip 10.0.0.12 --operator-grant
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run attach-volume \
--server-id 123456 --volume-id 777 --automount --operator-grant
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run downgrade-server \
--server-id 123456 --server-type cpx32 --operator-grant
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run delete-server \
--server-id 123456 --operator-grant
Build a dry-run gateway payload without calling Hetzner:
node skills/hetzner-cloud/hetzner_cloud.cjs --format json http-request list-servers --project acme
Resize/change type contract:
If the user named a server instead of giving an id, resolve it once:
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-servers \
--project datalion --name bastion
Ask for explicit approval for the exact server id and target type.
Build the request with the helper:
node skills/hetzner-cloud/hetzner_cloud.cjs --format json run downgrade-server \
--server-id 123456 --server-type cpx32 --operator-grant
Inspect the helper run response. Do not also call http_request for the
same request.
The change_type payload is json.server_type plus json.upgrade_disk.
Never send json.type, never omit upgrade_disk, and never rewrite
bearerSecretName: "HETZNER_API_TOKEN" into secretHeaders.
The helper emits generic skillRequestContract metadata for this operation;
pass it through unchanged so the gateway can validate the helper-built request.
Do not call list-server-types before a simple resize unless the user asks for
price or disk validation; Hetzner accepts cpx32 directly in server_type.
Working Rules
- Treat
delete-server, delete-vps, delete-snapshot,
destroy-snapshot, delete-volume, and restore-snapshot as red-risk
actions. Stop unless the operator grants the exact target id.
- Treat
create-server, create-volume, change-server-type,
upgrade-server, and downgrade-server as changing cost or capacity actions.
Ask for explicit approval before building a live request with
--operator-grant.
- For
change-server-type, upgrade-server, and downgrade-server, pass the
target plan as --server-type <name> or --server-type-id <id> to the helper.
The Hetzner change_type API accepts either an id or a name in server_type;
never send the old type field.
- Keep disk size by default for type changes. Use
--upgrade-disk only when
the operator explicitly asks to expand the primary disk, because expanded
disks cannot later be downgraded.
- Use read-only tokens for inventory and cost reporting. Ask for read-write
tokens only for the requested mutation window.
- For demo servers, include owner/project and TTL labels before provisioning.
- For rollback workflows, create the snapshot first, wait for the Hetzner
action to finish, and use
restore-snapshot only after the operator confirms
the target server id and snapshot id.
- Cost per assistant run is recorded by HybridClaw
UsageTotals; helper output
includes costMeasurement.system = "UsageTotals" for eval verification.
Eval Suite
node skills/hetzner-cloud/hetzner_cloud.cjs --format json eval-scenarios
The fixture at evals/scenarios.json contains 10 Cloud scenarios covering
inventory, cost reporting, provisioning, snapshots, rollback, and cleanup.
Validation
python3 skills/skill-creator/scripts/quick_validate.py skills/hetzner-cloud
node skills/hetzner-cloud/hetzner_cloud.cjs --help
node skills/hetzner-cloud/hetzner_cloud.cjs --format json eval-scenarios
1---2name: hetzner-cloud3description: Read and operate Hetzner Cloud servers, server types, locations, networks, volumes, snapshots, and cost estimates through gateway-proxied API requests.4---56# Hetzner Cloud78Use this skill for Hetzner Cloud VPS inventory, provisioning, network and volume9inspection, cost estimates, and snapshot lifecycle work.1011## Default Workflow12131. Start read-only: list servers, locations, server types, images, prices,14 volumes, and networks.152. Use `plan` for natural-language requests before building any write request.163. Treat `hetzner_cloud.cjs` as the API wrapper. Do not handcraft Hetzner Cloud17 API URLs, JSON bodies, tiers, or secret refs from memory.184. For prompt/user testing, stop after `plan` or after helper `http-request`19 payload generation. Do not call helper `run` or the built-in `http_request`20 tool.215. For real user requests that need live Hetzner API data, use helper `run`.22 The helper constructs the request, sends it through the HybridClaw gateway,23 and the gateway injects `bearerSecretName: "HETZNER_API_TOKEN"` server-side.24 Do not rewrite that secret reference into `secretHeaders`, preflight it,25 inspect it, or ask the model for the token.266. Use `http-request` only when you need to inspect the generated gateway27 payload or when the active runtime cannot give the helper gateway access.287. If a live helper `run` or `http_request` call returns 401 or 403, stop after29 that first30 failure. Do not retry, do not fan out to more endpoints, and ask the operator31 to set or verify `HETZNER_API_TOKEN`.328. Require an explicit operator grant before any changing action, including33 delete, upgrade, downgrade, buy/create, restore, attach, detach, snapshot,34 network, or volume mutation. Pass `--operator-grant` only after that grant.359. Use `--project acme` for project-scoped inventory and provisioning. The36 helper converts it to `project=acme` label selectors or labels where the37 Hetzner API supports them.3810. Never paste, print, or inspect `HETZNER_API_TOKEN`; the gateway injects it39 server-side with `bearerSecretName: "HETZNER_API_TOKEN"`.4011. Do not repeat the same read call unless the previous result was ambiguous or41 stale. For a named resize, one `list-servers --project <project> --name42 <name>` call is enough to resolve the server id.4344See [references/operator-setup.md](references/operator-setup.md) for operator45setup, token scope, autonomy defaults, and cost-reporting expectations.4647## Command Contract4849Run the helper:5051```bash52node skills/hetzner-cloud/hetzner_cloud.cjs --help53```5455Plan a request without contacting Hetzner:5657```bash58node skills/hetzner-cloud/hetzner_cloud.cjs --format json plan "Create a demo VPS in Falkenstein until Monday"59```6061Run live read requests:6263```bash64node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-servers --project acme65node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-server-types66node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-locations67node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-prices --project acme68node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-volumes --project acme69node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-networks --project acme70```7172Run guarded live write requests:7374```bash75node skills/hetzner-cloud/hetzner_cloud.cjs --format json run create-server \76 --name acme-demo --server-type cax11 --image ubuntu-24.04 --location fsn1 \77 --project acme --label ttl=2026-05-18 --operator-grant7879node skills/hetzner-cloud/hetzner_cloud.cjs --format json run create-snapshot \80 --project acme --server-id 123456 --description "pre-deploy" --operator-grant8182node skills/hetzner-cloud/hetzner_cloud.cjs --format json run restore-snapshot \83 --server-id 123456 --snapshot-id 987654 --operator-grant8485node skills/hetzner-cloud/hetzner_cloud.cjs --format json run attach-network \86 --server-id 123456 --network-id 555 --ip 10.0.0.12 --operator-grant8788node skills/hetzner-cloud/hetzner_cloud.cjs --format json run attach-volume \89 --server-id 123456 --volume-id 777 --automount --operator-grant9091node skills/hetzner-cloud/hetzner_cloud.cjs --format json run downgrade-server \92 --server-id 123456 --server-type cpx32 --operator-grant9394node skills/hetzner-cloud/hetzner_cloud.cjs --format json run delete-server \95 --server-id 123456 --operator-grant96```9798Build a dry-run gateway payload without calling Hetzner:99100```bash101node skills/hetzner-cloud/hetzner_cloud.cjs --format json http-request list-servers --project acme102```103104Resize/change type contract:1051061. If the user named a server instead of giving an id, resolve it once:107108 ```bash109 node skills/hetzner-cloud/hetzner_cloud.cjs --format json run list-servers \110 --project datalion --name bastion111 ```1121132. Ask for explicit approval for the exact server id and target type.1141153. Build the request with the helper:116117 ```bash118 node skills/hetzner-cloud/hetzner_cloud.cjs --format json run downgrade-server \119 --server-id 123456 --server-type cpx32 --operator-grant120 ```1211224. Inspect the helper `run` response. Do not also call `http_request` for the123 same request.124125The `change_type` payload is `json.server_type` plus `json.upgrade_disk`.126Never send `json.type`, never omit `upgrade_disk`, and never rewrite127`bearerSecretName: "HETZNER_API_TOKEN"` into `secretHeaders`.128The helper emits generic `skillRequestContract` metadata for this operation;129pass it through unchanged so the gateway can validate the helper-built request.130Do not call `list-server-types` before a simple resize unless the user asks for131price or disk validation; Hetzner accepts `cpx32` directly in `server_type`.132133## Working Rules134135- Treat `delete-server`, `delete-vps`, `delete-snapshot`,136 `destroy-snapshot`, `delete-volume`, and `restore-snapshot` as red-risk137 actions. Stop unless the operator grants the exact target id.138- Treat `create-server`, `create-volume`, `change-server-type`,139 `upgrade-server`, and `downgrade-server` as changing cost or capacity actions.140 Ask for explicit approval before building a live request with141 `--operator-grant`.142- For `change-server-type`, `upgrade-server`, and `downgrade-server`, pass the143 target plan as `--server-type <name>` or `--server-type-id <id>` to the helper.144 The Hetzner `change_type` API accepts either an id or a name in `server_type`;145 never send the old `type` field.146- Keep disk size by default for type changes. Use `--upgrade-disk` only when147 the operator explicitly asks to expand the primary disk, because expanded148 disks cannot later be downgraded.149- Use read-only tokens for inventory and cost reporting. Ask for read-write150 tokens only for the requested mutation window.151- For demo servers, include owner/project and TTL labels before provisioning.152- For rollback workflows, create the snapshot first, wait for the Hetzner153 action to finish, and use `restore-snapshot` only after the operator confirms154 the target server id and snapshot id.155- Cost per assistant run is recorded by HybridClaw `UsageTotals`; helper output156 includes `costMeasurement.system = "UsageTotals"` for eval verification.157158## Eval Suite159160```bash161node skills/hetzner-cloud/hetzner_cloud.cjs --format json eval-scenarios162```163164The fixture at `evals/scenarios.json` contains 10 Cloud scenarios covering165inventory, cost reporting, provisioning, snapshots, rollback, and cleanup.166167## Validation168169```bash170python3 skills/skill-creator/scripts/quick_validate.py skills/hetzner-cloud171node skills/hetzner-cloud/hetzner_cloud.cjs --help172node skills/hetzner-cloud/hetzner_cloud.cjs --format json eval-scenarios173```