公開日 ・ 約11分で読めます
Claude Codeを毎朝定時に走らせるlaunchd自動化

Claude Codeの定期実行とは、macOS標準のジョブ管理機能launchd(ラウンチディー。OSに最初から入っているスケジューラ)にコマンドを登録し、毎朝決まった時刻に、人がターミナルを開かなくてもClaude Codeを自動で走らせる仕組みです。この記事では、このブログ自体を無人運行している僕の3系統のlaunchdジョブの実物設定と実ログをもとに、「壊れない定時実行」の組み方を解説します。
対象読者は、Claude Codeを手動では使えているけれど、毎朝の起動が自分の手作業のままになっている人です。リサーチ、レポート、記事の下書きのような定型の仕事を「朝、自分が席に着く前に終わっている状態」にしたい経営者・実務者に向けて書きます。
Claude Codeの定期実行とは?手動起動と何が違うのか
手動起動は「自分の空き時間」に依存する
手動運用の問題は、作業の速さではなく開始の不確実さです。自分がターミナルを開かない日は、仕組みがどれだけ優秀でも何も起きません。
僕自身、PDF資料の制作を「自分がセッションを開いたときに回す」運用にしていた時期があり、2026年7月に週末2回、そのまま止まりました。当時のスクリプトの冒頭に、自分への戒めとしてこう書き残しています。
「私がセッションで回す」運用は週末に止まった。人を待たない設計に昇格。
定期実行に切り替えるというのは、開始のトリガーを人間の記憶からOSの時計に付け替えることです。変わるのは実行の速さではなく、仕事の開始が人に依存しなくなること。ここが手動起動との本質的な違いです。
「毎朝走る」は追加費用ゼロのMac標準機能で作れる
launchdはmacOSに組み込まれた標準機能なので、定時実行のために新しいツールや月額サービスを契約する必要はありません。必要なのは、設定ファイルを1枚書いて登録することだけで、この記事の手順はそのまま自分のMacで再現できます。
なぜMacではcronでなくlaunchdなのか
定時実行を調べると必ずcron(クーロン。Unix系OSの伝統的なスケジューラ)が出てきます。cronはMacでも動きますが、macOSのジョブ管理の公式な仕組みはlaunchdに一本化されており、Appleはcronを過去互換のために残している位置づけです。
実務で効く差はスリープ後の挙動です。cronは予定時刻にMacがスリープしていると、その回を黙って飛ばします。launchdの時刻指定(StartCalendarInterval)は、スリープ中に過ぎた予定を覚えていて、スリープ解除時に実行してくれます。毎朝の無人実行では、この差がそのまま欠便率の差になります。
もう一つの利点は、ログの出力先と環境変数を同じ設定ファイル1枚で宣言できることです。
Macで定時実行を組むならlaunchd一択です。cronとの比較検討に時間を使う場所ではありません。比較はこの節で終わりにして、組み方に進みます。
僕が毎日走らせている3系統のスケジュール
このブログは、記事の生成から計測まで3系統のlaunchdジョブで回っています。実物の運行表がこれです。
記事便(com.aivest.blog-article-daily): 9:12と15:07を主便に、12:07と18:07の予備便を加えて1日4回起動。記事の生成から公開までを1回で実行します。生成上限は1日2本で、超過分はジョブ自身がスキップします
PDF資料便(com.aivest.blog-pdf-cycle): 毎日10:23に起動。台帳を見て、最終制作日から2日未満なら何もせず終了します(実質2日に1回ペース)
週次計測便(com.aivest.blog-metrics-weekly ほか): 毎週月曜9:00にGSCとGA4(Google Search ConsoleとGoogle Analytics。検索と閲覧の実測データ)を取得し、続けて週次の診断レポートを生成します

ポイントは、起動回数は必要本数より多めに設定し、作りすぎの制御はジョブ自身のスキップ判定に任せるという設計です。朝の便が失敗しても午後の便が自動でリトライになり、成功していれば午後の便は上限判定で即終了します。
実際のログには、成功・スキップ・失敗の3パターンがこういう形で残ります(内部パスは省略しています)。
[2026-08-10 10:23:05 JST] SKIP: 1日前に制作済み
>
----- [2026-08-09 10:23:05 JST] FAILED exit=0 verify=incomplete -----
>
----- [2026-08-10 09:12:05 JST] done ok(実測verify: 記事URL 200 + sitemap掲載)-----
1回の実行につき結論が1行残る。これが後述する「止まったことに気づく仕組み」の土台になります。
launchdで毎朝走らせる設定手順
設定ファイルはplist(プロパティリスト。XML形式の設定ファイル)で、ユーザーのホーム配下の Library/LaunchAgents フォルダに置きます。手順は4ステップです。
launchdから直接claudeコマンドを呼ばず、間にbashスクリプトを1枚挟みます。中身は「claude -p "指示文"」(-pは画面を開かず裏で1回実行する起動方式)を軸に、開始時刻とスキップ判定と結果の記録を同じスクリプトに書きます。後から守りを足す場所を最初に確保しておく構成です。
指定するのは実質4項目です。Label(ジョブの名前)、ProgramArguments(1で作ったスクリプトのパス)、StartCalendarInterval(HourとMinuteの時刻指定。複数書けば1日複数回)、StandardOutPathとStandardErrorPath(出力とエラーの記録先ファイル)。僕の記事便のplistも本体はこの4項目だけです。
launchdが起動するシェルは、ターミナルで使っているPATH設定(コマンドの探し場所)を引き継ぎません。claudeコマンドはユーザー領域にインストールされるため、plistのEnvironmentVariablesにclaudeの場所を含むPATHを書きます。定時実行が初日に動かない原因の大半はここです。
launchctl load に続けてplistのパスを打てば登録完了です。launchctl start にジョブ名を渡すと定時を待たずに即時実行できるので、記録先のファイルに開始行と結論行が書かれることを確認してから、翌朝の定時に任せます。

設定作業はここまでです。難しさは設定そのものではなく、次の節の「無人でも壊れない作りにする」側にあります。
無人実行を壊す3つの落とし穴と守り方
僕の実ログに実際に痕跡が残っている順に、3つ挙げます。
落とし穴1: 二重起動
前の便の処理が長引いたまま次の便の時刻が来る。あるいは手動テストと定時便が重なる。無人実行では誰も画面を見ていないので、同じ記事を2本作ったり、2つの処理が同じ台帳ファイルを同時に書いて壊したりします。
守り方は.lockファイル(実行中の目印として置く空ファイル)です。僕のワークフローは開始時に.lockの有無を確認し、存在してタイムスタンプが2時間以内なら「先客がいる」と判断して中断、正常終了時に削除します。2時間を超えた.lockは前回の異常終了の残骸とみなして上書きするので、ロックが永久に残って全便止まる事故も防げます。
落とし穴2: 再実行による二重生成
launchdはスリープ復帰時の追い実行や予備便の設計で、想定より多く走ることがあります。これを異常と捉えず、何回走っても結果が変わらない「冪等」(べきとう)な作りを前提にするのが守り方です。
僕の記事便は、開始直後に当日分の成果物フォルダを数え、既に2本あればSKIPと1行書いて即終了します。PDF便は台帳の最終制作日で同じ判定をします。だから1日4回起動しても記事は2本しか生まれません。「走る回数」と「作る本数」を分離して、本数の上限は成果物側で数える。これが冪等スキップの実装です。
落とし穴3: 環境差と「exit 0の罠」
1つ目の環境差は手順3のPATH問題です。手動では動くのにlaunchdからは動かない場合、まずここを疑ってください。
2つ目が根深くて、exit 0(プロセスが正常終了したことを示すコード)を成功と見なすことです。僕は実際に、生成が途中で打ち切られたのにexit 0が返り、ログ上は成功に見える事故を経験しました。それ以来、スクリプトにはこの原則で検証を入れています。
成功の定義は「exit 0」ではなく「今日の記事が本番URLで公開されている」。スクリプトの最後に、公開URLが200を返しsitemapに載っていることを実測してからdoneと書く。
成功はプロセスの終了コードではなく、成果物の実在で判定する。無人実行の信頼性は、この1行の検証があるかどうかで決まります。

止まったことに気づく仕組みはどう作るか
無人実行の最後の課題は、止まったときに誰も見ていないことです。僕は3層で受けています。
ログは「1系統1ファイル・1回1行の結論」
plistのStandardOutPathで生の出力を残しつつ、スクリプト自身が開始・SKIP・done・FAILEDの結論行を日本時間のタイムスタンプ付きで1行追記します。結論行だけ拾い読みすれば、その週の運行が数秒で確認できる形です。
失敗したらmacOS通知を出す
スクリプトの失敗分岐に、osascriptのdisplay notification(Macの画面右上に出る標準の通知)を1行入れます。追加ツールなしで「静かに死なない」仕組みが作れます。
実例を挙げると、2026年8月7日から8日にかけて、サイト側の不具合で記事便が4回連続FAILEDになったことがあります。ログに4行の失敗が残り、都度通知が飛ぶので、失敗が沈黙のまま積み上がることはありませんでした。応用として、僕は「企画の在庫が4本を切ったら警告」も入れています。止まる前に気づくための通知です。
最後は週次で人間が見る
月曜朝の週次計測便が、成功も失敗も含めた1週間の実測をレポートにまとめ、公開された成果物は24時間以内に人間がレビューする運用にしています。自動化の最後の砦は、通知でも監視ツールでもなく「人間が定期的に見る場所を1つ決めておくこと」です。
スリープ中は起動しません。ただしlaunchdの時刻指定は、スリープ中に過ぎた予定を覚えていて、スリープ解除時に実行してくれます(cronはその回を飛ばします)。確実に走らせたいなら、電源接続時にスリープしない設定にするか、自分がMacを使っている時間帯に予定を置くのが現実的です。
どちらも時刻指定の自動実行ですが、macOSの公式な仕組みはlaunchdで、スリープ後の追い実行、ログ出力先の指定、環境変数の宣言までを設定ファイル1枚で完結できます。Macで新しく組むならlaunchdを選べば問題ありません。
launchdはターミナルのPATH設定を引き継がないためです。plistのEnvironmentVariablesにPATHを明示し、claudeのインストール先を含めてください。ターミナルで which claude を実行すると実際の場所を確認できます。
launchdはmacOS専用ですが、Windows標準のタスクスケジューラで同じ考え方がそのまま使えます。押さえる点は共通で、時刻起動・ログの追記・二重起動の防止・成果物での成功判定の4つです。
launchd自体はmacOSの標準機能なので追加費用はゼロです。かかるのはClaude Code側の利用枠だけで、同じ作業を手動でやる場合と変わりません。定時実行にすると走る回数が一定になるので、使用量の見積もりはむしろ立てやすくなります。
まとめ。定時実行は「時刻設定」ではなく「壊れない運用」の設計
launchdでClaude Codeを毎朝走らせる要点を整理します。
Macの定時実行はlaunchd一択。plistに時刻・スクリプト・ログ先・PATHの4点を書いて登録する
二重起動は.lockで、二重生成は冪等スキップで防ぐ。走る回数と作る本数を分離する
成功はexit 0でなく成果物の実在で判定し、失敗はmacOS通知とログの結論行で拾う
最後の砦として、人間が定期的に見る場所を1つ決めておく
この記事は「定時に走らせる器」の話に絞りました。器の中で何を走らせるかは、実例ごとに別記事に分けています。毎朝のリサーチを自動化した中身はこちらです。
関連記事Claude Codeに毎朝のリサーチを任せる仕組みの作り方毎朝9時にClaude Codeが追跡リストを巡回し、「今日の動き」を1枚に合成して通知する——2026年6月から無人で回り続けている僕の実運用をもとに、リサーチ自動化を組む5ステップと続けるための設計を解説します。週次のレポート自動化はClaude CodeでGSC/GA4の週次レポートを自動化、このブログ全体の無人運行と止まった記録はブログ記事をAIで自動化した仕組みと、4日止まった話にまとめています。
定時実行に載せる業務を決めるところから始めたい方向けに、自社の業務をAIに任せる候補として棚卸しするワークシートを無料公開しています。まず「毎朝何を走らせるか」を決める材料にしてください。
この記事が役に立ったらシェア
Related


