Cc Delegate
БесплатноНе проверенDelegates heavy development tasks from a supervisor to an autonomous worker on a cheaper model via MCP, with isolated git worktrees and provider-agnostic suppor
Описание
Delegates heavy development tasks from a supervisor to an autonomous worker on a cheaper model via MCP, with isolated git worktrees and provider-agnostic support.
README
cc-delegate
Delegate a whole dev task from your frontier-model supervisor to a cheaper worker model — isolated in a git worktree, graded against a rubric, reviewed as one clean diff.
License: MIT Claude Code plugin Runtime: uv

Your supervisor — Claude Code on a frontier model — stays on Anthropic and keeps doing what it's good at: planning and reviewing. A worker on any cheaper, litellm-routable model does the heavy implementation in the background, in its own git worktree. You review one diff at the end instead of watching a stream of half-finished edits, and only the worker's tokens land on the alternate provider.
Why cc-delegate
- Whole tasks, not per-call routing. One
run_dev_taskhands off a complete bounded task — implement, test, iterate — behind a single tool call, instead of routing individual completions. - Isolated by construction. Every task runs on its own
delegate/<task_id>branch in a throwaway worktree. Nothing touches your working tree until you review the diff. - "Done" is graded, not claimed. A rubric checks the result against your
definition_of_doneandtest_command, so the worker can't declare victory on its own say-so. - Non-blocking.
run_dev_taskreturns atask_idimmediately and the worker runs in the background. The supervisor ends its turn and polls on a schedule it sets itself, so you keep its full attention in between. - Bounded. A cost cap, a git-history guard, and a stall watchdog keep a runaway worker from overspending, touching shared branches, or hanging past its limits.
What a delegation looks like
Ask the supervisor to take on something large and the packaged skill kicks in:
You: Delegate implementing the token-refresh flow in
src/auth/— tests must pass.Supervisor: Starting a delegated task…
run_dev_task→t_…yqsldx. I'll check back in a couple of minutes.(a few cheap status polls later)
Supervisor: Done — 4 files changed, tests green, $0.24. Here's the diff.
The worker did that for $0.24; the supervisor spent only the handful of tokens to scope the task and read the diff back. That split is the point — the expensive model plans and reviews, the cheap one types.
When to delegate. Reach for it on large, bounded work: a multi-file feature, a refactor, a test-and-iterate loop. Skip it for one-line fixes and read-only questions — the supervisor answers those directly, faster than it can stand up a worktree.
How this compares
These tools overlap with cc-delegate without being drop-in alternatives; each sits at a different point in the design space. I haven't run them in anger, so the notes below are read from their docs — directional, not a benchmark.
| Dimension | cc-delegate | houtini-lm | Roo Code Orchestrator |
|---|---|---|---|
| Unit of work | A whole multi-turn task with its own agent loop | A single model call, routed per request | A subtask inside Roo's orchestrator/mode system |
| Completion check | Rubric graded against your definition_of_done / test_command |
Caller decides | Orchestrator reads the subtask's summary back |
| Isolation | Own git worktree + branch per task | Per-call, so there's no persistent state to isolate | Separate context per subtask, shared workspace |
| While it runs | Async: returns a task_id, supervisor polls on its own schedule |
Synchronous: the caller waits on the call | Synchronous: the orchestrator waits on the subtask |
| Setup & overhead | Needs uv and a worktree per task |
Just an MCP call — nothing to provision | Install the VS Code extension |
In practice. houtini-lm — also a Claude Code MCP server — is the lighter touch when you want to route individual completions and don't need isolation or a task loop; there's nothing to stand up. Roo Code fits if you'd rather work inside a full VS Code extension with its own UI than a Claude Code plugin. Both reach plenty of providers — houtini-lm through local runtimes (LM Studio, Ollama, vLLM) and hosted ones, Roo Code per-mode via LiteLLM — so provider breadth isn't the deciding axis. cc-delegate earns its worktree-and-rubric overhead when the thing you want to hand off is a whole bounded task and get back one reviewed diff.
Install
Installing the plugin is one command, but two things live outside Claude Code's control: a worker
API key and uv. Neither is guaranteed just because you have Claude Code. Go in order:
1. Get a worker API key. You'll need a key for whatever provider the worker runs on. Out of the box that's MiniMax — sign up at platform.minimax.io and generate a key — but any litellm-routable provider works; skip ahead to Configuration to point it elsewhere.
2. Install uv if uv --version
doesn't already show it. That's the only runtime prerequisite: uv run resolves the server's and
worker's inline Python dependencies (and Python itself, if needed) on first use — no pip install,
no Node.js, no build step.
3. Set DELEGATE_API_KEY as a persistent environment variable, then restart Claude Code. This
is the step most likely to trip you up: .mcp.json's ${DELEGATE_API_KEY} only reads the OS-level
environment of the process that launched Claude Code — there's no .env auto-loading and no
interactive prompt. Setting it after Claude Code is already running does nothing until you restart
from a shell that has the variable.
# Windows (PowerShell) — persists across terminals; restart Claude Code afterward
[Environment]::SetEnvironmentVariable("DELEGATE_API_KEY", "your-key-here", "User")
# macOS/Linux — add to ~/.zshrc or ~/.bashrc, then open a new shell
export DELEGATE_API_KEY="your-key-here"
4. Install the plugin.
/plugin marketplace add EtienneLescot/cc-delegate
/plugin install cc-delegate@cc-delegate-marketplace
Or locally during development: claude --plugin-dir .
5. Verify. Run /mcp — the checkpoint that surfaces a missing uv/key before you're mid-task.
A SessionStart hook additionally probes uv --version at the start of every session as an
earlier best-effort check (exec-form, so it behaves the same on Windows/macOS/Linux); treat it as a
bonus signal, not the primary one.
Configuration
The facade (preferred). The plugin configures itself through its own MCP tools, driven conversationally from Claude Code — no restart needed, changes apply to the next task:
- "Show me the provider status" →
provider_statuslists your model profiles, the default, and per-profile auth state (key reachable? OAuth token cache present?). - "Add a deepseek profile" →
set_model_profile("deepseek", "litellm:deepseek/deepseek-chat", "DEEPSEEK_API_KEY");set_default_profile/remove_model_profilemanage the menu. - "Add a fallback to deepseek if MiniMax fails" →
set_model_profile("mm", "litellm:minimax/MiniMax-M3", "MINIMAX_API_KEY", fallback_models=["litellm:deepseek/deepseek-chat"])— tried in order via litellm's own fallback mechanism if the primary model's call fails. - "Store my key for the deepseek profile" →
store_api_key("deepseek")asks for the key through a native Claude Code dialog (MCP elicitation, Claude Code ≥ 2.1.199): the secret goes straight back to the server without ever entering the model's conversation. - Per task: "delegate this on the deepseek profile" →
run_dev_task(..., profile="deepseek"). The supervisor's skill forbids it from picking a non-default profile on its own.
Profiles live in ~/.cc-delegate/config.json, facade-stored keys in
~/.cc-delegate/credentials.json. Any litellm-routable model works — see
litellm's provider list.
Subscription providers (OAuth). For a profile on an OAuth provider — GitHub Copilot
(set_model_profile("copilot", "litellm:github_copilot/gpt-5"), no API key) or ChatGPT
(set_model_profile("chatgpt", "litellm:chatgpt/gpt-5.3-codex")) — run
setup_provider_auth("<profile>"). It returns a verification URL and a user code; visit the URL,
enter the code, authorize, and auth_poll(flow_id) flips to authorized. litellm caches the
tokens, so later runs need no interaction and the key never touches the config. The device flow is
exercised for GitHub Copilot; the ChatGPT adapter is wired the same way but hasn't yet been run
end-to-end against a live subscription.
On terms of service (this varies by provider): OpenAI supports third-party tools using a ChatGPT subscription this way — its Codex for Open Source program lists such tools explicitly — and GitHub Copilot's device flow is widely used by third-party editors. Anthropic prohibits subscription use outside Claude Code itself, and Google does the same for Gemini CLI, so cc-delegate implements OAuth for neither.
Legacy env path (still supported). See .env.example for the full list:
DELEGATE_API_KEY, DELEGATE_MODEL, DELEGATE_API_KEY_ENV_VAR, and the guardrails
(DELEGATE_RECURSION_LIMIT, DELEGATE_RUBRIC_MAX_ITERATIONS, DELEGATE_TIMEOUT_MS,
DELEGATE_STALL_TIMEOUT_S, DELEGATE_MAX_BUDGET_USD, DELEGATE_ASK_TIMEOUT_S). This path applies
when no profile is defined; env changes require restarting Claude Code (the restart trap in Install
step 3 only concerns this path).
Architecture
flowchart LR
Supervisor["Claude Code supervisor<br/>(Anthropic API)"]
MCP["cc-delegate MCP server<br/>Python (uv run server/main.py), stdio<br/>run_dev_task (async), get_task_status,<br/>get_task_progress, answer_worker, steer_task,<br/>cancel_task, fetch_task_result, cleanup_task"]
Worktree["Disposable git worktree<br/>branch delegate/<task_id>"]
Worker["uv run worker/worker.py<br/>deepagents loop<br/>+ implementer / tester / reviewer subagents<br/>+ rubric grader"]
Provider["Provider<br/>(litellm-routed,<br/>e.g. MiniMax M3)"]
Review["Supervisor review<br/>of patch / diff"]
Supervisor -->|"run_dev_task /<br/>get_task_status / get_task_progress /<br/>steer_task / fetch_task_result / cleanup_task"| MCP
MCP -->|"createWorktree()"| Worktree
MCP -->|"uv run worker.py"| Worker
Worker -->|"litellm completion"| Provider
Provider -->|"model response"| Worker
Worker -->|"PROGRESS: {step, node, ...}<br/>QUESTION: {id, message}<br/>(live, flushed per step)<br/>RESULT_JSON: {status, summary,<br/>turns, cost_usd, total_tokens,<br/>rubric_status, error}"| MCP
MCP -->|"status + progress<br/>(get_task_status, on poll)"| Supervisor
Worktree -->|"git diff --cached"| MCP
MCP -->|"patch + diff"| Review
The MCP server (server/main.py, official mcp Python SDK, run via uv run) exposes the
delegation tools to the supervisor over stdio:
| Tool | What it does |
|---|---|
run_dev_task |
Start a delegated task (preflights your test_command first) and return a task_id immediately — the worker runs in the background. |
get_task_status |
Cheap liveness: running / needs_input / done. Poll it as often as you like. |
get_task_progress |
Verbose audit: files written so far, recent activity, cost. Call occasionally. |
answer_worker |
Reply to a worker blocked on a question. |
steer_task |
Redirect a running worker at any moment — delivered at its next tool call. |
cancel_task |
Kill a stalled/runaway worker's whole process tree, salvaging its work. |
fetch_task_result |
Final summary, patch, files changed, cost — including salvaged work from failed runs. |
cleanup_task |
Tear down a finished task's worktree, branch, and persisted job file. |
- Job persistence — every job is mirrored to
<repo>/.cc-delegate/jobs/<task_id>.jsonon each state change, so status, result, and cleanup queries survive MCP-server restarts: the in-memory registry is rebuilt from disk on demand. - The worker (
worker/worker.py) is a deepagents agent, run as a subprocess viauv run. It usesLocalShellBackendinvirtual_mode=Trueto scope filesystem and shell access to the worktree,SubAgents for implementer/tester/reviewer roles, andRubricMiddlewareto grade completion against yourdefinition_of_done/test_commandrather than the model's own "I'm done". Each run reportscost_usdandtotal_tokensvia a litellm callback and prints a flushedPROGRESS:line per step. - The packaged skill (
skills/delegate-heavy-dev/SKILL.md) teaches the supervisor when and how to delegate.
Why deepagents-as-a-library, not a CLI agent
We started with the worker calling @anthropic-ai/claude-agent-sdk's query() pointed at a
third-party endpoint, then tried shelling out to CLI coding agents (OpenCode, dcode) — both hit
either an unresolved Claude Code CLI headless-auth bug or a Windows/no-TTY hang in dcode's rich
terminal UI. Calling deepagents directly as a library sidesteps both: no CLI, no TTY dependency,
and real control over the loop (subagents, rubric-based convergence) instead of a black-box CLI.
The full story — three worker engines, two upstream bugs — is in
docs/build-journey.md; the reproducible bug reports are in
KNOWN_ISSUES.md.
Supervision model — async, scheduled polling
run_dev_task returns a task_id immediately and the worker runs in the background. The supervisor
never blocks: a standard MCP server can't push into the model's context, so the worker can't call
the supervisor — but the supervisor doesn't need to sit and wait either. It ends its turn (free) and
re-checks on a cadence it schedules itself: a background wait re-invokes it ("I'll check in ~2 min"),
or it simply checks when you next speak. Between checks, you have its full attention.
Two polling tools, split by cost so frequent checks stay cheap:
get_task_status— a tiny payload (running/needs_input/done, plus the pending question if blocked). Poll it freely; it barely touches the context.get_task_progress— a verbose audit (files written, recent shell commands, step, cost, elapsed). Heavier, so the supervisor calls it occasionally, or when you ask "how's it going?".
On needs_input, the supervisor decides: answer from its own context with answer_worker, or relay
the question to you when it's genuinely your call. On done, it reviews with fetch_task_result.
For large work, the supervisor decomposes into bounded sub-tasks and runs independent ones
(different files) in parallel — each run_dev_task gets its own worktree/branch — while
serializing sub-tasks that touch the same files to avoid merge conflicts.
Why not a blocking "watch" call or MCP progress notifications?
Both were tried and removed. A blocking call freezes the supervisor for the whole run, and progress notifications never enter the model's context and aren't rendered by the desktop app — so neither gives the supervisor something it can actually act on. Scheduled polling does.
Status line — always-visible ambient indicator (TUI)
For a passive, glance-able view without asking the supervisor, the status line keeps a one-line summary in Claude Code's status bar, token-free (TUI only — the desktop app does not render custom status lines):
⏳ delegate t_…yqsldx · MiniMax-M3 · step 24 · writing src/auth/tokens.js
⚠ delegate t_…yqsldx · asks: which token TTL? · → answer_worker
✓ delegate t_…yqsldx · done · 4 files · $0.24
It stays token-free on both ends: the MCP server (already resident) renders the line in Python and
writes it to ~/.cc-delegate/statusline; the status-line script Claude Code runs is a
dependency-free reader (no jq, no python, no JSON parsing) that just prints the pre-baked line
while it's fresh. The harness runs it locally, so it never consumes API tokens.
Wire it once in ~/.claude/settings.json (refreshInterval is required — status-line event
triggers go quiet while the session waits on the background worker, so the timer keeps the line
live):
{
"statusLine": {
"type": "command",
"command": "~/.claude/cc-delegate-statusline.sh",
"refreshInterval": 2
}
}
Copy statusline/cc-delegate-statusline.sh (or, on Windows without Git Bash, the .ps1 variant)
to ~/.claude/ and chmod +x it. A running task refreshes the line on every event; a blocked task
keeps its question visible until you answer; a finished task shows a short-lived summary that then
fades — no stale state left on screen.
Worker ↔ supervisor communication (and steering)
The worker is not fire-and-forget. Three tools are injected into its agent loop:
report_progress(update)— fire-and-forget one-liners at phase transitions; they surface throughget_task_progressand the status line.ask_supervisor(question, context)— blocks the worker (zero tokens while waiting) and flips the task toneeds_input. The supervisor discovers the question on its nextget_task_statuspoll, answers from its own context or relays it to you, then replies withanswer_worker. If no answer arrives withinDELEGATE_ASK_TIMEOUT_S(default 600s), the worker proceeds on its best conservative judgment.report_blocker(problem, attempts)— same mechanism, for "I've failed 3 times at the same error": the supervisor can correct course instead of letting the worker thrash until timeout.
Answers travel out-of-band through a file mailbox in <repo>/.cc-delegate/comm/<task_id>/, never
through the model conversation.
The other direction — steer_task(task_id, message) lets the supervisor redirect a running
worker at any moment, not only in reply to a question: "stop implementing X, do Y instead." It
doesn't block the worker or change its status; the message sits in the mailbox until the worker's
next tool call picks it up, typically within seconds. (Interrupting an in-flight LangGraph step from
outside would need a checkpointer, which this architecture doesn't use.) In testing, a message
dropped mid-task showed up in the next shell command's output and the worker changed course on its
following turn.
Safety
- Worktree confinement. The worker's
LocalShellBackendruns invirtual_mode=True, scoping filesystem and shell access to the disposable worktree. The supervisor always reviews the diff before deciding whether to merge branchdelegate/<task_id>. - Git-history guard.
SupervisedShellBackendrefusesgit push/merge/rebasebefore they run — the worker only ever operates on its own disposable branch, so there's no legitimate reason to touch shared history. - Budget cap.
run_dev_task(..., max_budget_usd=...)(default fromDELEGATE_MAX_BUDGET_USD, $5) stops the worker as soon as accumulated cost crosses the cap, checked after every step against the live cost tracker — so a run can't drift unbounded. - Stall watchdog. If the worker goes silent longer than
DELEGATE_STALL_TIMEOUT_S(default 300s) — e.g. a hung provider call inside rubric grading — its process tree is killed and the run fails fast instead of hanging until the full 30-minute run timeout. Salvage still runs, so completed work isn't lost. A worker legitimately waiting onanswer_workeris exempt. - Secret filtering. The worker's shell environment drops anything matching
API_KEY/TOKEN/SECRET/PASSWORD/CREDENTIAL; facade-stored keys and OAuth tokens never enter the model's conversation.
For maintainers
No build step. The server is plain Python (server/, stdlib + the mcp SDK declared inline in
main.py); the worker is worker/worker.py. Run the test suite with:
uv run python -m unittest discover -s server -p "test_*.py"
Verify the wiring end-to-end:
/mcplists thecc-delegateserver and its tools./statusin the supervisor session still showsapi.anthropic.com— no worker config ever leaks into the supervisor process.- Ask the supervisor to delegate a heavy task; it should call
run_dev_task, pollget_task_status, then present the diff viafetch_task_result.
License
MIT for this repository's own code. See NOTICE for a note on third-party terms of use.
Установка Cc Delegate
У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.
▸ github.com/EtienneLescot/cc-delegateFAQ
Cc Delegate MCP бесплатный?
Да, Cc Delegate MCP бесплатный — установка в пару кликов через Unyly без оплаты.
Нужен ли API-ключ для Cc Delegate?
Нет, Cc Delegate работает без API-ключей и переменных окружения.
Cc Delegate — hosted или self-hosted?
Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.
Как установить Cc Delegate в Claude Desktop, Claude Code или Cursor?
Открой Cc Delegate на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.
Похожие MCP
GitHub
PRs, issues, code search, CI status
автор: GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
автор: mcpdotdirectCompare Cc Delegate with
Не уверен что выбрать?
Найди свой стек за 60 секунд
Автор?
Embed-бейдж для README
Похожее
Все в категории development
