Claude Media
strictPluginOnlyCustomizationでskillsやhooksをプラグインに絞る

strictPluginOnlyCustomizationでskillsやhooksをプラグインに絞る

strictPluginOnlyCustomizationは、skills・agents・hooks・MCPの4面を管理設定でロックし、ユーザーとプロジェクト由来を読まなくします。遮断範囲と書き方、許可リストとの併用を解説します。

strictPluginOnlyCustomizationとは

strictPluginOnlyCustomizationは、skills・agents・hooks・MCPサーバーの4つを、プラグインと管理設定からしか読み込まなくする設定キーです。ユーザーのホームディレクトリにも、プロジェクトのリポジトリにも、これらの拡張を置けなくなります。

スコープはManagedだけです。managed-settings.json、MDM、サーバー管理設定のいずれかで配布したときに効きます。既定は未設定で、何もロックされません。

値の書き方は2通りあります。

  • true: 4面すべてをロックする
  • 配列: "skills" "agents" "hooks" "mcp" のうちロックしたい面だけを名前で並べる

skillsとhooksだけをロックし、agentsとMCPは従来どおりにする例は次のとおりです。

{
  "strictPluginOnlyCustomization": ["skills", "hooks"]
}

公式の設定リファレンスは、strictPluginOnlyCustomization.skillsのようなサブキーも索引に並べています。ただし型の欄が示すとおり、実体は独立したキーではありません。上の配列に入れる文字列です。

4面はそれぞれ何を止めて、何を残すか

ロックの中身は面ごとに違います。ここを取り違えると、ロックしたつもりで抜け道が残ります。

面読まなくなるもの読み込みが続くもの
skills読まなくなるもの~/.claude/skills/、.claude/skills/、~/.claude/commands/、.claude/commands/、--add-dir配下のskills、claude.aiアカウントから同期されたskills読み込みが続くものプラグインのskills、同梱skills、管理ポリシーディレクトリのskills
agents読まなくなるもの~/.claude/agents/、.claude/agents/読み込みが続くものプラグインのagents、組み込みagents、管理ポリシーディレクトリのagents
hooks読まなくなるものユーザー・プロジェクト・ローカルのsettings.jsonのhooks読み込みが続くものプラグインのhooks、管理設定のhooks
mcp読まなくなるもの~/.claude.jsonと.mcp.jsonのMCPサーバー読み込みが続くものプラグインのMCPサーバー、managed-mcp.jsonのサーバー、managedMcpServersのサーバー

skillsは同期分と旧コマンドまで止まる

skillsのロックは範囲が広めです。.claude/commands/にある旧来のカスタムコマンドも、--add-dirで追加したディレクトリのskillsも読まれなくなります。claude.aiのアカウントで同期していたskillsも対象です。

個人が手元で作ったskillが突然使えなくなる、という問い合わせの多くはここに当たります。ロックの前に、社内で使われているskillをプラグインへ移す作業が要ります。移行の流れはClaude Codeプラグイン化の移行手順にまとめています。

hooksはsettings.jsonの3スコープが対象

hooksのロックが止めるのは、ユーザー・プロジェクト・ローカルのsettings.jsonに書かれたhookです。プラグインのhookと、管理設定に書いたhookは動き続けます。

mcpは.mcp.jsonとホームの設定が対象

MCPのロックで読まれなくなるのは、~/.claude.jsonと.mcp.jsonのサーバー定義です。プラグインが同梱するサーバー、managed-mcp.jsonのサーバー、管理設定のmanagedMcpServersから配るサーバーは残ります。managedMcpServersはv2.1.259以降の設定です。

allowManagedHooksOnlyとの違いは「プラグインを通すか」

hooksだけを見ると、既存のallowManagedHooksOnlyと役割が近く見えます。違いはプラグインの扱いです。

  • strictPluginOnlyCustomizationのhooks: 管理設定のhookに加えて、プラグインのhook全般が動く
  • allowManagedHooksOnly: 管理設定のhookと、管理設定のenabledPluginsで強制有効化したプラグインのhookだけが動く。それ以外のプラグインのhookは止まる

つまり、前者は「プラグインという配布経路そのもの」を信頼し、後者は「組織が名指ししたもの」だけを信頼します。プラグインの出所をstrictKnownMarketplacesで絞る前提なら前者で足ります。個々のプラグインまで組織が選びたいなら後者です。

allowManagedHooksOnlyは、hook以外にも影響が及びます。公式の設定リファレンスには次の挙動が書かれています。

  • commandソースのプラグインは、管理設定のenabledPluginsで強制有効化したものも含めて無効になる。disableCommandPluginSourcesを明示的にfalseにしたときだけ例外
  • マーケットプレイスのheadersHelperコマンドも、disableCommandPluginSourcesを明示的にfalseにしない限り止まる(v2.1.238以降)
  • ステータスラインとファイル候補(fileSuggestion)は、管理設定に書いたものだけが読まれる
  • hookに依存する/goalコマンドは、このキーがある間は実行できない

これらは連鎖的に止まる項目で、詳細はallowManagedHooksOnlyの解説にあります。一方、strictPluginOnlyCustomizationのhooksロックについては、ステータスラインや/goalへの影響は公式に明記されていません。hooksだけを絞りたい場合、こうした周辺の挙動まで巻き込むかどうかも、二つのキーを選ぶ材料になります。

strictKnownMarketplacesと組み合わせて供給網を閉じる

公式は、strictPluginOnlyCustomizationとstrictKnownMarketplacesを組み合わせて、拡張の供給網全体を制御することを想定しています。役割は次のように分かれます。

  • strictKnownMarketplaces: ユーザーが追加・インストールできるマーケットプレイスのソースを許可リストで絞る
  • strictPluginOnlyCustomization: プラグインと管理設定以外の経路を閉じる

片方だけでは穴が残ります。プラグインだけに絞っても、誰でも任意のマーケットプレイスからプラグインを入れられるなら、個人のskillを自作プラグインとして持ち込めます。逆に許可リストだけを敷いても、~/.claude/skills/に置いたskillはそのまま読まれます。

両方をmanaged-settings.jsonに書いた例です。ここでは自社のGitHub組織のマーケットプレイスだけを許可しています。

{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "acme-corp/plugins" }
  ],
  "extraKnownMarketplaces": {
    "acme-tools": {
      "source": { "source": "github", "repo": "acme-corp/plugins" }
    }
  },
  "strictPluginOnlyCustomization": true
}

extraKnownMarketplacesは、許可したマーケットプレイスを全員の環境に自動登録するための項目です。strictKnownMarketplacesだけだと、ユーザーが/plugin marketplace addで自分で足す手間が残ります。許可ソースの書式(githubのオーナーワイルドカードやhostPatternなど)はstrictKnownMarketplacesの書式解説に任せます。

MCPについて、許可リストと拒否リストで個別サーバーを管理する設計はManaged MCPの許可リスト解説にあります。mcpをロックするとユーザーとプロジェクトのサーバー定義が丸ごと読まれなくなるので、allowedMcpServersで個別に通す運用とは発想が違います。

未知の面の名前は無視される

配列に書いた面の名前が、そのクライアントの知らないものだった場合、Claude Codeは設定ファイル全体を失敗にせず、その名前だけを無視します。公式は、新しい面が追加されたときに、全クライアントの更新を待たずに名前だけ先に足せるようにするための挙動としています。

裏を返すと、名前の綴り間違いも黙って無視されます。"skill"と単数形で書いても、エラーは出ずにロックされないだけです。文字列を書いたら、対象マシンで実際に効いているかを確かめてください。確認手段は次の節に置きます。

反映の確認と、ロック前に見ておくこと

管理設定が読み込まれたかは、対象マシンのClaude Codeで/statusを実行し、Setting sourcesの行で確かめられます。

/status

ロックが効いているかの実地確認は、ユーザー側に~/.claude/skills/のテスト用skillを1つ置き、スラッシュコマンドの候補に出てこないことを見るのが手早い方法です。hooksならsettings.jsonに試験用のhookを書き、発火しないことを見ます。

導入前には次の点を洗い出しておくと、配布後の混乱が減ります。

  1. 各チームのskills・agents・hooksがどこにあるか。リポジトリの.claude/配下にあるものは、ロック後に読まれなくなる
  2. プラグインとして配り直す先のマーケットプレイスを用意できているか
  3. MCPサーバーを.mcp.jsonで運用しているチームが、プラグイン同梱かmanagedMcpServersへ移せるか
  4. 移行の間は、ロックする面を絞って段階的に広げられるか(配列指定で面ごとに切り替えられる)

4番目の段階導入は、配列に面を1つずつ足していく形で進められます。順序は一例ですが、次の流れが考えられます。

  1. ["skills"]から始める。個人のskillや旧commands/が使えなくなるので、プラグイン化済みのskillが問題なく呼べるかを、代表的なチームの環境で確かめる
  2. ["skills", "hooks"]に広げる。各リポジトリのsettings.jsonにあるhookが発火しなくなるため、保護用のhookを管理設定かプラグインに移せているかを見る
  3. "agents"を足す。.claude/agents/のサブエージェントが読まれなくなるので、プラグイン側に同名の定義があるかを確認する
  4. 最後に"mcp"を足す。.mcp.jsonのサーバーが消えるため、managedMcpServersかプラグイン同梱へ移せていない接続がないかを洗い出す
  5. 全面で問題がなければtrueに切り替える。面の名前の綴り間違いが黙って無視される点があるので、各段階で試験用のskillやhookを使った実地確認を挟む

skillsとMCPとサブエージェントとhooksの役割の違いを先に押さえたい場合はClaude Code SkillsとMCPの違いが参考になります。

ゲートウェイ配布では、親から渡ったこのキーをロックで止められない

Claude appsゲートウェイでは、ゲートウェイ(親)が配下のクライアントへ設定を渡します。管理側にはロックが5つ用意されていて、親から渡る値の多くはこれで遮断できますが、strictPluginOnlyCustomizationはその例外に挙がっています。親がこのキーを渡すと、どのロックを設定していてもフィルタを通過し、Claude Codeは開発者自身のカスタマイズを無視します。無視される中には、開発者が入れた保護用のhookも含まれます。公式は「どのロックもこれを止めない」と書いています。

ゲートウェイを使わない通常の配布では関係しない話です。ゲートウェイ配布の環境では、保護用のhookを開発者のsettings.jsonに置いたままにせず、管理設定またはプラグインの側に移しておく必要があります。hooksロックで止まるのは、通常の配布でも同じです。

まとめ

strictPluginOnlyCustomizationは、4面をまとめて、または面ごとに閉じる管理設定です。読み込みが続くのは、プラグイン・同梱物・管理設定・管理ポリシーディレクトリ(面によって組み合わせが違う)に限られます。

供給網としての意味を持たせるには、strictKnownMarketplacesとセットにして、プラグインの出所を絞ることが前提になります。ロックする前に、手元の.claude/配下と.mcp.jsonの棚卸しが必要です。面の名前は綴りを間違えても黙って無視されるため、/statusと試験用のskillやhookで、実際に効いていることを確認してください。

この記事を共有:XはてブLinkedIn