Use Cursor CLI from Claude Code to delegate coding tasks to Composer 2 and other Cursor models.
A Claude Code plugin that hands off coding tasks from Claude to the Cursor CLI (cursor-agent). Claude stays the planner and reviewer; Cursor is the fast executor — composer-2-fast by default (Cursor's own current default, and the fastest Composer variant), in force/yolo mode, optionally in the background.
Nine slash commands under the cursor: namespace:
/cursor:delegate— hand a coding task to Cursor, foreground or background./cursor:from-plan— turn a Claude Code plan (from plan mode) into atasks/<file>.mdand hand it off to Cursor./cursor:browser— verify a URL / flow in a real browser via Cursor'schrome-devtoolsMCP./cursor:status— list recent jobs or inspect a specific one./cursor:result— print the final output of a finished job./cursor:cancel— terminate a running job (SIGTERM, then SIGKILL after 5 s)./cursor:resume— continue the previous Cursor chat with a follow-up./cursor:sessions— list Cursor's own chat sessions for this repo./cursor:setup— health-check the CLI, list models + configured MCPs, or guide installation.
Plus a cursor-runner subagent you can invoke from inside Claude to delegate well-scoped tasks automatically.
Short answer: Composer 2 is genuinely good at most day-to-day coding work — and I don't want a pile of terminal windows to drive it. I want Claude Code to be the orchestrator for everything. The flow that keeps working for me is simple: Claude makes the plan, Composer executes it, Claude reviews the diff. Two tools, each doing what it is best at.
"Why not do the whole thing inside Cursor, then?" Claude Code has a certain magic, particularly around planning. It is not purely about the underlying model — it is the whole rig (long-context sessions, subagents, the TUI, the way tools compose) that, in my experience, only really clicks inside Claude Code.
Cursor CLI has its own plan mode and it is fine, but execution is where Cursor really shines: file edits, applying diffs, crunching through a well-scoped task list in force mode. Cursor 2 and the Composer models are heavily tuned for exactly that CLI use-case. (The same is true of Codex and GPT on OpenAI's side, which is why openai/codex-plugin-cc exists — and which is what I borrowed from heavily when building this plugin. Credit where due.)
So: Claude plans, Cursor writes, Claude reviews, repeat. Glued together by seven slash commands and one subagent.
This plugin is built around delegating execution — writing code — to Cursor's Composer 2 for speed. Claude Code stays the orchestrator, planner, and reviewer. There is intentionally no /cursor:review or /cursor:adversarial-review command: Cursor is the "doer" here, not the critic. If you want review, ask Claude to review Cursor's diff in the usual way.
- Node.js ≥ 18.18
- A Cursor subscription (Composer 2 is included in paid tiers)
cursor-agenton yourPATH— install viacurl https://cursor.com/install -fsS | bashcursor-agent logincompleted at least once
Local, for immediate testing from this repository:
/plugin marketplace add /Users/you/path/to/cursor-plugin-cc
/plugin install cursor@tomas-cursor
/reload-plugins
/cursor:setup
From GitHub once published:
/plugin marketplace add freema/cursor-plugin-cc
/plugin install cursor@tomas-cursor
/reload-plugins
/cursor:setup
⚠️ Do not skip/reload-plugins. Right after/plugin installthe/cursor:*commands are NOT yet available — Claude Code only picks them up after a plugin reload. If you seeUnknown command: /cursor:setup, you forgot this step — run/reload-pluginsand try again.
The plugin ships as plain ESM JavaScript with zero runtime dependencies — just the Node stdlib. /plugin install is literally all you need; no npm install, no build step, no dist/ folder. Each slash command runs node "${CLAUDE_PLUGIN_ROOT}/scripts/<cmd>.mjs" directly from the committed source.
The first /cursor:setup run tells you if cursor-agent is missing or unauthenticated. For hacking on the plugin itself (tests, lint, formatting), see Contributing below.
Hand a coding task to cursor-agent -p ….
| Flag | Default | Effect |
|---|---|---|
--model <id> |
composer-2-fast |
Aliases → real Cursor ids: composer/fast → composer-2-fast, composer-2 → composer-2, sonnet → claude-4.6-sonnet-medium, opus → claude-opus-4-7-high, gpt/codex → gpt-5.3-codex, grok → grok-4-20, gemini → gemini-3.1-pro, auto → auto. Unknown ids forwarded as-is. Run /cursor:setup --print-models for the live list. |
--background |
off | Detach; the command returns a job id immediately. |
--wait |
on (if not --background) |
Block until finished. |
--fresh |
off | Start a brand-new Cursor session (no resume). |
--resume[=<chat-id>] |
off | Resume a prior chat. With no id, resume the latest for this repo. |
--no-force |
--force is ON |
Disable auto-approve (paranoid mode). |
--cloud |
off | Pass -c to cursor-agent. |
--timeout <sec> |
1800 |
Kill the job if it exceeds this. |
--no-git-check |
off | Allow running outside a git repo. |
Examples:
/cursor:delegate add a dark-mode toggle to the settings page
/cursor:delegate --model composer "write jest tests for utils/date.ts"
/cursor:delegate --background --model auto "migrate user repository to Doctrine 3"
/cursor:delegate --resume "continue with the failing edge case"
Takes a Claude Code plan file (anything written under ~/.claude/plans/ by Claude's plan mode) and rewrites it as a Cursor-shaped task file under tasks/<YYYYMMDD-HHmm>-<slug>.md. The task file has the standard five sections (Goal, Repo context, Acceptance criteria, Files to touch, How to verify) plus a guardrail block — exactly the shape the cursor-runner subagent enforces — and a link back to the source plan.
Two modes:
- Preview + hand-back (default): writes the task file, prints the exact
/cursor:delegate @tasks/…command to run next. Lets you review the task before any Cursor tokens get spent. - Auto-delegate (
--delegate/--yes): writes the task file AND invokes/cursor:delegatein one go. Use when you already trust the plan.
Examples:
# Plan mode first — Claude drops the plan under ~/.claude/plans/<slug>.md
# when you exit plan mode. Then:
/cursor:from-plan # newest plan → tasks/ → print delegate command
/cursor:from-plan dark-mode # match on a plan name fragment
/cursor:from-plan --delegate # newest plan → tasks/ → delegate immediately
/cursor:from-plan --delegate --model opus --background "some-slug"
/cursor:from-plan --list # show the 15 most recent plans
This is the closest thing to "plan in Claude, execute in Cursor" in one session: Claude does the thinking, Cursor does the typing, and the task file is a durable contract between the two.
Verify a page or a flow in a real browser via Cursor's chrome-devtools MCP. This is read-only by design — Cursor navigates, interacts, checks console/network and reports back; it will not modify your source files.
/cursor:browser http://localhost:3000 "login flow works for valid and invalid credentials"
/cursor:browser http://localhost:5173 "dark-mode toggle persists across reloads"
/cursor:browser localhost:8080 "no console errors on the home page; no 4xx/5xx requests"
Under the hood: the command pre-checks that chrome-devtools is configured in cursor-agent mcp list, then invokes cursor-agent -p --approve-mcps … with a prompt that scripts the standard flow (list_pages → navigate → take_snapshot → interact → wait_for → console/network checks → screenshot). No flags to remember.
Setup for this command (one-time): add the MCP server to your Cursor MCP config, usually ~/.cursor/mcp.json:
{
"mcpServers": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "chrome-devtools-mcp@latest", "--isolated"]
}
}
}Restart Cursor so cursor-agent picks up the new MCP. --isolated makes each run use a fresh Chrome profile, which sidesteps the common "profile already in use" lockout.
Verify with /cursor:setup --doctor — it now lists every MCP cursor-agent can see and whether each is loaded.
Without args, shows the last 10 jobs for this repository as a table. With an id, shows the full job record including the Cursor chat id (so you can resume manually with cursor-agent --resume=<id>). Pass --all to drop the 10-row limit.
/cursor:status
/cursor:status V1StGXR8_Z
Prints the final summary of a finished job. Defaults to the most recent one for this repo.
/cursor:result
/cursor:result V1StGXR8_Z
Cancels a running job. With no id, cancels the single running job (errors if there are several).
/cursor:cancel
/cursor:cancel V1StGXR8_Z
Shortcut for /cursor:delegate --resume <task...>. Without a task, sends an empty follow-up ("continue").
/cursor:resume "now wire it into the App shell"
/cursor:resume --resume=chat_abc123 "fix the failing test"
Shells out to cursor-agent ls and lists Cursor's own chat sessions for this repo. If that call times out or returns empty, the plugin falls back to its local job registry.
Runs a quick health-check. --doctor produces extended diagnostics (Node version, PATH, CURSOR_API_KEY presence masked, jobs dir writability, cursor-agent version). --print-models shells out to cursor-agent --list-models. --install prints the install command but does not run it — you must copy-paste it yourself.
This plugin is built around one pattern: Claude plans and reviews, Cursor writes code. Treat them as two separate roles, not one pipeline:
- Plan / spec — Claude Code scopes the change, picks the slice to delegate, and drafts acceptance criteria. This is where architectural judgment happens.
- Execute —
/cursor:delegate(or thecursor-runnersubagent) hands that spec to Cursor. Cursor writes files under--force, fast. - Review — Claude reads the diff Cursor produced. This is where correctness and style are checked.
- Iterate —
/cursor:resume "fix X"for the same thread, or/cursor:delegate --freshfor a new slice.
The plugin intentionally does not try to collapse these phases into one. Cursor is fast but context-starved; Claude has the whole session context but is slower per edit. Keeping them in separate phases is the whole point.
A good /cursor:delegate prompt has five sections:
- Goal — one sentence.
- Repo context — stack, and a pointer to whatever conventions file applies (
AGENTS.md,.cursor/rules,CLAUDE.md). - Acceptance criteria — 1–5 verifiable bullets.
- Files to touch — explicit list when you can predict it.
- How to verify — the exact commands (
npm test,task typecheck, …) that prove the task is done.
The cursor-runner subagent applies this template automatically. When you write /cursor:delegate by hand, aim for the same structure in the task string — it is the single biggest lever on Cursor's output quality.
cursor-agent --force will YOLO through whatever you give it. Keep slices small: ≤ 5 steps, ≤ 10 files, ≤ 2 architectural layers per /cursor:delegate call. If the plan is bigger, split it — one slice per call — and let Claude review between slices.
The plugin codebase is English, but it does not impose a language policy on your repo. When the cursor-runner subagent prepares a prompt, it reads the target repo's AGENTS.md / .cursor/rules / existing code and tells Cursor to match that style — whether that means Czech commits, German UI strings, or anything else. Do not put "write everything in English" in your own prompts unless that is actually your repo's convention.
Fast parallel task. You're in Claude Code. You want Cursor to handle something small while you keep working.
/cursor:delegate --background "write jest tests for src/utils/date.ts"
# keep talking to Claude
/cursor:result
Tight loop. Delegate in the foreground, let Claude review, then iterate.
/cursor:delegate "extract the retry logic from apiClient.ts into a hook"
# Claude reads the diff, suggests a fix
/cursor:resume "also add a unit test for the 429 path"
Escalation. Start small, upgrade if Cursor stalls.
/cursor:delegate --model composer "<task>"
# composer gave up — retry with opus from scratch
/cursor:delegate --model opus --fresh "<same task>"
Resume vs fresh. Use --resume (default) when the new task is the same thread of work. Use --fresh when the topic changed, or when the previous run went off the rails and resuming would just carry the confusion forward.
The two-phase loop above is the concept; here is the concrete workflow that falls out of it in practice, and the one I keep reaching for:
- Plan in Claude Code and write a task file. Describe what you want; ask Claude to draft a task spec — a markdown file with goal, acceptance criteria, files to touch, and how to verify (the same five sections the
cursor-runnersubagent enforces). Save it undertasks/<slug>.mdin the repo. - Hand the file to Cursor. Run
/cursor:delegate @tasks/<slug>.md implement this. The@pathshorthand inlines the file contents into the prompt, so Cursor gets the full spec without Claude having to re-type it. Composer 2 executes — it is genuinely fast, and a precisely defined task is usually a one-shot job. - Back in Claude Code: review the diff. Approve, or iterate with
/cursor:resume "fix X"on the same thread, or escalate with/cursor:delegate --model opus --fresh <same task file>if Composer stalled. - Keep the task files around.
tasks/becomes a little log of what the repo's delegated changes looked like. Handy when you want to re-delegate a similar slice — just copy an old file, tweak the bullets.
Why this works: Claude's tokens go into planning and reviewing, where thinking matters; Cursor's Composer 2 handles the actual typing, where it is cheaper and faster. The task file is the contract between the two phases — if it is sloppy, no model will save you. Writing a good one is itself a skill, and it is the only skill this workflow asks of you.
If you want Claude to do the whole thing automatically — draft the task file AND hand it off — that is what the cursor-runner subagent is for. Ask it to either "draft a task file for X" (it stops there) or "implement X via Cursor" (it drafts, hands off, and reports the diff).
If you already used Claude Code's plan mode for a task (the /plan … flow that drops a plan file under ~/.claude/plans/<slug>.md after you approve it), you do not need to re-type anything. Run /cursor:from-plan and the plugin will:
- Pick the newest plan under
~/.claude/plans/(or the one matching a name fragment you pass). - Extract the useful sections (Context → Repo context, Approach → Acceptance criteria, File list → Files to touch, Verification → How to verify), drop the dev-only bits (Effort, Risks, Scope exclusions), and add the standard guardrail block.
- Write the result to
tasks/<YYYYMMDD-HHmm>-<slug>.mdin the current repo and print the exact/cursor:delegate @tasks/…command for you to run.
So the full loop is:
/plan add a dark-mode toggle to the settings page
# Claude proposes a plan; you approve inside plan mode.
/cursor:from-plan --delegate --model opus
# Plan gets turned into a task file and handed off to Cursor in one step.
# Back in Claude Code: review the diff, /cursor:resume "fix X" if needed.
The task file stays in tasks/ as a durable record — the contract between plan and execution. Re-running a similar slice later is a two-line diff of that file away.
| Env var | Purpose |
|---|---|
CURSOR_API_KEY |
Forwarded to cursor-agent. Optional — cursor-agent login is usually enough. |
CURSOR_AGENT_BIN |
Override binary path (used by the test suite). |
CURSOR_PLUGIN_CC_HOME |
Override the jobs-registry root (default ~/.cursor-plugin-cc). |
A repo-local .cursor-plugin-cc.json is on the roadmap for overriding the default model per repo; until then, set --model per invocation.
Every finished job stores the Cursor chat_id. Read it from /cursor:status <job-id> or /cursor:result. Then, in any terminal:
cursor-agent --resume=<chat_id>
This re-opens the same Cursor session without going through Claude Code — handy when you want to finish something in Cursor's interactive UI.
Does it need a special Node version? Yes — ≥ 18.18. The CI matrix tests 18.18, 20, and 22 on Linux and macOS.
Does it use my existing Cursor auth? Yes. The plugin shells out to your already-installed cursor-agent, which uses whatever session cursor-agent login set up (or CURSOR_API_KEY if you prefer).
Does it upload my code anywhere? No — the plugin itself runs locally. cursor-agent of course sends your prompts to Cursor's backend; that is Cursor's normal behaviour, not something this plugin changes.
What does --force do? It is Cursor's auto-approve (aka --yolo). With it on, Cursor writes files without asking each time. This is necessary for non-interactive use but means Cursor can touch your working tree freely. Use --no-force if you want to test against an interactive flow — but note that most headless invocations will hang waiting for approval, so --no-force is really only useful for debugging.
The model list doesn't match what I see in Cursor. Run /cursor:setup --print-models — that shells out to cursor-agent --list-models and shows exactly what your account supports. The alias table in the plugin is a convenience; Cursor's actual model IDs drift over time.
cursor-agent hangs after finishing a task. Known quirk of the print-mode CLI. The plugin has a 5-second watchdog that SIGTERMs the process after a result event if it hasn't self-exited, then SIGKILLs 5 seconds later.
Things that bit users (and us) during development, with the exact fix each time.
You skipped /reload-plugins. Claude Code only picks up newly-installed plugin commands after a reload — /plugin install alone is not enough. Run /reload-plugins and the commands appear.
Zsh globbing on ? or * in your prompt. This should not happen in v0.2.0+ because every command wrapper quotes "$ARGUMENTS". If you see it, your plugin is outdated — reinstall: /plugin marketplace remove tomas-cursor && /plugin marketplace add freema/cursor-plugin-cc && /plugin install cursor@tomas-cursor && /reload-plugins.
Stale plugin cache from an older version. Same fix as above: remove marketplace, re-add, re-install, reload.
First-time Bash permission prompt. Approve node for this session (Claude Code asks once per session; the approval covers all plugin commands since all of them invoke node). If you denied it accidentally, /permissions lets you review/change.
The MCP server is not loaded in the current cursor-agent process. Three common causes:
- Not approved. Run
cursor-agent mcp enable chrome-devtools(or use--approve-mcpswhich/cursor:browseralready passes). - Not configured in
~/.cursor/mcp.json. Add the entry the error message suggests, including--isolatedin the args to avoid Chrome profile lockouts. - Cursor not restarted after editing
mcp.json. Cursor caches MCP config at startup; a restart is required.
Verify with /cursor:setup --doctor → the "Configured Cursor MCPs" section should list chrome-devtools with status loaded (or at least approved).
Claude Code only writes plan files when you explicitly enter plan mode and then exit it with approval. If you never did that, there is nothing to convert. Enter plan mode (/plan ...) first; run /cursor:from-plan --list afterwards to confirm the file is there.
Usually Cursor's backend, not us. The plugin has a default 30-minute timeout (--timeout 1800). For long tasks, bump it with --timeout 3600. For stuck jobs, /cursor:cancel <id> — SIGTERM with a 5 s grace window, then SIGKILL.
Safety check: by default the plugin refuses to run outside a git repo so Cursor cannot modify an unversioned tree. Pass --no-git-check if you know what you are doing.
Every job writes its full cursor-agent NDJSON stream to ~/.cursor-plugin-cc/jobs/<repo-hash>/logs/<job-id>.ndjson. When reporting bugs, include the first ~50 lines of the relevant log (after scrubbing anything sensitive).
Plugin users can skip this section — there is nothing to build.
Contributors, read CONTRIBUTING.md for the dev setup, branch naming, the "how to add a new slash command" recipe, and the release flow. The hard rules (zero runtime deps, no build step, etc.) live in AGENTS.md — the same file cursor-runner tells Cursor to read before touching any repo. Reporting a vulnerability? See SECURITY.md.
CI runs npm test and npm run lint on every PR across Node 18.18 / 20 / 22 on Ubuntu + macOS. No direct pushes to main — branch protection enforces PR review.
Things that are not in 0.1.0 but on the list:
- Additional browser MCPs — right now
/cursor:browserhard-codeschrome-devtoolsas the MCP name. Planned: a--mcp <name>flag plus autodiscovery so any DevTools-style MCP works. First follow-up target: Mozilla's firefox-devtools-mcp. - Per-repo defaults — a
.cursor-plugin-cc.jsonat repo root to override default model, timeout and MCP preference without re-typing flags. - npm publish — once the API stabilises, ship a tarball so users can
/plugin install cursor@tomas-cursorwithout acd plugins/cursor && npm installstep.
Contributions and ideas welcome.