Self-host a Cursor Agent SDK agent
Cursor's agents-as-code framework, on a machine you run.
Shelley handles the setup. About 10 minutes.
Prefer a terminal?
curl -fsSL https://exe-staging.dev/deploy/cursor-agent-sdk/prompt.txt | ssh exe.dev new --prompt=/dev/stdinCursor'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 whoaminames 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
https://my-cursor-agent.exe.xyz:3000/playground
the playground, for you and anyone you share the VM with
ssh my-cursor-agent.exe.xyz
the agent's code, evals, and logs
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-staging.dev/deploy/cursor-agent-sdk/prompt.txt \
| ssh exe.dev new --prompt=/dev/stdinWhat 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-staging.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 portat 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. Runagent-sdk loginagain, thensudo systemctl restart security-reviewer.requires a signed-in Cursor account: the VM was never signed in. Runagent-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:3000shows 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.
401on API calls through the proxy: the service is missing--allow-anonymous; compare theExecStartline 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