# Mode headless de Claude Code : claude -p en script et CI

URL: https://agentvera.dev/fr/blog/claude-code-headless-mode/ · Publié: 2026-10-27

Le mode headless de Claude Code expliqué : claude -p, sorties JSON et stream-json, --allowedTools, --max-turns, --bare, reprise de sessions, pipes, cron et CI.

**En bref:**

- claude -p "prompt" lance Claude Code une fois sans l’interface interactive, affiche le résultat et sort avec 0 en cas de succès : il s’intègre aux scripts shell, aux tâches cron, aux hooks git et à la CI.
- Utilisez --output-format json pour un seul objet exploitable (result, session_id, estimation du coût) ou stream-json avec --verbose pour les événements en direct ; --json-schema renvoie une sortie structurée validée.
- Pré-approuvez les outils avec --allowedTools, refusez le reste avec --permission-mode dontAsk, limitez les exécutions avec --max-turns et ajoutez --bare pour ignorer les hooks locaux, les serveurs MCP et CLAUDE.md.

Le mode headless de Claude Code, c’est l’option `-p`. `claude -p "votre prompt"` lance Claude Code une fois sans l’interface interactive : il lit votre prompt (et tout ce que vous lui envoyez par un pipe), travaille avec les outils que vous autorisez, affiche le résultat et s’arrête. Le code de sortie 0 signifie un succès, tout autre code un échec. Cela en fait un outil en ligne de commande ordinaire, que vous pouvez placer dans des scripts shell, des tâches cron, des hooks git et des pipelines CI.

Ce guide couvre les options que vous utiliserez vraiment : formats de sortie, permissions des outils, limites de tours et de budget, `--bare`, poursuite de sessions et envoi de données par pipe, puis des patterns prêts à l’emploi pour les scripts, cron et la CI, et le moment de passer à l’Agent SDK. Chaque option citée ici a été vérifiée dans la référence officielle du CLI telle qu’elle était en octobre 2026.

## Les bases

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

`-p` et `--print` sont la même option. La plupart des options interactives s’y combinent, comme `--model`, `--effort`, `--append-system-prompt` et `--mcp-config`. Quelques options n’existent qu’en mode print, parmi lesquelles `--max-turns`, `--max-budget-usd`, `--json-schema` et `--no-session-persistence`.

Deux détails comptent pour les scripts :

- Si vous passez une option invalide, l’erreur part sur stderr avant le début de l’exécution.
- Si quelque chose échoue pendant l’exécution, par exemple une authentification manquante, l’échec est affiché comme résultat sur stdout. Vérifiez le code de sortie, pas seulement la sortie.

## Envoyer des données en entrée, rediriger les résultats

Le mode headless lit stdin, donc les logs, les diffs et les fichiers arrivent comme avec n’importe quel outil 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."
```

L’entrée stdin par pipe est plafonnée à 10 Mo. Au-delà, Claude Code sort avec une erreur ; pour les grosses entrées, écrivez donc le contenu dans un fichier et nommez son chemin dans le prompt.

Vous pouvez aussi le brancher dans `package.json`, comme le fait la documentation officielle avec un linter de fautes de frappe :

```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.\""
  }
}
```

## Choisir un format de sortie

`--output-format` accepte trois valeurs :

| Format | Ce que vous obtenez | À utiliser pour |
| --- | --- | --- |
| `text` (par défaut) | La réponse finale en texte brut | Humains, fichiers, scripts simples |
| `json` | Un seul objet JSON à la fin | Scripts qui ont besoin de la réponse et des métadonnées |
| `stream-json` | Un événement JSON par ligne, au fil de l’eau | Progression en direct, interfaces sur mesure, journalisation |

L’objet JSON contient la réponse dans `result`, plus `session_id`, des chiffres d’usage et `total_cost_usd`. Ce coût est une estimation côté client et peut différer de votre facture.

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

### Sortie structurée avec --json-schema

Quand un script a besoin de données plutôt que de prose, passez un JSON Schema. Le résultat validé arrive dans `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"]}'
```

Si l’exécution se termine sans sortie structurée valide, par exemple parce que Claude a refusé, le champ est absent. Vérifiez sa présence avant de l’utiliser :

```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; }
```

### Événements en streaming

`stream-json` exige `--verbose`. Ajoutez `--include-partial-messages` pour recevoir les tokens au fur et à mesure qu’ils sont générés. Ceci n’affiche que le texte en 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'
```

Le premier événement est normalement `system/init`, avec le modèle, les outils, les serveurs MCP et les plugins. La dernière ligne est un message `result` avec le texte final, le coût et les métadonnées de session. Les nouvelles tentatives apparaissent sous forme d’événements `system/api_retry`. Un contrôle utile en CI : quand vous passez `--mcp-config`, une entrée de serveur dont la validation échoue est ignorée sans faire échouer l’exécution, et elle apparaît dans `mcp_server_errors` sur l’événement `init`. Faites échouer le job si ce tableau n’est pas vide.

## Contrôler ce que l’exécution a le droit de faire

Dans un script, personne n’est là pour répondre à une demande de permission ; décidez donc à l’avance ce que Claude peut faire.

**`--allowedTools`** pré-approuve des outils avec la syntaxe des règles de permission :

```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 *)"
```

L’espace avant `*` compte : `Bash(git diff *)` correspond aux commandes qui commencent par `git diff`, alors que `Bash(git diff*)` correspondrait aussi à `git diff-index`.

**`--permission-mode`** fixe le comportement de base pour tout ce qui n’est pas listé. En octobre 2026 (Claude Code v2.1.302 et versions suivantes), une exécution `-p` démarre en mode Manual quand rien ne fixe de mode, et un appel qui demande une approbation est refusé. Valeurs utiles :

| Mode | Comportement dans une exécution headless |
| --- | --- |
| `dontAsk` | Tout ce qui n’est pas pré-approuvé est refusé. Le choix prévisible pour les scripts |
| `acceptEdits` | Les modifications de fichiers sont autorisées sans demander |
| `plan` | Lecture et planification uniquement, aucune modification |
| `auto` | Un classifieur examine chaque action ; un blocage refuse cette action et l’exécution continue |
| `bypassPermissions` | Aucun contrôle. Uniquement dans un conteneur ou une VM jetable |

**`--tools`** restreint les outils intégrés qui existent tout court, et **`--disallowedTools`** ajoute des règles deny. **`--permission-prompts none`** indique à Claude que personne ne peut approuver les demandes, pour qu’il ne les retente pas sans fin ; les refus sont listés dans `permission_denials` sur le résultat final. Pourquoi contourner les permissions sur votre propre machine est risqué est expliqué dans [Claude Code et --dangerously-skip-permissions](/fr/blog/claude-code-skip-permissions/ "Claude Code skip permissions").

## Fixer des limites à chaque exécution sans surveillance

- **`--max-turns 20`** s’arrête après ce nombre de tours agentiques et sort avec une erreur. Pas de limite par défaut.
- **`--max-budget-usd 5.00`** s’arrête quand la dépense estimée atteint ce montant. Il s’appuie sur l’estimation côté client et la dépense peut légèrement dépasser le plafond, donc gardez de la marge.
- **`timeout`**, côté shell ou étape de CI, reste utile. Si vous arrêtez une exécution avec SIGTERM, Claude Code sort avec le code 143, n’enregistre aucun résultat pour le tour inachevé et lance quand même les hooks `SessionEnd`.

## Utiliser --bare pour des exécutions reproductibles

Sans `--bare`, `claude -p` charge les mêmes éléments qu’une session interactive : hooks, skills, plugins, serveurs MCP, mémoire automatique et `CLAUDE.md`, depuis le dossier de travail et depuis `~/.claude`. La même commande se comporte donc différemment sur votre portable et sur un runner de CI.

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

`--bare` saute toute cette découverte et démarre plus vite. Vous ne passez que ce dont l’exécution a besoin :

| À charger | Option |
| --- | --- |
| Instructions supplémentaires | `--append-system-prompt`, `--append-system-prompt-file` |
| Réglages | `--settings <file-or-json>` |
| Serveurs MCP | `--mcp-config <file-or-json>` |
| Agents personnalisés | `--agents <file-or-json>` |
| Un plugin | `--plugin-dir <path>` |

Le mode bare ne lit jamais les identifiants OAuth ni le trousseau du système. Avec l’API Anthropic, définissez `ANTHROPIC_API_KEY` ou fournissez un `apiKeyHelper` dans le JSON de `--settings`. La documentation officielle recommande `--bare` pour les appels scriptés et indique qu’il deviendra le comportement par défaut de `-p` dans une future version ; l’écrire explicitement dès maintenant garde vos scripts stables le jour où cela arrivera.

Une raison de plus d’y prêter attention : sans `--bare`, une exécution `-p` dans un dépôt fraîchement cloné lance les hooks de projet et les serveurs `.mcp.json` de ce dépôt sans boîte de dialogue de confiance. Ne lancez pas une exécution headless sans `--bare` sur du code que vous n’avez pas relu.

## Poursuivre et reprendre des sessions

Les exécutions headless sont enregistrées comme les sessions interactives, vous pouvez donc enchaîner les étapes :

```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
```

Quand plusieurs exécutions ont lieu en même temps, `--continue` peut choisir la mauvaise. Récupérez plutôt l’ID de session :

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

`--resume` retrouve la session par son ID depuis n’importe quel dossier de la machine, et accepte aussi un nom ou le chemin du transcript `.jsonl` d’une session. `--fork-session` démarre une nouvelle branche à partir de la conversation reprise au lieu de la prolonger, et `--no-session-persistence` évite d’enregistrer les exécutions ponctuelles.

## Patterns pour les scripts, cron et la CI

### Une boucle sur des fichiers

La page officielle des bonnes pratiques propose un bon modèle pour un changement mécanique sur de nombreux fichiers :

```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
```

Lancez-le d’abord sur trois fichiers, lisez les commits, corrigez le prompt, puis lancez le reste. Une exécution qui atteint la limite de tours sort avec une erreur, que votre boucle peut journaliser.

### Un script de revue

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

Enregistrez-le sous `review.sh` et lancez `bash review.sh 123` ; le texte de la revue est dans `result`.

### Une tâche cron de nuit

```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
```

Cron tourne avec un environnement minimal : assurez-vous que `claude` est dans son `PATH` et que `ANTHROPIC_API_KEY` est défini pour cet utilisateur. Lancez-le sur une branche ou dans un worktree, pas sur `main`. Si vous ajoutez `--worktree`, notez que les exécutions `-p --worktree` ne sont pas nettoyées pour vous ; supprimez-les avec `git worktree remove <path>`. Pour la configuration complète de nuit avec budgets et relecture le matin, voir [Lancer Claude Code la nuit](/fr/blog/run-claude-code-overnight/ "Lancer Claude Code la nuit"), et pour les minuteurs de chaque système, [Planifier des tâches Claude Code](/fr/blog/schedule-claude-code-tasks/ "Planifier des tâches Claude Code").

### Pipelines CI

En CI, utilisez `--bare`, gardez la clé API dans le gestionnaire de secrets de la CI et traitez le code de sortie comme le résultat de l’étape. Pour GitHub en particulier, l’action officielle s’en charge pour vous, avec des commentaires de PR et des mentions `@claude` : voir [Claude Code GitHub Actions](/fr/blog/claude-code-github-actions/ "Claude Code GitHub Actions"). Si vous utilisez un abonnement plutôt qu’une clé API, `claude setup-token` affiche un token OAuth longue durée pour la CI et les scripts ; il n’est pas enregistré, stockez-le donc tout de suite comme secret. N’oubliez pas que `--bare` ignore OAuth : un token d’abonnement exige une exécution sans `--bare`.

## Pièges

- **Skills et commandes slash.** Les skills utilisateur fonctionnent si vous mettez `/skill-name` dans le prompt. Les commandes qui n’existent que dans l’interface du terminal, comme `/login`, ne fonctionnent pas.
- **Refus d’outils silencieux.** Si Claude dit qu’il n’a pas pu faire quelque chose, regardez `permission_denials` dans le résultat JSON et ajoutez la règle manquante à `--allowedTools`.
- **Travail en arrière-plan.** Une exécution `-p` peut rester ouverte pour attendre des commandes en arrière-plan ou des subagents lancés par Claude ; par défaut, elle cesse d’attendre après 10 minutes d’inactivité.
- **Remplacer le prompt système.** `--system-prompt` remplace entièrement le prompt par défaut, y compris l’instantané du statut git. Préférez `--append-system-prompt`, sauf si vous voulez vraiment partir d’une page blanche.

## Quand passer à l’Agent SDK

`claude -p`, c’est le moteur de l’Agent SDK derrière un CLI. Dès que votre script commence à analyser des flux, à gérer des approbations ou à piloter de nombreuses sessions, passez à l’Agent SDK pour Python ou TypeScript. Il vous donne des objets message natifs, des callbacks d’approbation des outils et des sorties structurées directement dans le code, sans passer par le shell. L’article [Bonnes pratiques Claude Code](/fr/blog/claude-code-best-practices/ "Bonnes pratiques Claude Code") couvre ce qu’il faut mettre en place avant de laisser tourner une exécution sans surveillance.

## Avec AgentVera

Les exécutions headless se lancent et s’oublient ; parfois, vous voulez la même automatisation avec un terminal que vous pouvez regarder. Dans AgentVera, les [tâches planifiées](/fr/features/scheduled-tasks/ "Tâches planifiées") (sur toutes les offres) envoient un prompt à un agent selon un planning cron pendant que l’application est ouverte, et l’agent tourne dans un vrai volet que vous pouvez ouvrir et réorienter. Les [automatisations](/fr/features/automations/ "Automatisations") (Pro et Team) lancent un agent quand la CI passe au rouge ou qu’une PR reçoit un commentaire, et ne poussent jamais sur la branche par défaut. Le [centre CI/CD](/fr/features/ci-cd-center/ "Centre CI/CD") liste les exécutions GitHub Actions, GitLab et Jenkins et peut confier un log en échec à un agent. [Night shift](/fr/features/night-shift/ "Night shift") (Pro et Team) exécute le travail en file pendant la nuit dans un worktree sur une branche `night/<date>-<slug>`, committe sans pousser et laisse un rapport le matin. [Téléchargez AgentVera](/fr/download/ "Télécharger AgentVera") si vous voulez voir ces exécutions au lieu de les enfouir dans un fichier de log.

## En résumé

La recette de base du Claude Code headless est courte : `claude --bare -p "clear task with a check"`, une liste `--allowedTools` explicite, `--permission-mode dontAsk`, `--max-turns`, `--output-format json`, et un code de sortie que votre script respecte. Commencez petit, lisez ce que produisent les premières exécutions, et seulement ensuite mettez-le sur un minuteur.

## Questions fréquentes

**Qu’est-ce que le mode headless de Claude Code ?** C’est Claude Code lancé de façon non interactive avec l’option -p (ou --print). Vous passez un prompt, Claude fait le travail avec les outils que vous autorisez, affiche le résultat sur stdout et s’arrête. Le code de sortie 0 signifie un succès et un code non nul un échec, donc les scripts peuvent s’appuyer dessus.

**Comment laisser claude -p modifier des fichiers sans demander ?** Listez les outils avec --allowedTools, par exemple --allowedTools "Read,Edit,Bash(npm test *)". En octobre 2026, les exécutions -p démarrent en mode Manual quand rien ne fixe de mode, et les appels d’outils qui demandent une approbation sont refusés. Ajoutez --permission-mode dontAsk pour le rendre explicite, ou acceptEdits pour autoriser toutes les modifications de fichiers.

**Comment obtenir une sortie JSON de Claude Code ?** Ajoutez --output-format json. La réponse est un seul objet JSON avec la réponse dans result, plus session_id, usage et une estimation total_cost_usd. Passez-la à jq -r ".result" pour obtenir le texte. Ajoutez --json-schema pour obtenir des données validées dans structured_output, et vérifiez que le champ existe avant de l’utiliser.

**Peut-on poursuivre une session headless de Claude Code ?** Oui. claude -p "étape suivante" --continue reprend la conversation la plus récente du dossier courant. Pour en cibler une précise, récupérez session_id depuis une exécution JSON et passez-le à --resume ; Claude Code retrouve la session par son ID depuis n’importe quel dossier de cette machine.

**Le mode headless utilise-t-il mon abonnement Claude ou une clé API ?** Une exécution -p normale utilise la connexion présente sur la machine. Avec --bare, Claude Code ne lit jamais les identifiants OAuth ni le trousseau, il lui faut donc ANTHROPIC_API_KEY ou un apiKeyHelper dans le JSON de --settings. Pour la CI avec un abonnement, claude setup-token génère un token OAuth longue durée.

---

**À propos d’AgentVera.** AgentVera est une app de bureau pour macOS, Windows et Linux, développée par Solviera Teknoloji. Elle exécute 18 agents de code IA (Claude Code, Codex, Gemini CLI, Copilot, Cursor, Antigravity, opencode, Hermes, Qwen Code, Kimi Code, Kiro, Amp, Droid, Goose, Vibe, Crush, Aider, Cline) côte à côte, par projet, dans de vrais terminaux avec les installations et connexions CLI de l’utilisateur. L’offre gratuite inclut des agents illimités. Télécharger: https://agentvera.dev/fr/download/ · Tarifs: https://agentvera.dev/fr/pricing/
