Claude Code設定が反映されない原因の探し方 — 配置・書式のよくある見落とし
hooksが発火しない、MCPサーバーが繋がらない。原因の多くはファイルの置き場所か書式の細部にあります。/contextから辿る切り分け手順をまとめます。
設定が反映されない原因は2つに絞れる
CLAUDE.mdの指示が無視される、hooksが発火しない、追加したはずの機能が現れない。この手の症状は、設定ファイルが読み込まれていないか、読み込まれてはいるが別のファイルに上書きされているかのどちらかがほとんどです。原因を推測で決め打ちせず、Claude Codeが実際に何を読み込んだかを先に確認すると、切り分けの時間が大きく縮みます。
まず/contextで実際に読み込まれた内容を確認する
/contextは、現在のセッションでコンテキストウィンドウを占めている内容をカテゴリ別に表示します。システムプロンプト・システムツール・MCPツール・カスタムサブエージェント(読み込み元も表示)・メモリファイル・スキル・会話メッセージが対象です。CLAUDE.mdやスキルが本当に読み込まれているかは、まずここで確認します。バンドル済みスキル(/skillsには出ない標準搭載スキル)も/context側には表示されます。
より詳しく特定のカテゴリを見たい場合は、専用コマンドに進みます。
| コマンド | 表示内容 |
|---|---|
/memory | 表示内容ユーザー・プロジェクトスコープのメモリファイルの場所 |
/skills | 表示内容プロジェクト・ユーザー・プラグイン由来の利用可能なスキル |
/hooks | 表示内容現在有効なhook設定 |
/mcp | 表示内容接続中のMCPサーバーとその状態 |
/permissions | 表示内容現在有効な許可・拒否ルール |
/doctor | 表示内容インストール状態・不正な設定ファイル・重複サブエージェント名などの点検 |
/status | 表示内容有効な設定ソース(managed設定が効いているかを含む) |
/contextの一覧にメモリファイルが出ない場合は、CLAUDE.mdの読み込みルールとファイルの場所を照合します。読み込まれていることが確認できたのに特定の指示だけ無視される場合は、読み込みの問題ではなく指示の書き方の問題です。曖昧で複数の解釈ができる表現、2つのファイルが矛盾する方針を書いている、ファイル自体が長くなりすぎて個々のルールへの注意が薄まっている、のいずれかが典型的な原因です。新しいチームメンバーに口頭で伝えるつもりで、プロジェクトの規約やビルドコマンド、ファイルの置き場所を具体的に書くと遵守率が上がります。
CLAUDE.mdが読み込まれない典型パターン
サブディレクトリに置いたCLAUDE.mdは、セッション開始時には読み込まれません。Claude CodeがReadツールでそのディレクトリ内のファイルを読んだタイミングで、初めて読み込まれます。ファイルを作成・編集しただけでは発火しないので、「サブディレクトリのCLAUDE.mdが無視される」と感じたら、まずそのディレクトリのファイルをReadツール経由で開かせてみます。
もう1つの見落としが、組み込みのExploreサブエージェントとPlanサブエージェントです。これらはCLAUDE.mdを読み込みません。メインの会話や、自分で定義したカスタムサブエージェントは通常どおり読み込みます。ExploreやPlanに重要な指示を守らせたい場合は、CLAUDE.mdではなく委任するプロンプト自体にその指示を書き込む必要があります。カスタムサブエージェントの場合は、エージェント定義ファイルの本文(システムプロンプトになる部分)に重要な指示を置きます。
hooksが登録されているのに発火しない
/hooksに一覧が出ない場合、そもそも設定ファイルが読み込まれていません。hooksは独立したファイルではなく、settings.jsonの"hooks"キー直下に書く必要があります。プラグインだけは例外で、hooks/hooks.jsonという別ファイルから読み込まれます。
/hooksに出ているのに発火しない場合、原因の大半はmatcherフィールドの書き方です。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "./format.sh" }]
}
]
}
}matcherは単一の文字列で、複数のツール名は|区切りで指定します。,区切りも同等に動きますが、v2.1.191より前のバージョンでは,は正規表現の文字として文字通り評価され、一切マッチしません。バージョンが古い場合は|を使いますmatcherはツール名と大文字小文字まで一致させる必要があります。bashではなくBash、editではなくEditですmatcherが配列になっているのはスキーマエラーです。この場合Claude Codeは設定エラーの通知を出し、そのファイル(user/project/local)全体を拒否します。managed設定の場合はファイル全体ではなくhooksキーだけが落とされ、他の設定は生きたままになります。いずれもclaude doctorが原因を報告します
settings.jsonへの編集は、保存後に短いファイル安定性の遅延を経てセッションに反映されます。セッションの再起動は不要です。数秒待っても/hooksが古い定義のままなら、もう一度/hooksを実行して表示を更新します。それでも発火しない場合はclaude --debugでセッションを起動し、hook評価のたびにどのmatcherが照合され、実際の終了コードが何だったかをデバッグログで確認します。
MCPサーバーが設定通りに動かない
/mcpで接続状態と承認状況を確認します。設定自体は正しくてもツールが出てこないケースには、いくつか典型パターンがあります。
- プロジェクトスコープのサーバーは
.mcp.jsonに定義しますが、初回は承認が必要です。承認プロンプトを閉じてしまうと、/mcpから手動で承認するまで無効のままです - 起動に失敗したサーバーは
/mcpで失敗と表示されます。commandやargsに相対パスを使っていることが多い原因で、パスは.mcp.jsonの場所ではなくClaude Codeを起動したディレクトリ基準で解決されます - 接続済みと表示されるのにツールが0件のサーバーは、起動はしているがツール一覧を返していない状態です。
/mcpから再接続を試し、それでも0件のままならclaude --debug=mcpを実行し、~/.claude/debug/<session-id>.txtのサーバー側stderrを確認します
配置場所の間違いも頻出です。プロジェクトのMCP設定は.claude/配下ではなくリポジトリ直下の.mcp.jsonに置き、キーはmcpServersにします。VS Codeのmcp.jsonのようにトップレベルキーがserversになっていたり、.mcp.jsonを.claude/配下に置いてしまうと読み込まれません。同様に、settings.jsonにmcpServersキーを書いても読み込まれません。プロジェクトサーバーは.mcp.json、ユーザースコープのサーバーはclaude mcp add --scope userで登録します。
サーバーは起動しているのに、そのサーバーが期待する環境変数を受け取っていないケースもあります。Claude Codeがstdioサーバーへ渡す環境は、自分自身の環境から一部の変数を除いたものであり、起動時のシェル環境やワークスペースの信頼設定には依存しません。サーバーが必要とする環境変数は、.mcp.jsonのそのサーバーのエントリ内にenvとして個別に書く必要があります。
設定ファイルの置き場所を間違えやすい2パターン
グローバルな権限・hooks・環境変数を設定したつもりで反映されないとき、よくある原因は~/.claude.jsonへの書き込みです。
もう1つは、settings.local.jsonによる上書きです。優先順位はlocalがprojectを上書きし、projectがuserを上書きします。managed設定がある場合は最優先で適用されます。「settings.jsonに書いたのに効かない」ときは、同じキーがsettings.local.jsonに別の値で存在していないかを確認します。
スキルが/skillsに出ない・呼ばれない
スキルファイルを.claude/skills/name.mdのように単体で置くと認識されません。.claude/skills/name/SKILL.mdというフォルダ構成が必須です。
/skillsには表示されているのにClaudeが自発的に呼ばない場合は、フロントマターのdisable-model-invocation: trueが原因か、descriptionの言い回しが実際のリクエストの言い方と噛み合っていないかのどちらかです。/skillsのバッジ表示で「user-only」となっているスキルは、Claudeが自分の判断で呼び出すことはありません。
permissionsのdenyルールが効かないことがある
Bash(rm *)のようなdenyルールは、実行される実体のコマンドではなくコマンド文字列そのものにマッチします。そのため/bin/rmのようにパスを直接指定する呼び出しや、find . -deleteのような別コマンド経由の削除はすり抜けます。確実に止めたい操作がある場合は、denyルールの文字列パターンをバリエーションごとに追加するか、PreToolUse hookやサンドボックスで実行そのものを止める設計にします。
それでも直らないときは消去法に切り替える
ここまでの個別チェックで見つからない場合、次は原因を絞り込むのではなくすべてを一旦無効化してから戻すアプローチに切り替えます。claude --safe-modeとクリーンなCLAUDE_CONFIG_DIRでの起動比較による切り分け手順は、Claude Code safe modeで「壊れた」設定を1コマンドで切り分けるにまとめています。設定ファイルの各フィールドの意味そのものを確認したい場合は、Claude Code設定ガイドのフィールド一覧が網羅的です。
よくある質問
SessionEnd hookが実行されません
SessionEndイベントのhookは、明示的にsettings.jsonへ登録しないと動きません。PreToolUseやPostToolUseのhookを設定していても、SessionEndは別イベントとして個別に登録が必要です。
/statusと/doctorは何が違いますか
/statusは現在有効な設定ソース(user/project/local/managed)と、managed設定が効いているかどうかを表示します。/doctorはそれに加えて、不正な設定ファイル・未使用の拡張機能・同名のサブエージェントの重複などを点検し、修正案まで提示します。ターミナルからclaude doctorを実行すると、セッションを開始せずに読み取り専用の診断だけを実行できます。
環境変数で設定した値が反映されません
環境変数は設定の優先順位の中で、コマンドラインフラグと並ぶ別の上書き層として働きます。設定ファイルの値がそのまま使われていない場合、同じキーに対応する環境変数がシェルやCIの環境に残っていないかを確認します。
まとめ
設定が反映されないときは、まず/contextで実際に読み込まれた内容を確認します。多くの場合、原因はhooksのmatcherの書式、.mcp.jsonの置き場所、~/.claude.jsonとsettings.jsonの取り違え、settings.local.jsonによる上書きのいずれかです。個別の原因が見つからない場合は、safe modeとクリーンな設定ディレクトリでの消去法に切り替えます。