「Claude Code を毎朝決まった時刻に動かして、前日のログの点検や集計を任せたい」。この相談は、Claude Code を対話で使い始めた会社が次に必ず通る段階です。ただし、対話のときは人が承認していた操作を、無人のときは誰が止めるのかを先に決めないと、静かに止まるか、余計なことをするジョブになります。
この記事では、Claude Code の公式ドキュメント(2026年9月時点)だけを出典に、定期実行の3つの方式、ヘッドレスモード(claude -p)が対話と違う点、無人で許す操作の決め方、予算と回数の上限、そのまま使える雛形とチェックリストを整理します。読者は、社内の業務改善・情報システム・Web の担当者を想定しています。
結論 — 先に要点だけ
- 定期実行の置き場は3つ。 自社サーバーの cron から
claude -pを呼ぶ、クラウドの Routines に任せる、Desktop アプリのスケジュールタスクを使う。最短間隔・必要な機材・届く範囲が違うので、仕事の性質で選びます - スクリプトから呼ぶなら
--bareを付ける。 フォルダに置かれた hooks・MCP・CLAUDE.md を読まずに起動し、毎回同じ結果になります。公式も「スクリプトと SDK 呼び出しの推奨モード」としています - 無人実行の権限は
dontAskと許可リストの組み合わせが基本。 確認が必要な操作はすべて拒否され、--allowedToolsに書いた操作だけが動きます。bypassPermissionsは隔離環境専用です - 上限を3種類切る。 回数は
--max-turns、金額は--max-budget-usd、時間は cron 側のtimeout。JSON 出力のtotal_cost_usdを毎回残して実測します - 「動いた」と「できた」は別。 終了コード・拒否された操作の一覧・API エラー時のフックで失敗を拾い、Routines の緑色の状態表示を成否の判定に使わないこと
定期実行の3つの方式 — どこで動かすか
Claude Code のドキュメントは、繰り返し実行の方法をクラウド(Routines)・Desktop アプリ・セッション内の /loop の3つで比較しています。社内サーバーの cron から claude -p を呼ぶ方式は、この比較表には無い「自前の4つ目」ですが、実務では最も多い構成です。
| 方式 | 動く場所 | PC の電源 | 最短間隔 | 手元のファイル | 向く仕事 |
|---|---|---|---|---|---|
cron + claude -p | 自社サーバー・自分の PC | 必要 | cron 次第 | 届く | 社内システム・ログ・DB の点検や集計 |
| Routines(クラウド) | Anthropic 管理のクラウド環境 | 不要 | 1時間 | 届かない(毎回 clone) | GitHub 上のリポジトリを相手にする仕事 |
| Desktop スケジュールタスク | 自分の PC | 必要 | 1分 | 届く | 個人の PC にあるファイルの整理 |
/loop | 開いているセッション | 必要 | 1分 | 届く | 作業中の短時間のポーリング |
※ 出典: Claude Code Docs — Run prompts on a schedule(取得 2026-09)
/loop はセッションを閉じると止まり、繰り返しタスクは作成から7日で自動的に期限切れになります。恒常的な業務には向きません。Routines は「調査プレビュー」の位置づけで、Pro・Max・Team・Enterprise の各プランで使え、Team と Enterprise では管理者が組織全体で無効にできます。
※ 出典: Claude Code Docs — Automate work with routines(取得 2026-09)
この記事の以降は、まず cron + claude -p の構成を軸に説明し、最後に Routines を使う場合の注意をまとめます。両方に共通するのは「無人のときに何を許すか」の設計です。
ヘッドレスモードの基本 — claude -p が対話と違う点
claude -p "指示" と打つと、Claude Code は対話画面を出さずに1回分の仕事をして終了します。スクリプトから使うときに知っておく挙動は5つです。
| 挙動 | 内容 |
|---|---|
| 終了コード | 成功で 0、失敗で 0 以外。認証切れなど実行中の失敗は、結果として標準出力に出る |
| 標準入力 | パイプで渡せる(上限 10MB)。超えるとエラーで終了するので、大きい入力はファイルに書いてパスを渡す |
| 出力形式 | --output-format json で結果・セッション ID・total_cost_usd を含む JSON。--json-schema で構造を指定できる |
| 開始時の権限モード | どのプランでも手動(Manual)で始まる。無人なら明示的にモードを渡す |
| 信頼ダイアログ | 出ない。フォルダにある hooks・.mcp.json の MCP サーバーは、--bare を付けない限り読まれて動く |
※ 出典: Claude Code Docs — Run Claude Code programmatically(取得 2026-09)
最後の行が、無人実行で最初に押さえる点です。対話で claude を起動すると、初めてのフォルダでは「このフォルダを信頼するか」を聞かれます。-p ではこの確認が出ず、フォルダに置かれた設定ファイルの hooks や .mcp.json のサーバーがそのまま動きます。自分が書いていないリポジトリで定期実行するなら、これは事故の入口です。
対策が --bare です。hooks・スキル・カスタムコマンド・サブエージェント・プラグイン・MCP サーバー・自動メモリ・CLAUDE.md の自動検出をすべて飛ばして起動します。必要な文脈は --append-system-prompt(またはファイル指定)・--settings・--mcp-config で明示的に渡します。公式は「スクリプトと SDK 呼び出しの推奨モード」とし、将来 -p の既定にする予定と書いています。
--bare には認証の副作用があります。サブスクリプションのログイン情報(OAuth)や OS のキーチェーンを読まないため、Anthropic API を使うなら環境変数 ANTHROPIC_API_KEY に Console で作ったキーを入れます。Amazon Bedrock・Google Cloud・Microsoft Foundry 経由なら、それぞれの資格情報がそのまま使われます。なお -p では、ANTHROPIC_API_KEY が設定されていると常にそちらが使われます。
※ 出典: Claude Code Docs — Environment variables(取得 2026-09)
無人で許す操作の決め方 — 権限モードと許可リストの4層
対話では「この操作を許可しますか」に人が答えます。無人実行では、その答えを先に設定として書いておきます。層は4つです。
層1 — 権限モードで土台を決める
| モード | 確認なしで動くもの | 公式が示す用途 |
|---|---|---|
default(Manual) | 作業ディレクトリ内の読み取りと、組み込みの読み取り専用コマンド | 自分で毎回確認する |
acceptEdits | 上に加えて、作業ディレクトリ内のファイル編集と mkdir・mv・cp などの基本操作 | 編集を任せる |
dontAsk | 上の読み取りと、許可リストに書いた操作。確認が必要な操作はすべて拒否 | ロックダウンした CI とスクリプト |
auto | 分類器(別のモデル)が操作を審査して可否を決める | 人の代わりに審査させる |
bypassPermissions | ほぼすべて | 隔離されたコンテナと VM だけ |
※ 出典: Claude Code Docs — Choose a permission mode(取得 2026-09)
無人実行の土台は dontAsk です。読み取りと許可済みの操作だけが動き、それ以外は「誰も承認できない」として拒否されます。セッションが入力待ちで止まることがありません。
bypassPermissions(--dangerously-skip-permissions と同じ)は、公式が「隔離されたコンテナと VM だけ」と明記しています。deny ルールはこのモードでも効きますが、allow ルールは意味を持たず、.git や .claude のような保護パスへの書き込みも通ります。管理設定の disableBypassPermissionsMode で、組織としてこのモードを使えなくすることもできます。
auto モードは分類器が操作を審査する方式で、API アカウントでは分類器の呼び出しがトークン使用量に加算されます。無人実行で使うなら、--permission-prompts none と組み合わせ、分類器が「人に聞く」に倒した操作を拒否に変えます。
層2 — 許可リストで「動かしてよい操作」を列挙する
--allowedTools か設定ファイルの permissions.allow に、動かしてよい操作を書きます。書き方は Tool または Tool(指定) で、Bash は先頭一致のワイルドカードが使えます。
--allowedTools "Read" "Bash(npm test)" "Bash(git log *)" "Bash(git diff *)"
公式ドキュメントが挙げる CI の例は次の1行です。テストを走らせる以外は何も許していません。
claude -p "run the test suite" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read"
ワイルドカードは * の前の空白が重要です。Bash(git diff *) は git diff で始まるコマンドに一致しますが、Bash(git diff*) は git diff-index にも一致してしまいます。また * はサブコマンドの後に置きます。Bash(git * main) と書くと、git -c core.fsmonitor=<script> diff main のように任意のプログラムを実行させる形にも一致します。
deny は allow より常に強く、Bash(aws *) のような広い deny があると、Bash(aws s3 ls) のような狭い allow でも例外を作れません。読み取り専用として組み込みで許可されているコマンド(ls・cat・grep・find・head・tail・wc・diff・読み取り系の git など)は、どのモードでも確認なしで動きます。
※ 出典: Claude Code Docs — Configure permissions(取得 2026-09)
注意点が1つあります。リポジトリの .claude/settings.json に書いた permissions.allow は、そのフォルダを信頼するまで使われません。claude -p は信頼ダイアログを出さないので、ここに書いた allow は無視され、標準エラーに「this workspace has not been trusted」の警告が出ます。無人実行の許可リストは --allowedTools か --settings で渡す、あるいは ~/.claude.json の hasTrustDialogAccepted を手で立てる、のどちらかにします。
層3 — 確認を求める操作を「聞かない」に固定する
--permission-prompts none は、承認できる人がいない実行のためのフラグです。確認が必要な操作は拒否され、Claude には「誰も承認できないので再試行しない」と伝わります。人に質問するための AskUserQuestion ツールも取り除かれます。--output-format stream-json では拒否が permission_denied のシステムメッセージとして流れ、最後の結果メッセージの permission_denials に一覧が残ります。Claude Code v2.1.259 以降で使えます。
※ 出典: Claude Code Docs — Run Claude Code programmatically(取得 2026-09)
層4 — フックで「絶対に止める」を仕組みにする
許可リストは「何を許すか」の宣言です。「何があっても止める」は PreToolUse フックで実装します。フックが終了コード 2 を返すと、その操作は allow ルールがあっても止まります。逆にフックが allow を返しても、deny ルールは覆せません。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "/srv/claude/hooks/block-destructive.sh" }
]
}
],
"PostToolUse": [
{
"matcher": "*",
"hooks": [
{ "type": "command", "command": "/srv/claude/hooks/append-audit-log.sh" }
]
}
]
}
}
PostToolUse に記録用のコマンドを付ければ、どのツールが何をしたかを監査ログに落とせます。API エラーでターンが終わったときは StopFailure フックが動き、rate_limit・overloaded・authentication_failed などの種類で分岐できます。無人実行では、ここに通知を仕込むのが確実です。
※ 出典: Claude Code Docs — Hooks reference(取得 2026-09)
--bare はフォルダのフックを読まないので、このフック設定は --settings /srv/claude/settings.json のように明示的に渡します。フォルダに置いた設定に依存しない構成のほうが、サーバーを移しても同じ挙動になります。
なお、Bash(curl *) を deny しても /usr/bin/curl や sh -c 'curl …' には一致しません。ネットワークを本当に閉じたい場合は、権限ルールではなくサンドボックスのネットワーク許可リストを併用します。この点は法人導入ガイドのサンドボックスの節で扱っています。
最初の1本 — 毎朝の点検ジョブの雛形
上の4層を1本のスクリプトにまとめると、次の形になります。前日の変更を集めて Claude に渡し、決まった構造の JSON で「異常の有無」を返させ、ファイルに残す構成です。書き込みは一切許可していません。
#!/usr/bin/env bash
# /srv/claude/morning-check.sh — 毎朝の点検(読み取り専用)
set -euo pipefail
export ANTHROPIC_API_KEY="$(cat /etc/claude/api-key)" # 所有者のみ読める権限 600 のファイル
cd /srv/app
git log --since=yesterday --stat > /tmp/yesterday.txt
claude --bare -p "標準入力は前日の変更一覧です。テストを実行し、失敗と気になる変更を JSON で報告してください" \
--permission-mode dontAsk \
--permission-prompts none \
--allowedTools "Read" "Bash(npm test)" "Bash(git log *)" "Bash(git diff *)" \
--settings /srv/claude/settings.json \
--max-turns 20 \
--max-budget-usd 2 \
--output-format json \
--json-schema '{"type":"object","properties":{"status":{"type":"string","enum":["ok","warn","fail"]},"findings":{"type":"array","items":{"type":"string"}}},"required":["status","findings"]}' \
< /tmp/yesterday.txt \
> "/var/log/claude-check/$(date +%F).json"
cron の行は次のとおりです。終了コードの判定と通知はラッパーの側で行います。
# 平日 7:30(サーバーのタイムゾーン)に実行し、失敗したら通知スクリプトを呼ぶ
30 7 * * 1-5 /srv/claude/morning-check.sh || /srv/claude/notify-failure.sh
この雛形で意図的に決めていることを整理します。
- 書き込み系のツールを1つも許可していない。 最初の1本は「読んで報告する」だけにし、
EditやBash(git commit *)は次の段階で足します - 結果の構造を
--json-schemaで固定している。 後段のスクリプトがstatusを見て分岐できるので、Claude の文章を人が毎朝読む必要がありません - キーを crontab やスクリプトに直書きせず、権限を絞ったファイルから読む。 直書きすると、そのファイルを読める人全員にキーが見えます
--max-turnsと--max-budget-usdを両方付けている。 どちらか一方では、安いが延々と回る、または数回で高額になる、の片方を止められません
社内でこの定期実行を自分たちで組む場合の決め方と止め方は、企業向けの実務書にもまとめています。
止まる・暴走する・高くつくを防ぐ — 予算・回数・時間の上限
無人実行で怖いのは「暴走」よりも「静かに止まる」と「気づかないうちに費用がかさむ」です。上限は3種類を別々に切ります。
| 上限 | 手段 | 備考 |
|---|---|---|
| 回数 | --max-turns(print モード専用) | エージェントのターン数を制限する |
| 金額 | --max-budget-usd(print モード専用) | API 呼び出しに使う上限額。超えると停止 |
| 時間 | cron 側の timeout など | 実行全体の時間は、呼び出す側のスクリプトで切る |
| コマンド1本の時間 | BASH_DEFAULT_TIMEOUT_MS(既定 120000)・BASH_MAX_TIMEOUT_MS(既定 600000) | 長いテストやビルドを走らせるなら調整する |
※ 出典: Claude Code Docs — CLI reference(取得 2026-09)、Claude Code Docs — Environment variables(取得 2026-09)
時間で切るときは、送るシグナルに注意します。SIGTERM で止めると Claude Code は終了コード 143 で終わり、進行中のターンは未完のまま結果が記録されません。ターンを区切って終わらせたいなら、先に SIGINT を送ります。また、Claude がバックグラウンドで起動したシェル(開発サーバーなど)は最終結果の約5秒後に終了させられますが、バックグラウンドのサブエージェントは完了まで待ち、その待ちは既定で10分の無操作で打ち切られます(CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS で変更)。
※ 出典: Claude Code Docs — Run Claude Code programmatically(取得 2026-09)
費用の実測は --output-format json の total_cost_usd を毎回ログに残すのが最も簡単です。この値はクライアント側の推定で、請求額とは差が出ることがあります。組織としての上限は別の層で持ちます。Claude Console(API)ならワークスペース単位の支出上限、Team・Enterprise なら管理画面の支出上限、クラウド経由ならクラウド側の予算管理です。OpenTelemetry での出力はどの契約形態でも使え、利用者ごとのトークン数と費用を自社の監視基盤に流せます。
※ 出典: Claude Code Docs — Manage costs effectively(取得 2026-09)
MCP サーバーを --mcp-config で渡す構成では、起動時にサーバーの接続を待ちます。待ち時間の上限は MCP_TIMEOUT で、既定は30秒です。接続に失敗したサーバーは system/init イベントの mcp_server_errors に残るので、CI と同じように「この配列が空でなければ失敗」と判定できます。
クラウドの Routines を使う場合の注意
自社サーバーを持たない、あるいは対象が GitHub 上のリポジトリに閉じているなら、Routines は cron を用意せずに済む選択肢です。ただし、権限の考え方が cron + claude -p と根本的に違います。
- 権限モードの選択が無く、自律的に動く。 シェルコマンドの実行、リポジトリに置かれたスキルの利用、含めたコネクタの呼び出しを、承認で止まらずに行います。届く範囲を決めるのは「選んだリポジトリ」「環境のネットワーク許可と環境変数」「含めたコネクタ」の3つです
- コネクタは既定で「接続済みのすべて」が含まれる。 Slack や Linear など書き込みを伴うツールも許可なしで使われるので、不要なものは作成時に外します
- Default 環境のネットワークは許可リスト方式。 許可外のホストへの要求は 403 で失敗します。自社のサービスに届かせるなら環境の設定を Custom にしてドメインを足します
- 最短間隔は1時間。 それより短い cron 式は拒否されます。開始は数分ずれることがあります
- 実行一覧の緑色は成否ではない。 「セッションが基盤エラーなしで終わった」印なので、実際に何をしたかは実行のログを開いて確認します
- GitHub の接続が切れると最長72時間はスキップし、その後は停止する。 再接続してから自分で再開します
- ブランチの扱いに制約がある。
claude/で始まるブランチへの push は常に受け入れられ、保護ブランチ・他人の PR が開いているブランチ・他人のコミットを含むブランチへの push は拒否されます
※ 出典: Claude Code Docs — Automate work with routines(取得 2026-09)
Routines はサブスクリプションの利用枠を対話と同じように消費し、アカウントごとに1日の実行回数の上限があります。上限に達したときに使用クレジット(従量の追加枠)を有効にしていれば続行でき、無効なら次の期間まで拒否されます。組織で使うなら、この「誰の枠で動くか」を先に決めておきます。
導入前セルフチェックリスト(12項目)
最初の定期実行を本番に入れる前に、次の12項目を確認します。印刷して、担当者と承認者が別々に付けるのが目安です。
| # | 確認項目 | 参照 |
|---|---|---|
| 1 | 対象の仕事は「読んで報告する」から始めているか(書き込みは第2段階) | 雛形 |
| 2 | --bare を付け、必要な文脈を --settings や --append-system-prompt で明示しているか | ヘッドレス |
| 3 | 権限モードは dontAsk(または auto+--permission-prompts none)か | 層1・層3 |
| 4 | --allowedTools の各ルールは、サブコマンドの後に * を置き、空白を入れているか | 層2 |
| 5 | 止めたい操作は deny ルールか PreToolUse フックで機械的に止めているか | 層4 |
| 6 | API キーは権限を絞ったファイルや秘密管理から読み、環境変数に直書きしていないか | 雛形 |
| 7 | --max-turns と --max-budget-usd を両方付けているか | 上限 |
| 8 | 終了コードを判定して通知する仕組みがあるか | 上限 |
| 9 | total_cost_usd と permission_denials を毎回ログに残しているか | 上限 |
| 10 | 時間で切るときは SIGINT を先に送っているか | 上限 |
| 11 | 出力を --json-schema で固定し、後段が文章を読まなくても分岐できるか | 雛形 |
| 12 | 誰が・いつ・どう止めるか(cron の無効化、Routines の一時停止)が手順書にあるか | 運用 |
よくある失敗パターン 5つ
.claude/settings.jsonに allow を書いたのに効かない。claude -pは信頼ダイアログを出さないため、リポジトリの allow ルールは使われません。--allowedToolsか--settingsで渡します- 他人のリポジトリで
-pを回したら、知らない MCP サーバーが動いた。--bare無しの-pは.mcp.jsonのサーバーを確認なしで接続します。自分が書いていないリポジトリでは--bareを必須にします timeoutで切ったら結果が空だった。 SIGTERM は終了コード 143 で途中終了し、そのターンの結果を記録しません。SIGINT を先に送るか、--max-turnsで自然に終わらせます- サブエージェントが待ちに入り、ジョブが10分止まった。 バックグラウンドのサブエージェントの完了待ちは既定で10分です。定期ジョブでは
CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MSを短くするか、サブエージェントを使わない指示にします - Routines の一覧が緑なので安心していたら、何もしていなかった。 緑は基盤エラーが無かった印です。実行のログを読むか、結果を Slack などに書かせて確認します
※ 出典: Claude Code Docs — Run Claude Code programmatically(取得 2026-09)、Claude Code Docs — Automate work with routines(取得 2026-09)
公式ドキュメント・リソース集
この記事で参照した一次資料です。フラグや既定値は更新されるため、実装前に該当ページで最新の記述を確認してください。
- Run Claude Code programmatically(ヘッドレスモード・
--bare・出力形式) - CLI reference(
--max-turns・--max-budget-usd・--permission-promptsなど全フラグ) - Choose a permission mode(
dontAsk・bypassPermissionsの位置づけ) - Configure permissions(ルールの書き方・deny の優先・信頼ダイアログ)
- Settings files and precedence(設定ファイルの優先順位)
- Hooks reference(
PreToolUse・PostToolUse・StopFailure) - Run prompts on a schedule(
/loop・3方式の比較) - Automate work with routines(クラウドの定期実行)
- Manage costs effectively(支出上限・OpenTelemetry)
- Environment variables(
ANTHROPIC_API_KEY・タイムアウト)
よくある質問
Q. --dangerously-skip-permissions で全部許可してしまえば、無人実行は楽になりますか?
公式ドキュメントはこのモード(bypassPermissions)を「隔離されたコンテナや VM だけ」で使うものと位置づけています。無人実行では、dontAsk モードに「許可する操作の一覧」を足す形のほうが、何が動いたかを後から説明できます。管理設定で bypass モード自体を無効にすることもできます。
Q. Pro や Team のサブスクリプションのログインで、サーバーの cron から動かせますか?
スクリプト向けに推奨されている --bare モードは、サブスクリプションのログイン情報(OAuth)を読みません。Claude Console の API キーを ANTHROPIC_API_KEY で渡すか、Amazon Bedrock などクラウド側の資格情報で動かす想定です。手元の PC を使わない構成なら、サブスクリプションの範囲で動くクラウドの Routines も選べます。
Q. 1回の実行にいくらかかるか、事前に分かりますか?
事前の正確な見積もりはできません。代わりに --max-budget-usd で1回あたりの上限額を切り、--output-format json が返す total_cost_usd を毎回ログに残して実測します。この値はクライアント側の推定で、請求額と差が出ることがあります。組織全体の上限は Console のワークスペースや管理画面の支出上限で別に設けます。
Q. 社内にサーバーが無い会社は、クラウドの Routines だけで足りますか?
対象が GitHub 上のリポジトリで、最短1時間おきの実行(公式ドキュメントの記載)で足りる業務なら Routines で組めます。毎回まっさらな環境にリポジトリを clone するため、手元の PC のファイルや社内 LAN のシステムには届きません。社内システムを触る仕事は、社内サーバーの cron か、Desktop アプリのスケジュールタスクの側になります。
Q. ジョブが失敗したことに、どうやって気づけばよいですか?
終了コード(成功は 0)を cron のラッパーで判定して通知する、--output-format json の permission_denials に拒否された操作が残る、API エラーで止まったときに StopFailure フックが動く、の3つを組み合わせます。Routines の実行一覧の緑色は「セッションが基盤エラーなしで終わった」印で、仕事の成否ではありません。
次の一歩
まず、雛形のとおり「読んで報告する」だけのジョブを1本、平日の朝に動かしてください。1週間分の total_cost_usd と permission_denials がたまれば、書き込みを許す第2段階に進むかどうかを数字で判断できます。
対象の業務の選び方や、社内の権限・承認の決め方から相談したい場合は、お問い合わせから現在の状況をお知らせください。契約前提ではありません。Claude 導入支援の全体像はClaude 導入支援ハブに、既にある Claude Code の運用が安全かを確かめる無料の診断はハーネス健全度診断にまとめています。
更新履歴
- 2026-09-23: 初版公開