What I Learned Running Cursor Cloud Agents
The useful work was boring. The expensive part was still review.
Cursor cloud agents are useful in production. Mostly for boring things.
The first one I trusted with real work updated one section of one documentation file. A pull request changed the code, the agent checked whether the matching documentation was stale, and it opened a small follow-up when needed.
That job taught me more than the ambitious ones.
A cloud agent is Cursor working on a branch somewhere that isn’t my laptop. It can read the repository, make changes, run commands, and open a pull request. A person or an external trigger starts the session.
The detached runtime is the interesting bit. My laptop can be closed while the work continues. The agent still needs a task it can finish and an environment that makes the task real.
Start with the work nobody is fighting to own
The documentation updater was deliberately dull. It had a narrow definition of done and failed safely. A bad attempt could waste a few minutes of review or leave one paragraph stale.
That made it a good place to discover mundane requirements. Before opening a pull request, the agent had to check whether another draft already existed. It needed to connect the code change to one exact section. It had to leave unrelated prose alone.
If I were starting that use case today, I would also check whether Bugbot already covers it. Owning an automation is only fun until it becomes another small system that needs care.
My first prompt described a department
The original brief was roughly: keep the documentation consistent with the codebase.
That sounds clear until several pull requests change related code at the same time. The agent would prepare an update, another change would merge, and its work would be stale before review. It also had no sensible stopping point. “Consistent” could mean one sentence, every example, or a tour through the whole documentation tree.
I had handed it responsibility for a department and expected a tidy patch.
The useful version named one file and one section. It serialized overlapping runs. It checked for an existing draft before creating another. The job became small enough to finish before its assumptions expired.
That was my first real constraint: write “surgical” in the prompt, then make the environment enforce it.
A prompt is a note taped above the workbench
The next automation inspected a week of production errors and proposed low-impact fixes. The prompt said no refactors, no architectural changes, and no cleanup along the way.
That helped. It wasn’t enough.
An agent without the repository’s tools is like a mechanic standing in an empty room with a note that says “fix the brakes.” The instruction can be excellent. There is still no lift, no wrench, and no car manual.
Before the agent had a real development environment, each attempt began with a stack trace and code search. It guessed. Once it could run the repository and inspect nearby history, its patches became narrower and its explanations became easier to check.
I built a dedicated container with the project’s tooling and gave it scoped access to the repository context it needed. Cursor can use its own Dockerfile configuration or a .devcontainer. I have been moving toward the latter because the format also works for local development.
containers.dev is the useful starting point. Cursor also documents its environment resolution order, which matters once a repository has more than one container definition.
The container is the workbench. The prompt is the note taped above it. I spent too much time editing the note while the bench was empty.
The agent can do the big thing. I don’t want it to
The production-error automation had one repeated instruction: surgical fix only.
Agents are very willing to fix the nearby code while they are in there. The bug becomes a cleanup. The cleanup discovers inconsistent names. Soon the result is a 40-file pull request whose original purpose occupies 6 lines.
That can be valid work. It is terrible unattended work. I scope automations to one function or one file when the problem allows it. If the correct fix crosses an architectural boundary, the agent can explain that and stop.
The limit belongs in more than prose. Give the agent only the tools and credentials the task needs. Have it run the smallest relevant test. Reject output that touches obviously unrelated areas. A note above the bench works better when the wrong tools are not on the bench.
Daily automation lasted a couple of days
The first production-error runs were scheduled daily. We dialed them back within a couple of days.
The automation worked. That was the problem.
Each result still needed a person to ask whether the proposed change fixed the cause, whether the test proved anything, and whether a quiet failure mode had been missed. Small pull requests made those questions easier. They did not answer them.
Automation changes where the effort lands. It can remove the search through logs and the mechanical patch. It creates a queue of plausible changes that somebody has to understand. If that queue grows faster than the team can review it, the bot has built a new backlog.
We separated agent output from ordinary alerts so it could be reviewed on its own cadence. The exact channel matters less than the boundary. Production alerts demand immediate attention. Agent proposals are work products. Mixing them trains people to ignore both.
This is the part most demos skip because the demo ends when the pull request opens. In production, that is when the bill arrives.
Triggers are ordinary software
Schedules and GitHub webhooks covered most of our triggers. For custom filtering, a GitHub App gave us a first-class identity and scoped access to repository events without spending an agent run just to decide whether work existed.
The trigger should be boring. Receive an event, apply a small amount of deterministic filtering, and start the agent with the useful context. When trigger logic turns into its own agent conversation, latency and cost appear before the real task begins.
This is also where broad credentials sneak in. I prefer one narrow identity per workflow. It is more annoying to set up and much easier to reason about after the novelty wears off.
Reproducible repositories win before the agent starts
One small Go service was an easy target. It was containerized, well tested, and quick to become runnable. The agent could clone it, install what it needed, run the relevant test, and produce evidence with the patch.
A larger backend repository took minutes to become ready and depended on more local knowledge. The same automation exposed the repository’s operational limits immediately.
The model was the same. The prompt was the same. The workbench was different.
This is where I have to deflate the whole experiment a little. A cloud agent experiences an unreproducible development environment at machine speed, repeatedly, and sends the resulting confusion to a reviewer.
The best preparation for agent automation has looked suspiciously like ordinary platform work: deterministic setup, tests with useful scope, narrow credentials, and clear ownership. The agent simply makes the gaps harder to ignore.
I still don’t have a great answer for review cost. Slower schedules and smaller patches help, but both reduce how much work the automation can take on. If you are running agents against production code and found a better balance, I would genuinely like to hear about it.
An agent can only move as fast as a reviewer can still understand it.