Claude Code の設定が3層から読まれていて、CI などで個人用設定を切り離したい人向け
CI で個人用の設定を一切混ぜたくない、他人の不具合を自分のパソコンで再現したい、OSS の初回起動で個人の攻めた設定を切り離したい、といった「設定の読み込み元を絞って再現性を上げたい」場面で、claude コマンドの後ろに --setting-sources project のように足して起動する
Claude Code の設定は、自分のホーム配下にある個人用の~/.claude/settings.jsonと、プロジェクト直下の共有用.claude/settings.jsonと、同じくプロジェクト直下だが個人ローカル用の.claude/settings.local.jsonの3層から読まれます。普段はこの3層が重なって動いていて、便利なのですが、CI で「個人の好みは一切混ぜたくない」「プロジェクト共有の設定だけで動かしたい」という場面で詰まります。
--setting-sourcesは、この3層のうちどれを読むかを起動時に指定できる起動時の指定です。claude --setting-sources projectと叩けば、共有用の1層だけが読まれて、個人用の2層は完全に無視されます。
噛み砕くと
例えるなら、新しい職場に出社したときに「持ってきたカバンの中身は全部ロッカーに置いてきてください、机の上にある社内マニュアルだけを見て今日は仕事してください」と言われるイメージです。
普段なら自分のカバン(個人用の設定)と、机の社内マニュアル(共有用の設定)と、机の引き出しに入れてる自分用メモ(個人ローカル用の設定)の3つを全部見ながら作業します。--setting-sources projectを付けると「机の社内マニュアルだけ見ていい」になります。残り2つは見えないので、自分の好みやクセは完全に消えます。CI(自動テスト環境)や、レビューで他人の環境を再現したいときに使います。
大事な前提:3層は普段「重なって」効いている
3層の設定は、普段は重ね塗りのように効きます。同じ項目が複数の層に書いてあったら、local が一番強く、次が project、一番弱いのが user です。下の層が上の層を上書きする形です。
--setting-sourcesを付けて読む層を絞ると、絞られた層に書いてない項目はそもそも存在しないことになるので、Claude Code のデフォルト動作に戻ります。「user 層に書いた便利設定が消えたぞ」と慌てないように、これは仕様として頭に入れておきます。
「CI で個人の好みを完全に消す」を実演する
題材は、チームで運用しているcooking-blogというプロジェクトを GitHub Actions で自動チェックする場面です。手元では便利に動いていた個人用の設定が、CI で予想外の挙動を引き起こすので、それを切り離します。
ステップ1: 3層の中身を確認する
まず自分のパソコンの3層に何が書いてあるか見ます。
$ cat ~/.claude/settings.json
{
"permissions": {
"allow": ["Bash(npm install)"]
},
"model": "claude-sonnet-4-5"
}
$ cat .claude/settings.json
{
"permissions": {
"allow": ["Bash(npm test)", "Read", "Edit"]
}
}
$ cat .claude/settings.local.json
{
"permissions": {
"allow": ["Bash(rm *)"]
}
}
個人用にはnpm installの自動許可と、モデル指定が入っています。共有用にはnpm testとReadとEditが入っています。個人ローカル用には、自分のテスト用にrm *を許可してあります。
ステップ2: 普段通り起動して挙動を確認する
$ claude
このとき Claude Code は3層全部を読みます。許可は3つ全部足し算されるので、npm installもnpm testもrm *も全部通ります。モデルは個人用に書いたclaude-sonnet-4-5で動きます。
ステップ3: 共有用だけで動かしてみる
CI で動かす想定なので、共有用の1層だけを読ませます。
$ claude --setting-sources project
これで読まれるのは.claude/settings.jsonだけ。許可はnpm testとReadとEditの3つに絞られ、rm *は通らなくなります。モデル指定も消えるのでデフォルトに戻ります。
ステップ4: 2つの層を組み合わせる
共有用と個人用を読みたいけど、個人ローカル用のrm *は無視したい場合は、カンマで並べます。
$ claude --setting-sources user,project
ここで初心者がやりがちな勘違いがあります。値と値の間に空白を入れない。--setting-sources user, projectとスペースを入れた書き方は公式の説明に出てきません。素直にuser,projectと詰めて書きます。
ステップ5: GitHub Actions に組み込む
CI 用の.github/workflows/claude-check.ymlに書く例です。
- name: Run Claude Code review
run: |
claude --setting-sources project \
--print "コードレビューしてください"
これで CI ジョブが走るたびに、共有用の.claude/settings.jsonだけが効いた状態でレビューが回ります。CI 環境には個人用の設定そのものが存在しないので、何が起きても再現性があります。
ステップ6: 読み込まれた層を確認するクセをつける
意図通りに絞れているかは、起動直後にちょっと挙動を見れば分かります。普段は通っていた操作が「許可が必要です」と聞かれたら、その許可は除外した層にしか書いていなかった、という判定になります。
つまり --setting-sources は何をしてくれるのか
- やってくれる: 3層のうちどれを読むかを起動時に絞る。指定しなかった層は完全に無視される
- やってくれる: 個人用設定を切り離して CI やレビューで再現性のある環境を作る
- やってくれない: 設定ファイル自体の中身は書き換えない。読むか読まないかを切り替えるだけ
- やってくれない: 特定のファイル名を直接指定すること(それは別系統の起動時指定でやる)
- 意味が薄い場面: 個人開発で1人しか触らないプロジェクト。3層に同じことしか書いていないなら絞っても挙動は変わらない
使いどころ3シナリオ
シナリオ1: GitHub Actions で自動コードレビューを回すとき
チームで運用しているcooking-blogに PR が来るたびに Claude Code に差分レビューを走らせる構成にしました。最初はclaude --print "レビューして"とだけ書いていたのですが、CI ランナー側に Claude Code 用のホームフォルダが残っていて、過去のテストで作った許可設定が読み込まれていました。--setting-sources projectを付けたら、レビュー結果が毎回同じになり、レビュー漏れの再現調査もしやすくなりました。
シナリオ2: 他人の不具合を自分のパソコンで再現したいとき
同僚から「Claude Code が突然npm run buildを勝手に叩いて困る」と相談されました。同僚のプロジェクトをgit cloneして開きます。普段なら自分の個人用設定と個人ローカル用が混ざってしまい、原因が共有用にあるのか個人用にあるのか分かりません。claude --setting-sources projectで起動して再現すれば、共有された.claude/settings.jsonに犯人がいると一発で切り分けられます。
シナリオ3: OSS にコントリビュートする初回の起動
git cloneしてきた直後の OSS で、自分の個人用設定が予期せぬ動きをしないか不安なときに使います。例えば自分は普段~/.claude/settings.jsonで"autoApprove": trueのような攻めた設定を入れていて、OSS のスクリプトを Claude Code がガンガン実行してしまうと困ります。claude --setting-sources projectで立ち上げれば、OSS 側が用意した.claude/settings.jsonだけが効く状態になります。これは安心です。
初心者が踏みやすい落とし穴
- 値の間に空白を入れる。
user, projectのようにスペースを入れた書き方は公式の例に出てきません。詰めてuser,projectと書きます - 「設定ファイルを書き換える指定」だと思い込む。これは読むか読まないかの切り替えで、ファイルの中身は1文字も変えません
- 絞った後に「設定が消えた」と慌てる。絞られた層に書かれていない項目は、デフォルト動作に戻るだけです。バグではありません
- local だけ指定して project を外す。
--setting-sources localと書くと、共有用の.claude/settings.jsonが読まれません。チームで決めた共有ルールが効かなくなるので、CI 用途以外でこれを単独指定する場面はほぼないです - 3層と「
--settingsで特定ファイルを直接指定する別系統」を混ぜる。--setting-sourcesは層単位、--settingsはファイル単位。役割が違うので混同しないように - 許可の足し算が消えたことに気づかず暴走させる。3層全部読んでた時の感覚で「自動で許可される範囲」を覚えていると、絞った直後に確認プロンプトが頻発します。これは絞ったからこその正しい挙動です
- CI でモデル指定が外れていることを見落とす。個人用にだけ
"model": "claude-sonnet-4-5"と書いていた場合、--setting-sources projectで起動するとデフォルトモデルに戻ります。共有用にもモデル指定を書いておくか、CI 側で別途指定します
書き方
claude --setting-sources <層名>[,<層名>...]
値は user / project / local のいずれか、または複数を半角コンマで詰めて並べる(間に空白なし)
やってみるとこうなる
入力
claude --setting-sources user,project
出力例
起動時に ~/.claude/settings.json(個人用)と <プロジェクト直下>/.claude/settings.json(共有用)の2層だけが読まれた状態で Claude Code が立ち上がる。<プロジェクト直下>/.claude/settings.local.json(個人ローカル用)に書いてある設定は完全に無視される。指定しなかった層にしか書いていない項目は、Claude Code のデフォルト動作に戻る。
このページに出てきた言葉
- CI
- Continuous Integration の略。GitHub などにコードを上げたときに、自動でテストやチェックを走らせてくれる仕組み。代表例は GitHub Actions
- user 層
- 個人用の設定。<code>~/.claude/settings.json</code> に書く。自分のパソコンで動かす Claude Code 全体に効く
- project 層
- 共有用の設定。プロジェクト直下の <code>.claude/settings.json</code> に書く。Git に入れてチーム全員で共有する
- local 層
- 個人ローカル用の設定。プロジェクト直下の <code>.claude/settings.local.json</code> に書く。自分のパソコン内のこのプロジェクトだけに効き、Git には入らない
- permissions の allow
- Claude Code に「この操作は確認なしで実行していい」と前もって登録しておく一覧。<code>Bash(npm test)</code> のような書き方で個別操作を許可する
- GitHub Actions
- GitHub にコードを上げたときに自動でテストやチェックを走らせる仕組み。<code>.github/workflows/</code> に YAML ファイルを置くと動く