# Modo headless do Claude Code: claude -p em scripts e CI

URL: https://agentvera.dev/pt/blog/claude-code-headless-mode/ · Publicado: 2026-10-27

Modo headless do Claude Code: claude -p, saída JSON e stream-json, --allowedTools, --max-turns, --bare, retomar sessões, entrada via pipe, cron e CI.

**Resumo:**

- claude -p "prompt" roda o Claude Code uma vez sem a interface interativa, imprime o resultado e sai com 0 em caso de sucesso, então funciona em scripts de shell, cron jobs, git hooks e CI.
- Use --output-format json para um objeto parseável (result, session_id, estimativa de custo) ou stream-json com --verbose para eventos ao vivo; --json-schema devolve saída estruturada validada.
- Pré-aprove ferramentas com --allowedTools, negue o resto com --permission-mode dontAsk, limite com --max-turns e adicione --bare para ignorar hooks, servidores MCP e CLAUDE.md locais.

O modo headless do Claude Code é a flag `-p`. `claude -p "your prompt"` roda o Claude Code uma vez sem a interface interativa: ele lê o seu prompt (e o que você mandar via pipe), trabalha com as ferramentas que você permitir, imprime o resultado e sai. Código de saída 0 significa sucesso; qualquer outro, que a execução falhou. Isso o transforma em uma ferramenta de linha de comando comum, que você pode colocar em scripts de shell, cron jobs, git hooks e pipelines de CI.

Este guia cobre as flags que você vai usar de verdade: formatos de saída, permissões de ferramentas, limites de turnos e de orçamento, `--bare`, continuação de sessões e entrada via pipe, seguidos de padrões prontos para scripts, cron e CI, e de quando migrar para o Agent SDK. Cada flag aqui foi conferida na referência oficial da CLI em outubro de 2026.

## O básico

```bash
claude -p "What does the auth module do?"
```

`-p` e `--print` são a mesma flag. A maioria das opções interativas pode ser combinada com ela, como `--model`, `--effort`, `--append-system-prompt` e `--mcp-config`. Algumas opções existem só no modo print, entre elas `--max-turns`, `--max-budget-usd`, `--json-schema` e `--no-session-persistence`.

Dois detalhes importam para scripts:

- Se você passar uma flag inválida, o erro vai para o stderr antes de a execução começar.
- Se algo falhar dentro da execução, como falta de autenticação, a falha é impressa como resultado no stdout. Verifique o código de saída, não só a saída.

## Mande dados via pipe, redirecione os resultados

O modo headless lê o stdin, então logs, diffs e arquivos entram como em qualquer ferramenta Unix:

```bash
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
```

```bash
git diff main | claude -p "Review this diff for bugs. List each as file:line and one sentence."
```

O stdin via pipe tem limite de 10MB. Acima disso, o Claude Code sai com erro; para entradas grandes, escreva o conteúdo em um arquivo e cite o caminho no prompt.

Você também pode ligar isso ao `package.json`, como a documentação oficial faz com um linter de erros de digitação:

```json
{
  "scripts": {
    "lint:claude": "git diff main | claude -p \"you are a typo linter. for each typo in this diff, report filename:line on one line and the issue on the next. return nothing else.\""
  }
}
```

## Escolha um formato de saída

`--output-format` aceita três valores:

| Formato | O que você recebe | Use para |
| --- | --- | --- |
| `text` (padrão) | A resposta final em texto puro | Pessoas, arquivos, scripts simples |
| `json` | Um objeto JSON no final | Scripts que precisam da resposta e dos metadados |
| `stream-json` | Um evento JSON por linha, conforme acontece | Progresso ao vivo, interfaces próprias, logs |

O objeto JSON traz a resposta em `result`, além de `session_id`, números de uso e `total_cost_usd`. Esse custo é uma estimativa do lado do cliente e pode diferir da sua fatura.

```bash
claude -p "Summarize this project" --output-format json | jq -r '.result'
```

### Saída estruturada com --json-schema

Quando um script precisa de dados e não de prosa, passe um JSON Schema. O resultado validado cai em `structured_output`:

```bash
claude -p "Extract the main function names from auth.py" \
  --output-format json \
  --json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}'
```

Se a execução terminar sem uma saída estruturada válida, por exemplo porque o Claude recusou, o campo não aparece. Verifique antes de usar:

```bash
out=$(claude -p "Extract the main function names from auth.py" --output-format json --json-schema "$(cat schema.json)")
echo "$out" | jq -e '.structured_output' > /dev/null || { echo "no structured output" >&2; exit 1; }
```

### Eventos em streaming

`stream-json` exige `--verbose`. Adicione `--include-partial-messages` para receber os tokens à medida que são gerados. Isto imprime só o texto em streaming:

```bash
claude -p "Write a poem" --output-format stream-json --verbose --include-partial-messages | \
  jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
```

O primeiro evento normalmente é `system/init`, com o modelo, as ferramentas, os servidores MCP e os plugins. A última linha é uma mensagem `result` com o texto final, o custo e os metadados da sessão. Novas tentativas aparecem como eventos `system/api_retry`. Uma verificação útil para CI: quando você passa `--mcp-config`, uma entrada de servidor que não passa na validação é ignorada sem derrubar a execução, e aparece em `mcp_server_errors` no evento `init`. Faça o job falhar se esse array não estiver vazio.

## Controle o que a execução pode fazer

Em um script não há ninguém para responder a um pedido de permissão, então decida de antemão o que o Claude pode fazer.

**`--allowedTools`** pré-aprova ferramentas usando a sintaxe de regras de permissão:

```bash
claude -p "Look at my staged changes and create an appropriate commit" \
  --allowedTools "Bash(git diff *),Bash(git log *),Bash(git status *),Bash(git commit *)"
```

O espaço antes do `*` importa: `Bash(git diff *)` casa com comandos que começam com `git diff`, enquanto `Bash(git diff*)` também casaria com `git diff-index`.

**`--permission-mode`** define a base para tudo o que não está na lista. Em outubro de 2026 (Claude Code v2.1.302 e posteriores), uma execução `-p` começa no modo Manual quando nada define um modo, e uma chamada que precisa de aprovação é negada. Valores úteis:

| Modo | Comportamento em uma execução headless |
| --- | --- |
| `dontAsk` | Tudo o que não foi pré-aprovado é recusado. A escolha previsível para scripts |
| `acceptEdits` | Edições de arquivo são permitidas sem perguntar |
| `plan` | Só leitura e planejamento, sem edições |
| `auto` | Um classificador revisa cada ação; um bloqueio nega aquela ação e a execução continua |
| `bypassPermissions` | Nenhuma verificação. Só dentro de um contêiner ou VM descartável |

**`--tools`** restringe quais ferramentas nativas existem, e **`--disallowedTools`** adiciona regras de negação. **`--permission-prompts none`** avisa ao Claude que ninguém pode aprovar pedidos, para que ele não fique tentando de novo; as negações aparecem em `permission_denials` no resultado final. Por que ignorar permissões na sua própria máquina é arriscado está em [Claude Code skip permissions](/pt/blog/claude-code-skip-permissions/ "Claude Code skip permissions").

## Coloque limites em toda execução sem supervisão

- **`--max-turns 20`** para depois desse número de turnos do agente e sai com erro. Sem limite por padrão.
- **`--max-budget-usd 5.00`** para quando o gasto estimado chega ao valor. Ele usa a estimativa do lado do cliente e o gasto pode passar um pouco do teto, então deixe uma margem.
- Um **`timeout`** do seu shell ou da etapa de CI continua valendo a pena. Se você interromper uma execução com SIGTERM, o Claude Code sai com código 143, não registra resultado para o turno inacabado e ainda roda os hooks `SessionEnd`.

## Use --bare para execuções reproduzíveis

Sem `--bare`, o `claude -p` carrega as mesmas coisas de uma sessão interativa: hooks, skills, plugins, servidores MCP, memória automática e `CLAUDE.md`, do diretório de trabalho e de `~/.claude`. Isso significa que o mesmo comando se comporta de um jeito no seu notebook e de outro em um runner de CI.

```bash
claude --bare -p "Summarize README.md" --allowedTools "Read"
```

`--bare` pula toda essa descoberta e inicia mais rápido. Você passa só o que a execução precisa:

| Para carregar | Flag |
| --- | --- |
| Instruções extras | `--append-system-prompt`, `--append-system-prompt-file` |
| Configurações | `--settings <file-or-json>` |
| Servidores MCP | `--mcp-config <file-or-json>` |
| Agentes personalizados | `--agents <file-or-json>` |
| Um plugin | `--plugin-dir <path>` |

O modo bare nunca lê credenciais OAuth nem o keychain do sistema. Com a API da Anthropic, defina `ANTHROPIC_API_KEY` ou forneça um `apiKeyHelper` no JSON de `--settings`. A documentação oficial recomenda `--bare` para chamadas em scripts e diz que ele vai virar o padrão do `-p` em uma versão futura, então escrevê-lo explicitamente agora mantém seus scripts estáveis quando isso acontecer.

Mais um motivo para se importar: sem `--bare`, uma execução `-p` em um repositório recém-clonado roda os hooks de projeto e os servidores do `.mcp.json` desse repositório sem diálogo de confiança. Não aponte uma execução headless sem bare para código que você não revisou.

## Continue e retome sessões

Execuções headless são salvas como as interativas, então você pode encadear etapas:

```bash
# First request
claude -p "Review this codebase for performance issues"

# Continue the most recent conversation
claude -p "Now focus on the database queries" --continue
claude -p "Generate a summary of all issues found" --continue
```

Quando várias execuções acontecem ao mesmo tempo, `--continue` pode pegar a errada. Capture o ID da sessão:

```bash
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
```

`--resume` encontra a sessão pelo ID a partir de qualquer diretório da máquina, e também aceita um nome ou o caminho para a transcrição `.jsonl` de uma sessão. `--fork-session` inicia um novo ramo a partir da conversa retomada em vez de continuar nela, e `--no-session-persistence` evita que execuções avulsas sejam salvas.

## Padrões para scripts, cron e CI

### Um loop sobre arquivos

A página oficial de boas práticas tem um bom modelo para uma mudança mecânica em muitos arquivos:

```bash
for file in $(cat files.txt); do
  claude --bare -p "Migrate $file to the new logger API and commit. Reply OK or FAIL." \
    --allowedTools "Read,Edit,Bash(git add *),Bash(git commit *)" \
    --permission-mode dontAsk \
    --max-turns 20
done
```

Rode primeiro em três arquivos, leia os commits, ajuste o prompt e só então rode o resto. Uma execução que bate no limite de turnos sai com erro, que o seu loop pode registrar.

### Um script de revisão

```bash
gh pr diff "$1" | claude -p \
  --append-system-prompt "You are a security engineer. Review for vulnerabilities." \
  --output-format json
```

Salve como `review.sh` e rode `bash review.sh 123`; o texto da revisão fica em `result`.

### Um cron job noturno

```bash
# crontab -e
0 2 * * * cd /srv/app && claude --bare -p "Run the test suite, fix failing tests, commit on the current branch. Do not push." --allowedTools "Read,Edit,Bash(npm test *),Bash(git add *),Bash(git commit *)" --permission-mode dontAsk --max-turns 30 --output-format json >> /var/log/claude-nightly.jsonl 2>> /var/log/claude-nightly.err
```

O cron roda com um ambiente mínimo, então garanta que `claude` esteja no `PATH` dele e que `ANTHROPIC_API_KEY` esteja definida para esse usuário. Rode em uma branch ou em um worktree, não na `main`. Se você adicionar `--worktree`, note que execuções `-p --worktree` não são limpas automaticamente; remova-as com `git worktree remove <path>`. Para a configuração noturna completa com orçamentos e revisão de manhã, veja [Como rodar o Claude Code durante a noite](/pt/blog/run-claude-code-overnight/ "Rodar o Claude Code durante a noite"), e para timers em cada sistema operacional, [Como agendar tarefas do Claude Code](/pt/blog/schedule-claude-code-tasks/ "Agendar tarefas do Claude Code").

### Pipelines de CI

No CI, use `--bare`, guarde a chave de API no cofre de secrets do CI e trate o código de saída como o resultado da etapa. No caso do GitHub, a action oficial já embala tudo isso para você, com comentários em PR e menções a `@claude`: veja [Claude Code GitHub Actions](/pt/blog/claude-code-github-actions/ "Claude Code GitHub Actions"). Se você usa uma assinatura em vez de chave de API, `claude setup-token` imprime um token OAuth de longa duração para CI e scripts; ele não é salvo, então guarde-o como secret na hora. Lembre que `--bare` ignora OAuth, então um token de assinatura precisa de uma execução sem bare.

## Armadilhas

- **Skills e slash commands.** Skills do usuário funcionam se você colocar `/skill-name` no prompt. Comandos que só existem na interface do terminal, como `/login`, não funcionam.
- **Negações silenciosas de ferramentas.** Se o Claude disser que não conseguiu fazer algo, confira `permission_denials` no resultado JSON e adicione a regra que falta em `--allowedTools`.
- **Trabalho em segundo plano.** Uma execução `-p` pode ficar aberta esperando comandos em segundo plano ou subagentes que o Claude iniciou; por padrão, ela para de esperar após 10 minutos de inatividade.
- **Substituir o system prompt.** `--system-prompt` substitui o prompt padrão por inteiro, incluindo o retrato do git status. Prefira `--append-system-prompt`, a menos que você queira mesmo começar do zero.

## Quando migrar para o Agent SDK

O `claude -p` é o motor do Agent SDK por trás de uma CLI. Quando seu script começar a parsear streams, lidar com aprovações ou gerenciar muitas sessões, passe para o Agent SDK em Python ou TypeScript. Ele oferece objetos de mensagem nativos, callbacks de aprovação de ferramentas e saídas estruturadas no código, sem chamar o shell. O post [Boas práticas do Claude Code](/pt/blog/claude-code-best-practices/ "Boas práticas do Claude Code") mostra o que preparar antes de deixar qualquer execução sem supervisão.

## Fazendo isso com o AgentVera

Execuções headless são do tipo “dispara e esquece”; às vezes você quer a mesma automação com um terminal que dá para acompanhar. No AgentVera, as [tarefas agendadas](/pt/features/scheduled-tasks/ "Tarefas agendadas") (em todos os planos) enviam um prompt a um agente em uma agenda cron enquanto o app está aberto, e o agente roda em um painel real que você pode abrir e conduzir. As [automações](/pt/features/automations/ "Automações") (Pro e Team) iniciam um agente quando o CI fica vermelho ou um PR recebe um comentário, e nunca fazem push na branch padrão. A [central de CI/CD](/pt/features/ci-cd-center/ "Central de CI/CD") lista execuções do GitHub Actions, GitLab e Jenkins e pode entregar um log com falha a um agente. O [turno da noite](/pt/features/night-shift/ "Turno da noite") (Pro e Team) roda o trabalho enfileirado durante a noite em um worktree, em uma branch `night/<date>-<slug>`, faz commit sem push e deixa um relatório para a manhã. [Baixe o AgentVera](/pt/download/ "Baixar o AgentVera") se quiser essas execuções visíveis em vez de enterradas em um arquivo de log.

## Conclusão

A receita básica do Claude Code headless é curta: `claude --bare -p "clear task with a check"`, uma lista explícita em `--allowedTools`, `--permission-mode dontAsk`, `--max-turns`, `--output-format json` e um código de saída que o seu script respeite. Comece pequeno, leia o que as primeiras execuções produzem e só depois coloque isso em um timer.

## Perguntas frequentes

**O que é o modo headless do Claude Code?** É o Claude Code rodando de forma não interativa com a flag -p (ou --print). Você passa um prompt, o Claude faz o trabalho com as ferramentas que você permite, imprime o resultado no stdout e sai. O código de saída 0 indica sucesso e um código diferente de zero indica falha, então os scripts podem decidir com base nele.

**Como deixo o claude -p editar arquivos sem pedir confirmação?** Liste as ferramentas com --allowedTools, por exemplo --allowedTools "Read,Edit,Bash(npm test *)". Em outubro de 2026, execuções com -p começam no modo Manual quando nada define um modo, e chamadas de ferramenta que precisam de aprovação são negadas. Adicione --permission-mode dontAsk para deixar isso explícito, ou acceptEdits para permitir todas as edições de arquivo.

**Como obtenho saída JSON do Claude Code?** Adicione --output-format json. A resposta é um único objeto JSON com o texto em result, além de session_id, usage e uma estimativa total_cost_usd. Passe para jq -r ".result" para obter o texto. Adicione --json-schema para receber dados validados em structured_output, e confira se o campo existe antes de usá-lo.

**Posso continuar uma sessão headless do Claude Code?** Sim. claude -p "next step" --continue retoma a conversa mais recente no diretório atual. Para mirar uma específica, capture o session_id de uma execução JSON e passe para --resume; o Claude Code encontra a sessão pelo ID a partir de qualquer diretório daquela máquina.

**O modo headless usa minha assinatura do Claude ou uma chave de API?** Uma execução -p normal usa o login que a máquina tiver. Com --bare, o Claude Code nunca lê credenciais OAuth nem o keychain, então precisa de ANTHROPIC_API_KEY ou de um apiKeyHelper no JSON de --settings. Para CI com assinatura, claude setup-token gera um token OAuth de longa duração.

---

**Sobre o AgentVera.** AgentVera é um app desktop para macOS, Windows e Linux, desenvolvido pela Solviera Teknoloji. Ele roda 18 agentes de programação com IA (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) lado a lado, por projeto, em terminais reais com as instalações e logins de CLI do próprio usuário. O plano gratuito tem agentes ilimitados. Baixar: https://agentvera.dev/pt/download/ · Preços: https://agentvera.dev/pt/pricing/
