@justmpm/agent-runner
v0.3.0
Published
MCP Server para invocar CLIs de coding agents (Codex, Antigravity) em modo headless, com abstração unificada via Adapter Pattern
Maintainers
Readme
@justmpm/agent-runner
MCP Server para invocar CLIs de coding agents (Codex, Antigravity) em modo headless, com abstração unificada via Adapter Pattern.
Status: v0.2.3 — Codex + Antigravity. Auto-suficiente: expõe 10 tools (4 de criação + 6 de consulta/controle).
cwdé OBRIGATÓRIO emrun_agent/ask_agent.wait_for_completionaceitawaitUntilExit: true(sem timeout). Tools de consulta aceitamidOUname(resolveTerminalcentralizado). Plano de longo prazo: adicionar Claude Code, OpenCode, etc via adapters.
✨ O que faz
Permite que agentes de IA executem tarefas complexas via coding agents especializados — auditoria de qualidade, validação, investigação, implementação, correção, criação de testes, design de UI, geração de trackers. Tudo em modo headless (sem telão), com persistência via terminal manager.
Diferença vs @justmpm/term-manager: enquanto o term-manager executa scripts npm pré-definidos (build, test, lint), o agent-runner delega raciocínio para coding agents que interpretam o prompt e agem sobre o código.
🚀 Instalação
Pré-requisitos
| Requisito | Versão |
|-----------|--------|
| Node.js | >= 18 |
| OS | Windows 10 1809+ (para ConPTY) ou macOS/Linux |
| Codex CLI (opcional) | 0.142.0+ (npm i -g @openai/codex) |
| Antigravity CLI (opcional) | 1.0.10+ (https://antigravity.google/docs/cli) |
Opção 1: Instalação global (recomendada)
A forma mais limpa e estável. O binário agent-runner fica disponível no PATH e a versão fica fixa.
npm install -g @justmpm/agent-runnerVerificar instalação:
agent-runner --version
# Saída esperada: @justmpm/agent-runner v0.2.3Configuração do MCP Client
A configuração depende do client que você usa. Escolha o seu:
OpenCode (~/.config/opencode/opencode.json)
{
"mcpServers": {
"agent-runner": {
"command": "agent-runner"
}
}
}Vantagem do global install: funciona em QUALQUER projeto sem mudar config. A IA passa o cwd diretamente em cada chamada (ex: cwd: "${workspace}" é expandido pelo OpenCode no momento da call). Veja a Migration Guide v0.1.0 → v0.2.0+ abaixo para entender por que a env var AGENT_RUNNER_PROJECT_DIR foi removida.
Claude Desktop (%APPDATA%/Claude/claude_desktop_config.json)
{
"mcpServers": {
"agent-runner": {
"command": "agent-runner"
}
}
}Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"agent-runner": {
"command": "agent-runner"
}
}
}Windsurf (~/.codeium/windsurf/mcp_config.json)
{
"mcpServers": {
"agent-runner": {
"command": "agent-runner"
}
}
}Opção 2: npx (sem instalar)
Útil para experimentar sem comprometer o ambiente global. Mais lento (baixa o pacote a cada inicialização).
{
"mcpServers": {
"agent-runner": {
"command": "npx",
"args": ["-y", "@justmpm/agent-runner"]
}
}
}Opção 3: Desenvolvimento local
Para contribuir com o código ou rodar versão customizada.
git clone https://github.com/Just-mpm/Pacotes-Pessoais.git
cd Pacotes-Pessoais/mcps-ai/agent-runner
npm install
npm run build{
"mcpServers": {
"agent-runner": {
"command": "node",
"args": ["D:/Pictures/Pacotes-Pessoais/mcps-ai/agent-runner/dist/index.js"]
}
}
}Variáveis de ambiente úteis
| Var | Default | Descrição |
|-----|---------|-----------|
| AGENT_RUNNER_MAX_SIMULTANEOUS | 5 | Limite de terminais simultâneos (1-20) |
| AGENT_RUNNER_DEBUG | 0 | Se 1, mostra logs extras (ex: lista de adapters registrados) |
⚠️ Removido em v0.2.2: a env var
AGENT_RUNNER_PROJECT_DIRnão existe mais.cwdagora é obrigatório nos args derun_agent/ask_agent— não há fallback implícito. Veja a Migration Guide abaixo.
Troubleshooting de instalação
| Problema | Causa | Solução |
|----------|-------|---------|
| agent-runner: command not found (Linux/Mac) | npm global bin não está no PATH | Adicione $(npm config get prefix)/bin ao PATH |
| agent-runner: command not found (Windows) | npm global bin não está no PATH | Reinicie o terminal após instalar OU adicione %APPDATA%\npm ao PATH |
| Cannot find module 'node-pty' após update | native bindings desatualizados | npm install -g @justmpm/agent-runner --force |
| Permissão negada ao instalar global (Linux/Mac) | npm precisa de sudo | Use nvm ou configure npm com prefix em pasta do usuário |
| Build falha com gyp ERR! find Python (Mac/Linux) | node-pty precisa compilar native | npm install -g windows-build-tools (Win) ou xcode-select --install (Mac) |
🔄 Migration Guide v0.1.0 → v0.2.0+
A partir da v0.2.0, o agent-runner virou auto-suficiente (não depende mais do @justmpm/term-manager para consultar terminais) e em v0.2.2 houve uma quebra importante. Se você atualizou de uma versão < 0.2.0, ajuste sua config e calls.
O que mudou
| Mudança | Versão | Impacto |
|---------|--------|---------|
| Env var AGENT_RUNNER_PROJECT_DIR removida | v0.2.2 (BREAKING) | Não é mais consultada — cwd é obrigatório nos args |
| cwd agora é OBRIGATÓRIO em run_agent e ask_agent | v0.2.2 (BREAKING) | A IA deve passar conscientemente cada chamada |
| 6 tools de consulta/controle adicionadas | v0.2.0 | Não precisa mais do @justmpm/term-manager em outro processo |
| id OU name aceitos nas tools de consulta | v0.2.1 | Resolve o anti-padrão de esquecer ID numérico entre calls |
| waitUntilExit: true em wait_for_completion | v0.2.2 | Permite esperar o processo REALMENTE terminar (sem timeout) |
Configuração MCP (env var removida)
ANTES (v0.1.0):
{
"mcpServers": {
"agent-runner": {
"command": "agent-runner",
"env": {
"AGENT_RUNNER_PROJECT_DIR": "D:\\Pictures\\MeuProjeto"
}
}
}
}DEPOIS (v0.2.2+):
{
"mcpServers": {
"agent-runner": {
"command": "agent-runner"
}
}
}A env var
AGENT_RUNNER_PROJECT_DIRé simplesmente ignorada pelo código v0.2.2+ (não causa erro, mas também não faz nada).
Chamadas MCP (cwd agora obrigatório)
ANTES (v0.1.0): a IA podia omitir cwd e o server usava a env var como fallback.
DEPOIS (v0.2.2+): a IA sempre passa cwd explícito:
// run_agent — cwd obrigatório
run_agent({
provider: "codex",
agent: "code-validator",
prompt: "Audite src/",
cwd: "D:/Pictures/MeuProjeto", // ← OBRIGATÓRIO
owner: "nexus"
})
// ask_agent — cwd obrigatório
ask_agent({
provider: "codex",
prompt: "Esse plano tá bom?",
cwd: "D:/Pictures/MeuProjeto", // ← OBRIGATÓRIO
owner: "nexus"
})Tools de consulta (não precisa mais do term-manager)
ANTES (v0.1.0): para acompanhar um terminal criado por run_agent, era necessário rodar @justmpm/term-manager em outro processo — o que não funcionava (IDs são locais a cada processo).
DEPOIS (v0.2.0+): use as tools do mesmo MCP:
// Após run_agent → ID 5
wait_for_completion({ id: 5, timeoutMs: 900000, owner: "nexus" })
// ou por nome (v0.2.1+) — esqueceu o ID? sem problema
wait_for_completion({ name: "codex:fixer", timeoutMs: 900000, owner: "nexus" })
// Esperar INDEFINIDAMENTE (v0.2.2) — auditorias longas
wait_for_completion({ id: 5, waitUntilExit: true, owner: "nexus" })
read_output({ id: 5, lines: 50, owner: "nexus" })
search_output({ id: 5, pattern: "error", owner: "nexus" })
close_terminal({ id: 5, owner: "nexus" })Checklist pós-update
- Atualize o pacote:
npm install -g @justmpm/agent-runner@latest(ounpm updateno dev-local). - Remova
env.AGENT_RUNNER_PROJECT_DIRde TODOS os seus MCP clients (OpenCode, Claude Desktop, Cursor, Windsurf, dev-local). - Verifique que suas chamadas MCP passam
cwdexplícito em toda invocação derun_agent/ask_agent. - Se você usava
@justmpm/term-managerpara monitorar terminais do agent-runner, remova essa dependência — agora é auto-suficiente. - Rode
npm run build && npm publishse você forkou/mirrorou o pacote.
🔧 Tools MCP
Criação (v0.1.0)
| Tool | Descrição |
|------|-----------|
| list_providers | Auto-detecta CLIs no PATH (Codex, Antigravity). Retorna tabela com status de instalação, autenticação e versão. |
| list_agents | Lista agents/skills/plugins disponíveis em um provider (ou todos). Codex: 8 agents da whitelist + custom de ~/.codex/agents/*.toml. Antigravity: plugins de ~/.gemini/antigravity-cli/plugins/. |
| run_agent | Delega uma tarefa a um agent especializado do provider (code-validator, fixer, etc). Modo headless. |
| ask_agent | Conversa direta com o provider (sem subagent). Ideal para pedir opinião, validar abordagem, brainstorming. |
Consulta / Controle (v0.2.0 — NOVAS, auto-suficientes)
| Tool | Descrição |
|------|-----------|
| list_terminals | Lista todos os terminais criados (com filtro owner e status). |
| wait_for_completion | Aguarda o término de um terminal headless (com timeout). Ideal para delegações de 1-15min. Detecta terminais de provider (codex:, agy:, antigravity:, ask-) e aplica UX especial (tail maior + nota específica). |
| read_output | Lê as últimas N linhas do output (snapshot). Suporta offset para ler janela arbitrária. |
| search_output | Busca substring no output (case-insensitive, NÃO regex). Cada match classificado como [ERRO]/[WARN]/[INFO]. |
| stop_terminal | Envia Ctrl+C (graceful) para um terminal ativo. |
| close_terminal | Fecha um terminal e libera recursos (mata se running). |
v0.2.0: Antes era necessário o
@justmpm/term-managerem outro processo para acompanhar os terminais criados aqui — o que não funcionava (processos separados não enxergam IDs uns dos outros). Agora o agent-runner é auto-suficiente.
v0.2.1: As 5 tools de consulta (
wait_for_completion,read_output,search_output,stop_terminal,close_terminal) agora aceitamid(numérico) OUname(string). Por nome, pega o terminal mais recente com esse nome (statusrunningpreferido sobreexited). Resolve o anti-padrão onde a IA esquece o ID numérico entre calls.// Por ID (específico, sem ambiguidade) wait_for_completion({ id: 5, timeoutMs: 900000 }) // Por NAME (esqueceu o ID? sem problema — pega o mais recente) wait_for_completion({ name: "codex:fixer", timeoutMs: 900000 })Se ambos forem passados,
idtem prioridade.
🤖 Providers Suportados
| Provider | CLI | Versão mínima | Auth |
|----------|-----|---------------|------|
| codex | codex (OpenAI) | 0.142.0+ | codex login |
| antigravity | agy (Google) | 1.0.10+ | agy login (automático via silent auth) |
Instalação dos CLIs
Codex:
npm install -g @openai/codex
codex loginAntigravity:
Siga as instruções em https://antigravity.google/docs/cli. O agy faz silent auth automaticamente quando há chave no keyring.
📦 Sandbox (enum unificado)
Todas as tools aceitam o mesmo enum sandbox, mapeado internamente para flags nativas de cada provider:
| Modo (enum) | Codex (codex exec --sandbox) | Antigravity (agy --sandbox) |
|-------------|--------------------------------|-------------------------------|
| read-only (default para ask_agent) | --sandbox read-only | --sandbox (ativa) |
| workspace-write (default para run_agent) | --sandbox workspace-write | sem flag |
| danger-full-access | --sandbox danger-full-access | sem flag (limitação: agy não tem "danger") |
| none | vira read-only (limitação R-09) | sem flag |
Limitação documentada (R-09):
- Codex não tem "sem sandbox" →
noneviraread-only(a opção menos permissiva disponível). - Antigravity trata
--sandboxcomo boolean (não aceita valor). Mapeamento heurístico documentado acima.
🎯 Como usar (exemplos)
Workflow típico (auto-suficiente — v0.2.2)
// 1. Descobrir providers instalados
list_providers()
// → codex | ✅ sim | ? | 0.142.0
// → antigravity | ✅ sim | ? | 1.0.10
// 2. Descobrir agents disponíveis
list_agents({ provider: "codex" })
// → code-validator, gap-finder, investigator, worker, fixer, test, ui-designer, tracker-generator
// 3. Delegar uma auditoria (cwd é OBRIGATÓRIO)
run_agent({
provider: "codex",
agent: "code-validator",
prompt: "Audite src/tools/agent-runner.ts focando em SOLID, tipos, race conditions.",
cwd: "D:/Pictures/Pacotes-Pessoais", // ⚠️ obrigatório desde v0.2.2
owner: "nexus"
})
// → [ID: 1] [Nome: codex:code-validator]
// → ⚠️ COMO FUNCIONA (delegação ao subagent — leia antes de prosseguir)
// 4. Aguardar resultado (tools DESTE MCP — sem dependência externa)
// Modo padrão (com timeoutMs=15min):
wait_for_completion(id=1, timeoutMs=900000, owner="nexus")
// → ✓ SUCESSO (exit 0): agente terminou | Tempo: 1m 23s
// OU ⏱️ TIMEOUT: agente ainda analisando (chame de novo com timeoutMs maior)
// Modo NOVO v0.2.2 (sem timeout — espera o processo REALMENTE terminar):
wait_for_completion(id=1, waitUntilExit=true, owner="nexus")
// → ✓ SUCESSO (exit 0): agente terminou | Tempo: 1m 23s [waitUntilExit: ...]
// Útil para auditorias longas do Codex/Antigravity onde 15min é pouco.
// A IA fica parada até o processo morrer de verdade.
// 5. Ler output e investigar
search_output(id=1, pattern="error", owner="nexus") // se algo falhou
read_output(id=1, owner="nexus") // ver últimas 10 linhas
// 6. Liberar recursos
close_terminal(id=1, owner="nexus")Conversa direta (sem subagent)
ask_agent({
provider: "codex",
prompt: "Esse plano de implementação de autenticação tá bom?",
cwd: "D:/Pictures/Pacotes-Pessoais", // ⚠️ obrigatório desde v0.2.2
owner: "nexus"
})
// → [ID: 2] [Nome: ask-codex]
// → Agent: default (conversa geral, sem subagent)
// Aguardar e ler (mesmas tools deste MCP)
wait_for_completion(id=2, timeoutMs=60000, owner="nexus")
read_output(id=2, owner="nexus")
close_terminal(id=2, owner="nexus")⚠️ Mudança v0.2.2:
cwdagora é OBRIGATÓRIO emrun_agenteask_agent. A IA precisa passar conscientemente o diretório onde cada agent vai rodar. Não há mais fallback implícito (a env varAGENT_RUNNER_PROJECT_DIRfoi removida).
Workflow de monitoramento (múltiplos terminais)
// Disparar várias delegações em paralelo
const r1 = run_agent({ provider: "codex", agent: "code-validator", prompt: "...", owner: "nexus" });
const r2 = run_agent({ provider: "codex", agent: "gap-finder", prompt: "...", owner: "nexus" });
// Listar seus terminais ativos
list_terminals({ owner: "nexus", status: "running" })
// Aguardar cada um conforme necessário
wait_for_completion(id=r1.id, timeoutMs=900000, owner="nexus")
wait_for_completion(id=r2.id, timeoutMs=900000, owner="nexus")
// Cleanup
close_terminal(id=r1.id, owner="nexus")
close_terminal(id=r2.id, owner="nexus")🏗️ Arquitetura
Adapter Pattern isola as quirks de cada CLI atrás de uma interface unificada:
interface AgentAdapter {
readonly provider: ProviderId;
readonly binary: string;
readonly sandboxModes: readonly SandboxMode[];
readonly installHint: string;
detect(): Promise<DetectResult>;
listAgents(): Promise<AgentDefinition[]>;
buildRunCommand(args: RunCommandArgs): string;
buildAskCommand(args: AskCommandArgs): string;
}Cada provider é 1 arquivo (src/tools/adapters/{codex,antigravity}.ts) e se registra no ProviderRegistry. Adicionar novo provider = 1 arquivo + 1 linha no registry.
Stack
| Dependência | Versão | Uso |
|-------------|--------|-----|
| TypeScript | ^5.9.3 | Linguagem principal (strict mode, zero any) |
| Node.js | >= 18 | Runtime |
| node-pty | ^1.0.0 | Gerenciamento de terminais (ConPTY no Windows 10 1809+) |
| zod | ^3.24.0 | Validação de schemas de input |
| zod-to-json-schema | ^3.24.0 | Conversão de schemas Zod para JSON Schema (MCP) |
| @modelcontextprotocol/sdk | ^1.26.0 | MCP server e transporte stdio |
Como o prompt é passado (segurança + robustez)
- Node escreve o prompt em arquivo temporário (UTF-8).
- PowerShell lê via
Get-Content -Raw | <cli>, envia via stdin. - Bloco
try/finallydo PowerShell remove o temp file ao terminar. - Node só age em falha de spawn (não em
finallygenérico).
Isso resolve:
- Limite de argv do Windows (~8191 chars)
- Escape de aspas no prompt (vai via stdin, não argv)
- Não precisa encoding especial (UTF-8 cru)
🧪 Desenvolvimento
npm run build # compila TypeScript → dist/
npm test # roda Vitest
npm run dev # watch mode (tsc --watch)Adicionar novo provider (v0.2+)
- Criar
src/tools/adapters/<novo-provider>.tsimplementandoAgentAdapter. - Adicionar ID em
src/tools/adapters/types.ts(ProviderId). - Importar e registrar em
src/tools/adapters/index.ts:defaultRegistry.register(<novoProvider>Adapter); - Expandir enums
provideremrun-agent.tseask-agent.ts.
📋 Requisitos
| Requisito | Detalhe |
|-----------|---------|
| Node.js | >= 18 |
| OS | Windows 10 1809+ (necessário para ConPTY) |
| Codex CLI | 0.142.0+ (para usar provider codex) |
| Antigravity CLI | 1.0.10+ (para usar provider antigravity) |
🐛 Troubleshooting
| Problema | Causa | Solução |
|----------|-------|---------|
| codex ou agy não aparece em list_providers | CLI não está no PATH | Instale o CLI e reinicie o shell |
| agent "X" não encontrado para provider "codex" | agent fora da whitelist | Use list_agents(provider="codex") para ver válidos (8 hardcoded + custom) |
| agent "X" não encontrado para provider "antigravity" | plugin não instalado | Instale plugins em ~/.gemini/antigravity-cli/plugins/ ou use ask_agent |
| Limite de N terminais simultâneos atingido | maxSimultaneous | Use close_terminal (do term-manager) para liberar |
| Erro de validação: ... | argumento inválido | Veja o schema JSON da tool via tools/list |
| agy --print retorna silenciosamente | falta de TTY | Esperado fora do MCP. Quando invocado via node-pty (que nosso TerminalManager faz), funciona. |
| Race condition no temp file | (impossível) | Mitigada: cleanup só em falha de spawn (GATE-07) |
🔗 Links
- Repositório: https://github.com/Just-mpm/Pacotes-Pessoais
- Pacotes relacionados:
@justmpm/term-manager— pacote "irmão" para scripts npm. O agent-runner copia e adapta o motor (TerminalManager) do term-manager — veja a seção sobre compatibilidade noAGENTS.md.
- Koda AI Studio: https://kodaai.app
- Email: [email protected]
📄 Licença
MIT © Koda AI Studio
