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 --> PRMy 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.
| Piece | Job | Mine |
|---|---|---|
| Connector | Normalize the vendor API to launch → poll → PR | cursor.py — ~90 lines of stdlib |
| Tool | Expose it to any model as a function | cursor_code(task, repo, model) |
| Agent | A persona whose only job is to use the tool | ”Cursor Engineer” — a coding bot |
| Harness | Register it in the orchestrator’s engine set | engine=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 runLaunch 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 cloned | my machines | Cursor’s VM |
| Cost model | my Claude subscription | my Cursor subscription |
| Control over the loop | full (plan/build/test/review, human gates) | the vendor’s (fast, opinionated, auto-PR) |
| Model | Claude | composer · grok · opus · gpt |
| Best for | private code, my review checklist, gated flow | speed, 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.