DEV Community

Cover image for Your AI Coding Agent Shouldn't Live on Your Laptop
Jorge Peraza
Jorge Peraza

Posted on Originally published at monkeyscode.com

Your AI Coding Agent Shouldn't Live on Your Laptop

Every AI coding tool I have used makes the same assumption: the code is on the laptop you are sitting at.

That is true for maybe half of what an engineering team actually does. The rest happens on a dev box, in CI, on a staging environment, or on a build machine that has the toolchain your laptop does not.

We just shipped the MonkeysCode Code Agent, a desktop app for running coding agents across projects without an editor in the way. The most interesting part of it is not the agent loop. It is where the agent is allowed to run.

Four execution backends

The agent can execute against any of these, and you pick per workspace.

Local. Your machine. Full capability, including semantic search against a local index and interactive shell sessions.

SSH. A remote development box. Every command is translated and executed there, not here. This is the one nobody else offers, and it is the one I use most.

Cloud. A managed container workspace, sandboxed by default.

Remote control. A peer machine over WebSocket, running a remote host agent. A build server, a test rig, a colleague's environment.

Each backend declares its real capabilities honestly. Semantic search is not available over SSH, so the agent's system prompt says so and the UI adapts. It is not allowed to attempt something that will fail and then improvise around the error.

That last detail matters more than it sounds. A lot of agent frustration comes from the model confidently trying something the environment cannot do, failing, and then trying three more things. Telling it the truth up front is cheaper than letting it discover the constraint.

What this looks like for DevOps

Here is the part I think is genuinely underexplored in this category.

CI that fixes itself

The CLI runs the same engine headless, with structured output and real exit codes.

- name: Attempt automated fix
  if: failure()
  run: |
    mcode -p "The test suite failed. Read the output, find the cause, fix it." \
          --output json \
          --permission-mode accept-edits > result.json
    echo "exit=$?"
Enter fullscreen mode Exit fullscreen mode

Because every run is test-gated, a change that does not make the suite green never gets applied. The agent either produces a working fix or it produces nothing. There is no middle state where it commits something plausible and moves on.

That is what makes this usable unattended. Not the model quality, the guardrail.

Scheduled maintenance

Background and scheduled runs mean the boring recurring work can happen without a human starting it.

Every Monday 06:00
  → Update dependencies, run the suite, open a PR if green
Every night
  → Generate tests for files changed in the last 24h
Every deploy
  → Check the changelog matches what actually shipped
Enter fullscreen mode Exit fullscreen mode

Each one produces a signed record and a diff you review before merging. It is not autonomous merging, it is autonomous preparation.

Agents on the machine that has the toolchain

This is the SSH case and it comes up constantly.

Your laptop is macOS on ARM. Production is Linux on x86. The build needs a GPU you do not have, or a database that only exists on the dev box, or a proprietary compiler your security team will not license per-seat.

Point the agent at the machine where those things live. It reads the real filesystem, runs the real build, sees the real errors.

mcode --backend ssh --host devbox-3 \
      -p "The nightly build is failing on the arm64 target. Diagnose it."
Enter fullscreen mode Exit fullscreen mode

No syncing, no containerising your dev environment, no reproducing production locally.

Many agents, many projects

The desktop app orchestrates parallel runs across independent projects, each in an isolated workspace. A mission board shows what every agent is doing, an inbox collects the ones waiting on a decision, and you review a signed diff and test report before anything merges.

For anyone maintaining several services, this is the difference between an agent being a tool you use and an agent being work that happens.

The guardrails, because autonomy without them is a liability

Four permission modes, and you switch with a keystroke.

Mode Reads Edits Runs commands
Plan yes no no
Ask yes on approval on approval
Accept edits yes automatic on approval
Auto yes automatic automatic

Note that edit permission and command permission are deliberately separate. In practice people trust an agent to modify a file long before they trust it to run something in their shell. Bundling those into one autonomy slider was a mistake we made early and corrected.

Auto mode is only available inside a sandbox. Not as a policy, as an enforced constraint. Seatbelt on macOS, bubblewrap on Linux, AppContainer on Windows.

Two engineering details worth stealing

We did not build undo on git stash

Every file the agent touches is snapshotted before its first mutation, so you can revert one file or an entire run.

The obvious implementation is git stash push -u. One command, already there, works.

It also destroys your own uncommitted work.

Think about the actual scenario. You have half-finished changes in your tree. You ask an agent to do something unrelated. You do not like the result and you revert. With git stash, your half-finished changes went with it.

So we built a separate snapshot store. Pre-mutation capture per file, selective revert, workspace-scoped so it cannot reach into another project, and honest about limits: a recursive directory delete is flagged as unrevertable rather than silently skipped.

More work than one git command. But an undo feature that occasionally destroys your work is not an undo feature.

Diagnostics report only what the agent broke

After edits, the agent runs your project's type-checker or linter.

The important part is that it captures a baseline at run start and reports only what is new. If your codebase already has 400 warnings, you do not get 400 warnings. You get the ones it just introduced.

Anyone who has introduced a linter to a legacy codebase knows why this matters. Signal drowns in noise, people stop reading it, and the tool stops working. A verification step that produces noise is the same as no verification step.

It also detects the right checker per language, scopes to affected packages in a monorepo rather than checking everything, and retries once on transient failures so a mid-build state does not report a false problem.

Research that outlives the session

One more thing that does not exist elsewhere as far as I know.

Some work is not a task. It is a question you chase across days. A performance regression nobody can reproduce. A migration you are scoping. A bug that only appears under load. That is a dozen runs across a week, and by Thursday you have forgotten what you ruled out on Monday.

Investigations are long-lived threads scoped to a project. Runs link to them, findings accumulate, and the output is real markdown under .monkeyscode/docs/ in your repository. Git-tracked. Editable in any editor. Reviewable in a pull request.

Not locked in an application database that dies with the tool. If your work lives inside a vendor's storage, you do not own it.

On the model

The agent runs on Capuchin, which we train and serve ourselves, or on Claude, Gemini, ChatGPT, or a model on your own hardware. Switching is a setting.

Capuchin Reason scores 62.1% on SWE-bench Pro. Claude Opus, the current leader, scores 64.3%. We are 2.2 points behind, measured on our own production endpoint at the same quantization and context configuration we actually serve, with the methodology published.

The number I find more informative: in production, 92.7% of requests run on Capuchin rather than on a frontier model, even though every user can switch with one setting. For most daily work the 2.2 points are not something you feel.

Owning the model is also why we can support the ones we do not own. Capuchin is cheap enough for us to serve that we can include frontier allowances in the plan and support local models we earn nothing from.

What is not finished

Semantic search only works on the local backend. Over SSH or against a cloud container you get grep and file operations, not vector search. The agent is told this explicitly rather than being allowed to try and fail, but it is a real limitation.

We have not published a cost-per-task figure. Cursor has. We should, and we will, once the measurement is standardised.

The CLI is shipping shortly rather than shipped.

We are pre-1.0 and say so.

Try it

The Code Agent and the IDE are both included in every plan, including the free tier with your own API keys. Thirty days of unlimited Capuchin, no credit card.

👉 monkeyscode.com/code-agent

If you try it, I would rather hear what broke than get a signup. Comments are open and I read all of them, particularly if you have opinions about the SSH backend, which is the part I am least sure we have got right.

Top comments (0)