Claude Codeのヘッドレスモードとは、claude -p(または--print)を付けて対話画面を開かずにClaude Codeを実行し、結果を返したらそのまま終了させる動かし方です。結論から言うと、スクリプトやCI/CDに組み込みたい一回きりの処理があるなら、対話セッションを開く代わりに-p付きでコマンドを一度呼び出すだけで済みます。公式ドキュメントは、この仕組みを、Claude Codeを支えるツール・エージェントループ・コンテキスト管理をそのまま提供するAgent SDKの一部と位置づけており、CLIとしてはもちろん、Python・TypeScriptパッケージからも同じ土台を呼び出せると説明しています(Run Claude Code programmatically)。
最小構成の呼び出しは次の一行です。プロンプトと、必要なCLIオプションを添えるだけで動きます。
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"
この記事では、公式リファレンスに実在するフラグと挙動だけを根拠に、基本の使い方と終了コード、起動を速くするベアモード、標準入力のパイプ処理、出力形式と権限まわりの制御、SIGTERMで止めたときの挙動までを順に整理します。根拠は各段落に公式ページのリンクを置いています。Claude Code自体のインストールがまだの方は、先にClaude Codeの基本的な使い方を読んでから戻ると、フラグの意味がつながりやすくなります。
ヘッドレスモードとは何か|-p/–printで非対話実行する仕組み
【完全無料】AI×SNSで成果を出す100大特典を受け取る
AIの使い方を、SNS運用の実務につなげたい方へ。LINEで特典の案内を受け取れます。
ヘッドレスモードとは、任意のclaudeコマンドに-p(--print)フラグを付けて、対話的なやり取りなしに一回で実行する動かし方のことです。Claudeは応答を出力したらセッションを終了します。
公式リファレンスのコマンド一覧でも、claude -p "query"は「SDK経由で問い合わせてから終了する」動作として、通常の対話起動やclaude "query"(対話セッションを初期プロンプト付きで開始)とは別枠で説明されています(CLI reference)。ヘッドレスモードは新しい実行モードというより、いつものclaudeコマンドに付けるフラグ一つで切り替わる動作、という理解が実態に近いです。
このページが扱うのは、CLI経由(claude -p)でのAgent SDKの使い方です。構造化出力やツール承認コールバック、ネイティブなメッセージオブジェクトまで踏み込んだPython・TypeScriptパッケージについては、公式は別ページのAgent SDKドキュメントを参照するよう案内しています。CLIのヘッドレスモードは、そのAgent SDKの入り口の一つという位置づけです。
基本の使い方と終了コード|スクリプトが成否を判定する仕組み
ヘッドレスモードの終了コードは、成功時が0、実行が失敗した場合は0以外です。呼び出し側のスクリプトは、この終了コードで処理を分岐できます。
コードベースについて尋ねる例はこうなります。
claude -p "What does the auth module do?"
失敗の出方は、失敗するタイミングで変わります。無効なフラグを渡した場合は、実行が始まる前にエラーが標準エラー出力へ報告されます。一方、認証情報が無いなど実行の途中で問題が起きた場合は、その失敗が標準出力上の結果として出力されます(Run Claude Code programmatically)。両者は出力先も出るタイミングも異なるため、ログを拾うスクリプトは標準エラー出力と標準出力の両方を見ておくと取りこぼしが減ります。
| 失敗のタイミング | 出力先 | 具体例 |
|---|---|---|
| 正常に完了 | 標準出力(終了コード0) | 応答テキストや–output-format jsonの結果 |
| 実行が始まる前 | 標準エラー出力 | 存在しないフラグを渡した |
| 実行の途中 | 標準出力(結果として) | 認証情報が無い |
Agent SDKとの関係|claude -pは何を土台にしているか
claude -pは、Claude Codeを動かしているのと同じAgent SDKをCLIから呼び出す入り口です。ツール、エージェントループ、コンテキスト管理はすべて共通です。
公式ドキュメントは、Agent SDKが「Claude Codeを支えるのと同じツール・エージェントループ・コンテキスト管理」を提供すると説明しています。利用形態は三通りあり、スクリプトやCI/CD向けのCLI、そして完全にプログラムから制御したい場合のPython・TypeScriptパッケージです(Run Claude Code programmatically)。この記事で扱うclaude -pは、このうちCLIの形です。
CLIで完結する簡単な自動化ならヘッドレスモードで十分ですが、リクエストごとのコールバックや型付きのレスポンスが必要な統合を組む場合は、Python・TypeScript向けのAgent SDKパッケージのほうが向いています。どちらも裏側の仕組みは同じなので、CLIで動作を確認してからSDKへ移行する、という進め方も成り立ちます。
起動を高速化するベアモード(–bare)|読み込みをスキップする範囲
ベアモードとは、--bareを付けて、hooks・skills・カスタムコマンド・サブエージェント・インストール済みプラグイン・MCPサーバー・自動メモリ・CLAUDE.mdの自動検出をまとめてスキップし、起動を速くする実行方法です。
--bareを付けない-pセッションは、対話セッションと同じコンテキストを読み込みます。作業ディレクトリや~/.claudeに設定されたものすべてが対象になり、プロジェクトの.claude/settings.jsonのフックも、.mcp.jsonのMCPサーバーも、信頼したことのないフォルダであっても実行・接続されます。しかも-pセッションはワークスペース信頼ダイアログもサーバーごとの承認プロンプトも表示しません(Run Claude Code programmatically)。CIのように未知のリポジトリを機械的に処理する場面では、この挙動を把握したうえで--bareを使うかどうかを判断する必要があります。
--add-dirで追加したディレクトリだけは部分的な例外です。ベアモードでもそのディレクトリの.claude/skills/フォルダは読み込まれますが、.claude/commands/と.claude/agents/フォルダはスキップされたままです。読み込まれない分は、フラグで個別に渡せます。
| 渡したいもの | 使うフラグ |
|---|---|
| システムプロンプトへの追加 | --append-system-prompt / --append-system-prompt-file |
| 設定 | --settings <file-or-json> |
| MCPサーバー | --mcp-config <file-or-json> |
| カスタムエージェント | --agents <json> |
| プラグイン | --plugin-dir <path> / --plugin-url <url> |
公式ドキュメントは--bareを「スクリプト化・SDK呼び出しの推奨モードで、将来のリリースでは-pの既定になる予定」と位置づけています。フック(hooks)の使い方やCLAUDE.mdの書き方を先に設定している場合は、CI用の呼び出しに--bareを付け忘れると、意図せずそれらが読み込まれる点に注意してください。プラグインの使い方で配布物を導入している場合も同様です。
ベアモードの認証と使えるツール|ANTHROPIC_API_KEYと3つの標準ツール
ベアモードでは、Claude CodeはOAuth認証情報もシステムキーチェーンも読み込みません。Anthropic APIを使う場合は、環境変数でAPIキーを渡す必要があります。
具体的には、Claude Consoleで作成したキーをANTHROPIC_API_KEYとして環境に設定するか、--settingsのJSONにapiKeyHelperを指定します。Amazon Bedrock、Google CloudのAgent Platform、Microsoft Foundryを使っている場合は、これらの経路とは別に、各プロバイダー自身の認証情報を通常どおり読み込み続けます(Run Claude Code programmatically)。サブスクリプションのログイン情報は使われないため、ベアモードでの一回限りの呼び出しは次のような形になります。
claude --bare -p "Summarize README.md" --allowedTools "Read"
ベアモードでClaudeが使えるツールは、Bash・ファイル読み取り・ファイル編集の三つに絞られます。それ以外のツールが必要な場合は、前段の表にあるフラグで明示的に渡します。
標準入力のパイプ処理とビルドスクリプトへの組み込み|10MBの上限
非対話モードは標準入力を読み取るため、データをパイプで流し込み、応答をリダイレクトで受け取れます。他のコマンドラインツールと同じ感覚で組み込めます。
ビルドログの原因をClaudeに要約させ、ファイルへ書き出す例です。
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
パイプで渡す標準入力には10MBの上限があります。超えた場合、Claude Codeは明確なエラーとともに0以外のステータスで終了します。大きな入力を扱いたいときは、内容をファイルへ書き出し、プロンプトの中でそのファイルパスを参照させる形にします(Run Claude Code programmatically)。標準入力を読み取れない場合、たとえば呼び出し元のプロセスが接続を切っていた場合は、警告を標準エラー出力へ出したうえで、コマンドライン上のプロンプトだけで実行が続きます。
| 標準入力の状態 | Claude Codeの挙動 |
|---|---|
| 正常にパイプで渡された | そのまま読み取って処理する |
| 10MBを超えた | 明確なエラーと共に0以外のステータスで終了 |
| 読み取れない(切断済みなど) | 警告を標準エラー出力へ出し、コマンドライン上のプロンプトで続行 |
package.jsonのスクリプトへ組み込む例もあります。mainブランチとの差分をパイプで渡し、誤字だけを報告させる設定です。差分をパイプで渡す形にすると、Claudeがファイルを読むためのBash権限を別途持たなくても完結します。
{
"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.\""
}
}
-pモードで使えるコマンドの違い|スキル呼び出しと一部スラッシュコマンド
-pモードでは、プロンプト文字列に/skill-nameを含めれば、利用者が呼び出すスキルやカスタムコマンドを展開できます。一方、ターミナルの対話画面だけで動く組み込みコマンドは使えません。
公式リファレンスは、-pモードでのコマンド対応の違いを次のように整理しています。/loginのように対話インターフェースでしか動かない組み込みコマンドは使えません。一方でスキル(Skills)の使い方で説明されているような利用者呼び出しのスキルや、カスタムコマンドは、プロンプト文字列に含めればClaude Codeが実行前に展開します。/model・/effort・/fast・/color・/renameは/model sonnetのように値を引数として渡す形で使え、/mcpは引数なしでサーバー状態のテキスト要約を出します。設定を変えたいときは/configにkey=valueの形で渡します(Run Claude Code programmatically)。
出力スタイルの使い方で紹介されている/output-styleも-pで使えるコマンドの一つです。/output-style <style>で出力スタイルを切り替え、引数なしの/output-styleで一覧を表示します。
出力形式の選び方|text・json・stream-jsonと–json-schemaの構造化出力
–output-formatは、応答の返し方をtext・json・stream-jsonの三通りから選ぶフラグです。既定はtextで、プレーンテキストがそのまま出力されます。
それぞれの用途はこうなります。jsonは結果本文・セッションID・メタデータを含む構造化JSON、stream-jsonはリアルタイムのストリーミング向けに改行区切りで出力するJSONです。
| 形式 | 内容 | 向いている場面 |
|---|---|---|
text(既定) |
プレーンテキストのみ | 人が読む・そのままログへ流す |
json |
結果・セッションID・メタデータを含む構造化JSON | スクリプトが結果や費用をまとめて拾う |
stream-json |
改行区切りのJSONイベント列 | 途中経過を逐次表示・処理する |
--output-format jsonを使うと、レスポンスのペイロードにtotal_cost_usdとモデルごとの費用内訳が含まれるため、スクリプト側は使用量とコストの確認方法で説明しているダッシュボードを見なくても支出を追跡できます。--continueや--resumeで会話を継続した場合は、その回だけの費用ではなく、それ以前の実行分も含めた会話全体の合計が報告されます。どちらの数値もクライアント側の見積もりであり、実際の請求額とは差が出ることがあります(Run Claude Code programmatically)。
特定のスキーマに合わせたい場合は、--output-format jsonと--json-schemaを組み合わせます。関数名を配列として抽出する例です。
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"]}'
渡した値がJSON Schemaとして無効な場合、claudeはエラーで終了します。formatキーワード("format": "email"など)は注釈として受け付けられますが、その内容までは検証されません。スキーマを指定した応答は、jqのようなツールで.structured_outputを取り出すと扱いやすくなります。
ストリーミングとサブエージェントのメッセージ|–include-partial-messagesと–forward-subagent-text
–output-format stream-jsonに–verboseと–include-partial-messagesを組み合わせると、生成されたトークンを逐次受け取れます。最後の行が、最終的な応答テキストを含む結果メッセージです。
ストリームの中では、サブエージェントの使い方で起動したサブエージェントのメッセージも流れてきます。サブエージェントが送るメッセージには、それを起動したツール呼び出しのIDがparent_tool_use_idとして入り、メイン会話のメッセージではこの項目がnullになります。既定では、サブエージェントのtool_useとtool_resultのブロックだけがストリームに乗ります(Run Claude Code programmatically)。
--forward-subagent-text(または環境変数CLAUDE_CODE_FORWARD_SUBAGENT_TEXT)を有効にすると、サブエージェントのテキストと思考ブロックもストリームへ含まれるようになり、各サブエージェントのやり取りを後から再現できます。この設定は、Agentツールで起動したサブエージェントだけでなく、フォークされたスキルの実行にも同じように適用されます。
ツールの自動承認と権限モード|–allowedToolsとauto・dontAsk・acceptEdits
–allowedToolsは、指定したツールを権限プロンプトなしで使わせるフラグです。テストを実行して失敗を直させる例では、次のように書きます。
claude -p "Run the test suite and fix any failures" \
--allowedTools "Bash,Read,Edit"
セッション全体の基準を変えたいときは、個別のツール名を並べる代わりに権限設定(permissions)の使い方で説明されている権限モードを渡します。-pの既定の権限モードは、プランに関係なく「Manual」(設定値はdefault)です。対話セッションではプランやバージョンによって既定がautoになることもありますが、-pにはその既定は当てはまらないため、自動承認したいなら明示的にモードを渡す必要があります(Run Claude Code programmatically、Choose a permission mode)。
| モード | プロンプトなしで動くもの | 向いている場面 |
|---|---|---|
default(Manual) |
読み取りのみ | すべての操作を自分で確認したいとき |
acceptEdits |
読み取り・ファイル編集・mkdirやtouchなど共通のファイル操作コマンド |
レビュー前提でコードを反復修正するとき |
auto |
ほぼすべて(分類用のモデルが背後でレビュー) | 長時間タスクでプロンプト疲れを減らしたいとき |
dontAsk |
読み取りと事前承認済みのツールのみ。それ以外は拒否 | ロックダウンされたCIやスクリプト |
dontAskを選んだ場合、読み取り専用コマンドや--allowedTools・permissions.allowで許可した呼び出しは通常どおり動きますが、AskUserQuestion、組織側で「ask」に設定された接続ツール、requiresUserInteractionが付いたMCPツールは、許可ルールに一致していても拒否されます。acceptEditsを選んだ場合も、読み取り専用コマンド以外のシェルコマンドやネットワークアクセスには、別途--allowedToolsのエントリかpermissions.allowのルールが要ります。
無人実行での権限プロンプト制御|–permission-prompts noneが拒否する範囲
–permission-prompts noneは、誰も答えられない無人実行で使うフラグです。付けると、本来なら権限プロンプトになるはずの呼び出しは、確認を待たずに拒否されます。
このフラグが効いてくるのは、Agent SDKアプリのcanUseToolコールバックや--permission-prompt-toolで渡したMCPツールのように、権限プロンプトに答える「ホスト」がいる実行です。フラグを付けなければ、実行はそのホストが答えるまで待ちます。フラグを付けると、ホストへ確認せず、待つこともしなくなります。プロンプトになるはずだった呼び出しは、PermissionRequestフックが許可しない限り拒否され、Claudeには「誰も承認できないので再試行しないように」と伝わります(Run Claude Code programmatically)。ホストがいない-p実行では、これらのリクエストはいずれにせよ拒否されます。
claude -p "Update the dependency pins and run the tests" --permission-mode auto --permission-prompts none
このフラグを付けると、人による回答が必要なAskUserQuestionのようなツールはClaudeから呼び出せなくなります。--output-format stream-jsonと組み合わせた場合、拒否はpermission_deniedというシステムメッセージとして流れ、最終的な結果メッセージのpermission_denialsにも一覧されます。
バックグラウンドタスクと強制終了|終了時の猶予とSIGTERMの終了コード143
claude -pの実行中にバックグラウンドのBashタスクを開始した場合、そのシェルは、Claudeが最終結果を返して標準入力が閉じてから約5秒後に終了します。
この5秒の猶予があるおかげで、結果が返った直後に完了するタスクでも、出力を取りこぼしません。一方、バックグラウンドのサブエージェントやワークフローを開始した場合は挙動が異なり、その結果が最終出力の一部として扱われるため、claude -pはその作業が終わるまで開いたままになります。既定では、継続してアイドル状態が10分続くと待機を打ち切り、その時点で実行中のものを止めて部分的な結果を破棄します。上限はCLAUDE_CODE_PRINT_BG_WAIT_CEILING_MSで変更でき、0を指定すると上限なしで待ちます(Run Claude Code programmatically)。
実行をSIGTERMで止めた場合、たとえばkillコマンドやプロセススーパーバイザーからの停止では、Claude Codeは終了コード143で終わります。進行中だったターンはそのまま未完了になり、結果は記録されません。ターンをきちんと終わらせてから止めたいなら、SIGTERMの前にSIGINTを送るか、Agent SDKのinterrupt()を呼びます。SIGTERMを受け取ると、Claude Codeは実行中のBashコマンドのプロセスツリーを終了させ、SessionEndフックだけを実行してから終わります(Run Claude Code programmatically)。
| SIGTERM到達時の状態 | Claude Codeの扱い |
|---|---|
| コマンドを実行中 | そのコマンドをセッション内で強制終了として記録する |
| 権限プロンプトの回答待ち | プロセスへ直接SIGTERMを送った場合は未回答のまま残す。Agent SDK経由でセッションを閉じた場合は入力終了と同時にプロンプトを取り消す |
| 終了処理そのもの | 実行中のBashコマンドのプロセスツリーを終了させ、SessionEndフックだけを実行してから終わる。新しいツール呼び出しやモデルへのリクエストは送らない |
会話の継続とシステムプロンプトのカスタマイズ|–continue/–resumeと–append-system-prompt
–continueは直近の会話を、–resumeはセッションIDを指定した特定の会話を、それぞれ続きから再開するフラグです。どちらもヘッドレスモードで使えます。
レビューしてから追加の指示を送る例です。
# 最初のリクエスト
claude -p "Review this codebase for performance issues"
# 直近の会話を継続
claude -p "Now focus on the database queries" --continue
claude -p "Generate a summary of all issues found" --continue
複数の会話を並行して走らせている場合は、セッションIDを控えておいて--resumeで狙った会話へ戻ります。
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
セッションIDを指定した--resumeは、実行しているディレクトリを問わず、このマシン上のどのプロジェクトからでも見つけて再開できます。IDの代わりに、セッション管理と–resumeの使い方で扱っているトランスクリプトファイル(.jsonl)の絶対パスを渡すことも可能です。
システムプロンプトを調整したい場合は、既定の振る舞いを保ったまま指示を追加できる--append-system-promptが基本になります。PRの差分をパイプで渡し、セキュリティ観点でレビューさせるスクリプトの例です。
gh pr diff "$1" | claude -p \
--append-system-prompt "You are a security engineer. Review for vulnerabilities." \
--output-format json
既定のプロンプトを丸ごと差し替えたい場合は--system-promptを使います。コーディング用途を離れた非対話パイプラインなど、Claude Codeの既定の人格や安全指示が合わない場面向けのフラグです。
実行時間とコストの上限を決める|–max-turns・–max-budget-usdなど-p専用フラグ
–max-turnsと–max-budget-usdは、いずれも-p(print)モードでだけ使えるフラグで、エージェントのターン数や費用の上限を決められます。
--max-turnsはエージェンティックなターン数を制限し、上限に達するとエラーで終了します。既定では上限がありません。--max-budget-usdはAPI呼び出しに使う金額の上限で、サブエージェントの支出もこの上限に含まれます。上限に達すると、新しいサブエージェントの起動は失敗し、実行中のバックグラウンドサブエージェントは停止されます。--continueや--resumeで復元された過去の実行分の費用は、この上限には数えられません(CLI reference)。
| フラグ | 効果 |
|---|---|
--max-turns |
エージェンティックなターン数を制限し、上限到達でエラー終了 |
--max-budget-usd |
サブエージェント分も含めたAPI費用の上限。到達後は新規サブエージェント起動が失敗 |
--no-session-persistence |
セッションをディスクへ保存しない(printモード限定) |
--input-format |
printモードの入力形式をtextかstream-jsonから選ぶ |
どちらのフラグも、無人で回すバッチ処理が想定より長く、あるいは想定より高く実行され続けることを防ぐための歯止めです。使用量とコストの確認方法と組み合わせて、まずは緩めの上限から様子を見ると調整しやすくなります。
よくある質問(FAQ)
- Q1. ヘッドレスモードと通常の対話セッションはどう違いますか
- 対話セッションは画面上でやり取りしながら進みますが、ヘッドレスモードは
-p付きで一回呼び出すと結果を返してすぐ終了します。権限モードの既定も異なり、対話セッションではプランによってautoが既定になることがある一方、-pの既定はプランを問わずManualです。 - Q2. –bareを付けないとCIでは何が起きますか
- 付けない場合、対話セッションと同じコンテキストが読み込まれます。信頼したことのないリポジトリであっても、そのプロジェクトの
.claude/settings.jsonのフックや.mcp.jsonのMCPサーバーが動き、確認ダイアログも表示されません。同じ結果を毎回得たいスクリプト用途では--bareを付けるのが安全です。 - Q3. ヘッドレスモードでもスラッシュコマンドは使えますか
- 利用者が呼び出すスキルやカスタムコマンドは、プロンプト文字列に
/skill-nameを含めれば展開されます。ただし/loginのように対話インターフェース専用の組み込みコマンドは使えません。 - Q4. 実行結果からコストを取得できますか
--output-format jsonを使うと、レスポンスにtotal_cost_usdとモデルごとの内訳が含まれます。ただしクライアント側の見積もりのため、実際の請求額とは差が出ることがあります。- Q5. 実行を途中で止めたい場合はどうすればいいですか
- SIGTERMで止めると終了コード143になり、進行中のターンは未完了のまま記録されません。ターンを区切ってから止めたい場合は、SIGTERMの前にSIGINTを送るか、Agent SDKの
interrupt()を呼びます。 - Q6. 標準入力で渡せるデータに上限はありますか
- パイプで渡す標準入力は10MBが上限です。超えるとエラーとともに0以外のステータスで終了するため、大きなデータはファイルに書き出し、そのパスをプロンプトで参照させます。
まとめ
Claude Codeのヘッドレスモードは、-p(--print)というフラグ一つで、対話画面を開かずに一回実行して終了する動かし方です。最後に要点を整理します。
- 終了コード0が成功、0以外が失敗。無効なフラグは実行前に標準エラー出力、実行途中の失敗は標準出力の結果として出る
- 同じ結果をどの環境でも得たいスクリプト用途では
--bareを付け、代わりに必要なものだけをフラグで渡す - 自動承認したいなら
--allowedToolsか権限モードを明示する。-pの既定はプランを問わずManual - 無人実行では
--permission-prompts noneで待たずに拒否させる - 費用やターン数に歯止めをかけたいなら
--max-budget-usdと--max-turns - 途中で止めるならSIGINTかAgent SDKの
interrupt()。SIGTERMは終了コード143で、進行中のターンは記録されない
まずは手元のスクリプトに-pを一箇所足し、--output-format jsonで結果を受け取るところから試してみてください。フラグの詳細は版によって更新されるため、迷ったときは公式のRun Claude Code programmaticallyとCLI referenceを見比べるのが近道です。フックや権限まわりを先に固めたい方はフック(hooks)の使い方と権限設定(permissions)の使い方もあわせて読むと、自動化の全体像がつながります。
あわせて読みたい・姉妹メディア
