結論:Claude Code は対話シェルだけでなく、claude -p(--print)を付けるだけで「ワンショットの非対話コマンド」として動く。出力を --output-format json で受け取り、--permission-mode や --allowedTools で権限を絞れば、そのまま CI やスクリプトに組み込める。さらにプログラムから細かく制御したいときは Python / TypeScript の Claude Agent SDK を使う。
この記事の要点(2026年6月時点):
claude -p "..."で標準入力を受け取り、結果を標準出力に返すパイプ可能なコマンドになる--output-format text|json|stream-jsonで結果を機械可読に。jqで.resultを抜けば後続処理に渡せる- CI では
--permission-mode dontAskや--allowedToolsで許可を明示し、--dangerously-skip-permissionsは隔離環境のみ - GitHub Actions は公式の
anthropics/claude-code-action@v1が使える
対象読者:Claude Code を手で叩くのは慣れたが、CI・バッチ・自作ツールに組み込んで「人が見ていなくても動く」状態にしたいエンジニア・SRE・基盤チーム。
Claude Code を普段ターミナルで対話的に使っていると、「これ、夜間バッチで回せたら楽なのに」「PR が来たら勝手にレビューさせたい」と思う場面が出てくる。実は Claude Code は最初から非対話(headless)で動かす前提の口を持っていて、claude -p を覚えるだけで一気にスクリプタブルになる。
この記事では、claude -p の基本から、出力フォーマット(text / json / stream-json)、CI 向けのパーミッション制御、Claude Agent SDK でのプログラマティック活用、GitHub Actions への組み込みまでを、実際に動くコマンド例とともに整理する。フラグ名や仕様はすべて Claude Code 公式ドキュメントで2026年6月時点の現行版を確認した内容に揃えている。

そもそも「ヘッドレス(非対話)実行」とは何か
通常 claude とだけ打つと対話セッションが立ち上がり、プロンプトを入力 → 応答 → また入力、という TUI が始まる。これは人間が画面の前にいる前提のモードだ。
これに対してヘッドレスモードは、1回のプロンプトを渡して、結果を返したら終了するという挙動になる。Unix の他のコマンドと同じように、標準入力からデータを流し込み、標準出力に結果を吐き、終了コードで成否を返す。だからシェルスクリプト・cron・CI のステップにそのまま差し込める。
起動方法はシンプルで、-p(または --print)フラグを付けるだけだ。
claude -p "What does the auth module do?"
公式ドキュメントによれば、この非対話モードは内部的には Agent SDK 経由で動いており、--continue・--allowedTools・--output-format といった CLI オプションがそのまま使える。つまり「対話モードでできることは、だいたい -p でもできる」と考えてよい。
2026年6月15日からの料金変更(要確認):公式ドキュメントには、サブスクリプションプランでの Agent SDK および
claude -pの利用は、2026年6月15日以降、対話利用とは別枠の「月次 Agent SDK クレジット」から消費される旨が明記されている。CI で大量にバッチを回す予定なら、自分のプランでの扱いを事前に確認しておきたい。
標準入力をパイプで流し込む — Claude をコマンドの一部にする
ヘッドレスモードは標準入力を読むので、他のコマンドの出力をそのまま Claude に食わせられる。たとえばビルドエラーのログを渡して原因だけ説明させ、結果をファイルに書き出す、といった使い方だ。
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txt
「diff を渡してタイポだけ報告させる簡易リンター」のように、プロジェクト固有のチェックを package.json のスクリプトに仕込むこともできる。diff を標準入力で渡せば、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.\""
}
}
なお公式ドキュメントには、パイプで渡せる標準入力は Claude Code v2.1.128 時点で 10MB が上限とある。それを超えると明確なエラーで非ゼロ終了するので、大きな入力はファイルに書き出してパスをプロンプトで参照させるのが安全だ。
出力フォーマットを選ぶ — text / json / stream-json
スクリプトから結果を扱うなら、プレーンテキストより構造化された出力が欲しくなる。--output-format で3つのモードを選べる。
text(デフォルト):プレーンテキスト。人が読む用json:result・session_id・メタデータを含む構造化 JSON。スクリプト処理用stream-json:1行1イベントの改行区切り JSON。リアルタイム表示・ストリーミング用
たとえば JSON で受け取り、jq でテキスト結果だけを抜き出すなら次のようになる。
# プロジェクト要約を JSON で取得し、result フィールドだけを抽出
claude -p "Summarize this project" --output-format json | jq -r '.result'
JSON 出力には、そのリクエストにかかったコスト(total_cost_usd)やモデル別の内訳も含まれるので、呼び出しごとの支出をダッシュボードを見ずにスクリプトで追える。コスト管理を CI に組み込みたいときに便利だ。
特定のスキーマに沿った構造化データが欲しい場合は、--output-format json と --json-schema を組み合わせる。応答の structured_output フィールドにスキーマ準拠の結果が入る。
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"]}' \
| jq '.structured_output'
stream-json はトークンを生成され次第受け取りたいときに使う。--verbose と --include-partial-messages が必要で、各行が JSON イベントとして流れてくる。
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'
CI で安全に動かす — パーミッション制御の考え方
ヘッドレス実行で一番つまずくのが権限まわりだ。対話モードなら「これ実行していい?」というプロンプトで止まってくれるが、CI には答える人間がいないので、許可を事前に明示しておかないと、ツールを使おうとした瞬間に run が中断する。
制御の粒度は大きく2段階ある。
個別ツールを許可する:–allowedTools
--allowedTools で、プロンプトなしに使ってよいツールを列挙する。テストを回して失敗を直すなら、Bash,Read,Edit あたりを許可する。
claude -p "Run the test suite and fix any failures" \
--allowedTools "Bash,Read,Edit"
さらに細かく、コマンドの前方一致で絞ることもできる。Bash(git diff *) のように末尾に半角スペース+* を付けると「git diff で始まるコマンド」だけを許可できる(スペースを抜くと git diff-index まで一致してしまうので注意)。
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 *)"
セッション全体の基準を決める:–permission-mode
ツールを1つずつ列挙する代わりに、セッション全体のパーミッションモードを指定する手もある。公式の --permission-mode は default / acceptEdits / plan / auto / dontAsk / bypassPermissions を受け付ける。CI 向けには次の使い分けが軸になる。
| モード | 挙動 | CI での位置づけ |
|---|---|---|
dontAsk |
permissions.allow ルールと読み取り専用コマンド集合にないものはすべて拒否 |
ロックダウンした CI 向け。許可を明示した範囲だけ動く |
acceptEdits |
ファイル書き込みと mkdir/touch/mv/cp 等を自動承認。それ以外のシェルやネットワークは別途許可が必要 |
編集系タスク(lint 修正など)を自動で回したいとき |
plan |
計画を立てるのみで変更は加えない | 差分のレビュー・調査用 |
bypassPermissions |
すべての許可チェックをスキップ(--dangerously-skip-permissions と等価) |
隔離環境のみ。本番認証情報のあるマシンでは使わない |
たとえば lint 修正を自動適用するなら、編集を自動承認する acceptEdits が手堅い。
claude -p "Apply the lint fixes" --permission-mode acceptEdits
セキュリティの原則:
--dangerously-skip-permissions(=bypassPermissions)はすべての確認を飛ばす。便利だが、本番のクレデンシャルや書き込み権限を持つホストで使うと事故になり得る。使うなら使い捨てのコンテナ・隔離されたランナー上で、最小権限に絞ること。通常の CI では--allowedToolsや--permission-mode dontAskでホワイトリスト方式にするのが正解だ。
なお、CI のような毎回同じ結果が欲しい環境では、ローカルの設定を拾わない --bare モードも有効だ。--bare は hooks・skills・plugins・MCP サーバー・auto memory・CLAUDE.md の自動探索をスキップして起動を速くし、明示的に渡したフラグだけを効かせる。チームメイトの ~/.claude にあるフックが勝手に動く、といった再現性の崩れを防げる。
claude --bare -p "Summarize this file" --allowedTools "Read"
会話を継続する — –continue と –resume
1往復で終わらず、文脈を引き継いで追加の指示を出したいこともある。直近の会話を続けるなら --continue、特定のセッションを指定して続けるなら --resume にセッション ID を渡す。
# 最初のリクエスト
claude -p "Review this codebase for performance issues"
# 直近の会話を継続
claude -p "Now focus on the database queries" --continue
複数の会話を並行で回す場合は、JSON 出力から session_id をキャプチャしておき、後で名指しで再開する。
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"
Claude Agent SDK でプログラムから動かす
シェルから claude -p を叩くより、もっと細かくループや結果オブジェクトを扱いたい場合は、Python / TypeScript の Claude Agent SDK を使う。公式ドキュメントによれば、この SDK は Claude Code を支えるのと同じツール・エージェントループ・コンテキスト管理をライブラリとして提供するもので、claude -p 自体もこの Agent SDK 経由で動いている。
インストールはパッケージ名に注意したい。Python は claude-agent-sdk(Python 3.10 以上)、TypeScript は @anthropic-ai/claude-agent-sdk だ。
# Python
pip install claude-agent-sdk
# TypeScript
npm install @anthropic-ai/claude-agent-sdk
最小構成は、query() に非同期で渡してメッセージを受け取るだけ。ClaudeAgentOptions の allowed_tools でツールを絞る。認証は ANTHROPIC_API_KEY 環境変数で行う(Bedrock / Vertex / Azure 等のプロバイダ経由も可)。
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Find and fix the bug in auth.py",
options=ClaudeAgentOptions(allowed_tools=["Read", "Edit", "Bash"]),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
TypeScript も対称的なインターフェースになっている。
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Find and fix the bug in auth.ts",
options: { allowedTools: ["Read", "Edit", "Bash"] }
})) {
if ("result" in message) console.log(message.result);
}
SDK では permission_mode="acceptEdits" のような権限設定、PreToolUse/PostToolUse などのフック(コールバック関数)、サブエージェント、MCP サーバー接続、セッションの再開・フォークまでプログラムから扱える。claude -p が「シェルから1発」なのに対し、SDK は「自作アプリの中に Claude Code のエージェントループを埋め込む」用途と考えると整理しやすい。
公式の比較表では、インタラクティブな開発・単発タスクは CLI、CI/CD パイプライン・カスタムアプリ・本番自動化は SDK、という棲み分けが示されている。多くのチームは日常開発で CLI、本番で SDK と両方使う。
GitHub Actions に組み込む — 5ステップ
パイプラインに乗せる代表例が GitHub Actions だ。公式の anthropics/claude-code-action@v1(Claude Agent SDK の上に構築されている)を使えば、PR や Issue で @claude とメンションするだけで、コード分析・PR 作成・バグ修正までこなせる。導入手順を整理すると次のようになる。
- GitHub App をインストールする — 一番楽なのは、ターミナルで
claudeを起動して/install-github-appを実行する方法。GitHub App のセットアップと必要なシークレット登録をガイドしてくれる(リポジトリ管理者権限が必要)。 - API キーをシークレットに登録する — リポジトリの Secrets に
ANTHROPIC_API_KEYを追加する。キーをワークフローに直書きしないこと。 - ワークフローファイルを置く —
.github/workflows/にワークフローを追加する。最小構成は下記。 - CLI オプションを
claude_argsで渡す —--max-turns・--model・--allowedToolsなど、これまで紹介した CLI フラグはすべてclaude_args経由でそのまま渡せる。 - 動作確認する — Issue か PR のコメントで
@claudeをメンションして反応するか確かめる。
コメントの @claude メンションに反応する基本ワークフローは次の通り。
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
claude:
runs-on: ubuntu-latest
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# コメント中の @claude メンションに反応する
メンションを待たず、スケジュールで自走させることもできる。たとえば毎朝サマリーを生成するなら、prompt に指示を書き、claude_args でモデルやターン数を指定する。
name: Daily Report
on:
schedule:
- cron: "0 9 * * *"
jobs:
report:
runs-on: ubuntu-latest
steps:
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "Generate a summary of yesterday's commits and open issues"
claude_args: "--model opus --max-turns 5"
ベータ版から v1.0 への移行では破壊的変更がある点に注意したい。アクションは @beta → @v1、direct_prompt → prompt、max_turns/model/custom_instructions といった個別入力は claude_args へ集約する形に変わっている。Bedrock / Vertex AI 経由で動かす場合は、ANTHROPIC_API_KEY の代わりに OIDC ベースの認証(AWS_ROLE_TO_ASSUME や GCP_WORKLOAD_IDENTITY_PROVIDER)を使う構成が公式に用意されている。
つまずきやすいポイントと対処
非対話実行を組み込むときに引っかかりやすい点を、❌(やりがち)→⭕(こうする)で整理しておく。
- ❌ CI で許可を指定せず
claude -p "..."だけを置いて、ツール実行の瞬間に run が落ちる
⭕--allowedToolsか--permission-mode dontAskで、使うツールを事前にホワイトリスト化する - ❌ お手軽だからと本番ランナーで
--dangerously-skip-permissionsを常用する
⭕ それは隔離コンテナ専用と割り切り、通常 CI は最小権限のホワイトリスト方式にする - ❌
text出力を文字列パースして後続処理に渡し、表現が変わるたびに壊れる
⭕--output-format json+jq -r '.result'で構造化された値を取る。スキーマが要るなら--json-schema - ❌ 10MB を超えるログをパイプで流し込んでエラーになる
⭕ 大きな入力はファイルに書き、プロンプトでパスを参照させる - ❌ ローカルの hooks や MCP 設定に依存して、他人のマシン/CI で結果が変わる
⭕ 再現性が要る場面は--bareで自動探索を止め、必要な文脈はフラグで明示的に渡す
「まず手元で claude -p を --output-format json 付きで叩いて出力を固める → --allowedTools で権限を最小化する → その完成形を CI のステップにそのまま移す」という順で進めると、権限とパースの両方を安全に詰められる。
関連記事
Claude Code の自動化をさらに掘り下げたい人は、あわせて読みたい。
- Claude Code Hooks実践ガイド|整形・通知の自動化 — フックで整形・テスト・通知を自動化する手法。SDK のフックとも地続き。
- Claude CodeでCI/CDパイプライン自動構築|GitHub Actions設定5パターン — Claude Code で CI/CD そのものを構築する側の解説。本記事(Claude Code 自体を CI で動かす)と対で読むと全体像が掴める。
- CI/CD自動修復をClaude Codeで実装|5手順 — 失敗した CI を Claude Code に自動修復させる実装パターン。
- Claude Codeサブエージェント並列開発入門 — SDK の subagents で並列処理を組むときの前提知識。
まとめ
Claude Code をヘッドレスで動かす要は、たった4つの軸に集約できる。①claude -p で非対話実行 ②--output-format json + jq で結果を機械可読に ③--allowedTools/--permission-mode で CI 向けに権限を絞る ④さらに細かく制御したいなら Claude Agent SDK。GitHub Actions なら公式の anthropics/claude-code-action@v1 がこれらを束ねてくれる。
まずは手元で cat somefile | claude -p "..." --output-format json | jq -r '.result' を1本通してみるのが、ヘッドレス化の最短の第一歩だ。そこから権限の最小化、CI への移植へと段階的に広げていけば、「人が見ていなくても動く Claude Code」が現実的なものになる。
出典
- Run Claude Code programmatically(Claude Code 公式ドキュメント)
- CLI reference(Claude Code 公式ドキュメント)
- Agent SDK overview(Claude Code 公式ドキュメント)
- Claude Code GitHub Actions(Claude Code 公式ドキュメント)
- Permission modes(Claude Code 公式ドキュメント)