Skip to content

Self-host a Cursor Agent SDK agent

Cursor's agents-as-code framework, on a machine you run.

Deploy on exe.dev

Shelley handles the setup. About 10 minutes.

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

Cursor's Agent SDK builds agents as code: a folder with the prompt in Markdown, tools in TypeScript, channels that wake the agent on pull requests, Slack messages, or webhooks, and evals that check it still behaves. It is the framework Cursor built its own Bugbot, Security Reviewer, and Rollouts with, and it ships their review templates. agent-sdk deploy runs a project on Cursor's infrastructure, but the same project also runs as a single Node process, agent-sdk serve, on a machine of your own.

This page makes that machine an exe.dev VM. It runs Cursor's security reviewer template: on every new pull request in the repositories you pick, it reads the diff and posts one review comment that lists exploitable bugs, or says the change is clean. The VM stays on, runs the agent under systemd, keeps its sessions on disk, and serves the playground privately behind your exe.dev login. Pull request events reach it through your Cursor GitHub connection, so nothing on the VM is public and no GitHub token lives there. Its tools run here, next to whatever private services you give it; Cursor still runs the models.

What you get#

  • The Agent SDK CLI 0.4 on Node.js 24, and Cursor's security-reviewer template in ~/security-reviewer, a git repository that watches GITHUB_REPOS
  • The VM signed in to Cursor (agent-sdk whoami names the account), with no GitHub token on it
  • security-reviewer.service enabled, so it comes back after a reboot, with state in ~/agent-state
  • The playground answering at https://<vm>.exe.xyz:3000/playground, private to the VM's owner
  • Both smoke evals passing with agent-sdk eval
What's running, and where
Private https://my-cursor-agent.exe.xyz:3000/playground the playground, for you and anyone you share the VM with
Private ssh my-cursor-agent.exe.xyz the agent's code, evals, and logs
my-cursor-agent.exe.xyz exe.dev VM
Security reviewer Cursor's security-reviewer template, a git repository you edit ~/security-reviewer
agent-sdk serve @grok/agent-sdk 0.4 on Node.js 24, the security-reviewer systemd service :3000~/agent-state
Cursor Models, plus pull request events and GitHub calls through your Cursor GitHub connection

Deploy with Shelley#

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

Have these ready; Shelley asks for them:

  • GITHUB_REPOS: the GitHub repositories to review, as owner/name, comma-separated, all with the same owner and already connected to Cursor
Prefer a terminal?
curl -fsSL \
  https://exe.dev/deploy/cursor-agent-sdk/prompt.txt \
  | ssh exe.dev new --prompt=/dev/stdin
What Shelley is told
GITHUB_REPOS=<fill-this-in>

Set up Cursor Agent SDK on this VM by following the exe.dev recipe at https://exe.dev/deploy/cursor-agent-sdk.md from top to bottom.

The values at the top of this message are mine:
- GITHUB_REPOS: the GitHub repositories to review, as owner/name, comma-separated, all with the same owner and 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-agent. This VM's name is the output of `hostname`: use it wherever the recipe writes my-cursor-agent. 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 Agent SDK CLI 0.4 on Node.js 24, and Cursor's security-reviewer template in ~/security-reviewer, a git repository that watches GITHUB_REPOS
- The VM signed in to Cursor (`agent-sdk whoami` names the account), with no GitHub token on it
- security-reviewer.service enabled, so it comes back after a reboot, with state in ~/agent-state
- The playground answering at `https://<vm>.exe.xyz:3000/playground`, private to the VM's owner
- Both smoke evals passing with `agent-sdk eval`

Run "Install by hand" first, skipping VM creation; the walkthrough is for
the owner afterwards. Use GITHUB_REPOS exactly as given. For "Sign in to
Cursor", start `agent-sdk login` in a tmux session, give the owner the
URL it prints, and wait until `agent-sdk whoami` names an account; never
ask for, print, or copy an API key. Don't open, comment on, or review
pull requests yourself, and don't run `agent-sdk deploy`. Keep port 3000
private: never run share set-public or share port. Finish with
https://<vm>.exe.xyz:3000/playground, using this VM's name, and point the
owner to "Review a pull request".

Finish with the URLs I should open.

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

Before you start#

  • A Cursor account with model usage. The reviewer's turns bill like your other Cursor agent usage.
  • GitHub connected in Cursor for the repositories to review (Cursor dashboard, Integrations). If Bugbot or Cursor's cloud agents already work on a repository, it is connected.
  • The repositories' names, as owner/name. They must share one owner.

Set it up#

Deploy sets it up on a new VM and asks which repositories to watch. It shows you a Cursor sign-in link: open it on your computer and approve, and the VM gets a Cursor API key of its own. To do it yourself:

Install by hand

Create the VM#

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

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

Install Node.js and the CLI#

On the VM. The Agent SDK needs Node.js 22.13 or later; install Node.js 24 from NodeSource, and the CLI into ~/.local, so updates need no sudo:

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
npm config set prefix ~/.local
npm install --global @grok/agent-sdk@0.4
export PATH="$HOME/.local/bin:$PATH"
agent-sdk --version

Expect 0.4. and a patch version. ~/.local/bin is already on the PATH of new shells.

Create the reviewer#

Set GITHUB_REPOS to your repositories, then scaffold Cursor's security-reviewer template and put it under git:

GITHUB_REPOS=acme/api,acme/web
agent-sdk init ~/security-reviewer --template security-reviewer \
  --var repos="$GITHUB_REPOS" --json < /dev/null | grep '"ok"'
cd ~/security-reviewer
git init -q && git add -A && git commit -qm "security-reviewer from the Agent SDK template"
agent-sdk validate --dir .

Expect "ok": true and has no diagnostics. bot/lib/repos.ts now lists your repositories.

Sign in to Cursor#

agent-sdk login

It prints a https://cursor.com/loginDeepControl?... link and waits. Open the link on your computer, sign in, and approve. The CLI stores the API key it was given in ~/.config/agent-serve/credentials.json, mode 600. Check:

agent-sdk whoami

It names your Cursor account.

Run the evals#

The template's two smoke cases send a made-up diff (one with an XSS bug, one that only touches the README) and check that the reviewer flags the first and passes the second. Eval sessions skip the GitHub write.

agent-sdk eval --dir .

Expect 2 passed. These turns use your Cursor usage.

Start the service#

agent-sdk serve subscribes to pull request events for the repositories in bot/lib/repos.ts and serves the playground on port 3000. The exe.dev HTTPS proxy only lets in people signed in with access to the VM, so the server admits whoever gets that far (--allow-anonymous), including to the reviewer's GitHub access (--allow-anonymous-cursor-github). --cursor-scm-proxy sends GitHub API calls through Cursor instead of minting a GitHub token on the VM.

mkdir -p ~/agent-state
sudo tee /etc/systemd/system/security-reviewer.service > /dev/null <<'EOF'
[Unit]
Description=Cursor Agent SDK: security-reviewer
After=network-online.target
Wants=network-online.target

[Service]
User=exedev
WorkingDirectory=/home/exedev/security-reviewer
Environment=AGENT_SERVE_NO_UPDATE_CHECK=1
ExecStart=/home/exedev/.local/bin/agent-sdk serve --dir /home/exedev/security-reviewer --mode single --host 0.0.0.0 --port 3000 --state-root /home/exedev/agent-state --allow-anonymous --allow-anonymous-cursor-github --cursor-scm-proxy
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now security-reviewer
sleep 15
journalctl -u security-reviewer -n 20 --no-pager
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/playground

The log says security-reviewer listening and GitHub auth: channel API calls route through https://api.cursor.com/v0/github-proxy, and curl prints 200.

Warning

Keep port 3000 private. Anyone who can open the playground can run the reviewer with its access to your repositories. Never point share port at it or make it public.

Review a pull request#

Open a pull request in one of the watched repositories, or close and reopen one. Within a minute or two the reviewer posts a review comment headed Security review, with a verdict of CLEAN or a list of findings, each with a severity, a file and line, and a one-line fix. Drafts are skipped until they're marked ready for review.

To watch it work, open https://my-cursor-agent.exe.xyz:3000/playground and sign in to exe.dev. Runs lists each review session; open one to see the diff it read, each tool call, and the reply. The Chat tab talks to the same agent, and Evals runs the smoke cases from the browser.

From a shell on the VM, the same things:

agent-sdk session list --url http://127.0.0.1:3000
agent-sdk logs --once --url http://127.0.0.1:3000

Make it yours#

The agent is the folder ~/security-reviewer:

File What it does
bot/instructions.md What counts as a finding, and how to report it
bot/channels/github.ts Which events start a review; writes the diff to pr/diff.patch first
bot/tools/post_findings.ts The one tool the model calls: posts the review comment
bot/agent.ts The model, read-only tools (read, grep), and Cursor's local sandbox
bot/lib/repos.ts The watched repositories
evals/review.eval.ts The smoke cases

The loop: change a file, add an eval case for what you want, check, then restart. On the VM:

cd ~/security-reviewer
agent-sdk validate --dir . && npm run check && agent-sdk eval --dir .
sudo systemctl restart security-reviewer
git commit -am "Flag missing authz checks on admin routes"

To try a change on a real pull request before it goes live, stop the service, run the development server, and replay the pull request to it. The replay runs a real review, so it posts a comment: pick a pull request where that's fine.

sudo systemctl stop security-reviewer
agent-sdk dev --dir . --port 3000 --host 0.0.0.0 --allow-anonymous --allow-anonymous-cursor-github
# in a second shell:
agent-sdk github replay https://github.com/acme/api/pull/12 --dir .

Press Ctrl-C and sudo systemctl start security-reviewer when done.

Shelley, the coding agent on every exe.dev VM, can do this loop for you: open https://my-cursor-agent.shelley.exe.xyz and ask it to change the reviewer. The project's AGENTS.md and the SDK's bundled skills (agent-sdk skills list) tell coding agents how. Cursor's other review templates scaffold the same way: thermo-review (bugs and breaking side effects), thermo-quality-review (structure), and agentic-owners (approves what an owners policy allows); see the templates.

To keep the project on GitHub too, give the VM a repository through the GitHub integration and push to https://github.int.exe.xyz/<owner>/<repo>.git; no token is stored on the VM.

Share it#

On your computer:

ssh exe.dev share add my-cursor-agent ann@example.com

Ann signs in at the same playground address. Share it only with people you'd let run the reviewer against your repositories.

Back up#

The project is a git repository; sessions, memory, and eval runs are in ~/agent-state. Copy both off the VM now and then. On your computer:

mkdir -p cursor-agent-backup
rsync -av --exclude node_modules my-cursor-agent.exe.xyz:security-reviewer my-cursor-agent.exe.xyz:agent-state cursor-agent-backup/

To restore on a new VM, follow "Install by hand" up to "Sign in to Cursor" (skip init), copy both folders back, run npm install in ~/security-reviewer, then "Start the service". The Cursor credential isn't in the backup: sign in again, and revoke the old VM's key in the Cursor dashboard.

Update#

Update the Agent SDK

Read the changelog first. On the VM, update the CLI and the project's copy together, check, and restart:

npm install --global @grok/agent-sdk@0.4
cd ~/security-reviewer
npm install @grok/agent-sdk@0.4
agent-sdk validate --dir . && npm run check && agent-sdk eval --dir .
sudo systemctl restart security-reviewer
git commit -am "Update the Agent SDK"

For a new minor version, replace 0.4 with it in both commands.

Troubleshooting#

Troubleshooting

Start with the service log and the project's own checks:

journalctl -u security-reviewer -n 50 --no-pager
cd ~/security-reviewer && agent-sdk validate --dir . && agent-sdk whoami
  • The Cursor API key was rejected, and the service restarts every ten seconds: the key was revoked or expired. Run agent-sdk login again, then sudo systemctl restart security-reviewer.
  • requires a signed-in Cursor account: the VM was never signed in. Run agent-sdk login.
  • No review appears on a new pull request: check that the repository is in bot/lib/repos.ts, that GitHub is connected in Cursor for it, and that the pull request isn't a draft. agent-sdk session list --url http://127.0.0.1:3000 shows whether a session started; open it in the playground to see where it stopped.
  • The first turn reports [resource_exhausted]: the model is out of capacity, or GitHub rate-limited the event; wait and reopen the pull request.
  • The playground shows no agents: the service isn't running. See the log above.
  • 401 on API calls through the proxy: the service is missing --allow-anonymous; compare the ExecStart line with the unit above.

Cursor's troubleshooting page covers more.

Frequently asked questions#

What is the Cursor Agent SDK?

Cursor's framework for agents as code, the one behind its own Bugbot, Security Review, and Rollouts. A project is a folder: the prompt in bot/instructions.md, tools as TypeScript files, event channels for GitHub, GitLab, Bitbucket, Slack, and webhooks, and evals beside them. It is not the earlier Cursor SDK (@cursor/sdk), which drives Cursor's coding agent from your code; the Agent SDK is built on it. The npm package is @grok/agent-sdk, formerly @cursor/bdk.

Why self-host instead of running agent-sdk deploy?

agent-sdk deploy runs the agent on Cursor's infrastructure, and needs a team with agent hosting turned on. Self-hosting runs the same project as one Node process you control: its tools run on your VM, on your network, so they can reach private services, databases, and exe.dev integrations; you pick the egress, keep sessions on your disk, and can run long or heavy tools without a hosted sandbox's limits. Cursor's docs say to self-host "when you need your own network or process controls".

What still goes to Cursor?

The model turns: the agent loop runs on the VM, but every model call goes to Cursor and counts against your Cursor plan's usage, under your account's privacy setting. Pull request events and GitHub API calls also go through your Cursor GitHub connection. Diffs the reviewer reads are sent to the model.

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

No. The Agent SDK runs Cursor's agent harness, which only talks to Cursor's backend, and model in bot/agent.ts takes Cursor model IDs such as grok-4.5 or composer-2.5. Tools you write can still call https://llm.int.exe.xyz through the LLM integration, for example for a cheap classification step.

Do I need a public webhook URL or a GitHub token?

No. With cursorAccount, the agent pulls pull request events from Cursor and makes its GitHub calls through Cursor's GitHub proxy (--cursor-scm-proxy), using the GitHub connection you already have in Cursor. Nothing on the VM needs to be public, and no GitHub token is minted on it.

Which Cursor plan do I need?

A Cursor account with model usage: the reviewer's turns are billed like your other agent usage. Cursor's docs don't name a plan for self-hosting, which needs only an API key; Cursor-managed hosting needs a team with agent hosting turned on.

Can I run more than one agent on the VM?

Yes. Put each project in its own folder under one directory and point agent-sdk serve --dir at that directory in multi mode (the default); each agent then gets /<slug>/playground. Let only one process run schedules per project.

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