Claude Codeカスタムコマンドの作り方|Skills統合後の書き方と引数【2026年最新】
Claude Codeのカスタムコマンドは、繰り返し貼り付けている定型指示を /deploy のような1語で呼び出せるようにする仕組みです。2026年のアップデートでカスタムコマンドはスキル(Skills)へ統合され、公式ドキュメントも「Custom commands have been merged into skills」と明記しました。既存の .claude/commands/ のファイルは今も動きますが、これから作るなら書き方が変わります。本記事は公式仕様に沿って、作り方・引数の渡し方・スコープと優先順位・呼び出し制御までを整理します。
まとめ
- 統合された:
.claude/commands/deploy.mdと.claude/skills/deploy/SKILL.mdはどちらも/deployを作り、同じように動く。同名ならスキル側が優先される。 - これから作るならSKILL.md形式:付随ファイル(テンプレート・スクリプト・リファレンス)を同梱でき、Claudeに自動で呼ばせるかどうかもfrontmatterで制御できる。
- コマンド名はファイル名・ディレクトリ名で決まる。frontmatterの
nameは表示名であって、入力する名前ではない(プラグイン直下のSKILL.mdだけが例外)。 - 引数は
$ARGUMENTS/$0・$1。位置指定は0始まりで、$0が1つ目の引数。 - 置き場所でスコープが決まる:
~/.claude/skills/は全プロジェクト、.claude/skills/はそのリポジトリ(コミットすればチーム共有)。
以下、公式仕様の該当箇所を引きながら、実際に手を動かす順番で説明します。
2026年の変更点:カスタムコマンドはスキルに統合された
もっとも大きな変更は、カスタムコマンドとスキルが同じ仕組みになったことです。公式ドキュメント(Extend Claude with skills)は「Custom commands have been merged into skills.」と述べ、.claude/commands/deploy.md というファイルと .claude/skills/deploy/SKILL.md というスキルは、どちらも /deploy を作り同じように動作すると明記しています。既存の .claude/commands/ は引き続き動作し、frontmatterも同じものが使えます。
では何が違うのか。スキル形式で増えるのは次の3点です。付随ファイルを置けるディレクトリを持てること、呼び出し主体(あなたか、Claudeか)をfrontmatterで制御できること、そしてClaudeが関連する場面で自動的に読み込めることです。旧来のカスタムコマンドは「入力して呼ぶ」ものでしたが、スキルは説明文(description)が常時カタログに載り、Claudeが必要と判断したときに自分で引いてきます。Claude CodeのスキルはAgent Skillsのオープン標準に準拠し、Claude Code側が呼び出し制御・サブエージェント実行・動的コンテキスト注入を拡張として追加した形です。
同名が衝突したときの解決順も決まっています。エンタープライズ設定がパーソナルを上書きし、パーソナルがプロジェクトを上書きします。同名のスキルとコマンドが両方ある場合はスキルが勝ちます。スキルそのものの設計思想(SKILL.mdの書き方、claude.ai・API側での扱い)はClaude Skillsとは?SKILL.mdの書き方とclaude.ai・Claude Code・APIでの使い方で扱っているので、コマンドから一歩踏み込むならそちらを参照してください。
カスタムコマンドの作り方:commands形式とSKILL.md形式
最短:.claude/commands にMarkdownを1枚置く
最小構成は、ファイル1枚です。プロジェクト直下に .claude/commands/ を作り、コマンド名と同じ名前のMarkdownファイルにプロンプトを書くだけで / メニューに現れます。
mkdir -p .claude/commands
cat > .claude/commands/review-diff.md <<'EOF'
---
description: 未コミットの差分をレビューし、リスクを列挙する
---
未コミットの差分をレビューして、次の観点で問題を指摘してください。
1. エラーハンドリングの欠落
2. ハードコードされた値
3. 更新漏れのテスト
EOF
ファイル名の review-diff がそのままコマンド名になり、/review-diff で呼べます。既存資産がこの形式なら、無理に移行する必要はありません。公式も「引き続き動作する」と明言しています。
推奨:.claude/skills/<名前>/SKILL.md で作る
新規に作るなら、ディレクトリ+SKILL.md の形式が公式の推奨です。ディレクトリ名がコマンド名になります。
~/.claude/skills/summarize-changes/SKILL.md
---
description: 未コミットの変更を要約し、リスクを指摘する。差分のレビューやコミットメッセージを求められたときに使う。
---
## 現在の変更
!`git diff HEAD`
## 指示
上の差分を2〜3行の箇条書きで要約し、気づいたリスク(エラーハンドリングの欠落、ハードコードされた値、更新が必要なテスト)を列挙してください。差分が空なら「未コミットの変更はありません」と答えてください。
ディレクトリ形式の利点は、付随ファイルを同梱できる点にあります。テンプレート、期待する出力例、Claudeに実行させるスクリプト、詳細なリファレンスを同じフォルダに置き、SKILL.mdからは「必要になったら読む」形で参照させられます。SKILL.md本体は500行以内に収め、長い資料は別ファイルへ逃がすのが公式の推奨です。呼び出されたスキルの本文はセッション中コンテキストに残り続けるため、本文が長いほど毎ターンのトークン費用として効いてきます。
置き場所とスコープ:個人・プロジェクト・プラグイン
| スコープ | パス | 適用範囲 |
|---|---|---|
| エンタープライズ | managed settings で指定 | 組織の全ユーザー |
| パーソナル | ~/.claude/skills/<名前>/SKILL.md |
自分の全プロジェクト |
| プロジェクト | .claude/skills/<名前>/SKILL.md |
そのリポジトリのみ |
| プラグイン | <plugin>/skills/<名前>/SKILL.md |
プラグイン有効時 |
チームで配りたいなら、プロジェクトの .claude/skills/ をバージョン管理にコミットするのが基本形です。組織全体へ配るならmanaged settings、公開・再配布まで見るならプラグイン化という順で選びます。プラグインスキルは /プラグイン名:スキル名 という名前空間を持つため、他スコープと名前が衝突しません。配布形態としてのプラグインの位置づけはClaude Codeのおすすめ拡張機能6つを役割別に整理|プラグインとの違いで整理しています。
モノレポでは、作業中のファイルがあるサブディレクトリの .claude/skills/ も動的に読み込まれます。ルートと apps/web/ に同名の deploy があれば、後者は /apps/web:deploy というディレクトリ修飾名で共存します(v2.1.203以降)。
引数の渡し方:$ARGUMENTS と位置指定
コマンドに値を渡す仕組みは置換変数です。呼び出し時に続けて書いた文字列が本文に展開されます。
| 変数 | 展開される値 |
|---|---|
$ARGUMENTS |
渡された引数の全体 |
$ARGUMENTS[N] |
N番目の引数(0始まり) |
$N |
$ARGUMENTS[N] の短縮形。$0 が1つ目 |
$名前 |
frontmatterの arguments で宣言した名前付き引数 |
${CLAUDE_SKILL_DIR} |
SKILL.mdがあるディレクトリ |
${CLAUDE_PROJECT_DIR} |
プロジェクトのルート(v2.1.196以降) |
ここは間違えやすい箇所です。位置指定は0始まりで、$0 が1つ目の引数、$1 は2つ目を指します。シェルスクリプトの $1 の感覚で書くと1つずれます。複数語をひとつの引数として渡したいときは、シェル同様に引用符で囲みます。/my-skill "hello world" second なら $0 は hello world、$1 は second です。
---
name: migrate-component
description: コンポーネントを別フレームワークへ移行する
arguments: [component, from, to]
argument-hint: [component] [from] [to]
---
$component を $from から $to へ移行してください。既存の挙動とテストは維持すること。
本文に $ARGUMENTS を1つも書かなかった場合でも、引数は捨てられません。Claude Codeが本文末尾に ARGUMENTS: 入力値 を追記するため、指示の中で参照はできます。金額のように文中に $1.00 と書きたいときは \$1.00 とバックスラッシュでエスケープします。
frontmatterで挙動を決める
誰が呼ぶかを制御する2つのフィールド
既定では、あなたも /名前 で呼べるし、Claudeも関連しそうな場面で自動的に呼びます。この2方向を切るのが次の2フィールドです。
disable-model-invocation: true:あなたしか呼べなくなる。/commit・/deployのように副作用があり、実行タイミングを人間が握るべきものに付ける。user-invocable: false:Claudeしか呼べなくなる。「レガシーシステムの前提知識」のような、コマンドとして叩く意味のない背景知識に付ける。
デプロイ用コマンドに disable-model-invocation を付けない運用は勧めません。コードが完成して見えたという理由でClaudeが本番デプロイを起動しうるからです。このフィールドを付けたスキルは説明文がClaudeのコンテキストに載らなくなる(公式は「removes the skill from Claude’s context entirely」と記載)ため、後述するコンテキスト予算の節約にも効きます。
権限・モデル・サブエージェント実行
| フィールド | 効果 |
|---|---|
allowed-tools |
スキル実行中、承認なしで使えるツールを指定 |
disallowed-tools |
スキル実行中、使えなくするツールを指定 |
model / effort |
実行中のモデル・推論の強さを上書き |
context: fork |
会話履歴を切り離したサブエージェントで実行 |
agent |
fork 時の実行環境(既定は general-purpose) |
paths |
指定globにマッチするファイルを扱うときだけ自動起動 |
hooks |
このスキルのライフサイクルに紐づくフック |
when_to_use |
起動のきっかけとなる語句を description に補足 |
shell |
シェル注入に使うシェル。既定 bash/powershell も可 |
shell: powershell はWindowsでインラインのシェル実行をPowerShellに切り替える指定で、環境変数 CLAUDE_CODE_USE_POWERSHELL_TOOL=1 が前提です。
allowed-tools は「事前承認」であって「制限」ではありません。列挙したツールが承認なしで使えるようになるだけで、他のツールが封じられるわけではない点は誤解しやすいところです。禁止したいなら disallowed-tools、恒久的に止めるなら権限設定のdenyルールを使います。権限まわりの挙動はClaude Codeオートモードの定義と、通常モード・標準実行との本質的な違い、フックの基礎はClaude Codeにおける「フック(Hooks)」の意味と定義で補足できます。
context: fork は調査系と相性が良い一方、注意点があります。フォークされたサブエージェントは会話履歴を持たないため、「このAPI規約に従って」といったタスクを含まない指針だけのスキルをforkすると、実行するものが無いまま返ってきます。forkするのは、それ単体で完結する明示的な手順を書いたスキルだけにしてください。agent の指定によって読み込むものも変わります。組み込みの Explore・Plan はCLAUDE.mdとgit statusを読まずコンテキストを小さく保つ設計で、それ以外のエージェント型ではCLAUDE.mdが読まれます。
コマンド実行前にシェル出力を差し込む
カスタムコマンドが単なる定型文と決定的に違うのが、この動的コンテキスト注入です。行頭(または空白の直後)の !`コマンド` は、Claudeが本文を読む前に実行され、その出力に置き換わります。Claudeが見るのは、実データが埋め込まれ終わったプロンプトです。
---
name: pr-summary
description: プルリクエストの変更内容を要約する
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---
## PRのコンテキスト
- 差分: !`gh pr diff`
- コメント: !`gh pr view --comments`
- 変更ファイル: !`gh pr diff --name-only`
## タスク
このプルリクエストを要約してください...
この処理は前処理であり、Claudeがコマンドを実行しているわけではありません。展開は元ファイルに対して1回だけ走り、コマンドの出力は再スキャンされないため、出力の中に別のプレースホルダを仕込んで多段展開することはできません。複数行を実行したい場合は、! 付きのフェンス(```!)でブロックにします。なお KEY=!`cmd` のように ! が文字の直後に来る形は展開されず、リテラルとして残ります。
組織として無効化したい場合は、設定に "disableSkillShellExecution": true を入れます。各コマンドは実行されず [shell command execution disabled by policy] に置換されます。バンドル済みスキルと管理下スキルは影響を受けません。なお、スキル本文のどこかに ultrathink と書いておくと、そのスキルの実行時により深い推論を要求できます。
組み込みコマンドとの違い・一覧の見方
/help・/clear・/compact といった組み込みコマンドは、CLIに実装された固定ロジックを直接実行します。公式が「同名で置き換えられる」と明記しているのは、実体がスキルであるバンドルスキルのほうです。
| コマンド | 種別 | 用途 |
|---|---|---|
/help |
組み込み | ヘルプと利用可能なコマンドの表示 |
/clear |
組み込み | コンテキストを空にして新しい会話を開始 |
/compact |
組み込み | 会話を要約してコンテキストを空ける |
/context |
組み込み | コンテキスト使用量の可視化 |
/model |
組み込み | モデルの切り替え |
/permissions |
組み込み | ツール権限のallow・ask・denyルール管理 |
/agents |
組み込み | サブエージェント設定の管理 |
/mcp |
組み込み | MCPサーバー接続・認証の管理 |
/code-review |
スキル | 差分のレビュー(バグ・整理) |
/debug |
スキル | デバッグログ有効化と切り分け |
/batch |
スキル | 大規模変更の並列オーケストレーション |
/loop |
スキル | プロンプトの繰り返し実行 |
/doctor |
スキル | セットアップ診断 |
この「種別」列がそのまま上書き可否を分けます。組み込み側はCLIの固定ロジックですが、スキル側はプロンプトなので自作で置き換えられます。
紛らわしいのがバンドルスキルです。/code-review・/debug・/loop・/batch・/doctor・/claude-api は、見た目は組み込みコマンドと同じですが実体はスキル(プロンプト)で、Claudeが自分のツールで作業を組み立てます。実体がスキルなので、同名のスキルを自分で作れば上書きできます。プロジェクトの .claude/skills/code-review/ を置けば、バンドルの /code-review ではなく自社版が動きます。まとめて止めたい場合は disableBundledSkills 設定を使います(v2.1.205以降、/doctor だけは例外として残る)。バンドルスキルが実務でどう振る舞うかはClaude Code 2.1.63の/simplifyと/batchが開発現場にもたらす実務インパクトが具体例になります。
自分の環境で今どのコマンドが使えるかは /help、スキルの一覧と表示状態は /skills で確認するのが確実です。ネット上の「コマンド一覧」記事はバージョンによって実在しない項目を含むため、最終確認は手元のCLIで行ってください。
チームに配る前に踏みやすい3つの地雷
作り方より、配り始めてから効いてくる問題のほうが厄介です。ここは競合記事がほとんど触れていない領域なので、先に潰しておきます。
1つ目はコンテキスト予算です。 スキルの説明文(description+when_to_use)は、Claudeが「何が使えるか」を知るために常時コンテキストへ載ります。この一覧の予算はモデルのコンテキストウィンドウの1%が既定で、あふれると使用頻度の低いスキルから説明文が削られます。名前は必ず残りますが、マッチに必要なキーワードが説明文ごと落ちるため自動選択の精度は下がり、「作ったのに呼ばれない」という症状になります。1件あたりの説明文は1,536文字で切られるので、主要な用途を先頭に書くこと。現状のコストは /doctor で概算できます。優先度の低いものを skillOverrides で "name-only" にすれば予算が空き、逆に枠自体を広げるなら skillListingBudgetFraction(例: 0.02 で2%)や環境変数 SLASH_COMMAND_TOOL_CHAR_BUDGET を使います。
2つ目は命名衝突です。 同名ならエンタープライズ>パーソナル>プロジェクトの順で上書きされ、スキルはコマンドに優先します。個人の ~/.claude/skills/deploy/ がある人だけ、リポジトリの deploy が動かないという事故が起きます。チーム配布するコマンドには、汎用名を避けてプロジェクト固有の接頭辞を付けるか、プラグイン化して名前空間を切るのが安全です。
3つ目はシェル実行と権限です。 プロジェクトの .claude/skills/ に置かれたスキルは、ワークスペースの信頼ダイアログを承認した時点で allowed-tools が有効になります。つまりリポジトリに含まれるスキルは、自分自身に広いツール権限を与えられます。加えて !`コマンド` はClaudeが読む前に走ります。外部リポジトリをcloneしてClaude Codeを起動する前に、.claude/ 配下を必ず目視してください。
そもそも作らない判断も要ります。1回しか使わない指示、プロジェクト全体に常時効かせたい恒常ルール(コーディング規約やディレクトリ構成)は、カスタムコマンドではなくCLAUDE.mdに書くべきもの。公式も「CLAUDE.mdの一節が事実ではなく手順に育ってきたとき」がスキル化の目安だとしています。手順になっていないものをコマンド化すると、呼ばれないファイルが増えるだけです。
動かないときの切り分け
/メニューに出ない:セッション開始時に存在しなかったトップレベルのスキルディレクトリを新規作成した場合は再起動が必要。既存ディレクトリ内でのファイル追加・編集はセッション中に反映される(ライブ変更検知)。- 呼べるがClaudeが自動で使わない:
descriptionにユーザーが実際に口にする語が入っているかを見直す。「どんなスキルが使える?」と聞いて一覧に出るかを確認する。 - frontmatterが効いていない:YAMLが壊れていると、Claude Codeはメタデータ空のまま本文だけ読み込む。
/名前では動くのにClaudeが自動起動しない、という紛らわしい状態になる。--debugでパースエラーを確認する。 - 意図と違う版が動く:同名スキルの優先順位(エンタープライズ>パーソナル>プロジェクト、スキル>コマンド)を疑う。
- 途中から効かなくなった:スキル本文はコンテキストに残り続けるが、自動圧縮の際は各スキル先頭5,000トークン・合計25,000トークンの予算で再添付される。多数呼んだセッションでは古いものが落ちるため、必要なら呼び直す。v2.1.202以降は、内容が同じスキルを呼び直しても本文は二重に積まれず「既に読み込み済み」の注記になる。
よくある質問
claude.aiの「カスタム指示」とカスタムコマンドは同じものですか
別物です。claude.ai(チャット)側にあるのはプロジェクト単位のプロジェクト指示で、口調や役割など応答の前提を固定する設定です。本記事のカスタムコマンドはCLIツールであるClaude Codeの機能で、/ から呼び出す手順テンプレートを指します。「claude カスタム指示 どこ」で探している場合、目的がチャットの応答調整ならclaude.aiのプロジェクト設定、開発作業の定型化ならこの記事の .claude/skills/ が答えになります。
既存の .claude/commands は廃止されますか
公式ドキュメントは、.claude/commands/ のファイルは引き続き動作し、同じfrontmatterをサポートすると記載しています。廃止の告知はありません。ただし付随ファイルの同梱など新機能はスキル形式側にしか無いため、公式の推奨は SKILL.md 形式です。
コマンド名はどこで決まりますか
置き場所です。.claude/skills/deploy-staging/SKILL.md なら /deploy-staging、.claude/commands/deploy.md なら /deploy になります。frontmatterの name は一覧に出る表示名で、入力する名前は変えません。例外はプラグイン直下の SKILL.md で、この場合だけ name がコマンド名になります。
Claudeに勝手に実行されたくないコマンドはどうしますか
frontmatterに disable-model-invocation: true を付けます。あなたが /名前 と入力したときだけ動き、Claudeの自動呼び出し対象から外れます。加えて権限設定でdenyルールを書けば、ツール経由の起動も止められます。構文は完全一致が Skill(deploy)、引数付きも含めた前方一致が Skill(deploy *) です。
引数を複数渡すとき、$1 は1つ目ですか
いいえ、$0 が1つ目です。$N は $ARGUMENTS[N] の短縮形で0始まりのため、$1 は2つ目の引数を指します。全体をまとめて受けたいなら $ARGUMENTS を使ってください。