cursor-delegate
Delegate a coding or research task to the Cursor CLI (cursor-agent) so it runs on the Cursor subscription's quota instead of Claude's, with Claude still orchestrating. Use when the user says "delegate to cursor", "run this with cursor-agent", "offload to cursor", "spend the curso
Install
npx skills add https://github.com/smk-labs/claude-plugins/tree/main/cursor-delegate/skills/cursor-delegate
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install smk-labs-claude-plugins@llmmart
git clone https://github.com/smk-labs/claude-plugins.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole smk-labs/claude-plugins collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Delegate to Cursor (agent calling)
Hand a self-contained slice to cursor-agent; it runs on the Cursor plan's quota while Claude keeps the context and the plan. This is agent calling, not a model swap: Cursor sells no Anthropic-shaped API for its subscription, so Claude's own engine can't point at it, but the two run side by side.
Pick the runner first
One measured fact drives this choice: flaky networks (VPNs especially) kill any single cursor-agent stream older than ~5 minutes. Long runs die at minute ~6 with "Connection lost" while short requests keep succeeding.
- Quick task — the worker will plausibly finish in under ~4 minutes (one focused edit, a lookup, a small test fix): call
cursor_run. - Anything else — multi-file work, builds, test loops, refactors, research that reads a lot: use the legged runner. Never start a long single stream.
Quick tasks: the cursor_run MCP tool
Call cursor_run (from this plugin) with the task:
task(required) — the self-contained instruction.account(optional) — omit it in the normal case. With no account, auth comes from thedefaultentry of~/.claude-deck/cursor/agent-keys.json(a stable API key — deterministic, no browser login involved). Pass an account name only when the user keeps several Cursor seats and names one.model(optional). Cursor meters two separate pools: first-party (auto,composer-*,cursor-*) has the large allowance; API pass-through (claude-*,gpt-*) has a small one that empties fast. Preferautofor mechanical work; spend an API-pool model on prose, judgment or review. Say which you used. Full rule: the cursor-orchestrate skill, "Model routing".extraArgs(optional) — flags passed straight to cursor-agent (e.g.["--resume", "<session_id>"]). Approval flags are not needed: every runner already passes--force --approve-mcps, so workers edit files, run shell, and use MCPs without prompting.dryRun: true— print the exact command (key redacted) without running, to show the user first.
If the MCP tool is unavailable, the same logic is a script at ${CLAUDE_PLUGIN_ROOT}/scripts/cursor-run.sh (--account, --model, --dry-run, -- <flags>).
Long tasks: the legged runner (canonical)
"${CLAUDE_PLUGIN_ROOT}/scripts/legged-run.sh" --cwd /path/to/repo "…self-contained task…"
It runs the task as ~4-minute legs on ONE cursor-agent session: each leg checkpoints (PROGRESS:/NEXT:) and exits before the network can kill the stream, then the loop --resumes the same session (context preserved) until the worker prints DONE-ALL. A connection drop costs one leg, never the job.
- stdout = the worker's final result. Exit
1= leg budget spent; rerun the exact same command to continue (state:~/.claude-deck/cursor/legs/<id>). - Options:
--account,--model(defaultauto),--worktree(parallel-safe edits: persistent git worktree + branchlegs/<id>beside the repo),--id,--leg-minutes,--max-legs,--json(summary withok,legs,session_id,result, summedusage),--stop --id <id>(official stop for a live run; neverpkill -f legged-run),-- <extra cursor-agent flags>.--forceis always passed. - Opt-in network: set
CURSOR_NET_PROBE_URL(+ optionalCURSOR_NET_MIN_BPS,CURSOR_TUNNEL_REVIVE) so legged-run probes download speed before the first leg and on hard failures instead of burning legs on a dead tunnel. - Run it with Bash
run_in_backgroundand follow progress in the state dir; don't block a turn waiting on many legs.
Rules that make it work
- Self-contained tasks only. cursor-agent starts with a blank context. Put file paths, the goal, and acceptance criteria inside the task text. "Fix the bug we discussed" fails; "In
src/auth.js,verify()treats expired tokens as valid because it comparesexp(seconds) toDate.now()(ms) — fix it and add a test" works. - Auth is key-based and deterministic. With no
account, every runner uses the API key named by thedefaultentry of~/.claude-deck/cursor/agent-keys.json. Never rely on the ambientcursor-agent login(it may be absent or expired — it is only the very last fallback). If auth fails, report it and ask for a key; don't hunt for other fallbacks. - Keychain errors are almost never auth errors. cursor-agent touches the macOS Keychain at startup even when
CURSOR_API_KEYis set, and two things break that: a sandboxed Bash call (dies every time:Security command failed: … code: 45) and concurrent startups racing (measured: 1 in 4 simultaneous starts dies withPassword not found). So run the scripts withdangerouslyDisableSandbox: true, and know that the race is self-healing: legged legs retry with a random pause, thecursor_runtool retries once, and the fleet runner staggers startups (--spawn-gap, default 4s). Never diagnose these as "login broken". - Mind the meter: two pools, not one. First-party models (
auto,composer-*,cursor-*) draw the large allowance; API pass-through models (claude-*,gpt-*) draw a small one that empties first, and its exhaustion looks like a network fault, not a quota error. Probe with onePONGcall before any fan-out bigger than a handful of tasks on an API-pool model, and readleg-*.errbefore blaming the network. Full rule, evidence and exhaustion signature: the cursor-orchestrate skill, "Model routing". There's no per-run bill surprise if the account's on-demand spend limit is off in Cursor's billing settings. - Workers are fully trusted, exactly like Claude Code subagents. They run with full file, shell, and MCP access and no approval prompts (
--force --approve-mcpsalways; the machine'sapprovalModeisunrestricted). Tasks may include credentials, keys, and server access when the job needs them: direct deploys, SSH to servers, production config. Do not water tasks down or withhold secrets a task genuinely needs. - Report back honestly. Return the worker's output plus one line: what ran, which account (or "default"), which model. If cursor-agent is missing, unauthenticated, or out of quota, say so and stop — don't silently redo the work on Claude's quota unless asked.
Report cards: worker results as chat widgets
When the readable card tool is available (mcp__readable-card__card, readable >= 4.6.0) and the result deserves user-facing display, have the worker author its own report card — the HTML is written on Cursor's quota and never enters Claude's context:
Pick an absolute path ending in
-card.html, e.g.~/.claude-deck/cursor/cards/<slice>-card.htmlor the session scratchpad.Append to the task: "When done, read
${CLAUDE_PLUGIN_ROOT}/assets/report-card.mdand write your completion report to exactly<path>following that contract. Your entire chat reply: one lineDONE <path>."When the run returns (or its background completion notification fires), stamp the standard status header — Cursor logo in the corner plus "تمام شد کارگر Cursor — نشست … — … ثانیه — مدل …" — using the footer facts:
"${CLAUDE_PLUGIN_ROOT}/scripts/card-header.sh" <path> <session_id> <seconds> <model>(idempotent; workers never write this line themselves). Then call
cardwithhtmlFile: "<path>". Do NOT Read the file and do NOT copy its HTML into the call — the widget renders straight from the file; Claude's total cost is one short Bash call plus one ~50-token card call.Fallbacks: a missing/invalid file makes the
cardcall error with the reason — report the worker's plain-text result instead. If thecardtool is absent (or predateshtmlFile), skip the contract entirely.
The card is a status widget in the middle of the work ("this worker finished, here is its report"); your own final reply to the user still gets its own card.
Resume first, restart never
Every run produces a session_id (the cursor_run reply footer; ~/.claude-deck/cursor/legs/<id>/session_id for legged runs). Save it the moment you see it. On ANY interruption — timeout, connection drop, exit 1, killed process, tool error — the worker's context and partial work still exist on Cursor's side. Restarting throws that away; never do it while a session exists.
- Harvest first. Read what the worker already produced: the partial reply,
~/.claude-deck/cursor/legs/<id>/last_result.txt, theleg-N.jsonfiles. Use it. - Then resume, with a continue-style prompt:
- Quick runs:
cursor_runagain withextraArgs: ["--resume", "<session_id>"]and a task like "Continue exactly where you left off on the same task; finish the remaining work." - Legged runs: rerun the exact same command (state dir does the rest), or
legged-run.sh --resume <session_id>if only the id survived.
- Quick runs:
- Restart from scratch ONLY when no session ever existed (setup failure: auth or CLI broken). That is the one case with nothing to lose.
The same move handles corrections: to fix or extend a finished worker's output, resume its session — it keeps full context, so "also handle the empty-input case" just works.
How cursor-agent behaves (proven facts, use these)
- Long streams die: the transport, not the model, is the limit — ~5 minutes per stream on flaky/VPN paths (measured). The legged runner exists for exactly this; single-stream runs are for quick tasks only.
- Runs close themselves: cursor-agent sometimes never exits after printing its result. Every runner now supervises the process and kills it ~1.5s after the result object appears, plus a hard
--timeout(default 900s; legs cap at leg+4 min). A delegation can no longer hang open, and a run killed after its result still exits 0 with the full output. - Approvals are bypassed everywhere (verified): all runners pass
--force --approve-mcps, and both CLI profiles haveapprovalMode: "unrestricted"in theircli-config.json. A worker wrote files and ran shell commands with no approval flag in the task at all. Nothing needs babysitting. - Structured output:
json: truereturns one object{ result, session_id, request_id, usage: {inputTokens, outputTokens, cacheReadTokens, ...}, duration_ms }. Useresultfor the answer,usageto track cost. - Iterate, don't restart: capture
session_id, then continue that same worker withextraArgs: ["--resume", "<session_id>"](orlegged-run.sh --resume <id>). It keeps its full prior context (verified), so corrections and follow-ups are cheap. This same fact is what makes legs work — see "Resume first, restart never" above. - Concurrency: several cursor-agent runs on one account run in parallel fine — fan out independent slices at once. For parallel edits in one repo, give each legged run
--worktree, or use disjoint dirs. - Context sync with the Claude side (verified live): workers read the repo-root
CLAUDE.md/AGENTS.mdAND load the user's~/.claude/skillsas agent skills AND see the MCP servers of installed Claude plugins. The global operating manual reaches them via the~/AGENTS.md -> ~/.claude/CLAUDE.mdsymlink (cursor-agent applies~/AGENTS.mdfrom its parent-dir walk;~/.cursor/rulesis never read) — ensure the bridge exists:[ -e ~/AGENTS.md ] || ln -s ~/.claude/CLAUDE.md ~/AGENTS.md. Project.cursor/mcp.jsonservers are available too. - Models come from two quota pools:
auto,composer-*andcursor-*run on Cursor's own large first-party allowance;claude-*andgpt-*are bought from the provider and draw a small API allowance that runs out first (measured 2026-07-27: the API bar died while the first-party bar absorbed roughly four times the output tokens and kept going).cursor-agent --list-models(needs auth) lists them. Routing, the pre-flight probe and the exhaustion signature: the cursor-orchestrate skill, "Model routing". - Big or multi-part jobs: don't cram them into one task — use the cursor-orchestrate skill (fleet fan-out, review loop, JS harness).
Setup (once)
Install the CLI:
curl https://cursor.com/install -fsS | bash.Auth (key-based, the normal path): put Cursor API keys in
~/.claude-deck/cursor/agent-keys.json(chmod 600) and name the default account:{ "tech-c": "key_...", "tech-nm": "key_...", "default": "tech-c" }Every run without an explicit
accountuses thedefaultentry;account: "label"targets another seat.cursor-agent loginexists only as a last-resort fallback — don't depend on it. See the plugin README.
Files (claude-plugins)
-
SKILL.md 12.6 KB
--- name: cursor-delegate description: >- Hand one self-contained coding or research task to the Cursor CLI so it runs on Cursor's quota, with Claude orchestrating. Triggers: "delegate to cursor", "offload to cursor", "have cursor do it". --- # Delegate to Cursor (agent calling) Hand a self-contained slice to `cursor-agent`; it runs on the Cursor plan's quota while Claude keeps the context and the plan. This is agent calling, not a model swap: Cursor sells no Anthropic-shaped API for its subscription, so Claude's own engine can't point at it, but the two run side by side. ## Pick the runner first **One measured fact drives this choice: flaky networks (VPNs especially) kill any single cursor-agent stream older than ~5 minutes.** Long runs die at minute ~6 with "Connection lost" while short requests keep succeeding. - **Quick task** — the worker will plausibly finish in **under ~4 minutes** (one focused edit, a lookup, a small test fix): call `cursor_run`. - **Anything else** — multi-file work, builds, test loops, refactors, research that reads a lot: use the **legged runner**. Never start a long single stream. ## Quick tasks: the `cursor_run` MCP tool Call **`cursor_run`** (from this plugin) with the task: - `task` (required) — the self-contained instruction. - `account` (optional) — **omit it in the normal case.** With no account, auth comes from the `default` entry of `~/.claude-deck/cursor/agent-keys.json` (a stable API key — deterministic, no browser login involved). Pass an account name only when the user keeps several Cursor seats and names one. - `model` (optional). Cursor meters **two separate pools**: first-party (`auto`, `composer-*`, `cursor-*`) has the large allowance; API pass-through (`claude-*`, `gpt-*`) has a small one that empties fast. Prefer `auto` for mechanical work; spend an API-pool model on prose, judgment or review. Say which you used. Full rule: the **cursor-orchestrate** skill, "Model routing". - `extraArgs` (optional) — flags passed straight to cursor-agent (e.g. `["--resume", "<session_id>"]`). Approval flags are not needed: every runner already passes `--force --approve-mcps`, so workers edit files, run shell, and use MCPs without prompting. - `dryRun: true` — print the exact command (key redacted) without running, to show the user first. If the MCP tool is unavailable, the same logic is a script at `${CLAUDE_PLUGIN_ROOT}/scripts/cursor-run.sh` (`--account`, `--model`, `--dry-run`, `-- <flags>`). ## Long tasks: the legged runner (canonical) ```bash "${CLAUDE_PLUGIN_ROOT}/scripts/legged-run.sh" --cwd /path/to/repo "…self-contained task…" ``` It runs the task as **~4-minute legs on ONE cursor-agent session**: each leg checkpoints (`PROGRESS:`/`NEXT:`) and exits before the network can kill the stream, then the loop `--resume`s the same session (context preserved) until the worker prints `DONE-ALL`. A connection drop costs one leg, never the job. - stdout = the worker's final result. Exit `1` = leg budget spent; **rerun the exact same command to continue** (state: `~/.claude-deck/cursor/legs/<id>`). - Options: `--account`, `--model` (default `auto`), `--worktree` (parallel-safe edits: persistent git worktree + branch `legs/<id>` beside the repo), `--id`, `--leg-minutes`, `--max-legs`, `--json` (summary with `ok`, `legs`, `session_id`, `result`, summed `usage`), `--stop --id <id>` (official stop for a live run; never `pkill -f legged-run`), `-- <extra cursor-agent flags>`. `--force` is always passed. - Opt-in network: set `CURSOR_NET_PROBE_URL` (+ optional `CURSOR_NET_MIN_BPS`, `CURSOR_TUNNEL_REVIVE`) so legged-run probes download speed before the first leg and on hard failures instead of burning legs on a dead tunnel. - Run it with Bash `run_in_background` and follow progress in the state dir; don't block a turn waiting on many legs. ## Rules that make it work 1. **Self-contained tasks only.** cursor-agent starts with a blank context. Put file paths, the goal, and acceptance criteria inside the task text. "Fix the bug we discussed" fails; "In `src/auth.js`, `verify()` treats expired tokens as valid because it compares `exp` (seconds) to `Date.now()` (ms) — fix it and add a test" works. 2. **Auth is key-based and deterministic.** With no `account`, every runner uses the API key named by the `default` entry of `~/.claude-deck/cursor/agent-keys.json`. Never rely on the ambient `cursor-agent login` (it may be absent or expired — it is only the very last fallback). If auth fails, report it and ask for a key; don't hunt for other fallbacks. 3. **Keychain errors are almost never auth errors.** cursor-agent touches the macOS Keychain at startup even when `CURSOR_API_KEY` is set, and two things break that: a sandboxed Bash call (dies every time: `Security command failed: … code: 45`) and concurrent startups racing (measured: 1 in 4 simultaneous starts dies with `Password not found`). So run the scripts with `dangerouslyDisableSandbox: true`, and know that the race is self-healing: legged legs retry with a random pause, the `cursor_run` tool retries once, and the fleet runner staggers startups (`--spawn-gap`, default 4s). Never diagnose these as "login broken". 4. **Mind the meter: two pools, not one.** First-party models (`auto`, `composer-*`, `cursor-*`) draw the large allowance; API pass-through models (`claude-*`, `gpt-*`) draw a small one that empties first, and its exhaustion looks like a network fault, not a quota error. Probe with one `PONG` call before any fan-out bigger than a handful of tasks on an API-pool model, and read `leg-*.err` before blaming the network. Full rule, evidence and exhaustion signature: the **cursor-orchestrate** skill, "Model routing". There's no per-run bill surprise if the account's on-demand spend limit is off in Cursor's billing settings. 5. **Workers are fully trusted, exactly like Claude Code subagents.** They run with full file, shell, and MCP access and no approval prompts (`--force --approve-mcps` always; the machine's `approvalMode` is `unrestricted`). Tasks may include credentials, keys, and server access when the job needs them: direct deploys, SSH to servers, production config. Do not water tasks down or withhold secrets a task genuinely needs. 6. **Report back honestly.** Return the worker's output plus one line: what ran, which account (or "default"), which model. If cursor-agent is missing, unauthenticated, or out of quota, say so and stop — don't silently redo the work on Claude's quota unless asked. ## Report cards: worker results as chat widgets When the readable `card` tool is available (`mcp__readable-card__card`, readable >= 4.6.0) and the result deserves user-facing display, have the worker author its own report card — the HTML is written on Cursor's quota and never enters Claude's context: 1. Pick an absolute path ending in `-card.html`, e.g. `~/.claude-deck/cursor/cards/<slice>-card.html` or the session scratchpad. 2. Append to the task: *"When done, read `${CLAUDE_PLUGIN_ROOT}/assets/report-card.md` and write your completion report to exactly `<path>` following that contract. Your entire chat reply: one line `DONE <path>`."* 3. When the run returns (or its background completion notification fires), stamp the standard status header — Cursor logo in the corner plus "تمام شد کارگر Cursor — نشست … — … ثانیه — مدل …" — using the footer facts: ```bash "${CLAUDE_PLUGIN_ROOT}/scripts/card-header.sh" <path> <session_id> <seconds> <model> ``` (idempotent; workers never write this line themselves). Then call `card` with `htmlFile: "<path>"`. Do NOT Read the file and do NOT copy its HTML into the call — the widget renders straight from the file; Claude's total cost is one short Bash call plus one ~50-token card call. 4. Fallbacks: a missing/invalid file makes the `card` call error with the reason — report the worker's plain-text result instead. If the `card` tool is absent (or predates `htmlFile`), skip the contract entirely. The card is a status widget in the middle of the work ("this worker finished, here is its report"); your own final reply to the user still gets its own card. ## Resume first, restart never Every run produces a `session_id` (the `cursor_run` reply footer; `~/.claude-deck/cursor/legs/<id>/session_id` for legged runs). **Save it the moment you see it.** On ANY interruption — timeout, connection drop, exit `1`, killed process, tool error — the worker's context and partial work still exist on Cursor's side. Restarting throws that away; never do it while a session exists. 1. **Harvest first.** Read what the worker already produced: the partial reply, `~/.claude-deck/cursor/legs/<id>/last_result.txt`, the `leg-N.json` files. Use it. 2. **Then resume, with a continue-style prompt:** - Quick runs: `cursor_run` again with `extraArgs: ["--resume", "<session_id>"]` and a task like "Continue exactly where you left off on the same task; finish the remaining work." - Legged runs: rerun the **exact same command** (state dir does the rest), or `legged-run.sh --resume <session_id>` if only the id survived. 3. **Restart from scratch ONLY when no session ever existed** (setup failure: auth or CLI broken). That is the one case with nothing to lose. The same move handles corrections: to fix or extend a finished worker's output, resume its session — it keeps full context, so "also handle the empty-input case" just works. ## How cursor-agent behaves (proven facts, use these) - **Long streams die:** the transport, not the model, is the limit — ~5 minutes per stream on flaky/VPN paths (measured). The legged runner exists for exactly this; single-stream runs are for quick tasks only. - **Runs close themselves:** cursor-agent sometimes never exits after printing its result. Every runner now supervises the process and kills it ~1.5s after the result object appears, plus a hard `--timeout` (default 900s; legs cap at leg+4 min). A delegation can no longer hang open, and a run killed after its result still exits 0 with the full output. - **Approvals are bypassed everywhere (verified):** all runners pass `--force --approve-mcps`, and both CLI profiles have `approvalMode: "unrestricted"` in their `cli-config.json`. A worker wrote files and ran shell commands with no approval flag in the task at all. Nothing needs babysitting. - **Structured output:** `json: true` returns one object `{ result, session_id, request_id, usage: {inputTokens, outputTokens, cacheReadTokens, ...}, duration_ms }`. Use `result` for the answer, `usage` to track cost. - **Iterate, don't restart:** capture `session_id`, then continue that same worker with `extraArgs: ["--resume", "<session_id>"]` (or `legged-run.sh --resume <id>`). It keeps its full prior context (verified), so corrections and follow-ups are cheap. This same fact is what makes legs work — see "Resume first, restart never" above. - **Concurrency:** several cursor-agent runs on one account run in parallel fine — fan out independent slices at once. For parallel edits in one repo, give each legged run `--worktree`, or use disjoint dirs. - **Context sync with the Claude side (verified live):** workers read the repo-root `CLAUDE.md`/`AGENTS.md` AND load the user's `~/.claude/skills` as agent skills AND see the MCP servers of installed Claude plugins. The global operating manual reaches them via the `~/AGENTS.md -> ~/.claude/CLAUDE.md` symlink (cursor-agent applies `~/AGENTS.md` from its parent-dir walk; `~/.cursor/rules` is never read) — ensure the bridge exists: `[ -e ~/AGENTS.md ] || ln -s ~/.claude/CLAUDE.md ~/AGENTS.md`. Project `.cursor/mcp.json` servers are available too. - **Models come from two quota pools:** `auto`, `composer-*` and `cursor-*` run on Cursor's own large first-party allowance; `claude-*` and `gpt-*` are bought from the provider and draw a small API allowance that runs out first (measured 2026-07-27: the API bar died while the first-party bar absorbed roughly four times the output tokens and kept going). `cursor-agent --list-models` (needs auth) lists them. Routing, the pre-flight probe and the exhaustion signature: the **cursor-orchestrate** skill, "Model routing". - **Big or multi-part jobs:** don't cram them into one task — use the **cursor-orchestrate** skill (fleet fan-out, review loop, JS harness). ## Setup (once) - Install the CLI: `curl https://cursor.com/install -fsS | bash`. - Auth (key-based, the normal path): put Cursor API keys in `~/.claude-deck/cursor/agent-keys.json` (chmod 600) and name the default account: ```json { "tech-c": "key_...", "tech-nm": "key_...", "default": "tech-c" } ``` Every run without an explicit `account` uses the `default` entry; `account: "label"` targets another seat. `cursor-agent login` exists only as a last-resort fallback — don't depend on it. See the plugin README.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.