How to stop a GPU and verify release over remote MCP
Stopping a rental and keeping files are different steps. Confirm saved files, or Job output_collection status succeeded, before you destroy a running instance. Then destroy that instance, or recognize that a finished Job already released its GPU, and read get_status, list_instances, or the stop result until the instance is no longer running and billing has stopped. A lost response or an ambiguous state does not authorize another allocation; keep the original instance id or Job id and poll that id.
Keeping the files is How to save GPU results over remote MCP. Finding the running instance_id is How to reuse a running GPU over remote MCP. The pricing page is the billing source.
Preconditions
The owner authorizes the MCP connection first. Remote Streamable HTTP is https://cloudgpu.app/mcp. Local stdio is the published cloudgpu-mcp 0.16.3 package. Setup is in the MCP guide. After authorization, read the tool list that session returns. Local and remote tool sets differ.
https://cloudgpu.app/.well-known/mcp.json lists stop_instance in the stdio inventory and says the remote tool set excludes local filesystem and SSH. The published server card sets the remote tool count at 23, and the 0.16.3 package README says that remote endpoint exposes 23 tools that do not need a local filesystem or SSH. Those 23 names are not published. An unauthenticated POST https://cloudgpu.app/mcp returns 401 invalid_token, so the session list is the list to use. stop_instance is not a filesystem or SSH tool. Do not assume it is present on remote MCP, and do not assume it is absent. If stop_instance is missing from the current session list, skip it and use the documented REST destroy path below, or another tool that session actually lists. Do not invent a remote SSH download.
Confirm results first
stop_instance and instance termination erase the instance disk. A Job releases its GPU when the command ends, including when output collection fails. Confirm the save before either of those. Tool names, outputs.files, and the local-versus-remote split are in How to save GPU results over remote MCP.
Stop a running instance
When stop_instance is on the current tool list, cloudgpu-mcp 0.16.3 takes instance_id (string) and force (boolean, default false). The tool destroys the instance and stops billing. The disk is erased. Omit force for the common case. The default is false.
{
"instance_id": "<running instance id>"
}
The download guard is a rule in that local stdio process. run_command marks the instance as ran. The local download tool marks it as downloaded. If this process ran commands on that instance and nothing was downloaded, stop_instance returns an error and does not destroy the instance unless force is true. The refusal text is: “Not stopped: nothing has been downloaded from this instance yet, and stopping erases its disk. Download the results first, or ask the user and call again with force=true.” Send force true only after the owner confirms the results are not needed. The guard tracks download in this process. It is not a server-side block, and Job output collection does not set it. force true is not the default call.
The agent guide stop step is POST /v1/gpu/instances/{id}/destroy. Billing stops when the instance is destroyed. OpenAPI describes that POST as the same operation as DELETE /v1/gpu/instances/{id}: it stops billing and erases the disk. The 0.16.3 local client calls DELETE. Use POST when the client cannot send DELETE. If you set max_minutes or max_spend_usd, the instance is also destroyed when that limit is reached. idle_minutes can end it the same way. Cap fields and what happens when a cap is reached are in How to set GPU budget caps over remote MCP.
Verify release
After a stop call, or when a cap may already have ended the rental, call get_status with that instance_id, list_instances, or both.
{
"instance_id": "<the same instance id>"
}
list_instances takes no parameters. get_status reports status creating, running, stopped, or failed, minutes run, cost so far, whether SSH is ready, api_url when the template has one, and the auto-shutdown limits. The OpenAPI limits object has max_minutes, max_spend_usd, idle_minutes, expires_at, and stopped_by. expires_at is the Unix time when max_minutes ends the instance. stopped_by is max_minutes, max_spend, or idle when one of those limits ended the instance, and null otherwise. cost_usd is spent so far while running, and the final charge once stopped. Report the fields the response contains. The agent rules say to tell the owner the final cost from stop_instance. Do not fill in an amount.
On success, the 0.16.3 client returns the public instance object plus the note Destroyed. Billing has stopped. That object drops the SSH host, user, and password and adds ssh_ready. If the API returns cannot_destroy and a follow-up read shows the instance is no longer running, the client returns the same public object plus the note Already stopped; nothing more to do. Billing has stopped. Treat that as a verified no-op. It does not authorize another allocation. stop_instance is marked idempotentHint: true.
list_instances still includes stopped records from the last 7 days. A listed row with status stopped is a record. The disk is already erased. Job status stopping, and needs_attention, are not a confirmed release.
Jobs and instances
run_job starts a GPU, runs one command, and releases that GPU when the command ends. Its input has no instance_id. Do not call stop_instance to finish that Job. A Job object can include instance_id for the GPU that Job used. That field is not a second rental to destroy. A finished Job is not a running rental.
Call get_job with the original job_id. The agent guide status table says succeeded means the command exited with code 0 and the GPU is destroyed, failed carries an error.code, and cancelled means the Job was cancelled with POST /v1/jobs/{id}/cancel. stopping means the GPU is being destroyed. needs_attention means CloudGPU could not confirm the GPU state and will not retry the Job automatically. Confirm output_collection in the save-results guide. Collection can fail and the GPU can still be released.
When cancel_job is listed, cloudgpu-mcp 0.16.3 takes job_id only. The tool description says it stops the job, destroys the GPU if one was started, and stops billing, and that output not yet uploaded by the command is lost. It is marked idempotentHint: true. The REST call is POST /v1/jobs/{id}/cancel. Then read get_job again. stopping and needs_attention are still not a confirmed release.
{
"job_id": "<the original job id>"
}
When the instance is still starting
If stop_instance gets instance_provisioning, the 0.16.3 client returns this error and does not treat the instance as destroyed: “The instance is still starting and cannot be destroyed yet. Wait for get_status to show running (or failed; failed instances are not charged), then call stop_instance again.” Wait until get_status is running or failed, then decide. OpenAPI’s create description says nothing is charged if the instance ends up failed, and failure_reason is described as why provisioning failed, with the same parenthetical that failed instances are not charged. The agent rules say to inspect final billing and release evidence for a failed instance and not assume the cost is zero. Read get_status or the stop result, including cost_usd, before you tell the owner the cost. A failed start still needs that release evidence. It does not authorize another allocation.
Published OpenAPI documents destroy responses as 200, 404, and 409. It does not name cannot_destroy or instance_provisioning. Those codes are the ones the 0.16.3 client handles. Any other cannot_destroy result, including one where the follow-up read is still running, is the API error from that call. Poll the original id.
Exceptions
Local stdio and remote MCP do not expose the same tools. The download and force guard belongs to the local stdio session. max_spend_usd, max_hours / max_minutes, and idle_minutes can destroy the instance without an explicit stop. Collection can fail and the GPU can still be released. An already-stopped result is idempotent in the 0.16.3 client. A lost response does not authorize another allocation. Keep the original instance id or Job id and poll that id.
Related
Rent, reuse, and release boundaries are in the rent-and-reuse guide. Quotes and Jobs are in GPU Jobs for AI agents and the quote and reuse note. SSH, rsync, and Hub uploads from a machine you can reach are in Save your work before you destroy a cloud GPU. Tool rules are in AGENTS.md. Connection wording is in the MCP guide and the agent guide.
Questions and answers
Does stopping the GPU keep the files?
No. stop_instance and instance termination erase the instance disk. A Job releases its GPU when the command ends, including when output collection fails. Files remain only after a confirmed save. Stopping is not that save.
How do I know billing has stopped?
Read get_status or list_instances for that instance id, or read the stop result. On success, cloudgpu-mcp 0.16.3 returns the public instance object plus the note Destroyed. Billing has stopped. If the API returns cannot_destroy and the instance is no longer running, the note is Already stopped; nothing more to do. Billing has stopped. A get_status value of stopped or failed is release evidence for that id. Report cost_usd and running_minutes from the response. Job status stopping and needs_attention are not a confirmed release.
What if the instance is already stopped?
The 0.16.3 client treats that as a verified no-op when it returns the note Already stopped; nothing more to do. Billing has stopped. stop_instance is marked idempotentHint true. That result does not authorize another allocation. If the response was lost, poll the original instance id.
Does a finished Job still need stop_instance?
No. run_job starts a GPU, runs one command, and releases that GPU when the command ends. stop_instance is the destroy tool for an instance rental, not the release step for that Job. Confirm get_job. Status succeeded, failed, or cancelled means the Job is finished. stopping and needs_attention are not a confirmed release. When cancel_job is listed, pass only job_id, then read get_job again.