Claude Codeをスクリプト・CIでclaude -p経由で回している人向け
CIやcronで機密情報を含むプロンプトをClaude Codeに渡す場面で、ローカルのjsonl履歴に痕跡を残したくない時に使う。具体的には『料理ブログの自動下書きを毎日CIで動かす』で在庫データを渡す、本番DB接続情報を一回限り分析させる、共有Linuxサーバーで他人に会話を覗かれたくない、の3パターンで claude -p --no-session-persistence の形でつける。対話モードでは効かないので、その場合は CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 の設定値版に切り替える。
毎日CIで Claude Code を claude -p 経由で回していると、叩いた中身が ~/.claude/projects/ の下に jsonl として全部残ります。普段はそれが便利な履歴になりますが、本番DBの接続情報を一回限り渡したい時や、共有マシンで他の人にも見られる場所で動かす時は、その jsonl 自体を作らせたくない。--no-session-persistence はその「今回の1回だけ、ディスクに書かないで」を指示する起動スイッチです。
言い換えると、印刷モードで Claude Code を呼ぶ時だけ効く「履歴OFFスイッチ」です。普段の対話モードでは効きません。ここを勘違いすると静かに残り続けます。
噛み砕くと
普段の Claude Code は、会話の中身をパソコンの中の決まった場所に jsonl ファイルとして自動で書き出しています。あとで claude --resume で「あの時の続きから」をやれるのは、この jsonl が残ってるからです。
--no-session-persistence は、その自動保存だけを今回の1回限り止めるスイッチです。会話の中身は実行中だけ Claude Code のメモリに乗って、コマンドが終わると同時に消えます。スーパーのレシートを「今回はもらわない」と言ってるイメージに近い。買い物は普通にできますが、後から見返す手段はなくなります。
これがあるおかげで、CIや自動化で機密情報を含む1回限りの質問を投げても、jsonl の中に痕跡を残さずに済みます。
大事な前提:このスイッチは「印刷モードの時だけ」効く
公式の説明にもはっきり「Print mode only」と書いてあります。対話画面を開いて使う普段の claude 単独起動で --no-session-persistence をつけても、効きません。jsonl はいつも通り保存されます。
つまりこのスイッチは、claude -p "質問" の形でスクリプトから呼ぶ時専用です。対話モードで履歴OFFにしたい場合は、後で出てくる CLAUDE_CODE_SKIP_PROMPT_HISTORY という別の手段を使います。ここの使い分けが落とし穴の中心です。
「料理ブログの自動下書きを毎日CIで動かす」を例に、実際の動きを見る
毎朝6時に、社内DBから昨日の食材在庫を取ってきて、それを Claude Code に渡して「今日のおすすめレシピ記事の下書きを書いて」と頼む自動化を組んでいるとします。スクリプトは GitHub Actions で回す。在庫データには社内の仕入れ単価や取引先情報が含まれていて、jsonl に残したくない。
ステップ1: 普段の書き方だと履歴が全部残る
最初に書きそうな素朴な形はこれです。
$ claude -p "次の食材在庫から、今日のレシピ記事の下書きを書いて: $(cat stock.json)"
これだと ~/.claude/projects/<プロジェクトID>/<UUID>.jsonl の中に、stock.json の中身が仕入れ単価込みで丸ごと残ります。GitHub Actions のランナーは使い捨てだから問題ない、と思いがちですが、ランナーが使い回し領域を残す設定だと jsonl が次回に持ち越されることもある。これは怖い。
ステップ2: --no-session-persistence をつける
1単語追加するだけです。
$ claude -p --no-session-persistence "次の食材在庫から、今日のレシピ記事の下書きを書いて: $(cat stock.json)"
これで jsonl は作られません。Claude Code は質問を受け取り、答えを画面に印字し、その瞬間に会話の中身を捨てて終了します。GitHub Actions のログには Claude Code が返した記事下書きだけが残り、入力した在庫データはどこにも保存されません。GitHub Actions のログ側に明示的に出さない限り、外には漏れない。
ステップ3: 出力だけはちゃんと拾う
jsonl が残らないので、後から「あの日 Claude Code に何を聞いたっけ」を見返す手段は無くなります。だからCI側で、Claude Code の標準出力(画面に出た答え)をファイルに保存しておく運用が必須です。
$ claude -p --no-session-persistence "..." > today-draft.md
こうしておけば、結果の下書きだけはCIアーティファクトとして残せます。入力(機密含む)は残らない、出力(公開予定の下書き)は残る、という切り分けが成立する。
ステップ4: ここで初心者がやりがちな勘違い
同じプロンプトを今度は対話モードで試したくなって、こう打ってしまう。
$ claude --no-session-persistence
> 次の食材在庫から…
これは効きません。対話モードで起動した瞬間に、いつもの jsonl が作られ始めます。「--no-session-persistence をつけたから安心」と思って機密を貼り付けると、しっかり jsonl に残ります。対話モードで履歴を止めたい場合は、次のステップで出てくる別の手段を使います。
ステップ5: 対話モードでも履歴を止めたい時は設定値版を使う
同じ「履歴OFF」を対話モードでもやりたい場合、Claude Code は CLAUDE_CODE_SKIP_PROMPT_HISTORY という設定値を見ています。これを 1 にしておくと、印刷モード・対話モード問わず jsonl への保存が止まります。
$ CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 claude
> 機密情報を含む質問…
頭につけて1回だけ有効にする形だと、その実行だけが履歴OFF、次に普通に claude を叩いた時は通常通り保存されます。CIスクリプトの先頭で export しておくのもアリです。
ステップ6: 公式ドキュメントの記述
公式の CLI リファレンスにはこう書かれています。
Disable session persistence so sessions are not saved to disk and cannot be resumed. Print mode only. The CLAUDE_CODE_SKIP_PROMPT_HISTORY environment variable does the same in any mode
太字でまとめると、ディスクに保存しない、後から再開もできない、印刷モード専用、任意モードで同じことをやりたいなら設定値版を使え。この4点に集約されます。
つまり --no-session-persistence は何をしてくれるのか
- やってくれる: 印刷モードで叩いた1回分の会話を、jsonl としてディスクに書かない。実行中だけメモリに乗って、終了と同時に消える
- やってくれない: 対話モードで叩いた時の履歴OFF。標準出力の自動隠蔽。Claude Code が Anthropic のAPIに送る通信内容の遮断。あくまでローカルへの保存を止めるだけで、ネットワーク遮断とは別物
- 意味が薄い場面: 普段の個人開発で、過去の会話を
--resumeや--continueで呼び戻したい時。むしろつけてはいけない。「あの日の Claude Code に聞いた内容」を呼び戻せなくなる
使いどころ3シナリオ
シナリオ1: cron で毎日深夜2時に Claude Code を回す自動投稿バッチ
料理ブログの自動下書きCIがまさにこれ。社内DBの在庫情報・売上情報を毎日 Claude Code に渡して記事下書きを生成、WordPress にPOSTする一連の流れを cron で組む。jsonl が日々溜まると、社内データを含む履歴が共有サーバー上に積み上がります。claude -p --no-session-persistence を使えば、毎晩のバッチ実行で機密データが履歴に残らない。出力下書きだけ > today-draft.md でファイルに落として WordPress に送る、で完結します。
シナリオ2: 本番DBの接続文字列を一回限り渡して Claude Code に分析させる
本番のPostgreSQLに接続して、特定テーブルのスキーマ崩壊原因を Claude Code に1回だけ調べさせたい。接続文字列にはログイン用の秘密文字列が含まれていて、jsonl にプレーンテキストで残るのは事故案件です。claude -p --no-session-persistence "次のDB情報を見て、users テーブルの…" で1回叩いて、結果を見て終わる。jsonl は作られないので、後から「あの本番DBの接続情報、どこに残ってたっけ」と探し回る心配がない。
シナリオ3: 他の人と共有しているマシンで Claude Code を使う
社内の共有Linuxサーバー、本番運用用のEC2インスタンス、SSH先の検証マシン。~/.claude/projects/ の中身は、そのマシンにログインできる人なら誰でも読めてしまうリスクがあります。デフォルトでは自分のホームディレクトリ配下なので、root と自分は読めるのが原則です。共有マシンで claude -p を叩く時は、--no-session-persistence をデフォルトでつける運用にしておくと、他人に会話を覗かれるリスクが下がります。
初心者が踏みやすい落とし穴
- 対話モードでつけても無効。
claude --no-session-persistence単独はエラーにこそならないものの、jsonl への保存は止まりません。「印刷モードの時だけ」と公式が明記しているのを見落とすパターンの定番 - jsonl が残らないので後から見返せない。「あの日 Claude Code に何を聞いたっけ」を
--resumeで呼び戻したくても、保存されていないので無理。CI側の標準出力ログを別途保存しておく運用が必須 --resumeや--continueとの同時指定は破綻する。再開元のセッションを作らない設定なので、過去を呼び戻すスイッチと組み合わせても、呼び戻す先が存在しない--fork-sessionの元としても使えない。--fork-sessionは既存のセッション履歴を分岐させる仕組みなので、そもそも履歴を残さない--no-session-persistenceとは噛み合わない--session-idを併用しても resume できない。「セッションIDは指定したから後で復元できるはず」と思いがちですが、ディスクに保存していないので、IDだけでは何も呼び戻せない- 対話モードで履歴OFFしたい時に
--no-session-persistenceを使い続ける。これは設計違い。CLAUDE_CODE_SKIP_PROMPT_HISTORY=1という設定値版が用意されていて、そちらは対話モード・印刷モードどちらでも効きます。使い分けを覚えるのが正解 - Anthropic 側に送らない設定だと勘違いする。これはあくまで自分のパソコン内の jsonl 保存を止めるスイッチで、Anthropic の API には通常通り会話の中身が送られます。ネットワーク遮断とは別物
書き方
claude -p --no-session-persistence "質問内容"
やってみるとこうなる
入力
claude -p --no-session-persistence "次の食材在庫から、今日のレシピ記事の下書きを書いて: $(cat stock.json)"
出力例
(Claude Codeが下書き本文を画面に印字して終了。~/.claude/projects/配下にjsonlファイルは作られない。同じ内容を後から --resume で呼び戻すことはできない。出力だけを残したい場合は > today-draft.md などで標準出力をファイルに保存する運用にする)
このページに出てきた言葉
- 印刷モード
- <code>-p</code> または <code>--print</code> をつけて Claude Code を呼ぶ使い方。対話画面を開かずに1回だけ質問を投げ、答えを画面に印字して終わる。CIや自動化スクリプトから呼ぶのが主用途
- jsonl
- 1行に1個のJSONデータを書いたファイル形式。Claude Codeのセッション履歴はこの形式で <code>~/.claude/projects/<プロジェクトID>/<UUID>.jsonl</code> に保存される
- session persistence
- Claude Codeが会話の中身を自動でディスクに書き出して、後から <code>--resume</code> や <code>--continue</code> で復元できるようにする仕組み
- CLAUDE_CODE_SKIP_PROMPT_HISTORY
- パソコンが起動時に覚えてる設定値の1つ。<code>1</code> にすると Claude Code が jsonl を作らなくなる。<code>--no-session-persistence</code> と違い対話モードでも効くのが特徴
- CI
- 決まった作業を決まったタイミングで自動実行する仕組み。GitHub Actions・cron・社内Jenkinsなどが代表
- UUID
- 世界で1つしかないことを保証されたランダム識別子。Claude Codeは1セッションごとにこれを振ってjsonlファイル名にする