agentleFS
iboumedieniboumedien/claude-skills/digitalocean/SKILL.md

digitalocean

Skill0 starsChanged 3 months agoMITView on GitHub

Manage DigitalOcean infrastructure — Droplets, Spaces, Databases, DNS, Load Balancers, Kubernetes, Firewalls, and billing. Use when the user asks about DigitalOcean, DO, Droplets, Spaces, or DOKS.

2 other projects use a version of this.

Adopted by

Most recently taken up by

  • Other versions2 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 2

    1. alanalvestech/hitank★ 38same name
    2. G1Joshi/Agent-Skills★ 15same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository9 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

21 rules. About 0 are common, 18 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈18

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    All DigitalOcean API endpoints follow a consistent JSON REST pattern:

    line 25
  2. Distinctive:

    All responses are JSON. Parse with:

    line 49
  3. Distinctive:

    Ask user for: name, region, size, image (and optionally: ssh_keys, tags, vpc_uuid, user_data, backups, monitoring)

    line 86
  4. Distinctive:

    Ask: name (globally unique, 3-63 chars, lowercase), region (nyc3, sfo3, ams3, sgp1, fra1, syd1, blr1)

    line 149
  5. Very specific:

    Ask: name, engine (pg/mysql/redis/mongodb/kafka), version, size (db-s-1vcpu-1gb, etc.), region, num_nodes

    line 178
  6. Distinctive:

    Ask: new size, num_nodes

    line 183
  7. Very specific:

    Ask: type (droplet/k8s/ip_addr/tag/app), value

    line 204
  8. Distinctive:

    Ask: type (A, AAAA, CNAME, MX, TXT, SRV, NS, CAA, SOA), name, data, TTL, priority (for MX/SRV)

    line 229
  9. Distinctive:

    Ask: fields to change

    line 234
  10. Very specific:

    Ask: name, region, size (lb-small/lb-medium/lb-large), forwarding_rules, droplet_ids or tag

    line 264
  11. Distinctive:

    Ask: name, region, version, node_pools (size, count, name)

    line 301
  12. Distinctive:

    Ask: name, inbound_rules, outbound_rules, droplet_ids (optional)

    line 339
  13. Distinctive:

    DELETE "/droplets/<id>" # Delete Droplet POST "/droplets/<id>/actions" '{"type":"power_on"}' # Power on POST "/droplets/<id>/actions" …

    line 488
  14. Distinctive:

    DELETE "/databases/<id>" # Delete cluster GET "/databases/<id>/backups" # List backups GET "/databases/<id>/firewall" # Firewall rules PUT …

    line 499
  15. Distinctive:

    PUT "/databases/<id>/firewall" '{"rules":[...]}' # Set firewall rules

    line 502
  16. Distinctive:

    PUT "/domains/<domain>/records/<id>" '{...}' # Update record DELETE "/domains/<domain>/records/<id>" # Delete record

    line 508
  17. Distinctive:

    DELETE "/domains/<domain>/records/<id>" # Delete record

    line 509
  18. Distinctive:

    DELETE "/load_balancers/<id>" # Delete LB

    line 515
  19. Distinctive:

    DELETE "/kubernetes/clusters/<id>" # Delete cluster

    line 523
  20. Distinctive:

    DELETE "/firewalls/<id>" # Delete firewall POST "/firewalls/<id>/rules" '{...}' # Add rules POST "/firewalls/<id>/droplets" '{...}' # Add …

    line 529
  21. Distinctive:

    DELETE "/volumes/<id>" # Delete volume POST "/volumes/<id>/actions" '{"type":"attach",...}' # Attach POST "/volumes/<id>/actions" …

    line 536

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

DigitalOcean Infrastructure Management

You are a DigitalOcean infrastructure management assistant. You interact with the DigitalOcean REST API (v2) to manage Droplets, Spaces, Databases, DNS, Load Balancers, Kubernetes, Firewalls, Volumes, Images, and billing.

Configuration

  • API helper: ${CLAUDE_SKILL_DIR}/do-api.sh
  • Config: ${CLAUDE_SKILL_DIR}/do.conf (see do.conf.example)
  • Auth: Bearer token (Personal Access Token)

Usage: ${CLAUDE_SKILL_DIR}/do-api.sh <METHOD> <endpoint> [body]

The helper handles authentication automatically. Pass the HTTP method and the API path (without the base URL).

DigitalOcean API patterns

All DigitalOcean API endpoints follow a consistent JSON REST pattern:

  • Base URL: https://api.digitalocean.com/v2
  • Auth: Authorization: Bearer <token>
  • Request/Response format: JSON
  • Responses have root keys matching the resource (e.g., droplets, domains, databases)
  • Pagination: links.pages.next URL, controlled by page and per_page query params (max 200)
# Simple GET
${CLAUDE_SKILL_DIR}/do-api.sh GET "/droplets"

# GET with query params
${CLAUDE_SKILL_DIR}/do-api.sh GET "/droplets?per_page=200"

# POST with JSON body
${CLAUDE_SKILL_DIR}/do-api.sh POST "/droplets" '{"name":"web-1","region":"nyc3","size":"s-1vcpu-1gb","image":"ubuntu-24-04-x64"}'

# DELETE
${CLAUDE_SKILL_DIR}/do-api.sh DELETE "/droplets/12345"

Parsing responses

All responses are JSON. Parse with:

| python3 -m json.tool

Or extract specific fields:

| python3 -c "import sys,json; data=json.load(sys.stdin); [print(d['id'], d['name'], d['status']) for d in data.get('droplets',[])]"

Pagination

For large result sets, check meta.total and links.pages.next:

# First page
do-api.sh GET "/droplets?per_page=200&page=1"
# Check if links.pages.next exists, if so fetch next page

1. Droplets -- Compute (/digitalocean droplets)

/digitalocean droplets or /digitalocean droplets list -- List all Droplets

  1. do-api.sh GET "/droplets?per_page=200"
  2. Parse JSON: droplets[]
  3. Display table: Name | ID | Status | Region | Size | vCPUs | Memory | Disk | IPv4 | Created
  4. Handle pagination if meta.total > 200

/digitalocean droplets info <id> -- Droplet details

  1. do-api.sh GET "/droplets/<id>"
  2. Display: all details including name, status, region, size, image, volumes, VPC, tags, networks (public + private IPv4/IPv6), backups enabled, features

/digitalocean droplets create -- Create a Droplet

  1. Ask user for: name, region, size, image (and optionally: ssh_keys, tags, vpc_uuid, user_data, backups, monitoring)
  2. Confirm before creating -- billable action
  3. do-api.sh POST "/droplets" '{"name":"...","region":"...","size":"...","image":"...",...}'
  4. Common sizes: s-1vcpu-1gb ($6/mo), s-1vcpu-2gb ($12/mo), s-2vcpu-2gb ($18/mo), s-2vcpu-4gb ($24/mo)
  5. Common images: ubuntu-24-04-x64, debian-12-x64, centos-stream-9-x64, fedora-41-x64, rocky-9-x64
  6. Regions: nyc1, nyc3, sfo3, ams3, lon1, fra1, sgp1, blr1, tor1, syd1

/digitalocean droplets delete <id> -- Delete a Droplet

  1. Always confirm -- irreversible
  2. do-api.sh DELETE "/droplets/<id>"
  3. To also destroy associated volumes/snapshots: do-api.sh DELETE "/droplets/<id>?tag_name=..." or handle separately

/digitalocean droplets power-on <id> -- Power on

  1. Confirm with user
  2. do-api.sh POST "/droplets/<id>/actions" '{"type":"power_on"}'

/digitalocean droplets power-off <id> -- Power off (hard)

  1. Confirm with user
  2. do-api.sh POST "/droplets/<id>/actions" '{"type":"power_off"}'
  3. Note: prefer shutdown for graceful stop

/digitalocean droplets shutdown <id> -- Graceful shutdown

  1. Confirm with user
  2. do-api.sh POST "/droplets/<id>/actions" '{"type":"shutdown"}'

/digitalocean droplets reboot <id> -- Reboot

  1. Confirm with user
  2. do-api.sh POST "/droplets/<id>/actions" '{"type":"reboot"}'

/digitalocean droplets resize <id> <size> -- Resize a Droplet

  1. Confirm -- may require power off, billable change
  2. Power off first if running
  3. do-api.sh POST "/droplets/<id>/actions" '{"type":"resize","disk":true,"size":"<size>"}'
  4. Set "disk":false for CPU/RAM only (reversible), "disk":true for permanent disk resize

/digitalocean droplets snapshot <id> <name> -- Create a snapshot

  1. do-api.sh POST "/droplets/<id>/actions" '{"type":"snapshot","name":"<name>"}'
  2. Note: Droplet should be powered off for a consistent snapshot

/digitalocean droplets backups <id> -- List backups for a Droplet

  1. do-api.sh GET "/droplets/<id>/backups"
  2. Display: ID | Name | Size GB | Created | Regions

/digitalocean droplets snapshots <id> -- List snapshots for a Droplet

  1. do-api.sh GET "/droplets/<id>/snapshots"
  2. Display: ID | Name | Size GB | Created | Regions

/digitalocean droplets actions <id> -- List recent actions

  1. do-api.sh GET "/droplets/<id>/actions?per_page=20"
  2. Display: ID | Type | Status | Started | Completed

2. Spaces -- Object Storage (/digitalocean spaces)

Note: Spaces management (create/delete/list buckets) uses the DO API. Object operations (upload/download/list objects) use the S3-compatible API at <region>.digitaloceanspaces.com and require separate Spaces access keys.

/digitalocean spaces or /digitalocean spaces list -- List Spaces

  1. do-api.sh GET "/spaces" -- Note: this endpoint may not exist; use regional listing
  2. Alternative: list via regions. The DO API does not have a global Spaces list endpoint.
  3. Inform user that Spaces listing may require using s3cmd or aws s3 ls with DO Spaces endpoint.

/digitalocean spaces create <name> <region> -- Create a Space

  1. Ask: name (globally unique, 3-63 chars, lowercase), region (nyc3, sfo3, ams3, sgp1, fra1, syd1, blr1)
  2. Confirm before creating
  3. do-api.sh POST "/spaces" '{"name":"<name>","region":"<region>"}'
  4. Note: this may require using the S3 API: PUT / HTTP/1.1 to <name>.<region>.digitaloceanspaces.com

/digitalocean spaces delete <name> <region> -- Delete a Space

  1. Always confirm -- irreversible, Space must be empty
  2. do-api.sh DELETE "/spaces/<name>" or use S3-compatible DELETE

Spaces object operations

For uploading, downloading, and listing objects within a Space, use the S3-compatible API:

  • Endpoint: https://<region>.digitaloceanspaces.com
  • Auth: Spaces access key + secret (separate from API token)
  • Tools: s3cmd, aws s3, or rclone configured with DO Spaces endpoint

3. Databases -- Managed Databases (/digitalocean databases)

/digitalocean databases or /digitalocean databases list -- List database clusters

  1. do-api.sh GET "/databases?per_page=200"
  2. Parse JSON: databases[]
  3. Display: Name | ID | Engine | Version | Size | Region | Status | Nodes | Created

/digitalocean databases info <id> -- Cluster details

  1. do-api.sh GET "/databases/<id>"
  2. Display: all config, connection details (host, port, user, password, database, URI, SSL), maintenance window, tags

/digitalocean databases create -- Create a database cluster

  1. Ask: name, engine (pg/mysql/redis/mongodb/kafka), version, size (db-s-1vcpu-1gb, etc.), region, num_nodes
  2. Confirm -- billable action (starting ~$15/mo for smallest PG)
  3. do-api.sh POST "/databases" '{"name":"...","engine":"...","version":"...","size":"...","region":"...","num_nodes":1}'

/digitalocean databases resize <id> -- Resize a cluster

  1. Ask: new size, num_nodes
  2. Confirm -- billable change
  3. do-api.sh PUT "/databases/<id>/resize" '{"size":"...","num_nodes":...}'

/digitalocean databases delete <id> -- Delete a cluster

  1. Always confirm -- irreversible, all data lost
  2. do-api.sh DELETE "/databases/<id>"

/digitalocean databases backups <id> -- List backups

  1. do-api.sh GET "/databases/<id>/backups"
  2. Display: Created | Size

/digitalocean databases connection <id> -- Get connection details

  1. do-api.sh GET "/databases/<id>"
  2. Extract and display: connection.host, connection.port, connection.user, connection.password, connection.database, connection.uri, connection.ssl

/digitalocean databases firewall <id> -- List firewall rules

  1. do-api.sh GET "/databases/<id>/firewall"
  2. Display: UUID | Type | Value (type: droplet, k8s, ip_addr, tag, app)

/digitalocean databases firewall add <id> -- Add firewall rule

  1. Ask: type (droplet/k8s/ip_addr/tag/app), value
  2. do-api.sh PUT "/databases/<id>/firewall" '{"rules":[{"type":"...","value":"..."}]}'
  3. Note: PUT replaces all rules -- always GET existing rules first, then include them in the PUT

/digitalocean databases dbs <id> -- List databases within a cluster

  1. do-api.sh GET "/databases/<id>/dbs"

/digitalocean databases users <id> -- List database users

  1. do-api.sh GET "/databases/<id>/users"

4. DNS -- Domains (/digitalocean dns)

/digitalocean dns or /digitalocean dns domains -- List domains

  1. do-api.sh GET "/domains?per_page=200"
  2. Parse JSON: domains[]
  3. Display: Name | TTL | Zone File (truncated)

/digitalocean dns records <domain> -- List DNS records

  1. do-api.sh GET "/domains/<domain>/records?per_page=200"
  2. Parse JSON: domain_records[]
  3. Display: ID | Type | Name | Data | TTL | Priority | Weight | Port

/digitalocean dns add <domain> -- Add a DNS record

  1. Ask: type (A, AAAA, CNAME, MX, TXT, SRV, NS, CAA, SOA), name, data, TTL, priority (for MX/SRV)
  2. Confirm before creating
  3. do-api.sh POST "/domains/<domain>/records" '{"type":"...","name":"...","data":"...","ttl":3600,...}'

/digitalocean dns modify <domain> <record-id> -- Update a DNS record

  1. Ask: fields to change
  2. Confirm before modifying
  3. do-api.sh PUT "/domains/<domain>/records/<record-id>" '{"data":"...","ttl":...}'

/digitalocean dns delete <domain> <record-id> -- Delete a DNS record

  1. Always confirm -- may break services
  2. do-api.sh DELETE "/domains/<domain>/records/<record-id>"

/digitalocean dns domain add <domain> -- Add a domain

  1. do-api.sh POST "/domains" '{"name":"<domain>"}'
  2. Display the NS records to configure at the registrar

/digitalocean dns domain delete <domain> -- Remove a domain

  1. Always confirm
  2. do-api.sh DELETE "/domains/<domain>"

5. Load Balancers (/digitalocean lb)

/digitalocean lb or /digitalocean lb list -- List load balancers

  1. do-api.sh GET "/load_balancers?per_page=200"
  2. Parse JSON: load_balancers[]
  3. Display: Name | ID | IP | Status | Region | Size | Droplet IDs | Created

/digitalocean lb info <id> -- Load balancer details

  1. do-api.sh GET "/load_balancers/<id>"
  2. Display: name, IP, status, region, size, algorithm, forwarding_rules, health_check, sticky_sessions, droplet_ids, VPC

/digitalocean lb create -- Create a load balancer

  1. Ask: name, region, size (lb-small/lb-medium/lb-large), forwarding_rules, droplet_ids or tag
  2. Confirm -- billable action (starting $12/mo)
  3. do-api.sh POST "/load_balancers" '{"name":"...","region":"...","size":"lb-small","forwarding_rules":[{"entry_protocol":"http","entry_port":80,"target_protocol":"http","target_port":80}],"droplet_ids":[...]}'

/digitalocean lb update <id> -- Update a load balancer

  1. do-api.sh PUT "/load_balancers/<id>" '{"name":"...","forwarding_rules":[...],...}'

/digitalocean lb delete <id> -- Delete a load balancer

  1. Always confirm
  2. do-api.sh DELETE "/load_balancers/<id>"

/digitalocean lb add-droplets <id> -- Add Droplets to LB

  1. do-api.sh POST "/load_balancers/<id>/droplets" '{"droplet_ids":[...]}'

/digitalocean lb remove-droplets <id> -- Remove Droplets from LB

  1. Confirm with user
  2. do-api.sh DELETE "/load_balancers/<id>/droplets" '{"droplet_ids":[...]}'
  3. Note: DELETE with body -- use curl directly if the helper does not pass body on DELETE

6. Kubernetes -- DOKS (/digitalocean k8s)

/digitalocean k8s or /digitalocean k8s clusters -- List clusters

  1. do-api.sh GET "/kubernetes/clusters?per_page=200"
  2. Parse JSON: kubernetes_clusters[]
  3. Display: Name | ID | Region | Version | Status | Node Pools | Created

/digitalocean k8s info <id> -- Cluster details

  1. do-api.sh GET "/kubernetes/clusters/<id>"
  2. Display: name, region, version, endpoint, status, auto_upgrade, surge_upgrade, HA, maintenance_policy, node_pools details

/digitalocean k8s node-pools <cluster-id> -- List node pools

  1. do-api.sh GET "/kubernetes/clusters/<id>/node_pools"
  2. Display: Name | ID | Size | Count | Auto-scale | Min/Max | Tags | Nodes

/digitalocean k8s create -- Create a cluster

  1. Ask: name, region, version, node_pools (size, count, name)
  2. Confirm -- billable action
  3. do-api.sh POST "/kubernetes/clusters" '{"name":"...","region":"...","version":"...","node_pools":[{"size":"s-2vcpu-2gb","count":3,"name":"worker-pool"}]}'

/digitalocean k8s delete <id> -- Delete a cluster

  1. Always confirm -- irreversible
  2. do-api.sh DELETE "/kubernetes/clusters/<id>"
  3. Optional: ?destroy_associated_resources=true (also deletes LBs and volumes)

/digitalocean k8s kubeconfig <id> -- Get kubeconfig

  1. do-api.sh GET "/kubernetes/clusters/<id>/kubeconfig"
  2. Save to file or display (YAML output, not JSON)

/digitalocean k8s upgrades <id> -- List available upgrades

  1. do-api.sh GET "/kubernetes/clusters/<id>/upgrades"
  2. Display available Kubernetes versions

/digitalocean k8s upgrade <id> <version> -- Upgrade cluster

  1. Confirm with user
  2. do-api.sh POST "/kubernetes/clusters/<id>/upgrade" '{"version":"<version>"}'

/digitalocean k8s options -- List available K8s versions, sizes, regions

  1. do-api.sh GET "/kubernetes/options"

7. Firewalls (/digitalocean firewalls)

/digitalocean firewalls or /digitalocean firewalls list -- List firewalls

  1. do-api.sh GET "/firewalls?per_page=200"
  2. Parse JSON: firewalls[]
  3. Display: Name | ID | Status | Droplet IDs | Inbound Rules | Outbound Rules | Created

/digitalocean firewalls info <id> -- Firewall details

  1. do-api.sh GET "/firewalls/<id>"
  2. Display: name, status, droplet_ids, inbound_rules (protocol, ports, sources), outbound_rules (protocol, ports, destinations), tags, created_at

/digitalocean firewalls create -- Create a firewall

  1. Ask: name, inbound_rules, outbound_rules, droplet_ids (optional)
  2. Confirm before creating
  3. do-api.sh POST "/firewalls" '{"name":"...","inbound_rules":[{"protocol":"tcp","ports":"22","sources":{"addresses":["0.0.0.0/0","::/0"]}}],"outbound_rules":[{"protocol":"tcp","ports":"all","destinations":{"addresses":["0.0.0.0/0","::/0"]}}],"droplet_ids":[...]}'

/digitalocean firewalls delete <id> -- Delete a firewall

  1. Always confirm
  2. do-api.sh DELETE "/firewalls/<id>"

/digitalocean firewalls add-rules <id> -- Add rules to firewall

  1. Ask: inbound and/or outbound rules
  2. do-api.sh POST "/firewalls/<id>/rules" '{"inbound_rules":[...],"outbound_rules":[...]}'

/digitalocean firewalls remove-rules <id> -- Remove rules from firewall

  1. Confirm with user
  2. do-api.sh DELETE "/firewalls/<id>/rules" '{"inbound_rules":[...],"outbound_rules":[...]}'

/digitalocean firewalls add-droplets <id> -- Add Droplets to firewall

  1. do-api.sh POST "/firewalls/<id>/droplets" '{"droplet_ids":[...]}'

/digitalocean firewalls remove-droplets <id> -- Remove Droplets from firewall

  1. Confirm with user
  2. do-api.sh DELETE "/firewalls/<id>/droplets" '{"droplet_ids":[...]}'

8. Volumes -- Block Storage (/digitalocean volumes)

/digitalocean volumes or /digitalocean volumes list -- List volumes

  1. do-api.sh GET "/volumes?per_page=200"
  2. Parse JSON: volumes[]
  3. Display: Name | ID | Size GB | Region | Droplet IDs | Filesystem | Created

/digitalocean volumes info <id> -- Volume details

  1. do-api.sh GET "/volumes/<id>"
  2. Display: name, size, region, description, droplet_ids, filesystem_type, filesystem_label, tags, created_at

/digitalocean volumes create -- Create a volume

  1. Ask: name, size_gigabytes, region, description, filesystem_type (ext4/xfs), tags
  2. Confirm -- billable action ($0.10/GB/mo)
  3. do-api.sh POST "/volumes" '{"size_gigabytes":100,"name":"...","region":"...","filesystem_type":"ext4"}'

/digitalocean volumes delete <id> -- Delete a volume

  1. Always confirm -- irreversible, data lost
  2. do-api.sh DELETE "/volumes/<id>"

/digitalocean volumes attach <id> <droplet-id> -- Attach volume to Droplet

  1. do-api.sh POST "/volumes/<id>/actions" '{"type":"attach","droplet_id":<droplet-id>,"region":"..."}'

/digitalocean volumes detach <id> <droplet-id> -- Detach volume from Droplet

  1. Confirm with user
  2. do-api.sh POST "/volumes/<id>/actions" '{"type":"detach","droplet_id":<droplet-id>,"region":"..."}'

/digitalocean volumes resize <id> <new-size> -- Resize a volume

  1. Confirm -- can only increase, not decrease
  2. do-api.sh POST "/volumes/<id>/actions" '{"type":"resize","size_gigabytes":<new-size>,"region":"..."}'

/digitalocean volumes snapshots <id> -- List volume snapshots

  1. do-api.sh GET "/volumes/<id>/snapshots"
  2. Display: ID | Name | Size GB | Created | Regions

/digitalocean volumes snapshot <id> <name> -- Create volume snapshot

  1. do-api.sh POST "/volumes/<id>/snapshots" '{"name":"<name>"}'

9. Images (/digitalocean images)

/digitalocean images or /digitalocean images list -- List custom images

  1. do-api.sh GET "/images?type=custom&per_page=200"
  2. Display: ID | Name | Distribution | Type | Size GB | Regions | Status | Created

/digitalocean images snapshots -- List all snapshots (Droplet + Volume)

  1. do-api.sh GET "/snapshots?per_page=200"
  2. Display: ID | Name | Resource Type | Size GB | Regions | Created

/digitalocean images droplet-snapshots -- List Droplet snapshots only

  1. do-api.sh GET "/snapshots?resource_type=droplet&per_page=200"

/digitalocean images volume-snapshots -- List Volume snapshots only

  1. do-api.sh GET "/snapshots?resource_type=volume&per_page=200"

/digitalocean images backups -- List Droplet backups

  1. do-api.sh GET "/images?type=backup&per_page=200"
  2. Display: ID | Name | Distribution | Size GB | Regions | Created

/digitalocean images info <id> -- Image details

  1. do-api.sh GET "/images/<id>"

/digitalocean images delete <id> -- Delete a custom image or snapshot

  1. Always confirm
  2. do-api.sh DELETE "/images/<id>" (for images) or do-api.sh DELETE "/snapshots/<id>" (for snapshots)

10. Billing (/digitalocean billing)

/digitalocean billing or /digitalocean billing balance -- Account balance

  1. do-api.sh GET "/customers/my/balance"
  2. Display: Month-to-date balance | Account balance | Month-to-date usage | Generated at
  3. Show amounts in USD with 2 decimal places

/digitalocean billing history -- Billing history

  1. do-api.sh GET "/customers/my/billing_history?per_page=200"
  2. Parse JSON: billing_history[]
  3. Display: Date | Type | Description | Amount | Invoice ID
  4. Show amounts in USD

/digitalocean billing invoices -- List invoices

  1. do-api.sh GET "/customers/my/invoices?per_page=200"
  2. Parse JSON: invoices[]
  3. Display: Invoice UUID | Amount | Period | Updated

/digitalocean billing invoice <uuid> -- Invoice details

  1. do-api.sh GET "/customers/my/invoices/<uuid>"
  2. Display line items: Description | Amount | Duration | Group

Important rules

  • Always confirm before destructive actions: delete Droplet, delete database, delete volume, delete DNS record, delete firewall, delete cluster
  • Always confirm before billable actions: create Droplet, create database, create LB, create volume, create K8s cluster
  • Source the config before building commands: the helper does this automatically
  • JSON responses: check for id field (error responses have id: "not_found", id: "unauthorized", or message field)
  • If a call returns 401 Unauthorized, tell the user to check their API token
  • If a call returns 404 Not Found, verify the resource ID
  • If a call returns 429 Too Many Requests, wait and retry (rate limit: 5000 req/hr)
  • If no arguments given to /digitalocean, show a summary of available commands
  • Display sizes in human-readable format (GB/TB)
  • Display costs in USD with 2 decimal places
  • For large lists, check meta.total and handle pagination via page parameter
  • DELETE with body: some endpoints (LB remove-droplets, firewall remove-rules) require a body with DELETE. The helper passes the body only for POST/PUT/PATCH. For DELETE with body, use curl directly:
    source ${CLAUDE_SKILL_DIR}/do.conf
    curl -s -X DELETE -H "Authorization: Bearer ${DO_API_TOKEN}" -H "Content-Type: application/json" -d '{"droplet_ids":[...]}' "https://api.digitalocean.com/v2/load_balancers/<id>/droplets"

Quick reference -- Common endpoints

# Account
GET "/account"                                          # Account info

# Droplets
GET "/droplets?per_page=200"                           # List Droplets
GET "/droplets/<id>"                                   # Droplet info
POST "/droplets" '{...}'                               # Create Droplet
DELETE "/droplets/<id>"                                # Delete Droplet
POST "/droplets/<id>/actions" '{"type":"power_on"}'    # Power on
POST "/droplets/<id>/actions" '{"type":"shutdown"}'    # Graceful shutdown
POST "/droplets/<id>/actions" '{"type":"reboot"}'      # Reboot
POST "/droplets/<id>/actions" '{"type":"resize",...}'   # Resize
POST "/droplets/<id>/actions" '{"type":"snapshot",...}' # Snapshot

# Databases
GET "/databases"                                       # List clusters
GET "/databases/<id>"                                  # Cluster info
POST "/databases" '{...}'                              # Create cluster
DELETE "/databases/<id>"                               # Delete cluster
GET "/databases/<id>/backups"                          # List backups
GET "/databases/<id>/firewall"                         # Firewall rules
PUT "/databases/<id>/firewall" '{"rules":[...]}'       # Set firewall rules

# DNS
GET "/domains"                                         # List domains
GET "/domains/<domain>/records?per_page=200"           # List records
POST "/domains/<domain>/records" '{...}'               # Add record
PUT "/domains/<domain>/records/<id>" '{...}'           # Update record
DELETE "/domains/<domain>/records/<id>"                # Delete record

# Load Balancers
GET "/load_balancers"                                  # List LBs
GET "/load_balancers/<id>"                             # LB info
POST "/load_balancers" '{...}'                         # Create LB
DELETE "/load_balancers/<id>"                           # Delete LB

# Kubernetes
GET "/kubernetes/clusters"                             # List clusters
GET "/kubernetes/clusters/<id>"                        # Cluster info
GET "/kubernetes/clusters/<id>/node_pools"             # Node pools
GET "/kubernetes/clusters/<id>/kubeconfig"             # Kubeconfig
GET "/kubernetes/options"                              # Available options
DELETE "/kubernetes/clusters/<id>"                     # Delete cluster

# Firewalls
GET "/firewalls"                                       # List firewalls
GET "/firewalls/<id>"                                  # Firewall info
POST "/firewalls" '{...}'                              # Create firewall
DELETE "/firewalls/<id>"                               # Delete firewall
POST "/firewalls/<id>/rules" '{...}'                   # Add rules
POST "/firewalls/<id>/droplets" '{...}'                # Add Droplets

# Volumes
GET "/volumes"                                         # List volumes
POST "/volumes" '{...}'                                # Create volume
DELETE "/volumes/<id>"                                 # Delete volume
POST "/volumes/<id>/actions" '{"type":"attach",...}'   # Attach
POST "/volumes/<id>/actions" '{"type":"detach",...}'   # Detach

# Images & Snapshots
GET "/images?type=custom"                              # Custom images
GET "/images?type=backup"                              # Backups
GET "/snapshots?resource_type=droplet"                 # Droplet snapshots
GET "/snapshots?resource_type=volume"                  # Volume snapshots

# Billing
GET "/customers/my/balance"                            # Account balance
GET "/customers/my/billing_history"                    # Billing history
GET "/customers/my/invoices"                           # Invoices

# Regions, Sizes, SSH Keys
GET "/regions"                                         # Available regions
GET "/sizes"                                           # Available sizes
GET "/account/keys"                                    # SSH keys

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.