npx skills add ...
npx skills add runpod/runpod-plugins-official --skill lifecycle-crud
Create, verify by read-back, and manage the lifecycle of Runpod''s reusable plumbing (templates,
npx skills add runpod/runpod-plugins-official --skill lifecycle-crud
You own the lifecycle of Runpod's reusable resources: templates, network volumes, container registry credentials, account secrets, registered SSH public keys, and multi-node clusters. The goal is a correctly provisioned resource the user can rely on: provision cleanly, confirm by reading the resource back, and leave it standing. Tear down only when the user asked for a create-then-clean-up demo or explicit cleanup. Read the existing resources first so you never collide with or clobber something the user already has.
Named as capabilities; the tool serving each one on this server is in the tool binding below.
podCount × gpuCountPerPod GPUs from creation, so state that total hourly price (per-GPU price × the GPU count, from the catalog reads) before creating one.networkVolumeTypes on the data-center read). State the storage cost. Read it back and leave it to serve its purpose. It bills until deleted, so say so; delete and confirm only on an explicit cleanup ask. A volume's size may only increase; a shrink is rejected.include:["GPU_AVAILABILITY"]) to pick a data center that has the target GPU in stock for the product you will run there, and create the volume there. Explain the wiring: mount path into the Pod/worker, weights downloaded once and reused, and the cold-start effect (first job pays the download, later jobs mount the cached weights). Place, don't guess: the volume must live in the same data center as the compute or the mount won't attach, and network volumes attach to Secure Cloud compute only. On a Pod the mount path is the one you set in mounts (no default); a Serverless worker always sees the volume at /runpod-volume, so weights staged from a Pod are read by the endpoint handler at /runpod-volume, not the pod path.name is unique across the account and immutable, so a colliding create is rejected with 409. Create it with the user's real value (they are the only source; never invent one), read it back to confirm the metadata, and tell the user how it is consumed: set an env var on the template, pod, or endpoint to {{ RUNPOD_SECRET_<name> }} and Runpod substitutes the stored value when the pod or worker boots. The value itself is write-only: no read returns it, and you never echo it into the transcript. When the user has not given the value yet, give the whole plan first (the secret name you will use, that the endpoint or template reads it as {{ RUNPOD_SECRET_<name> }}, and that the value is never shown back), then ask for the value. Rotating is update-secret; the new value reaches pods and workers at their next boot, so say that a running instance keeps the value it started with. Deleting a secret is not blocked while it is in use: the references stop resolving and the next pod or worker start that needs them fails, so point the user at the references before a delete.update-ssh-keys is a replace-all PUT, not an append: read the current keys first, send them back together with the new one, and confirm with a read. Sending only the new key silently removes every other key on the account, and [] removes all of them. Keys apply to pods created afterwards with startSsh; a running pod is not updated.include:["AVAILABILITY"] with product:["CLUSTER"], because cluster stock differs from pod stock) and the price first. Then put the exact shape (nodes, GPUs per node, data center) and the total hourly price (podCount × gpuCountPerPod GPUs of the chosen type, priced from the catalog) in front of the user and ask for the go. Only an explicit go in this conversation unlocks create-cluster; a request to create or provision a cluster is the request for that plan, not the go. When the read shows no stock for that GPU, say so and propose the closest shape the read shows in stock. The cluster type, GPU type and GPUs per pod are fixed at creation and update-cluster only renames; pods are added or removed from the console (Scale cluster), not through these tools. So get the shape right the first time and hand a resize to the console. Cluster pods can carry a higher rate than the pod GPU price, so after creation confirm the real rate with list-cluster-billing. templateId provisions every member pod from a pod template and is the only private-image path (a bare registry on the create body is rejected). Read the cluster back with get-cluster for the aggregate pod summary, and list-cluster-pods for the member pods themselves; list-cluster-billing is the spend read.update-ssh-keys overwrites the whole set; a send that omits an existing key deletes it.204 with no body. That is success; confirm with a follow-up read.username/password is expected (write-only), not a bug.409 means the name is taken. Names are immutable, so pick another or rotate the existing secret with update-secret.update-secret carrying both a value and a description is not atomic: if the description write fails after the value rotated, the error response comes back with the new value already in effect. Send the two in separate calls when that partial outcome matters.| Capability | Tool |
|---|---|
| Templates (list/get/create/update/delete) | list-templates, get-template, create-template, update-template, delete-template |
| Network volumes (list/get/create/update/delete) | list-network-volumes, get-network-volume, create-network-volume, update-network-volume, delete-network-volume |
| Registry credentials (list/get/create/delete) | list-registries, get-registry, create-registry, delete-registry |
| Data centers with per-GPU availability (for placement) | list-data-centers / get-data-center (include:["GPU_AVAILABILITY"]); list-gpu-types (include:["AVAILABILITY"] with product) |
| CUDA versions with capacity, per GPU type | the GPU read's cudaVersions; get-capacity for the matrix view |
| Account secrets (list/get/create/update/delete) | list-secrets, get-secret, create-secret, update-secret, delete-secret |
| Registered SSH public keys (read/replace) | get-ssh-keys, update-ssh-keys |
| Clusters (list/get/create/rename/delete, member pods, billing) | list-clusters, get-cluster, create-cluster, update-cluster, delete-cluster, list-cluster-pods, list-cluster-billing |
If a tool named here is missing from the session's tool list, say so and use the nearest read instead of inventing a result.
When asked what exists on the account (inventory, audit, "what's running"): list pods, endpoints, templates, and network volumes; a table per non-empty kind works well (name, id, status, GPU/size, $/hr where the read provides it), with empty kinds noted in a line ("templates: none"). Close with the totals (counts per kind, summed $/hr of running pods) and, if the user implied a concern (cost, stuck resources), the verdict in one sentence.
The cross-journey answer contract (definite facts from reads, commit-don't-hedge, mutations bind to this conversation's creations, a standalone final message, honest failure, granted tools only) is defined in the runpod-mcp skill and applies to every reply from this journey. If the runpod-mcp skill has not been loaded in this conversation, load it now, before the next tool call: its rules on which resources you may change, when a request is the go, and when to stop for the user are not repeated here.