Skip to content

Run Cursor cloud agents on your own machine

Cursor's cloud agents, running their tools on a VM you own.

Deploy on exe.dev

Shelley handles the setup. About 10 minutes.

Prefer a terminal?
curl -fsSL https://exe.dev/deploy/cursor/prompt.txt | ssh exe.dev new --prompt=/dev/stdin

Cursor's Cloud Agents normally run in a VM that Cursor starts for each task. With My Machines, Cursor still runs the agent loop and the models, but every file edit and terminal command runs on a machine you choose. A worker process there holds an outbound HTTPS connection to Cursor and carries out the agent's tool calls. You start agents the usual way, from cursor.com/agents, the desktop app, Slack, GitHub, or Linear, and pick your machine.

Plenty of people point this at a Mac mini in a closet. This page uses an exe.dev VM instead. It is always on, with nothing to buy or keep powered. The worker only dials out, so nothing on the VM is reachable from the internet. Whatever the agents install stays installed for the next task. The repository comes in through the exe.dev GitHub integration, so no GitHub token sits on the VM. And a Linux worker can open an agent's live workspace in the Cursor desktop app, which a Mac can't.

What you get#

  • The Cursor CLI in ~/.local/bin, signed in to your Cursor account (agent about shows your email)
  • GITHUB_REPO cloned into ~/repos through the exe.dev GitHub integration, with origin left at github.com and no GitHub token on the VM
  • cursor-worker.service enabled, so the worker reconnects after a crash or a reboot
  • Worker is now running in the service's log, under this VM's name, with GITHUB_REPO as its repository
What's running, and where
Private ssh my-cursor.exe.xyz a shell, the worker's log, and the checkouts the agents work in
my-cursor.exe.xyz exe.dev VM
Cursor worker agent worker from the Cursor CLI, the cursor-worker systemd service ~/.local/share/cursor-agent
Your repository Cloned through the exe.dev GitHub integration, with origin left at github.com ~/repos
Cursor The agent loop and models, started from cursor.com/agents, the desktop app, Slack, GitHub, or Linear

Deploy with Shelley#

Click Deploy and Shelley will set up Cursor Cloud Agents on a new VM, then check that it works. No config-file wrangling required.

Have these ready; Shelley asks for them:

  • GITHUB_REPO: the GitHub repository the agents work on, as owner/name, already connected to Cursor
Prefer a terminal?
curl -fsSL \
  https://exe.dev/deploy/cursor/prompt.txt \
  | ssh exe.dev new --prompt=/dev/stdin
What Shelley is told
GITHUB_REPO=<fill-this-in>

Set up Cursor Cloud Agents on this VM by following the exe.dev recipe at https://exe.dev/deploy/cursor.md from top to bottom.

The values at the top of this message are mine:
- GITHUB_REPO: the GitHub repository the agents work on, as owner/name, already connected to Cursor
Ask me for any that still say <fill-this-in> before you need them.

The recipe's example VM name is my-cursor. This VM's name is the output of `hostname`: use it wherever the recipe writes my-cursor. Skip the step that creates the VM; you are on it.

You are done when all of these are true. Check each one yourself:
- The Cursor CLI in ~/.local/bin, signed in to your Cursor account (`agent about` shows your email)
- GITHUB_REPO cloned into ~/repos through the exe.dev GitHub integration, with origin left at github.com and no GitHub token on the VM
- cursor-worker.service enabled, so the worker reconnects after a crash or a reboot
- `Worker is now running` in the service's log, under this VM's name, with GITHUB_REPO as its repository

Run "Install by hand" first, skipping VM creation; the rest of the page
is for the owner afterwards. Use GITHUB_REPO exactly as given. Before
cloning, run `git ls-remote https://github.int.exe.xyz/<GITHUB_REPO>.git`;
if it fails, give the owner the `integrations add github` command with
this VM's name (or `integrations attach <name> vm:<vm>` if they already
have an integration for it) and wait until it works. Set git's
user.name and user.email to the owner's; ask if you don't know them.
For "Sign in to Cursor", run `NO_OPEN_BROWSER=1 agent login` in a tmux
session named cursor-login, give the owner the whole link from
`tmux capture-pane -p -J -t cursor-login`, and wait until `agent about`
shows their email; if the link stops working, start it again. Never ask
for, print, or copy an API key. Don't start Cloud Agents, push to the
repository, or turn on the live workspace or computer use unless the
owner asks. Finish by telling the owner to pick this VM's name under My
Machines at https://cursor.com/agents.

Finish with the URLs I should open.

Also at /deploy/cursor/prompt.txt. The recipe it follows is /deploy/cursor.md.

Before you start#

  • A Cursor plan with Cloud Agents: Premium or higher, Teams, Enterprise, or a legacy paid plan. On a team, an admin must turn on Allow Personal Machines or Allow Self-Hosted Machines in the Cloud Agents dashboard.
  • GitHub connected in Cursor for the repository. If Cloud Agents or Bugbot already work on it, it is.
  • Your GitHub account linked to exe.dev on the Integrations page.

Set it up#

Deploy sets it up on a new VM and asks for the repository. Shelley gives you one command to run on your computer, which lets the VM reach the repository. Then it shows you a Cursor sign-in link: open it on your computer and approve. To do it yourself:

Install by hand

Create the VM#

On your computer (pick another name if my-cursor is taken):

ssh exe.dev new --name=my-cursor

Give the VM your repository#

On your computer, attach the repository to the VM through the GitHub integration, with yours in place of acme/app:

ssh exe.dev integrations add github --name app --repository acme/app --attach vm:my-cursor

If you already have an integration for the repository, attach that one instead: ssh exe.dev integrations attach <name> vm:my-cursor.

Install the Cursor CLI#

On the VM (ssh my-cursor.exe.xyz):

curl https://cursor.com/install -fsS | bash
export PATH="$HOME/.local/bin:$PATH"
agent --version

It prints a version such as 2026.10.22-27dcf5f. The installer puts agent in ~/.local/bin, which new shells already have on their PATH.

Clone the repository#

Set GITHUB_REPO to yours. The insteadOf rule sends git's traffic for that repository through the integration, while the checkout's origin stays the github.com address Cursor matches tasks against:

GITHUB_REPO=acme/app
git config --global url."https://github.int.exe.xyz/$GITHUB_REPO.git".insteadOf "https://github.com/$GITHUB_REPO.git"
mkdir -p ~/repos
git clone "https://github.com/$GITHUB_REPO.git" ~/repos/"${GITHUB_REPO#*/}"
git -C ~/repos/"${GITHUB_REPO#*/}" config --get remote.origin.url

It prints https://github.com/acme/app.git. Agents commit, so give git a name and an email, yours:

git config --global user.name "Your Name"
git config --global user.email you@example.com

Sign in to Cursor#

NO_OPEN_BROWSER=1 agent login

It prints a https://cursor.com/loginDeepControl?... link and waits. Open the link on your computer, sign in, and approve. Then check:

agent about

User Email shows your Cursor account.

Run the worker#

A small script starts the worker named after the VM, with every checkout in ~/repos as a place agents can work. systemd runs it, and starts it again whenever it exits. The unit's PATH puts ~/.local/bin first, so the agents' commands find tools installed there:

cat > ~/.local/bin/cursor-worker <<'EOF'
#!/bin/bash
# Runs the Cursor worker, named after this VM, for every git checkout in ~/repos.
set -euo pipefail
dirs=()
for d in "$HOME"/repos/*/; do
  [ -d "$d.git" ] && dirs+=(--worker-dir "${d%/}")
done
if [ ${#dirs[@]} -eq 0 ]; then
  echo "cursor-worker: no git checkouts in ~/repos" >&2
  exit 1
fi
exec "$HOME/.local/bin/agent" worker --name "$(hostname)" "${dirs[@]}" start
EOF
chmod +x ~/.local/bin/cursor-worker

sudo tee /etc/systemd/system/cursor-worker.service > /dev/null <<'EOF'
[Unit]
Description=Cursor Cloud Agents worker (My Machines)
After=network-online.target
Wants=network-online.target

[Service]
User=exedev
WorkingDirectory=/home/exedev
Environment=PATH=/home/exedev/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
ExecStart=/home/exedev/.local/bin/cursor-worker
Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now cursor-worker
sleep 10
journalctl -u cursor-worker -n 20 --no-pager

The log says Worker is now running, then Name: my-cursor and the directory. To check what Cursor sees (your account, the repository the worker registered, and whether Cursor finds the worker):

agent worker debug

Run an agent on the VM#

  1. Open cursor.com/agents, or Cloud Agents in the Cursor desktop app.
  2. In the menu that sets where the agent runs, pick my-cursor under My Machines.
  3. Send a task in your repository, for example "Run the tests and fix the first failure."

The agent's commands run on the VM as exedev, in ~/repos/app. To watch from a shell on the VM:

journalctl -u cursor-worker -f
git -C ~/repos/app status

The agent's git commands use the VM's own credentials, so its pushes go through the GitHub integration. They show up as exe-dev-github-integration[bot] unless you turn on --act-as-user for the integration.

From Slack, GitHub, or Linear#

Name the machine with worker= (or machine=):

  • Slack: @Cursor worker=my-cursor fix the flaky test
  • A GitHub issue or pull request comment: @cursoragent worker=my-cursor fix the flaky test
  • Linear: worker=my-cursor in the issue body, then mention @Cursor in a comment.

Cursor runs the task here only if the machine is yours and a checkout on it is the task's repository. Otherwise it refuses, rather than running the task somewhere else.

Between tasks#

The worker doesn't clone, switch branches, or clean up: each agent starts from the checkout as the last one left it. Before a new task, put it back on the default branch:

cd ~/repos/app
git status --short
git switch main && git pull --ff-only

Add another repository#

On your computer, give the VM the repository:

ssh exe.dev integrations add github --name web --repository acme/web --attach vm:my-cursor

On the VM, clone it the same way, then restart the worker so it picks up the new checkout. A restart ends running agents, so do it between tasks:

GITHUB_REPO=acme/web
git config --global url."https://github.int.exe.xyz/$GITHUB_REPO.git".insteadOf "https://github.com/$GITHUB_REPO.git"
git clone "https://github.com/$GITHUB_REPO.git" ~/repos/"${GITHUB_REPO#*/}"
sudo systemctl restart cursor-worker

Open the live workspace#

With the live workspace on, the Cursor desktop app (3.25 or later) can open an agent's files, changes, terminal, and forwarded ports. Add --connect-workspace to the worker and restart it:

sed -i 's|agent" worker |agent" worker --connect-workspace |' ~/.local/bin/cursor-worker
sudo systemctl restart cursor-worker

When the app first opens an agent, the worker downloads Cursor's signed server build into ~/.cursor-server and runs it on 127.0.0.1; no port opens on the VM.

Warning

Anyone who can open the agent gets a terminal on the VM as exedev: you, and teammates if a team admin turns on Allow VM sharing.

Let agents use a desktop and a browser#

With computer use, agents can take screenshots, click, and type in a desktop the worker starts on the VM, and drive Chrome in it. Install the desktop packages and Chrome (about 1.2 GB), then add --computer-use:

sudo apt-get install -y --no-install-recommends \
  dbus-x11 ffmpeg tigervnc-standalone-server \
  x11-utils x11-xserver-utils xdotool xfce4
curl -fsSLo /tmp/chrome.deb https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt-get install -y /tmp/chrome.deb
sed -i 's|agent" worker |agent" worker --computer-use |' ~/.local/bin/cursor-worker
sudo systemctl restart cursor-worker

To watch the agent's desktop from Cursor, add --share-desktop the same way. See Cursor's computer use guide for the details.

Back up#

Little on the VM is hard to replace. The work that matters is in ~/repos, and the agents' branches are on GitHub once pushed: check for anything unpushed before deleting the VM.

for d in ~/repos/*/; do git -C "$d" status --short --branch; done

The Cursor sign-in isn't worth copying: on a new VM, sign in again and remove the old machine in the Cursor dashboard.

Update#

Update the Cursor CLI

On the VM, between tasks:

agent update
sudo systemctl restart cursor-worker
agent --version

Troubleshooting#

Troubleshooting

Start with the worker's log and Cursor's own checks:

journalctl -u cursor-worker -n 50 --no-pager
agent worker debug

Authentication required for worker mode. The VM isn't signed in to Cursor. Run NO_OPEN_BROWSER=1 agent login again; the service retries every 15 seconds and connects on its own once you approve.

The machine isn't in the picker. Check that agent about shows the same account as the app, and that the log says Worker is now running. Then check the checkout's origin:

git -C ~/repos/app config --get remote.origin.url

It must be https://github.com/.... If it is https://github.int.exe.xyz/..., set it back with git remote set-url origin https://github.com/acme/app.git, add the insteadOf rule from "Clone the repository", and restart the worker.

worker=my-cursor is registered on your machine but for a different repository. The VM has no checkout of the repository the task is for. Add it as in "Add another repository".

The worker can't reach Cursor. It needs outbound HTTPS to api2.cursor.sh and api2direct.cursor.sh. A VM whose egress policy is integrations can't reach them: ssh exe.dev egress my-cursor on your computer shows the policy.

Clone, fetch, or push fails. Check that the VM reaches the repository through the integration:

git ls-remote https://github.int.exe.xyz/acme/app.git | head -1

An error means the integration isn't attached to this VM, or names another repository. A push refused with a 403 means the integration is read-only.

Please tell me who you are. Git has no identity for the agents' commits. Set user.name and user.email as in "Clone the repository".

Frequently asked questions#

Which Cursor plan do I need?

One that includes Cloud Agents: Premium or higher, Teams, Enterprise, or a legacy paid plan; Free and Plus don't. My Machines, the personal worker on this page, needs no Enterprise plan. On a team, an admin must turn on Allow Personal Machines or Allow Self-Hosted Machines in the Cloud Agents dashboard. Agents bill like other Cloud Agent usage, at the model's rate.

Why a VM instead of a Mac mini?

There's nothing to buy, power, or keep online, and the worker only dials out, so the VM needs no open ports. A Linux worker can also open an agent's live workspace (files, terminal, forwarded ports) in the Cursor desktop app, which macOS workers can't. Keep the Mac for iOS builds and for agents that drive macOS apps.

What runs on the VM, and what goes to Cursor?

Every file edit, terminal command, and local (stdio) MCP server runs on the VM, as exedev. Cursor runs the agent loop and the models, so the worker sends it what the agent reads: file contents, terminal output, diffs, and screenshots. Artifacts such as screenshots and videos upload to Cursor's storage. Privacy Mode applies as usual.

Can the agents use exe.dev's LLM gateway instead of Cursor's models?

No. The agent loop runs on Cursor's servers with Cursor's models, on your Cursor plan. Commands the agents run on the VM can still use the LLM integration, and so can Claude Code, Codex, and Shelley, which come with every VM.

Why does the checkout's origin still say github.com?

Cursor sends a task to your machine only when a checkout's origin names the task's repository. The worker reads origin as written and treats hosts it doesn't know as their own servers, like GitHub Enterprise: cloned from https://github.int.exe.xyz/acme/app.git, the checkout registers as github.int.exe.xyz/acme/app and never matches acme/app. Git's insteadOf rule keeps origin at github.com and sends the traffic through the integration.

Can several agents run on the VM at once?

Yes: a My Machines worker takes several agents at the same time, and they all work in the same checkouts. For parallel work on one repository, set up a second VM the same way; each VM is its own machine in the picker.

Can I run a Team Pool on exe.dev VMs instead?

Team Pools (agent worker --pool) need a Cursor Enterprise plan and a service account API key. The worker is the same CLI, so a pool worker runs on an exe.dev VM too, but this page covers the personal My Machines worker.

Updated Oct 30, 2026 · Markdown · manifest.json · Something wrong? Tell us