Drive Codex and Cursor coding agents as subagents that behave just like native Claude Code subagents: give a prompt, pick a model + working dir + sandbox level, get one clean final answer back (optionally as structured JSON). Fan a prompt out across many models in parallel for consensus or a second opinion.
The engine is a single stdlib-Python CLI called subagent, installed wherever Codex,
Cursor, and Claude are authenticated — either the machine you're on, or a remote host you
reach over ssh with subagent-remote (set SUBAGENT_HOST to that host).
When to use this
- You (Claude/Fable) want to hand a self-contained task to another model — e.g. let
grok-4.5orcomposer-2.5write a function, review a diff, or research something. - You want a second opinion / adversarial check from a different model family.
- You want cross-model consensus: same question to grok + composer + gpt-5.5 + claude, compare answers.
- You want to parallelize independent subtasks across several agents.
If the work is Claude-native and you're already in Claude Code, just use the normal Agent
tool. Reach for subagent when you specifically want a non-Claude model or a fan-out.
How to call it
Two ways to invoke, depending on where subagent is installed:
Locally (agents authed on this machine): call subagent directly.
On a remote host from your laptop: set SUBAGENT_HOST once, then use the subagent-remote
shim — it forwards over ssh, quoting-safe, with stdin piped through (prompt via arg or -):
export SUBAGENT_HOST=my-agent-box # any ssh host/alias where subagent is installed
# one subagent
subagent-remote run cursor -m grok --sandbox read "Explain what this repo does" -C /path/on/host
# prompt via stdin (avoids all quoting pain — preferred for long/complex prompts)
printf '%s' "$PROMPT" | subagent-remote run codex --sandbox read -
# fan out one prompt across models, parallel
subagent-remote fanout "Is this SQL injection-safe? yes/no + why" \
--on cursor:grok --on cursor:composer --on codex --on claude:sonnet --sandbox read
(subagent-remote is just ssh "$SUBAGENT_HOST" 'subagent …' with the quoting handled.)
The recipes below use plain subagent; prefix with subagent-remote when driving a remote host.
The four commands
| command | what it does |
|---|---|
subagent run <backend> [opts] "prompt" |
run one subagent, print its final answer |
subagent fanout "prompt" --on b:model ... |
same prompt across many targets, parallel, prints JSON array |
subagent run … --background → jobs/wait/logs |
detached execution + polling |
subagent models [backend] |
list available models (and aliases) |
subagent doctor |
check every backend is installed + authed |
Backends: claude, codex, cursor.
run options (also apply to fanout)
-m, --model— model id or alias (see below). Omit for the backend default.-e, --effort minimal|low|medium|high|xhigh— reasoning effort (codex: config knob; cursor: selects the grok tier; claude: encode in model).-C, --cwd DIR— working directory (default: cwd).--sandbox read|write|all— read = analysis only, write (default) = autonomous edits in the workspace, all = no sandbox (dangerous). See mapping below.--system TEXT— system prompt / role instructions (claude:--append-system-prompt; codex & cursor: prepended as a[SYSTEM INSTRUCTIONS]block).--schema FILE— JSON-schema file → structured JSON output (codex native; others best-effort).--worktree NAME— run inside an isolated git worktree (parity with Claude'sisolation:"worktree");--worktree-base BRANCHsets the base. Edits don't touch your tree.--image FILE— attach an image (codex only; repeatable).--background— run detached, print a job id; poll withsubagent wait <id>/ inspect withsubagent jobsandsubagent logs <id>.--json— print the full normalized envelope (backend, ok, result, session_id, usage, duration_ms, worktree, cmd) instead of just the answer.--resume ID— continue a prior session (session_id from a previous envelope). Multi-turn continuity is verified on codex and cursor.--timeout SECONDS— default 900.--add-dir DIR— extra readable/writable dir.
Model aliases (the ones worth remembering)
- cursor:
grok→grok-4.5-high,grok-max→grok-4.5-xhigh,composer→composer-2.5,composer-fast→composer-2.5-fast,opus→claude-opus-4-8-thinking-high,sonnet→claude-4.5-sonnet,gpt→gpt-5.5-high,gemini→gemini-3.1-pro. - codex: omit
-mfor the default;gpt→gpt-5.5. - claude:
opus|sonnet|haiku.
⚠️ Cursor model ids must include an effort suffix — grok-4.5 alone is rejected; use
grok-4.5-high (or the grok alias). Run subagent models cursor for the full live list.
Sandbox mapping (what each level does per backend)
| level | codex | cursor | claude |
|---|---|---|---|
read |
-s read-only |
--mode ask |
--permission-mode plan |
write |
-s workspace-write |
--force --sandbox enabled |
--permission-mode acceptEdits |
all |
--dangerously-bypass-approvals-and-sandbox |
--force --sandbox disabled |
--permission-mode bypassPermissions |
Use read for reviews/research/second-opinions. Use write when the subagent should
actually edit files. Only use all when you explicitly need un-sandboxed shell.
Recipes
Second opinion on a diff (read-only):
git -C /path/to/repo diff | subagent run cursor -m grok --sandbox read \
"Review this diff for bugs. Be terse: list only real issues." -C /path/to/repo
Cross-model consensus, then you synthesize:
subagent fanout "Should we index this column? table has 50M rows, queried by user_id range." \
--on cursor:grok --on cursor:composer --on codex --sandbox read
# -> JSON array; read each .result, reconcile disagreements yourself.
Delegate a real edit to composer:
subagent run cursor -m composer --sandbox write \
"Add type hints to utils.py and run the tests." -C /path/to/repo
Structured output:
# schema.json describing your object
subagent run codex --schema /path/to/schema.json --sandbox read \
"Extract {title, severity, file} for each finding."
Notes & gotchas
- Codex is authed via ChatGPT login; Cursor via a session token lifted from the
Mac keychain into
~/.config/subagentmaxxing/cursor-access.jwt(valid ~2 months). Whensubagent doctorwarns the token is near expiry, runlift-cursor-tokenon the Mac to refresh it. Seedocs/auth.md. - Always prefer stdin (
-) for prompts through the remote shim — it sidesteps every layer of shell quoting. subagent runprints only the answer; add--jsonwhen you need session_id (to resume), token usage, or the exact command that ran.- Fanout runs up to
--max-parallel(default 6) concurrently and prints a progress line per task to stderr; the JSON array goes to stdout. - This is not a replacement for the native Agent tool when you want a Claude subagent — it's for reaching Codex/Cursor models specifically.
Full backend feature coverage: docs/backends.md · parity table: docs/feature-matrix.md.