Claude Code を月額プラン(Pro / Max)のまま毎朝 cron で無人実行して 27 日、API の従量課金は 0 円でした。「勝手に課金されるのでは」が自動化に踏み切れない最大の理由だと思うので、結果を先に書きます。
毎朝 6 時 40 分、私が寝ている間に、その日の判断材料が 1 枚にまとまって置いてあります。KPI の前日比、計画とのズレ、今日決めるべきことと選択肢。作っているのは AI で、決めるのは私です。
27 日間で動いたのは 25 日、動かなかったのは 2 日。それとは別に 1 回だけ、「成功」と記録されているのに何も作られていなかった日があります。この記事は、その仕組みと 27 日分の実測値の記録です。
- 対象読者: Claude Code を対話で日常的に使っているが、無人で走らせたことはない人
- 検証環境: Windows 11 + WSL2(Ubuntu)、Claude Max プラン
- 検証期間: 2026-07-07 〜 2026-08-02(27 日間)
手順だけ知りたい方は、後半の「今日から試す最小構成」まで飛ばしてください。
「役員会議」と呼んでいるものの中身
大げさな名前をつけていますが、実体は A4 一枚のマークダウンファイルです(ファイル名の末尾に「意思決定ボード」と付けています。以降のコード例にこの名前が出てきます)。毎朝 AI が生成し、私が上から読んで、最後の欄に決定を書き込みます。
構成はこうなっています。
| セクション | 中身 |
|---|---|
| 3 行サマリ | 今日の状況を 3 行で |
| KPI 前回比 | 記事の閲覧数、登録者数などが昨日からどう動いたか |
| 計画との対比 | 各マイルストーンの期日と実績、順調か要注視かの判定 |
| GAP 分析 | 計画と実績がズレている箇所と、その理由 |
| 仮説 | ズレの原因についての現時点の見立て |
| 今日の意思決定 | 決めるべきこと(選択肢つき) |
| 記入欄 | 私が決定を書く場所 |
実際に生成されたファイルの「KPI 前回比」の部分は、こうなっています。
| 指標 | 前回 (08/01) | 今回 (08/02) | 増減 |
|---|---|---|---|
| Qiita 累計PV | 2281 | 2414 | +133 |
| Zenn likes | 41 | 41 | +0 |
| メルマガ登録者 (確認済み) | 0 | 0 | +0 |
| note 売上 (手入力) | 0 | 0 | +0 |
売上 0 円、登録者 0 人が毎朝そのまま並びます。都合の悪い数字が自動で目に入る、というのがこの仕組みのいちばんの価値です。
報告 → 論点 → 決裁という並びは、役員会議の議事進行そのものです。違うのは、出席者が AI ひとりで、決裁者が私しかいないことだけです。
なぜ作ったか — 朝の 30 分が「集める」で終わっていた
以前は、朝にこういう手順を踏んでいました。
- 各サービスの管理画面を開いて数字を控える
- 前日の記録と見比べて、増減を計算する
- 計画表を開いて、期日が近いものを探す
- そこまでやって、ようやく「で、今日は何をするか」を考え始める
問題は、1〜3 が判断ではなく作業だったことです。しかも作業の量は毎日ほぼ同じで、疲れている日ほど雑になります。雑になると、悪い数字を見落とします。
見落とすとどうなるか。私の場合、有料記事の閲覧数が 1 か月ほとんど動いていないことに気づくのが 3 週間遅れました。気づいた時には、打ち手を試す時間が減っていました。
判断材料を集める作業を自分でやっている限り、忙しい日ほど判断が雑になる。 これが自動化した理由です。
27 日間の実測値
測り方
先に測定方法を書きます。ログの「成功」表示ではなく、成果物ファイルが実際に存在するかどうかで数えました。理由は後述しますが、ログは嘘をつくことがあるからです。
# 期間内の日付を並べ、その日付のファイルが存在するかを数えた
# (私の作業フォルダ構成です。読者の環境では、後述する出力先フォルダの
# ファイル数を数える形に置き換えてください)
ls 07_Operations/デイリーブリーフ/*_意思決定ボード.md | wc -l
# → 25 (期間中に生成された日数)
# 27 日分の日付一覧とこの結果を突き合わせ、抜けている日 (7/27・7/28) を特定した
結果
| 項目 | 実測値 |
|---|---|
| 期間 | 2026-07-07 〜 2026-08-02(27 日間) |
| 生成された日 | 25 日 |
| 生成されなかった日 | 2 日(7/27・7/28) |
| 成功率 | 93% |
| 認証切れ | 0 件 |
| レート制限に当たった回数 | 0 件 |
| API の従量課金 | 0 円 |
認証切れとレート制限の件数は、実行ログに残るエラー文字列を検索して数えました。該当する行が 1 件もなかったため 0 件と書いています。従量課金の 0 円は、後述する Anthropic のコンソール画面の数字です。
動かなかった 2 日の原因は、AI ではありませんでした
7/27 と 7/28 のログには、エラーも警告も残っていません。行が 1 つもないのです。
調べ方は単純でした。その 2 日間に更新されたファイルを、作業フォルダ全体から検索しました。
find /path/to/vault -newermt "2026-07-27 00:00" ! -newermt "2026-07-29 00:00" -type f | wc -l
# → 0
0 件。他の定時処理も 1 つも動いていません。つまり PC の電源が入っていなかった日でした。土日に PC を開かなかっただけです。
これは個人の PC で自動化する場合の、避けようのない制約です。同種の記事では Raspberry Pi のような常時起動の機械を使う例が多いのですが、普段使いの PC でやる限り、電源を切った日は動きません。
対策は、諦めるか、リカバリを仕込むかの二択です。私は後者にしました。
# 毎朝 6:40 に実行
40 6 * * * /path/to/morning.sh
# PC 起動から 90 秒後にも実行(その日まだ動いていなければ走る)
@reboot sleep 90 && /path/to/morning.sh
@reboot は、cron(決まった時刻にコマンドを自動実行する Linux の仕組み)が持っている特殊な指定で、マシンが起動したタイミングで 1 回だけ実行されます。これを入れておくと、朝 6 時 40 分に PC が落ちていても、昼に電源を入れた時点でその日の分が作られます。
実際、27 日分の実行時刻を見ると 04:31、06:06、06:49 とばらついています。定時に動いた日と、起動時に走り直した日が混ざっているからです。
sleep 90 を挟んでいるのは、起動直後はネットワークがまだ繋がっていないことがあるためです。
いちばん怖かったのは、失敗ではなく「成功したふり」でした
7/25 のログにこの 1 行が残っています。
2026-07-25 05:38 失敗 (exit 0)。ボード未生成 (マーカー未設定、次のトリガーで再試行)
「マーカー」は、私の運用で使っている「今日はもう成功したか」を記録する目印ファイルのことです。ここで見てほしいのは仕組みの名前ではなく、exit 0(正常終了)なのに成果物が空だったという一点です。
exit 0 は、コマンドが正常終了したことを示す終了コードです。プログラムは「成功した」と言って終わったのに、成果物は 1 つも作られていませんでした。
もしこの日、私が「エラーが出ていないから動いているはずだ」と考えていたら、気づくのは数日後です。しかも気づくきっかけは「そういえば最近ファイルを見ていないな」という曖昧な違和感になります。
無人で動かす仕組みで本当に怖いのは、止まることではなく、止まったことに気づけないことです。
対策として、成功判定を終了コードから成果物の存在に変えました。
# 悪い例: 終了コードだけを見る
claude -p "$PROMPT" && echo "成功"
# 良い例: 成果物ができたかを見る
claude -p "$PROMPT"
if [ -f "$OUTPUT_FILE" ]; then
echo "成功: $OUTPUT_FILE"
else
echo "失敗: ファイルが作られていない"
fi
この記事の成功率 93% を「ファイルの存在で数えた」と最初に書いたのは、この経験があるからです。ログを信じて数えていたら、実測値はもっと良く見えていました。
WSL2 で動かす人だけが踏む、もう 1 つの罠
私の作業フォルダは Windows 側のドライブにあり、WSL2 からは 9p というプロトコル経由で見えています。ここで実測した現象がありました。
AI がファイルを書き終えた直後に別のプロセスから確認すると、まだ存在しないように見えることがあります。 キャッシュの反映が遅れるためです。判定を書き込み直後に行うと、実際には成功しているのに「失敗」と記録されます。
対策は待つことです。
# 書き込み直後は見えないことがあるので、最大 30 秒リトライする
for _ in 1 2 3; do
[ -f "$OUT" ] && break
sleep 10
done
Linux ネイティブのファイルシステム(/home 配下など)に出力する場合は不要です。Windows 側のフォルダ(/mnt/c/... や、Obsidian の保管庫を Windows 側に置いている場合)に書き出すなら、この待ちを入れてください。
仕組み — 対話画面なしで Claude を動かす
claude -p とは
Claude Code には、対話画面を開かずにコマンドとして実行するモードがあります。-p(または --print)を付けるだけです。
claude -p "今日のKPIをまとめて、意思決定ボードを作って"
公式ドキュメントの説明はこうです。
任意の
claudeコマンドに-p(または
これを cron に登録すれば、決まった時刻に AI が仕事をします。仕組みとしてはこれだけです。
認証は月額プランのまま通ります
ここが多くの人の不安な点だと思います。**「自動化するには API の従量課金契約が必要では?」**という疑問です。
結論から書くと、月額プラン(Pro / Max)の認証情報のまま動きます。Claude Code は初回ログイン時に認証情報をローカルに保存しており、claude -p はそれをそのまま使います。
27 日間、認証切れは 0 件でした。トークンは自動で更新されるため、途中でログインし直す操作は一度も必要ありませんでした。
ただし注意すべき変更が進行中です。claude -p の利用を月額プランの枠から切り離す変更が計画され、2026 年 6 月 15 日付の公式アナウンスで「一時停止する」と告知されました。
Update June 15: We're pausing the changes to Claude Agent SDK usage described below. For now, nothing has changed: Claude Agent SDK,
claude -p, and third-party app usage still draw from your subscription's usage limits.(6 月 15 日の更新: 以下に記載した Claude Agent SDK の利用に関する変更を一時停止します。現時点では何も変わっていません。Claude Agent SDK、
claude -p、およびサードパーティアプリの利用は、引き続きサブスクリプションの利用枠から消費されます。)— Use the Claude Agent SDK with your Claude plan(最終更新 2026-06-16)
「Claude Agent SDK」は Claude Code の土台になっている開発キットの名前です。ここでは「claude -p にも同じ課金ルールが適用される」と読めれば十分です。
この記事は 2026 年 8 月時点の状態に基づいています。 再開される可能性があるため、始める前に上記ページを確認してください。
意図しない課金を防ぐ設定と、確認のしかた
自動化で怖いのは、寝ている間に課金が積み上がることです。実際に事故は起きています。
Anthropic の GitHub リポジトリには、Max プラン契約者が claude -p を自動実行したところ、2 日間で約 1,800 ドルの API 課金が発生したという報告があります(Issue #37686)。原因は、シェルの設定に API キーが残っていたことでした。
設定 1: API キーを「別の名前」で保管する
公式ヘルプに、この事故の原因がはっきり書かれています。
If you have an ANTHROPIC_API_KEY environment variable set on your system, Claude Code will use this API key for authentication instead of your Claude subscription
(システムに
ANTHROPIC_API_KEY環境変数が設定されている場合、Claude Code は Claude サブスクリプションの代わりに、この API キーを認証に使用します。)
つまり ANTHROPIC_API_KEY という名前の環境変数が存在するだけで、月額プランではなく従量課金が使われます。
対策としてよく言われるのは「使わないなら消す」ですが、別のスクリプトで API を叩きたい場合は消せません。私は名前を変えて保管しています。
# .env の中身(実際の記述)
# ANTHROPIC_API_KEY は設定しない(Claude CodeがProサブスクではなくAPI従量課金で動作してしまうため)
ANTHROPIC_API_KEY_FOR_SCRIPTS=sk-ant-...
公式が「サブスクリプションより優先する」と明言しているのは ANTHROPIC_API_KEY という名前だけです(上の引用)。**他の名前を Claude Code が読みに行くかどうかまでは公式文書に記載がないため、断定はしません。**私は名前を変えて保管しています(_FOR_SCRIPTS は分かりやすさのための自己流の命名で、決まりごとではありません)。API を使いたいスクリプトの中でだけ、この変数を参照します。キーは保持したまま、混入する経路だけを物理的に断つやり方です。
加えて、自動実行するスクリプトからは .env を読み込まないようにしています。読み込む行が 1 行もなければ、混入のしようがありません。
設定 2: 支払い方法で上限を作る
設定ミスは起こりうる前提で、起きた時の損失額に天井を作ります。
| 設定 | 状態 | 効果 |
|---|---|---|
| 自動リロード | オフ | 残高が尽きたら API が止まる。青天井にならない |
| クレジット残高 | 少額のみ入金 | 万一暴走しても損失はこの額が上限 |
| 月次請求(後払い) | 契約しない | 使った分を後から請求されない |
自動リロードを有効にしていると、残高が減るたびに自動で補充されます。便利ですが、暴走時に止まる場所がなくなります。前述の 1,800 ドルの事故も、止まる仕組みがなかったから膨らみました。
私は自動リロードをオフにしたまま運用しています。27 日間の API 課金は 0 円、残高も 1 円も減っていません。
設定 3: 「0 円のまま」を自分の目で確認する — ただし罠があります
ここまでは事故を防ぐ設定です。実際に課金されていないかは、設定を信じずに数字で確認してください。
まず間違いやすい確認方法から書きます。claude -p は --output-format json を付けると実行結果を JSON で返し、その中に total_cost_usd(今回の実行コスト)という項目があります。JSON から特定の項目だけ取り出すのに使っているのが jq(JSON 用の grep のようなコマンド。sudo apt install jq で入ります)です。
claude -p "1+1は?" --model sonnet --output-format json | jq -r '.total_cost_usd'
私の環境で実行した結果はこうでした。
0.1228272
0 ではありません。 これを見て「課金されている」と慌てるところですが、そうではありません。公式ドキュメントにこう書かれています。
/usageのセッションブロックは API トークン使用量を表示し、API ユーザーを対象としています。Claude Max および Pro サブスクライバーはサブスクリプションに使用量が含まれているため、セッションコスト数値は請求目的では関連がありません。
つまり total_cost_usd は「もし API 従量課金で同じことをしたら、いくらだったか」という換算値です。月額プランで動いている限り、この数字が出ても実際には請求されません。
では本当の確認はどこでするか。Anthropic のコンソールの請求画面です。
- console.anthropic.com にログインし、Billing(請求)を開く
- クレジット残高が減っていないことを確認する
- 「今月の使用額」が $0.00 のままであることを確認する
この記事の「27 日間 0 円」は、total_cost_usd ではなくこの画面の数字が根拠です。残高は 1 円も減っていません。
自動実行を始めた最初の 3 日は、毎朝この画面を開いて確認することをおすすめします。設定が正しいかどうかは、設定ファイルを読み返すより残高を見るほうが早く分かります。
「外に出る操作」は持たせていません
この仕組みには、メール送信・SNS 投稿・git push を実行させていません。技術的にはできますが、意図的に外しています。
理由は、無人実行では間違いを止める人がいないからです。
対話で使っている時は、AI がおかしな判断をしても、送信ボタンを押す前に私が気づきます。無人実行にはその一瞬がありません。誤った内容のメールが送られてから気づくことになります。
そこで役割をこう分けました。
| 誰が | 何を |
|---|---|
| AI(無人) | 読む・数える・比べる・書く(ローカルのファイルまで) |
| 私(手動) | 外に出す判断と実行(送信・投稿・公開) |
生成されたファイルは私が読んでから使うので、間違いがあっても外には出ません。取り返しがつく範囲だけを無人に任せる、という線引きです。
この線引きは、口約束ではなくコマンドで強制します
「送信させない」をプロンプトで指示するだけでは足りません。AI が指示を読み違える可能性が残るからです。使える道具そのものを制限します。
claude -p には --allowedTools というオプションがあり、ここに書いた道具しか使えなくなります。私の本番の呼び出しはこうです。
timeout 600 "$CLAUDE_BIN" -p "$PROMPT" \
--model sonnet \
--allowedTools "Read,Glob,Grep,Write" \
>> "$LOG" 2>&1
許可しているのは 4 つだけです。
| 道具 | できること |
|---|---|
Read |
ファイルを読む |
Glob |
ファイルを名前で探す |
Grep |
ファイルの中身を検索する |
Write |
ファイルを書く |
**この 4 つにはシェルコマンドの実行が含まれていません。**つまり curl でどこかへ送信することも、git push することも、メールを出すこともできません。プロンプトで何を書こうと、道具がないので実行できない状態です。
timeout 600 は、処理が終わらなくなった時に 10 分で打ち切る指定です。無人実行では固まっても誰も気づかないため、上限を決めています。
--model sonnet でモデルを指定しているのは、この作業(決まった形式の集計と要約)に上位モデルの推論力が要らないためです。使用量の枠を節約できます。
今日から試す最小構成
いきなり判断材料を作らせる必要はありません。1 つのファイルを毎朝作らせるだけから始められます。
1. 認証を通し、フルパスを控える
claude
ログイン済みであれば、認証情報がローカルに保存されます。あわせて実行ファイルの場所を調べておきます。
which claude
# 例: /home/username/.local/bin/claude
この出力をコピーしておいてください。次に出てくるスクリプトの /home/username/.local/bin/claude は、必ずここで得た自分のパスに書き換えます。
cron から実行する時は、普段のシェルとは環境変数が異なります。claude とだけ書くとコマンドが見つからず、何も起きないまま終わることがあります。フルパスで書けば確実です。
2. スクリプトを書く
#!/bin/bash
# morning.sh
TODAY=$(date +%Y-%m-%d)
OUT="$HOME/daily/${TODAY}_report.md"
LOG="$HOME/daily/run.log"
MARKER="$HOME/.cache/morning/${TODAY}.done"
mkdir -p "$HOME/daily" "$HOME/.cache/morning"
# 今日すでに成功していれば何もしない (後述の @reboot と併用するため)
[ -f "$MARKER" ] && exit 0
timeout 600 /home/username/.local/bin/claude -p \
"今日の日付を確認し、${OUT} に『今日やることの候補を3つ』書き出して" \
--model sonnet \
--allowedTools "Read,Glob,Grep,Write" \
>> "$LOG" 2>&1
# 終了コードを見ず、成果物の存在で判定する
if [ -f "$OUT" ]; then
touch "$MARKER"
echo "$(date '+%F %H:%M') 成功: $OUT" >> "$LOG"
else
echo "$(date '+%F %H:%M') 失敗: ファイル未生成" >> "$LOG"
fi
4 つの指定が入っています。
-
--allowedTools: この 4 つの道具しか使わせません。シェルコマンドが含まれないので、外部への送信は物理的にできません -
timeout 600: 10 分で打ち切ります。無人実行では固まっても誰も気づかないためです - マーカーファイル: 今日すでに成功していれば、二重に実行しません
-
出力先を絶対パス(
$HOME/...)で書く: これを相対パスにすると事故ります(次項)
出力先は必ず絶対パスで指定してください
検証中に踏んだので書いておきます。プロンプトで相対パスのファイル名を指定したところ、AI は「作成しました」と報告したのに、指定した場所にファイルがありませんでした。
探すと、**まったく別のフォルダに作られていました。**AI が実行時に認識している作業フォルダが、こちらの想定と違っていたためです。
対話で使っている時は目の前に結果が出るので気づきます。無人実行では、ファイルが「どこかに」作られ、判定は「無い」と記録され、原因が分からないままになります。前述の「成功したふり」の正体は、これでした。
プロンプトの中でも出力先は絶対パスで書きます。上のスクリプトが ${OUT}(中身は $HOME/daily/...)を渡しているのはこのためです。
3. cron に登録する
crontab -e
40 6 * * * /home/username/morning.sh
@reboot sleep 90 && /home/username/morning.sh
2 行目が、PC を落としていた日のリカバリです。**マーカーファイルがあるので、朝 6 時 40 分に成功していれば、その日 PC を再起動しても二重には走りません。**この 2 行はセットで使ってください。
4. 3 日後に、ログではなくファイルを見る
run.log の中身ではなく、~/daily/ にファイルが 3 つ増えているかを確認してください。増えていなければ、ログに何が書いてあっても動いていません。
同時に、Anthropic のコンソールでクレジット残高が減っていないことも見ておきます。ここまで確認して、初めて「動いている」と言えます。
27 日やってわかったこと
AI は 27 日間サボりませんでした。サボったのは私の PC でした。
止まった原因は認証でもレート制限でも課金でもなく、電源でした。技術的な障害より、生活のリズムのほうが影響が大きかったということです。だから対策も技術的なものではなく、「PC を開いた時に走り直す」という生活側に寄せた設計になりました。
そして毎朝、売上 0 円という数字が自動で目に入ります。集める作業を手放したぶん、その数字を見て考える時間が残るようになりました。役員会議で本当に価値があるのは資料を作る時間ではなく、資料を見て決める時間だったということです。
役員でなくても、決裁する場所は自分で作れます。出席者が AI ひとりでも、会議は成立しました。
**この記事の 4 ステップ(認証確認 → スクリプト作成 → cron 登録 → 3 日後にファイルを数える)だけで、明日の朝から同じものが動きます。**まずは無害な 1 本から試してみてください。
検証環境: Windows 11 + WSL2 (Ubuntu) / Claude Max プラン / 検証期間 2026-07-07 〜 2026-08-02
注記: claude -p の課金仕様は 2026 年 6 月に変更が計画され、現在は一時停止中です。開始前に公式ヘルプで最新の状態を確認してください。
📢 8/29(土) にオンライン勉強会をやります
この記事で書いた「AI に毎朝働いてもらう仕組み」の実物を、40 分でお見せします。50 案件の進捗催促を Slack・スプレッドシート・cron で自動化した構成とデモ、うまくいかなかった部分も含めて話します。オンライン・無料・定員 20 名です。