I already run my own autonomous engineer. I assign a task and a repo; a Claude Agent SDK executor plans, writes the code, runs the tests, reviews its own diff, and opens a pull request. I call it Origin, and it lives entirely on my own machines.

Then I wanted Cursor’s cloud agents too — their isolated cloud VM, the speed of composer, and a model mix (grok, opus, gpt) I don’t host myself. The obvious question is “which one do I standardize on?” It’s the wrong question. The right answer turned out to be: don’t choose the executor — make it swappable.

That reframing is the whole story. Once you’ve built the orchestration layer, adding a second engine — even a hosted, third-party one — isn’t a rewrite. It’s a thin adapter. Here’s the shape of it.

The orchestrator is the platform; the executor is a plug-in

An agent platform is really two separable things: the surface + orchestrator — how tasks get assigned, tracked, reviewed, evaluated, budgeted — and the executor, the thing that actually does the work. All my differentiation is in the first. The second should be swappable.

flowchart TD
  subgraph Platform["My platform — the part I own"]
    S["Surface: chat · task board · issues"]
    O["Orchestrator: state, review, evals, budget, PR flow"]
  end
  O --> REG{"Engine registry"}
  REG -->|self-hosted| C["Claude Agent SDK<br/>(my machines)"]
  REG -->|hosted| CUR["Cursor Cloud Agents<br/>(their VM)"]
  REG -->|local| L["Local model<br/>(Ollama)"]
  C --> PR([Pull request])
  CUR --> PR
  L --> PR

My platform already had an engine registry — three of them. Adding Cursor meant adding a fourth value, cursor, and teaching the orchestrator what to do when it sees it. Nothing above the registry changed: same task board, same reviewers, same evals, same PR review.

An integration agent is four small pieces

Wrapping a hosted coding agent as a first-class engine took exactly four parts. This is the reusable recipe.

PieceJobMine
ConnectorNormalize the vendor API to launch → poll → PRcursor.py — ~90 lines of stdlib
ToolExpose it to any model as a functioncursor_code(task, repo, model)
AgentA persona whose only job is to use the tool”Cursor Engineer” — a coding bot
HarnessRegister it in the orchestrator’s engine setengine=cursor on the task board

The connector is the only real code, and it’s small because Cursor’s Cloud Agents API is well-shaped for it:

sequenceDiagram
  participant P as My platform
  participant A as api.cursor.com
  participant G as GitHub
  P->>A: POST /v1/agents {prompt, repo, model, autoCreatePR}
  A->>G: clone repo into an isolated VM
  A-->>P: {id, latestRunId, status}
  loop until terminal
    P->>A: GET /v1/agents/{id}/runs/{runId}
    A-->>P: {status, result, git.branches[].prUrl}
  end
  A->>G: push branch + open PR
  P-->>P: surface the PR url on the run

Launch with a prompt and a repo, poll the run until a prUrl appears, surface it. That’s the entire contract. My connector exposes one blocking helper with an on_event callback, so the task board streams Cursor’s status transitions live — exactly like my self-hosted engine does.

One surface, chosen per task

Because the engine is just a field on the task, the choice is per-task, not per-platform. My task board’s engineer picker simply lists both:

Self-hosted (Claude)Cursor Cloud
Where the code is clonedmy machinesCursor’s VM
Cost modelmy Claude subscriptionmy Cursor subscription
Control over the loopfull (plan/build/test/review, human gates)the vendor’s (fast, opinionated, auto-PR)
ModelClaudecomposer · grok · opus · gpt
Best forprivate code, my review checklist, gated flowspeed, throwaway tasks, model variety

Same kanban, same assignee/labels/comments, same GitHub-issue sync, same PR review. I pick the engine like I’d pick a runtime.

Why bother — three concrete wins

  • No lock-in. The vendor is an executor, not my platform. If Cursor’s pricing or behavior changes, I flip a field, not migrate a workflow.
  • One pane of glass. Hosted and self-hosted runs share a task board, an event stream, an eval harness, and a review flow. I compare engines on my golden sets, not their marketing.
  • The integration is cheap. Any hosted agent with a launch-and-poll REST API drops into the same four slots. The expensive part — the orchestrator — I only built once.

That last point is the real lesson. The industry keeps shipping better executors; that’s a gift, not a threat, as long as my platform treats them as interchangeable. I built the surface and the orchestration I’d want regardless of who’s behind it, registered the engines as plug-ins, and now the best one wins per task.

Export for reading

Comments