cc-delegate
The cc-delegate server lets you delegate heavy development tasks from a Claude Code supervisor to an autonomous worker agent (typically a cheaper model), managing the full lifecycle of asynchronous coding tasks.
run_dev_task: Launch an autonomous coding worker on an isolated git worktree with a natural-languagespecandrepo_path. Optionally configurebase_branch,test_command,definition_of_done,max_turns,timeout_ms, andmax_budget_usd. Returns atask_idimmediately for async tracking.get_task_status: Poll the current status, progress, turn count, and estimated cost of a running or completed task using itstask_id.fetch_task_result: Once a task has succeeded, retrieve the full result including a summary, patch path, list of changed files, test outcomes, and cost incurred.
The worker runs in a disposable worktree, and the supervisor can review diffs before merging. Configuration (worker model, API key, timeouts, recursion limits) is managed via environment variables.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cc-delegateRefactor the authentication service to use async/await."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
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.
Related MCP server: codex-as-mcp
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 | 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 | 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 | Synchronous: the caller waits on the call | Synchronous: the orchestrator waits on the subtask |
Setup & overhead | Needs | 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-marketplaceOr 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"| ReviewThe 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 |
| Start a delegated task (preflights your |
| Cheap liveness: |
| Verbose audit: files written so far, recent activity, cost. Call occasionally. |
| Reply to a worker blocked on a question. |
| Redirect a running worker at any moment — delivered at its next tool call. |
| Kill a stalled/runaway worker's whole process tree, salvaging its work. |
| Final summary, patch, files changed, cost — including salvaged work from failed runs. |
| 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.
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.
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.24It 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.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityBmaintenanceAn MCP server that delegates coding and sysops work to cheaper agents via durable background queues, with git worktree isolation, safety policies, and clarification rounds to avoid hitting limits of frontier models.Last updated2Apache 2.0
- Flicense-qualityAmaintenanceDelegates work from MCP clients (like Claude Code) to the Codex CLI, allowing spawning of autonomous Codex subagents for tasks.Last updated169
- Flicense-qualityCmaintenanceSpawn headless OpenCode workers on cheap models to delegate expensive tool-using tasks to a fleet of parallel workers with isolated git worktrees.Last updated
- AlicenseAqualityBmaintenanceDelegate coding tasks to external AI coding agents in isolated git worktrees with independent verification, enabling any MCP client to orchestrate multi-agent workflows.Last updated5MIT
Related MCP Connectors
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
The project brain for AI coding agents — memory, decisions, sprints, knowledge base via MCP.
Agent-native collaboration network: orchestrate a team of long-running agents from any MCP client.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/EtienneLescot/cc-delegate'
If you have feedback or need assistance with the MCP directory API, please join our Discord server