codex-supervisor-mcp

Execute workers paralelos do Codex CLI a partir do Claude Code ou de qualquer cliente MCP: um git worktree por worker, estado em SQLite, perguntas paralelas para um worker, integrando seus commits, painel web.

Documentação

codex-supervisor-mcp

English | 中文

npm version npm downloads license CI node

Site oficial codex-supervisor.zriyo.com · llms.txt para modelos lerem

Vários agentes alterando o mesmo repositório ao mesmo tempo resulta em sobrescritas mútuas, ninguém sabe quem mudou o quê, e o contexto da thread principal fica entupido com a saída dos workers.

codex-supervisor-mcp é um MCP server do Codex que tira a "distribuição de tarefas" e a "contabilidade" do contexto do modelo e coloca no disco: uma thread principal (Claude Code, Codex ou qualquer cliente MCP) comanda vários workers do Codex CLI simultaneamente, um worker por Git worktree, com estado persistido em SQLite e um painel web anexo.

演示:一个 Claude Code 主线程同时派 3 个 Codex worker,各自独立 worktree,并行跑完后合并提交

Rodando de verdade em 30 segundos: create_codex_worker ×3, três workers em worktrees paralelos, a thread principal recebe 3 diffs e combina em um único commit.

O que resolve

ProblemaSolução
Vários workers sobrescrevem arquivos uns dos outrosUm worker por Git worktree, ownedPaths verifica conflitos antes de distribuir
A saída dos workers estoura o contexto da thread principalEventos gravados em data/runs/<taskId>.jsonl, com limit / maxChars / kinds como três filtros na leitura
A thread principal estoura ao ler o estado uma vezget_orchestration_overview compacta todos os workers em 7000 bytes
Após reiniciar o processo, ninguém sabe quem ainda está rodandosupervisor.sqlite um work por linha, com thread_id
Trocar de sessão não conecta aos workers anterioresresume_codex_worker via codex exec resume <thread_id>, conecta na mesma sessão do Codex
Não distingue "falhou ao rodar" de "processo morreu"A máquina de estados separa failed de lost
Worker diz que terminou mas não terminouDistribui com comando de aceite acceptance, o supervisor roda no worktree do worker após a saída; se falhar, land rejeita
Não dá para ver o andamento de um lote de tarefascodex-supervisor-web abre um painel, mostrando o que cada worker está fazendo por sessão

Os workers rodam com codex exec, com model repassado: a thread principal fica no Claude, os workers podem usar DeepSeek ou qualquer modelo com provider configurado no Codex, com cobranças separadas.

Rodando em cinco minutos

Pré-requisitos: Node.js 22.13.0 ou superior, CLI codex no PATH. Funciona em macOS, Linux e Windows.

1. Instalação

npm install -g codex-supervisor-mcp

postinstall instala a skill e registra o MCP. Se não aparecer em claude mcp list (npx, pnpm, --ignore-scripts não rodam postinstall), adicione manualmente:

claude mcp add -s user codex-supervisor -- npx -y codex-supervisor-mcp
codex mcp add codex-supervisor -- npx -y codex-supervisor-mcp

Reinicie o Claude Code / Codex. Não precisa atualizar manualmente depois — veja "Atualização". Se quiser apenas a skill sem o MCP: npx skills add zriyox/codex-supervisor-mcp.

2. Distribua o primeiro lote

No Claude Code, fale diretamente em linguagem natural; a skill fará o fluxo correto:

Complete os testes unitários destes três módulos, use codex-supervisor para rodar em três vias paralelas, sessão chamada "completar testes".

O que a thread principal faz por trás (você também pode chamar as ferramentas diretamente):

create_codex_worker ×3   每路带 session_id、session_title、ownedPaths、goal
wait_codex_workers       默认等 2 分钟,到点返回快照,没完就接着等
get_worker_result ×3     收每路的汇报,带它真跑过的命令和退出码

As alterações de cada via ficam no próprio branch codex/<taskId>; mesclar ou não, e como, é decisão da thread principal.

3. Abra o painel

codex-supervisor-web
# 没全局装也能起:
npx -p codex-supervisor-mcp codex-supervisor-web

Abra http://127.0.0.1:7877. O diretório de estado é localizado na ordem SUPERVISOR_HOME, .mcp.json mais recente, ~/.codex-supervisor; use SUPERVISOR_WEB_PORT para mudar a porta. O painel é somente leitura — não distribui tarefas nem cancela.

Como eu uso

Qualquer coisa que conecte via MCP pode ser a thread principal; isto é apenas o meu uso. Abro duas sessões do Claude Code: uma só para documentação, outra só para distribuir tarefas: uma sessão que escreve o design detalhado e fica de olho nos workers estoura o contexto em duas horas.

QuemOnde abreO que gerencia
EuDefino requisitos, decido, vejo relatórios
Sessão de planejamentoRepositório de requisitos e documentaçãoConverso sobre requisitos, escrevo design detalhado, uma especificação de tarefa por bloco, com uma mensagem final para o cérebro no fim
Sessão cérebroUm worktree do repositório de códigoLê especificações, distribui workers do Codex, revisa os diffs de cada via, preenche os resultados na especificação, me reporta. Não escreve código de negócio
Workers do CodexSeus próprios worktreesUm worker faz um passo, um commit, compila e valida na máquina remota. Não faz push, não mescla

Entre as duas sessões, apenas um texto é passado; cole na sessão cérebro e conecte com /goal. Estrutura fixa:

【角色】   你是主脑:读文档和代码,派 worker,核结果,更新文档,向我汇报。不写业务代码。
           派活和盯进度用 codex-supervisor 这个 skill,开工前先加载它。
【背景】   这一块为什么做,上一块留下了什么
【先读】   哪几份文档的哪几节。几份说法不一样时以哪份为准
【仓和分支】工作目录在哪,各分支现在在哪个提交,哪些分支只读
【做什么】 照任务书第几节那张表做。一步一个提交,这步验证过了才做下一步。表里没有的不做
【派活】   先 search_works 看有没有派过,别重复
           整批用同一个 session_id
           改同一批文件就串行,文件完全不重叠才并行,每路 ownedPaths 写清
           一个 worker 只做一步。task 写全:背景、文档出处、要改的文件、验证命令、输出格式
           验证命令同时填 acceptance,supervisor 替你跑,它说过了不算
           worker 交回来先看 diff。它说过了不算,你看到才算
【构建和测试】全走远端机器,本机不跑
【红线】   不改什么,不推什么,不读什么
【必须停下来问我】
【汇报】   中文,表格优先,报哪几项,然后停下来等我

Ferramentas que o cérebro usa em uma rodada:

search_works            查这批活派过没有
create_codex_worker     一步一个 worker,同一个 session_id,ownedPaths 不重叠
wait_codex_workers      2 分钟一轮,compact: true,没完接着调
get_worker_result       它说自己做了什么,verification 里是它真跑过的命令
get_worker_diff         它实际做了什么
ask_codex_worker        对不上就问它为什么,只读,不动它的线程
resume_codex_worker     要改就追一条,让它 amend 进原来那个提交;主线走远了带 rebaseOnto
land_codex_worker       核过了,落进集成分支

O último bloco teve 25 passos; a sessão cérebro acompanhou do passo 1 ao 25 sozinha, com apenas a especificação e os relatórios de cada via no contexto, sem estourar com a saída dos workers.

Por que um worker faz apenas um passo: se o passo 5 der errado, o worker do passo 5 faz resume_codex_worker, corrige, faz --amend e volta ao próprio commit; o cérebro revisa de novo e só então integra ao branch de integração. Se um worker tivesse feito os passos 5, 6 e 7, o passo 5 errado não poderia ser corrigido assim — os commits 6 e 7 já estariam empilhados sobre o 5, e corrigir o 5 exigiria refazer 6 e 7 também.

O que tem no painel

LocalConteúdo
Coluna esquerdaUma linha por sessão: título, número de workers, quantos rodando, atividade recente. No canto inferior esquerdo, versão e aviso de atualização
Página da sessãoEstatísticas (total / rodando / concluídos / falhos / perdidos); com workers rodando, lista o comando em execução de cada via
Registro de workersUma linha por via: status, título, comando em execução ou último relatório, tempo decorrido, arquivos alterados, comandos executados
Gaveta do workerSete abas: visão geral, relatório, alterações, comandos, eventos, especificação, perguntas paralelas
Perguntas paralelasPergunte algo ao worker; é o /btw do Codex: bifurca uma sessão paralela somente leitura do thread dele para responder, sem tocar no trabalho em andamento. Multirrodadas, interrompível, reconecta automaticamente ao voltar para a aba

Tema claro e escuro seguem o sistema; sem recursos externos.

Ferramentas

19 no total.

FerramentaParâmetrosFunção
create_codex_workertask, cwd, ownedPaths, goal, acceptance, session_id, session_title, session_note, dependsOn, baseRef, sandbox, model, reasoningEffort, title, skipGitRepoCheckInicia um worker. acceptance é o comando de aceite; após o worker sair, o supervisor roda no worktree dele; código de saída 0 = aprovado. baseRef define de qual commit o worktree parte; padrão HEAD; para conectar em outra via, use o codex/<id> dela
create_codex_followup_workertask_id, followup_prompt, session_id, demais como acimaAbre uma nova sessão, montando o prompt, estado e eventos recentes do worker antigo
resume_codex_workertask_id, prompt, rebaseOnto, acceptanceContinua na mesma sessão do Codex; thread_id não muda. rebaseOnto primeiro move o worktree para o novo head da linha principal (stash, reaplica os commits dele, recoloca); conflitos retornam como estão, sem iniciar worker
wait_codex_workerstask_ids, mode(any/all), timeoutMinutes, timeoutMs, compact, includeEvents, eventLimit, eventMaxChars, eventKindsAguarda estado final. Padrão 2 minutos; ao estourar, retorna com snapshot e o worker continua. compact retorna uma linha por via, com idle_seconds / command_running, distinguindo comando longo de travamento
get_orchestration_overviewstatus, limitTabela de status de todos os workers, limitada a 7000 bytes. Inclui version e update
get_worker_resulttask_id, limit, maxChars, includeFilesRelatório do próprio worker; padrão 6000 bytes truncados, truncated avisa para ler tudo. acceptance indica se o aceite rodado pelo supervisor passou; verification são os comandos e códigos de saída que ele rodou; base_behind mostra o progresso da linha principal
get_worker_difftask_id, maxChars, pathsO que o worker realmente mudou: patch do início do worktree até a área de trabalho, incluindo alterações commitadas ou não. maxChars controla o total; arquivos acima do limite aparecem só com o nome
ask_codex_workertask_id, question, timeoutMs, maxChars, fresh, endPergunta paralela ao worker. O thread é bifurcado em sessão lateral somente leitura, sem rede, sem ferramentas MCP; o worker não é afetado. Se o worker foi retomado, um novo fork é criado automaticamente; fresh força a troca; end exclui
land_codex_workertask_id, onto, commitMessage, ignoreAcceptanceFaz cherry-pick dos commits do worker em codex/<id> para o branch atual do diretório de distribuição. O destino precisa estar limpo; conflitos revertem; aceite failed rejeita. commitMessage primeiro commita as alterações não commitadas do worker; ignoreAcceptance libera
get_worker_summarytask_idUm parágrafo: goal, status, alterações, último comando e mensagem
get_codex_worker_statustask_id, includePrompt, promptMaxCharsDetalhes de status de um worker
get_codex_worker_eventstask_id, limit, maxChars, kindsFluxo de eventos bruto
get_worker_goaltask_idGoal registrado na distribuição + goal nativo do Codex (tokens, tempo)
list_codex_workersstatus, includeHistory, includeDetailsLista workers; padrão apenas os em execução
get_session_workssession_idTodos os workers de uma sessão. A thread principal usa para recuperar o lote após reiniciar
describe_sessionsession_id, title, noteRegistra título e descrição da sessão
search_worksquery, limitBusca substring em title / goal / prompt / last_message, do mais novo ao mais antigo
check_for_updateforcePergunta ao registry se há nova versão
cancel_codex_workertask_idEncerra o worker. Fallback entre processos por pid, confirmando antes que o pid roda codex

Dois são obrigatórios: ownedPaths (interseção entre a distribuição e os workers em execução; se houver sobreposição, rejeita — só consulta na distribuição) e goal.objective (o worker cria goal nativo do Codex). Sem session_id, não há agrupamento; use o mesmo valor para um lote.

Diferença para o subagent do Claude Code

Isolamento de arquivos não é a diferença: o subagent também pode abrir worktrees. A diferença está no modelo e no processo.

Claude Code subagentworker do codex-supervisor
Quais modelos pode rodarApenas Claudemodel repassa ao Codex CLI; DeepSeek também funciona
Quem executaO próprio Claude CodeProcesso codex exec independente
Duas vias escrevem no mesmo arquivoIsoladas por worktree, sem declaração de caminhoVerifica interseção de ownedPaths antes de distribuir; sobreposição rejeita direto
Processo da thread principal morreWorkers morrem juntothread_id fica no sqlite; resume_codex_worker reconecta na mesma sessão
Quem pode dirigirApenas Claude CodeQualquer cliente MCP
Ver o processoApenas a conclusão retornadaJSONL bruto e painel web

Máquina de estados

statusSignificado
queuedDistribuído, não iniciado
runningEm execução. phase: starting → thinking → command → editing → reporting
completedSucesso
failedCódigo de saída não zero, turn.failed, falha no spawn
cancelledInterrompido por cancel_codex_worker
lostMorto por sinal externo, processo MCP sumiu, ou linha escrita mas o processo nunca subiu. resume_codex_worker reconecta

O estado final é gravado em duas etapas: turn.completed primeiro define status como completed; só após a saída do processo grava exit_code; wait_codex_workers só retorna quando exit_code foi gravado. Windows não tem sinais; kill externo reporta apenas failed com código de saída. paused / blocked do goal nativo do Codex contam como running e entram em needs_attention; usageLimited / budgetLimited contam como failed.

Armazenamento de estado

Padrão em ~/.codex-supervisor/:

ArquivoConteúdo
data/supervisor.sqlitetasks (um work por linha), task_events, sessions, side_sessions / side_turns (perguntas paralelas)
data/runs/<taskId>.jsonlSaída bruta do --json do Codex
data/update-check.json, auto-update.jsonRegistros de verificação e atualização em segundo plano
worktrees/<taskId>/Git worktree do worker

changed_files é calculado pelo diff real do worktree; alterações feitas via shell ou commitadas pelo worker aparecem. Nomes de arquivo em chinês retornam como estão. Bancos antigos migram automaticamente na primeira abertura.

Variáveis de ambiente

VariávelPadrãoFunção
SUPERVISOR_HOME~/.codex-supervisorDiretório raiz de estado. MCP e painel devem apontar para o mesmo
CODEX_HOME~/.codexSomente leitura; lê o goals_1.sqlite nativo do Codex e a configuração do MCP
CODEX_BINcodexCaminho do Codex CLI. No Windows, o shim .cmd é contornado automaticamente
GIT_BINgitCaminho do Git
SUPERVISOR_WEB_PORT / SUPERVISOR_WEB_HOST7877 / 127.0.0.1Endereço de escuta do painel
CODEX_SUPERVISOR_NO_UPDATE_CHECKNão definido1 desativa a verificação de atualização
CODEX_SUPERVISOR_REGISTRYhttps://registry.npmjs.orgRegistry usado para verificação e atualização automática
CODEX_SUPERVISOR_UPDATE_TIMEOUT_MS4000Limite de espera pelo registry
CODEX_SUPERVISOR_NO_AUTO_UPDATENão definido1 desativa a atualização automática em segundo plano (apenas avisa)
CODEX_SUPERVISOR_SKIP_SKILL_SYNCNão definido1 desativa a sincronização da skill na inicialização do server
CODEX_SUPERVISOR_SKIP_SETUPNão definido1 pula a instalação automática de postinstall
CODEX_SUPERVISOR_NPMNão definidonpm usado na atualização automática; padrão é o npm do Node atual

Clientes GUI (Claude Desktop, Cursor, Windsurf) não rodam postinstall; adicione este trecho ao arquivo de configuração MCP do cliente. PATH frequentemente não tem codex; forneça CODEX_BIN explicitamente:

{
  "mcpServers": {
    "codex-supervisor": {
      "command": "npx",
      "args": ["-y", "codex-supervisor-mcp"],
      "env": { "CODEX_BIN": "/usr/local/bin/codex" }
    }
  }
}

Atualização

Não precisa atualizar manualmente. Na inicialização, o server verifica o registry em segundo plano; se houver nova versão, inicia um processo separado npm i -g no mesmo caminho global. Sessões em andamento não são afetadas; a próxima sessão nova já usa a nova versão. Vale apenas para a instalação feita por npm i -g; código-fonte via git e instâncias iniciadas por npx não são tocadas. A skill também: a cada inicialização, atualiza o diretório de skills existente; alterações são primeiro copiadas como SKILL.md.bak-<时间戳>.

Se a instalação falhar (diretório global exige sudo), o campo update traz o motivo; faça npm install -g codex-supervisor-mcp@latest manualmente. Versões 0.6.1 e anteriores apenas avisam, sem instalação automática; atualize manualmente uma vez para entrar no fluxo automático. Se trocar a versão do Node, o caminho registrado invalida; reinstale após claude mcp remove -s user codex-supervisor, codex mcp remove codex-supervisor. Para rodar a instalação novamente: codex-supervisor-setup (--skill-only / --mcp-only / --dry-run).

Desinstalação:

npm uninstall -g codex-supervisor-mcp
claude mcp remove -s user codex-supervisor
codex mcp remove codex-supervisor
rm -rf ~/.claude/skills/codex-supervisor ~/.agents/skills/codex-supervisor ~/.codex/skills/codex-supervisor ~/.codex-supervisor

Windows

  • O CLI instalado via npm é codex.cmd; o Node se recusa a fazer spawn direto. Aqui contornamos via node_modules/@openai/codex/bin/codex.js usando node, sem shell: true — assim o cancelamento não mata apenas o shell.
  • Cancelamento entre processos usa taskkill /PID <pid> /T /F para matar a árvore inteira, confirmando antes que o pid roda codex.
  • Além de PATH, também detecta %APPDATA%\npm, %LOCALAPPDATA%\pnpm, %LOCALAPPDATA%\Volta\bin, %ProgramFiles%\nodejs.

Solução de problemas

SintomaCausaTratamento
Não aparece em claude mcp listInstalação não roda postinstallcodex-supervisor-setup ou claude mcp add manual
Distribuição reporta codex only resolved to a shell shimNo Windows, só encontrou .cmd e o entry point do pacote sumiuReinstale @openai/codex, ou aponte CODEX_BIN para codex.js
Worker sai com failed logo ao iniciar, spawn codex ENOENTO processo PATH não tem codexDefina CODEX_BIN na configuração
Cannot find module 'node:sqlite'Node abaixo de 22.13.0Atualize o Node
Worker lostProcesso MCP morto; worker morreu juntoReconecte com resume_codex_worker
Worker diz git add e reporta index.lock: Operation not permittedO sandbox padrão define .git como somente leituraAo recolher, use land_codex_worker com commitMessage, ou distribua com danger-full-access
ownedPaths overlap with active worker(s)Duas vias reivindicaram o mesmo caminhoMude a divisão, ou cancele a via que está ocupando
Painel abre vazioPainel e MCP não usam o mesmo SUPERVISOR_HOMEInicie no diretório do projeto com .mcp.json configurado, ou passe explicitamente o mesmo SUPERVISOR_HOME
port 7877 ... is already in useJá existe um painel rodandoAbra o existente, ou use SUPERVISOR_WEB_PORT=8080 e inicie outro

Limitações conhecidas

  • O worker é subprocesso do processo MCP. Se o MCP for morto, o worker morre junto e é liquidado como lost; worktree e thread_id permanecem; resume_codex_worker reconecta. Para não morrer junto, seria necessário um daemon residente — está no Roadmap.
  • No sandbox padrão workspace-write, o worker não consegue commitar (o Codex define .git como somente leitura). Ou use land_codex_worker com commitMessage ao recolher para commitar por ele, ou distribua com danger-full-access.
  • O worktree parte de um commit; o que não foi commitado na sua área de trabalho não está nele.
  • Apenas o diretório de trabalho é isolado. Diretórios temporários, banco de dados e portas são compartilhados.
  • ownedPaths só verifica na distribuição; não impede o worker de criar arquivos fora da lista. Veja o diff ao recolher.
  • Aceite verifica apenas o que está escrito em acceptance. O que não está escrito não é verificado; verification são apenas os comandos que o worker rodou; o resto fica com a thread principal, revisando o diff.
  • Uma única chamada de wait_codex_workers não espera até o fim; o timeout de ferramenta MCP do cliente é um limite duro — chame repetidamente.
  • search_works é correspondência por substring; algumas centenas de itens são suficientes.

Roadmap

Concluído: CODEX_BIN / SUPERVISOR_HOME / GIT_BIN; status e phase separados; ownedPaths / goal / dependsOn; thread_id persistido + resume_codex_worker; escrita concorrente e multiprocesso no banco; session_id, search_works, goal nativo; Windows; painel web; baseRef; trio de recolhimento get_worker_diff / ask_codex_worker / land_codex_worker; atualização automática em segundo plano.

Próximo: daemon residente, tirando a distribuição e o ciclo de vida dos processos do processo MCP.

Não faremos: busca vetorial (correspondência por substring é mais rápida nesta escala e sem manutenção), ordenação por usage_count (na prática, de 80 works, apenas 2 foram referenciados novamente).

Desenvolvimento

npm install
npm test               # fake-codex 回放,快且确定
npm run test:edge      # 只跑 test/edge
npm run test:real      # 真 codex CLI 端到端
npm run web:dev        # 看板开发,/api 代理到 7877
npm run web:build      # 打包到 web/dist,发 npm 前自动跑

CI roda em Ubuntu / macOS / Windows, com um job extra em Node 22.13.0 para fixar o limite inferior de engines.

Contribuindo

Veja CONTRIBUTING.md. Problemas de segurança devem ser reportados pelo canal privado, conforme SECURITY.md.

Licença

MIT