原典: Run Claude Code programmatically / 日本語版
一行要約
claude -p は Agent SDK の CLI 版であり、CI やスクリプトで再現性が要るなら --bare(hook / skill / カスタムコマンド / subagent / plugin / MCP サーバ / auto memory / CLAUDE.md の自動発見をすべて飛ばす)を付けるのが推奨。
要点
基本
claude -p "Find and fix the bug in auth.py" --allowedTools "Read,Edit,Bash"-pは--printの別名- 成功で exit code 0、失敗で非ゼロ。スクリプトは exit status で分岐できる
- 不正なフラグは実行前に stderr へ報告される。実行中の失敗(認証エラーなど)は stdout に結果として出る
-pと併用できないオプションがある —--bgは拒否される。--cloudはタスク記述と併用すると拒否され、セッション ID と併用するとそのクラウドセッションにメッセージを積んで終了する
--bare(CI での推奨)
Add
--bareto reduce startup time by skipping auto-discovery of hooks, skills, custom commands, subagents, plugins, MCP servers, auto memory, and CLAUDE.md.
--bareを付けると、hook・skill・カスタムコマンド・subagent・plugin・MCP サーバ・auto memory・CLAUDE.md の自動探索を省略して起動時間を短縮できる。
A hook in a teammate’s
~/.claudeor an MCP server in the project’s.mcp.jsonwon’t run, because bare mode never reads them.teammate の
~/.claudeにある hook や、プロジェクトの.mcp.jsonにある MCP サーバは動かない。bare モードはそれらを一切読まないからである。
--bare を付けないと、信頼していないフォルダの設定がそのまま走る:
Without
--bare, a-psession runs the hooks in a project’s.claude/settings.jsonand connects the servers in its.mcp.json, even in a folder you’ve never trusted. A-psession shows no workspace trust dialog and no per-server approval prompt.
--bareが無いと、-pのセッションはプロジェクトの.claude/settings.jsonにある hook を走らせ、.mcp.jsonにあるサーバに接続する。一度も信頼していないフォルダでもそうなる。-pのセッションには workspace trust のダイアログもサーバごとの承認プロンプトも出ない。
--add-dir は部分的な例外: bare mode はそのディレクトリの .claude/skills/ から skill を読む。.claude/commands/ と .claude/agents/ は読まない。
認証の注意: bare mode は OAuth 認証情報も system keychain も読まない。Anthropic API を使うなら ANTHROPIC_API_KEY を環境に設定する(Bedrock / Agent Platform / Foundry は各プロバイダの認証情報を通常どおり読む)。
bare mode で使えるツールは Bash、ファイル読み取り、ファイル編集。必要な context はフラグで渡す。
走っている間も制限が効く(v2.1.286 以降。それより前は一部しか効いていなかった):
- MCP サーバ ——
--mcp-configなどコマンドラインで渡したものだけがつながる。対話セッションでは--ideを付けない限り IDE への自動接続もしない - system reminder —— Claude はプロンプトとツール結果だけを受け取る。前に読んだファイルがディスク上で変わっても知らされず、使える skill の一覧(
--add-dirのフォルダの skill を含む)も届かない - バックグラウンドタスク —— 走らない。タイムアウトに達したコマンドはバックグラウンドに移らず止まる
| ロードしたいもの | フラグ |
|---|---|
| system prompt への追記 | --append-system-prompt, --append-system-prompt-file |
| 設定 | --settings <file-or-json> |
| MCP サーバ | --mcp-config <file-or-json> |
| カスタムエージェント | --agents <file-or-json> |
| plugin | --plugin-dir <path>, --plugin-url <url> |
出力形式
--output-format | 内容 |
|---|---|
text(既定) | プレーンテキスト |
json | 結果・セッション ID・メタデータを含む構造化 JSON。total_cost_usd とモデル別のコスト内訳も含む(クライアント側の推定値。--continue / --resume で続けた実行は、以前の実行の分も含めた会話全体の合計を出す) |
stream-json | 改行区切り JSON。リアルタイムストリーミング |
スキーマに従わせるには --output-format json + --json-schema。結果は structured_output フィールドに入る。
Claude Code accepts schemas that use the
formatkeyword, such as"format": "email", but treatsformatas an annotation and doesn’t enforce it.Claude Code は
"format": "email"のようにformatキーワードを使うスキーマを受け付けるが、formatは注釈として扱い、強制はしない。
スキーマが JSON Schema として不正なら Error: --json-schema is not a valid JSON Schema とバリデータの診断を出して終了する(v2.1.205 より前は不正なスキーマを黙って無視し、構造化されていないテキストを返していた。format を含むスキーマも一律に不正扱いだった)。
ストリーミング
--output-format stream-json --verbose --include-partial-messages でトークンごとに受け取る。最後の行は result メッセージで、最終応答テキスト・コスト・セッションメタデータを含む。
読み手が遅いとき、Claude Code は溜まった出力を吐き切るまで終了を待つ。待ち時間は残量に応じて伸び、上限は30秒(v2.1.214 より前は約2秒が上限で、大きな応答の末尾が切れることがあった)。
subagent のメッセージは parent_tool_use_id にそれを起こしたツール呼び出し(Agent ツール、または fork で走る skill なら Skill ツール)の ID を持つ(メイン会話は null)。foreground の subagent の最初のメッセージは、それを動かすプロンプトを載せた user メッセージ(subagent で走る skill も同じ形)。既定では subagent の tool_use / tool_result ブロックだけが出る。 --forward-subagent-text または CLAUDE_CODE_FORWARD_SUBAGENT_TEXT でテキストと thinking も出せる。入れ子の subagent も全深さで転送されるので、ID を辿れば入れ子ツリーを再構築できる。
主要なイベント:
| イベント | 用途 |
|---|---|
system/init | セッションメタデータ(モデル、ツール、MCP サーバ、plugin)。通常は最初のイベント |
system/api_retry | リトライ可能なエラーでの再試行。attempt / max_retries / retry_delay_ms / error_status / error |
system/plugin_install | marketplace plugin のインストール進捗(CLAUDE_CODE_SYNC_PLUGIN_INSTALL 設定時) |
CI で plugin / MCP のロード失敗を検知する(system/init のフィールド):
| フィールド | 内容 |
|---|---|
plugins | ロードに成功した plugin |
plugin_errors | ロード時エラー。エラーがなければキー自体が省略される。--plugin-dir のディレクトリやアーカイブ自体が読めなかったときは、解決後の絶対パスが path に入る(複数の --plugin-dir のどれが落ちたかが分かる。v2.1.283 以降) |
mcp_servers | セッション内の MCP サーバと status |
mcp_server_errors | 検証で skip された --mcp-config エントリ。エラーがなければキーが省略されるので、非空配列で CI を落とせる |
system/initのcapabilities配列を見ればプロトコル挙動を feature-detect できる。バージョン文字列の比較ではなくこちらを使う。
--mcp-config を -p と併用すると、最初のターンの前に pending のサーバを待つ —— 上限は MCP_TIMEOUT(既定30秒)。ツール一覧がキャッシュされているリモートサーバはこの待ちを飛ばし、system/init には pending と出て、最初のツール呼び出しのときに接続する。
権限の扱い
- 何も permission mode を決めていない
-pは組み込みの開始モードで走り、それはautoになりうる(permission-modes)。基準を決めたいなら自分で渡す --allowedToolsで個別ツールを事前承認する。ただし auto mode で始まる run では、裸のBashは広すぎる allow として落とされ、コマンドごとに auto mode が審査する- セッション全体の基準を決めるなら permission mode を渡す
auto— 分類器がほとんどの操作を代わりに審査するdontAsk—permissions.allowと読み取り専用コマンド以外を拒否。ロックダウンした CI 向け。AskUserQuestion、組織がaskにした connector ツール、requiresUserInteractionの MCP ツールは、allow ルールに一致していても拒否されるacceptEdits— ファイル書き込みとmkdir/touch/mv/cpを自動承認。読み取り専用のコマンド以外のシェルコマンドとネットワークリクエストには、まだ--allowedToolsかpermissions.allowのルールが要る(確認に答える相手のいない-pでは、他に何も決めないリクエストは拒否され、run は続く)
無人実行で prompt を止める --permission-prompts none(v2.1.259 以降。それより前は unknown-option で拒否される):
- 効くのは応答役がいる run —— Agent SDK の
canUseToolコールバックや--permission-prompt-toolで渡した MCP ツール。このフラグが無いと、run はその応答役の返事を1件ずつ待つ - 付けると応答役に問い合わせも待ちもしない。
PermissionRequesthook が許可しない限り拒否され、Claude には「承認できる者はいない、再試行するな」と伝わって run は続く - 人の答えを要するツール(
AskUserQuestionなど)は取り除かれ、Claude は呼べなくなる。Elicitationhook が答えない MCP の elicitation 要求は cancel される --output-format stream-jsonでは拒否がpermission_deniedの system メッセージとして出て、最後の result メッセージのpermission_denialsに並ぶ
The
--allowedToolsflag uses permission rule syntax. The trailing*enables prefix matching, soBash(git diff *)allows any command starting withgit diff. The space before*is important: without it,Bash(git diff*)would also matchgit diff-index.
--allowedToolsフラグは permission ルールの構文を使う。末尾の*が前方一致を有効にするので、Bash(git diff *)はgit diffで始まる任意のコマンドを許可する。*の前の空白が重要である。空白がないとBash(git diff*)はgit diff-indexにも一致してしまう。
バックグラウンドタスクの扱い
- バックグラウンド Bash タスク(dev server や watch build)は、最終結果が返り stdin が閉じてから約5秒後に終了させられる
- バックグラウンドの subagent と workflow はこの5秒の対象外 — 結果が最終出力の一部なので
claude -pは完了を待つ。待ち時間は既定で最大10分(CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MSで調整、0で無制限)。上限に達すると走っているものを止め、その部分結果は捨てる - Monitor の watch も待つ。watch がタイムアウトするか10分の上限に達するかの早いほうまで。watch の既定のタイムアウトは開始から5分。待っている間も Claude は watch の報告に応え続ける
SIGTERM で停止したとき(kill や process supervisor から):
Claude Code exits with code 143. Claude Code leaves the turn that was in progress unfinished and records no result for it. To end the turn instead, send SIGINT, or call the Agent SDK’s
interrupt(), before you stop the process.Claude Code は exit code 143 で終了する。進行中だったターンは未完了のまま残り、その結果は記録されない。ターンのほうを終わらせたいなら、プロセスを止める前に SIGINT を送るか、Agent SDK の
interrupt()を呼ぶ。
- 実行中の Bash のプロセスツリーを終了させ、
SessionEndhook を走らせて終了する。終了処理の間は、新しいツール呼び出しもモデルへのリクエストも起こらず、SessionEnd以外の hook も走らない - コマンド実行中だった場合、そのコマンドはセッションに killed として記録される
- permission prompt の返事を待っていた場合、SIGTERM では未応答のまま残る。Agent SDK 側からセッションを閉じた場合は、SDK が先に入力を閉じるので prompt は cancel される
- セッションを resume しても、SIGTERM が中断したターンはそのまま残り、次のプロンプトで会話が進む。中断したターンの続きから再開させたいなら
CLAUDE_CODE_RESUME_INTERRUPTED_TURN=1
作業ディレクトリがセッションの途中で消えたとき: -p と Agent SDK のセッションは走り続ける。ディレクトリが無い状態でターンが始まると stream-json 出力に警告メッセージが出て、ディレクトリが戻るまでシェルコマンドは失敗する。
その他の注意
- パイプで渡す stdin は 10MB が上限。 超えるとエラーで非ゼロ終了する。大きい入力はファイルに書いてパスをプロンプトで参照する
-pモードでも user-invocable な skill とカスタムコマンドは使える — プロンプト文字列に/skill-nameを入れれば展開される。/loginのような端末専用の組み込みコマンドは使えない/model、/effort、/fast、/color、/renameは値を引数として受け取る(/model sonnet)。引数なしの/mcpはサーバ状態のテキスト要約を出す(v2.1.205 以降)。設定変更は/config thinking=falseの形、/output-style <style>で出力スタイルを切り替える(v2.1.269 以降)- stdin が読めないとき(起動元が自分の端を切ったなど)は、stderr に警告を出してコマンドラインのプロンプトで続行する
--continueは終了済みのバックグラウンドセッションは開くが、まだ走っているものは開かない(v2.1.257 以降)--resumeにはセッション ID のほか、セッションの.jsonlトランスクリプトの絶対パスも渡せる。ID はこのマシンのどのプロジェクトからでも見つかる(v2.1.223 より前は、同じディレクトリから実行しないと見つからなかった)--append-system-promptは既定の挙動を保ったまま追記する。既定のプロンプトごと置き換えたいなら--system-prompt
そのまま使える具体例
CI 向けの最小形:
claude --bare -p "Summarize README.md" --allowedTools "Read"パイプで渡してファイルに書き出す:
cat build-error.txt | claude -p 'concisely explain the root cause of this build error' > output.txtpackage.json に typo linter として組み込む(diff をパイプするので 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 -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 で取り出す:
claude -p "Summarize this project" --output-format json | jq -r '.result'
claude -p "Extract function names from auth.py" \
--output-format json \
--json-schema '{"type":"object","properties":{"functions":{"type":"array","items":{"type":"string"}}},"required":["functions"]}' \
| jq '.structured_output'ストリーミングしてテキストだけ流す:
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'ツールを事前承認する:
claude -p "Run the test suite and fix any failures" \
--allowedTools "Bash,Read,Edit"
claude -p "Apply the lint fixes" --permission-mode acceptEditsコミットを作らせる(接頭辞マッチの空白に注意):
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 *)"PR のセキュリティレビュースクリプト(review.sh、bash review.sh 123 で実行):
gh pr diff "$1" | claude -p \
--append-system-prompt "You are a security engineer. Review for vulnerabilities." \
--output-format json会話を継続する:
# First request
claude -p "Review this codebase for performance issues"
# Continue the most recent conversation
claude -p "Now focus on the database queries" --continue
# 特定のセッションを resume する
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
claude -p "Continue that review" --resume "$session_id"原典で言及されている関連文書
- permission-modes —
dontAsk/acceptEditsの詳細 - sub-agents — バックグラウンド subagent の待機とツールセット
- hooks-guide —
-pモードで走る hook(--bareでは走らない) - workflows —
-pでは workflow が待機実行になる - costs —
--output-format jsonのtotal_cost_usd - cli-reference — 全 CLI フラグ
- env-vars