I run a small company, Kilawatt Cloud, that lets an AI agent rent GPU compute on its own and pay per job. In mid-October we tested that with real jobs on real hardware. This is an account of what we built, what broke, and which safeguards turned out to be necessary. I have tried to keep what we demonstrated apart from what we hope to build.
What we built
The working piece is an extension for the open-source Goose agent, published as kilawatt-mcp-server. It gives an agent tools to get a quote, run a job and check job status, paying per job with the x402 standard. Behind it, Kilawatt Cloud routes the job to one of five suppliers we connect to by API: Vast.ai, RunPod, Hyperstack, Lambda and Thunder Compute. We also published the interface as a small open specification so others can implement it.
What we demonstrated
On October 14 we ran 73 real jobs in one evening across the five suppliers, from our own test account. Twelve were refused before any machine existed. Sixty-one launched. Fifty-two reached ready and ran. Nine launched but never became ready. That is a record of one evening. It is not a reliability rate, and the mix of suppliers and GPU types was not designed to be representative.
What broke
Three things stand out.
First, cleanup. On one supplier, our code deleted machines without confirming they were gone. Ten machines stayed running, and later launches were refused because the account hit its limit. We found it because we checked the supplier's own list instead of trusting our records. The fix reads the supplier's list after every delete. On October 15 we ran one real deletion test: we created one machine, deleted it, and the supplier's list showed zero machines afterwards. That is one test, so the supplier stays limited to internal test traffic for now.
Second, failover bookkeeping. When a job moved to a new machine, our code overwrote the original machine's identifier on two jobs, which would have made cleanup of the first machine unreliable. We fixed it.
Third, an outside tester reviewed our code on October 10 and gave us nine findings. We fixed eight in published code. Two of the nine could have caused an overpayment or a double payment.
Which safeguards were necessary
The lesson running through all of this is that an agent calls tools quickly and repeatedly, so limits have to live in the tool, not in the prompt.
Spending limits per job and per session, set in the extension's configuration, plus a limit of three active jobs at a time.
An explicit confirmation flag and a maximum price on every call, so an agent cannot buy by accident.
Secrets never printed. The extension's tests assert that its output contains neither the API key nor the payment key.
Verification after every destructive step: read the supplier's own state, do not trust our own record.
A new supplier is held to internal test traffic until it passes repeated checks.
The failover result
We ran two deliberate kill tests, stopping a machine in the middle of a job. In the first, the system detected the loss in 238 seconds and we resumed the job by hand. In the second, it detected the loss in 121 seconds and resumed automatically from the last saved checkpoint, about 253 seconds from the kill to work running again. So detection ranged from 121 to 238 seconds across two tests.
The limits
Two tests are not a guarantee. We have not tested a kill during a checkpoint write, several failures at once, or failover on every supplier. All of this ran on our own account with small jobs, not on customers' production traffic. The extension's automated tests use mocked responses, so they show how the code behaves, not live behavior. We also publish a count of more than 70 capacity sources seen available across the five suppliers; that counts listings we could see, not sources that have run our jobs.
Demonstrated versus vision
Demonstrated: an agent can quote, launch, monitor and clean up real GPU jobs across five suppliers under hard limits, and one job survived a machine being killed. The vision is agents buying compute across many suppliers with failover as a routine, trustworthy default. We are not there. Our next step is a larger batch of runs, and we will publish what breaks.


