Claude Codeのカスタムコマンドは、毎回貼り付けている定型の指示を /fix-issue 123 のような1行で呼び出す仕組みです。いまはスキル(Skills)と同じものとして扱われ、公式ドキュメントも「Custom commands have been merged into skills」と明記しています。コマンド名の決まり方、組み込みコマンドの上書き、allowed-tools の効く範囲は、古い解説記事と現在の仕様が食い違いやすい箇所です。本記事は2026年10月30日時点の公式仕様(npmの最新版は2.1.314)に沿って、作り方・引数・呼び出しの制御と、そのまま使える雛形3本を示します。
まとめ
- 2つの形式は同じ動き:
.claude/commands/deploy.mdと.claude/skills/deploy/SKILL.mdはどちらも/deployになる。同名ならスキルが勝つ。新しく作るならSKILL.md形式。 - コマンド名はディレクトリ名か
name:スキルでは frontmatter のnameが入力する名前になり、ディレクトリ名でも呼べる。.claude/commands/側はnameとpathsを使えない。 - 引数は0始まり:
$0が1つ目、$1が2つ目。全体は$ARGUMENTS、名前で受けるならargumentsを宣言する。 - 副作用のあるコマンドには
disable-model-invocation: true:付けないと、Claudeが自分の判断でデプロイやコミットを始めうる。 allowed-toolsは呼び出したターンだけの事前承認:次のメッセージで消える。逆にワークスペースの信頼確認には左右されないので、他人のリポジトリのスキルは中身を見てから使う。
カスタムコマンドとスキルの関係:統合で変わったこと
公式のExtend Claude with skillsは、.claude/commands/deploy.md と .claude/skills/deploy/SKILL.md がどちらも /deploy を作り、同じように動くと書いています。既存の .claude/commands/ は今も動き、廃止の告知はありません。
違いは、スキル形式にしかない機能です。付随ファイルを置くディレクトリを持てること、Claudeが関係しそうな場面で自動的に読み込めること、そしてfrontmatterの一部です。公式のフィールド一覧には「A command file in .claude/commands/ accepts the same fields except name and paths」とあり、旧形式ではnameによる呼び出し名の変更と、pathsによる対象ファイルに応じた自動読み込みの指定ができません。
Claude CodeのスキルはAgent Skillsのオープン標準に沿い、呼び出し制御・サブエージェント実行・シェル出力の差し込みをClaude Code独自の拡張として足しています。claude.aiへのアップロードやSkills APIで通るfrontmatterは name・description・license・compatibility・metadata・allowed-tools の6つだけで、argument-hint などが残っていると「Unexpected key(s) in SKILL.md frontmatter」で止まります。仕様の全体像はAgent Skillsとは?SKILL.md仕様とAAIF寄贈後も移植性を保つ実装手順、claude.ai・API側での使い方はClaude Skillsとは?SKILL.mdの書き方とclaude.ai・Claude Code・APIでの使い方で扱っています。
カスタムコマンドを作る手順
.claude/commands形式のファイル作成(旧形式)
いちばん短いのはファイル1枚です。.claude/commands/ にMarkdownを置くと、拡張子を除いたファイル名がコマンド名になります。
mkdir -p .claude/commands
cat > .claude/commands/review-diff.md <<'EOF'
---
description: 未コミットの差分をレビューし、リスクを列挙する
---
未コミットの差分をレビューして、次の観点で問題を指摘してください。
1. エラーハンドリングの欠落
2. ハードコードされた値
3. 更新漏れのテスト
EOF
これで /review-diff が使えます。サブディレクトリに置くと区切りが : になり、.claude/commands/frontend/component.md は /frontend:component です。手元の資産がこの形式なら、急いで移す必要はありません。
SKILL.md形式のディレクトリとファイル作成(推奨)
新しく作るならディレクトリと SKILL.md の組です。次のコマンドでディレクトリを作り、その中にSKILL.mdという名前で続くMarkdownを保存します。既存のコミットがあるGitリポジトリで、追跡対象ファイルの差分を要約する例です。
mkdir -p ~/.claude/skills/summarize-changes
---
description: 未コミットの変更を要約し、リスクを指摘する。変更点の確認、コミットメッセージ作成、差分のレビューを頼まれたときに使う。
---
## 現在の変更
!`git diff HEAD`
## 指示
上の差分を2〜3行の箇条書きで要約し、気づいたリスク(エラーハンドリングの欠落、ハードコードされた値、更新が必要なテスト)を列挙してください。差分が空なら「追跡中のファイルに未コミットの変更はありません(未追跡ファイルは対象外)」と答えてください。
/summarize-changes と打っても、「何を変えた?」と聞いても動きます。後者はClaudeが description と照合して自動で読み込む動きです。!`git diff HEAD` の行も権限チェックを受け、オートモード以外で許可されていなければ読み込みの時点で止まります(後述の「シェル出力の事前差し込み」)。止まる場合はfrontmatterに allowed-tools: Bash(git diff *) を足します。
ディレクトリにはテンプレート、出力例、実行させるスクリプトを同梱し、SKILL.mdから「詳細は reference.md」のように参照させます。公式はSKILL.mdを500行未満に収めるよう勧めています。呼び出されたスキルの本文は以後のターンも会話に残るため、長い本文はそのまま毎ターンのトークン費用になります。
置き場所ごとのスコープと同名時の優先順位
| 置き場所 | パス | 読み込まれる範囲 |
|---|---|---|
| エンタープライズ | 管理設定ディレクトリの .claude/skills/ |
組織が配った端末の全ユーザー |
| パーソナル | ~/.claude/skills/<名前>/ |
この端末の全プロジェクト |
| プロジェクト | .claude/skills/<名前>/ |
そのリポジトリ(コミットで共有) |
| ネスト | <subdir>/.claude/skills/<名前>/ |
その配下のファイルを扱ったとき |
| プラグイン | <plugin>/skills/<名前>/ |
/プラグイン名:スキル名 |
同名が衝突したときは、エンタープライズ>パーソナル>プロジェクトの順に勝ち、スキルはコマンドファイルに勝ちます。プラグインは名前空間が付くので衝突しません。パーソナルスキルはCoworkやクラウドのセッションでは読まれません。Coworkとプロジェクト内のクラウドスレッドではclaude.aiのアカウントでスキルを有効にし、それ以外のクラウドセッションならリポジトリの .claude/skills/ にコミットしても使えます。
モノレポでは、起動したディレクトリより下の .claude/skills/ は、Claudeがそこのファイルを初めて読むか編集した時点で加わります。ルートと apps/web/ の両方に deploy があれば、/deploy はルート側、/apps/web:deploy はネスト側です。
コマンド名の決まり方
古い解説で「表示名」とされていることが多いのが name です。現在の公式は、パーソナル・プロジェクトのスキルでは frontmatter の name が「the command that the / menu shows and that you type」になると書いています。.claude/skills/deploy-staging/SKILL.md に name: deploy と書けば /deploy で呼べ、ディレクトリ名の /deploy-staging も引き続き使えます。ただし同じ名前を別のコマンドが使っていれば、name の方は効きません。
ゼロ幅スペース・制御文字・連続した空白・<・> を含むディレクトリ名やファイル名は読み込まれません。拒否された名前は claude --debug のログを [names] で検索すると分かります。
引数を渡す:$ARGUMENTS・$0・名前付き引数
コマンド名に続けて書いた文字列は、本文中の置換変数に展開されます。
| 変数 | 展開される値 |
|---|---|
$ARGUMENTS |
入力した引数の全体 |
$ARGUMENTS[N] / $N |
N番目の引数(0始まり。$0 が1つ目) |
$名前 |
arguments で宣言した名前付き引数 |
${CLAUDE_SKILL_DIR} |
SKILL.mdのあるディレクトリ |
${CLAUDE_PROJECT_DIR} |
プロジェクトのルート |
${CLAUDE_SESSION_ID} |
現在のセッションID |
${CLAUDE_EFFORT} |
現在のeffort(low〜max) |
位置指定は0始まりで、シェルの $1 の感覚で書くと1つずれます。複数語を1つの引数にするには引用符で囲み、/my-skill "hello world" second なら $0 が hello world、$1 が second です。
足りない引数の扱いは、変数の種類で違います。1つしか渡していないのに本文に $2 があると、$2 という文字のまま残ります。arguments で宣言した名前付き引数は空文字になります。本文にどの変数も無いときは、末尾に ARGUMENTS: 入力値 が足されるので、引数は捨てられません。文中に金額として $1.00 と書きたいときは \$1.00 とエスケープします。
---
description: コンポーネントを別フレームワークへ移行する
arguments: [component, from, to]
argument-hint: "[component] [from] [to]"
---
$component を $from から $to へ移行してください。既存の挙動とテストは維持すること。
argument-hint は入力補完に出るヒントです。[a] [b] のように角括弧が2つ以上並ぶ値は、YAMLの規則では引用符なしだとパースエラーになる書き方なので、引用符で囲んでおきます。
スキルの呼び出し主体と実行条件
disable-model-invocationとuser-invocableによる呼び出し主体の制限
既定では、あなたも /名前 で呼べ、Claudeも関係しそうな場面で自動的に呼びます。片方を止めるのが次の2つです。
| 指定 | あなた | Claude | 説明文の常駐 |
|---|---|---|---|
| (既定) | 呼べる | 呼べる | 常にコンテキストに載る |
disable-model-invocation: true |
呼べる | 自分からは呼べない | 載らない |
user-invocable: false |
呼べない | 呼べる | 常にコンテキストに載る |
/deploy・/commit のように副作用があるものには disable-model-invocation: true を付けてください。付けないと、コードが仕上がったように見えたという理由でClaudeがデプロイを始めかねません。付けた状態でClaudeが呼ぼうとすると、Claude Codeが止めて別の手段で同じ手順を再現しないよう指示するため、Claudeは「/deploy を実行してください」と促す側に回ります。
user-invocable: false は、旧システムの前提知識のように「コマンドとして打つ意味はないがClaudeには知っていてほしい」内容向けです。メニューから隠れるだけで、Claudeは呼べます。
スキル名の記述位置と最大6個の連続呼び出し
スキルが直接実行されるのは、メッセージの先頭に /名前 を書いたときだけです。「go ahead and /deploy to staging」のように文中に書くと何も実行されず、そのメッセージでスキルを使ってよいという許可として扱われます。スキルの話をしたいだけなら、スラッシュを付けずに書きます。
端末のプロンプトでは、先頭に複数のスキルを並べられます。/write-tests /fix-issue 123 は両方を読み込み、末尾の 123 をそれぞれの $ARGUMENTS に渡します。展開されるのは先頭とその後ろ5個までの計6個です。context: fork のスキルや /loop が来たところで展開は止まります。claude -p やAgent SDKでは先頭の1個だけが読み込まれ、残りは引数になります。
skillOverridesによるスキルの表示・呼び出し制御
リポジトリにコミットされたスキルのSKILL.mdを書き換えずに表示を変えたいときは、設定の skillOverrides を使います。値は "on"(既定)・"name-only"(Claudeには名前だけ見せる)・"user-invocable-only"(Claudeから隠し、メニューには出す)・"off"(どちらからも隠す)の4つです。
/skills で対象を選び Space で切り替え、Esc で .claude/settings.local.json に保存されます。プラグインのスキルには効かないので、そちらは /plugin で無効にします。
frontmatterによる権限・モデル・実行環境の設定
| フィールド | 効果 | 効く期間 |
|---|---|---|
allowed-tools |
承認なしで使えるツール | 呼び出したターン |
disallowed-tools |
使えなくするツール | 呼び出したターン |
model |
モデルの上書き | 呼び出したターン |
effort |
推論の強さ(low〜max) | 呼び出したターン |
context: fork |
会話履歴なしのサブエージェントで実行 | その実行 |
agent |
fork時のエージェント種別 | その実行 |
background |
false でfork結果を待つ(既定 true) |
その実行 |
paths |
指定globのファイルを扱うときだけ自動起動 | 常時 |
hooks |
呼び出し後に登録されるフック | セッション終了まで |
shell |
bash(既定)か powershell |
差し込み実行時 |
誤解が多いのは allowed-tools です。これは事前承認であって制限ではなく、列挙しなかったツールも使えます。しかも承認はそのターン限りで、次のメッセージを送ると消えます。セッション全体で許可したいなら、権限設定のallowルールに書きます。禁止は disallowed-tools か、恒久的にはdenyルールです。権限モードとの関係はClaude Codeのパーミッションモードの違いと設定方法で整理しています。
context: fork は名前に反して、今の会話を引き継ぎません。agent で指定した種別の新しいサブエージェントが、SKILL.mdの本文だけをプロンプトとして受け取ります。「このAPI規約に従う」のような手順の無い指針をforkすると、することが無いまま戻ってきます。agent: Explore や Plan はCLAUDE.mdもgit statusも読まずに始まるので、必要な前提はSKILL.mdに書き切ります。forkは既定でバックグラウンド実行になり、バックグラウンド実行の編集は新しいチェックポイントを作りません。/rewind で戻せるのは会話側ですでに編集・記録したファイルで、それ以外のファイルへの編集は残ります。サブエージェント側の設計はClaude Codeのサブエージェントとは?作り方・設定項目・使い方を参照してください。
シェル出力の事前差し込みと失敗時の挙動
行頭か空白の直後に書いた !`コマンド` は、Claudeが本文を読む前に実行され、出力に置き換わります。Claudeが受け取るのは実データが入ったプロンプトで、コマンドそのものは見ません。複数行は ```! で始めるフェンスで書きます。KEY=!`cmd` のように文字の直後に ! があると実行されず、そのまま残ります。
運用で効いてくるのは、失敗時と権限の挙動です。
- 1つ失敗するとスキル全体が止まる:終了コードが0以外なら、その行だけでなく呼び出しごと中止され、Claudeは本文を受け取らない。検索・比較系のコマンドが返す終了コード1だけは正常扱い。問題を見つけると1を返すチェックスクリプトなどは
|| trueを付ける。 - 承認プロンプトは出ない:差し込みの各コマンドは権限ルールと照合され、denyに当たれば中止。オートモード以外では、allow以外(ask含む)でも中止になる。止めたくないコマンドは
allowed-toolsで事前承認する。
組織として止めたいなら、設定に "disableSkillShellExecution": true を入れると、各コマンドが [shell command execution disabled by policy] に置き換わります。バンドルスキルと管理下のスキルは対象外です。claude.aiから同期されたスキルの差し込みは、この設定に関係なく手元では実行されません。
そのまま使えるカスタムコマンドの雛形3本
以下はSKILL.md形式で、現在の仕様で事故が起きにくい組み合わせにした3本です。呼び出し主体とツールの事前承認を用途に合わせて指定しています。
/fix-issueのIssue番号引数と修正手順
---
description: GitHubのIssueを番号で受け取り、修正とテストまで行う
argument-hint: "[issue-number]"
arguments: [issue]
disable-model-invocation: true
---
GitHub Issue #$issue を修正してください。$issue が正の整数でなければ、コマンドを実行せず入力し直すよう伝えてください。GitHub CLIがインストールされ、対象リポジトリへの認証が済んでいることを確認してください。
1. `gh issue view $issue` で内容を読む
2. 再現テストを先に書き、失敗することを確認する
3. 修正し、テストが通ることを確認する
4. コミットはせず、変更点を3行で報告する
/fix-issue 123 で動きます。Issue番号は差し込み(!`…`)に入れず、本文の指示として渡しています。引数を差し込みのコマンドに埋めると、入力した文字列がそのままシェルに渡る形になるためです。
/commitのステージ済み変更のコミットと事前承認
---
description: ステージ済みの変更をコミットする
disable-model-invocation: true
allowed-tools: Bash(git status *) Bash(git diff *) Bash(git commit *)
---
## ステージ済みの変更
!`git status --short`
!`git diff --cached`
## 指示
上のステージ済み差分だけを対象に、Conventional Commits形式で件名50字以内のメッセージを作り、git commit してください。git addやgit commit -aは実行せず、ステージ内容を変更しないでください。差分が空なら何もせず、その旨を伝えてください。
allowed-tools に git status・git diff を入れているのは、差し込みのコマンドを権限チェックで止めないためです。ここに無くても通常の権限ルールで許可されていれば実行できます。オートモード以外では権限判定がallowにならないと呼び出しが中止され、明示的なask・denyルールはこの事前承認より優先します。git add を許可に入れず本文でも禁じているのは、どのファイルをコミットするかを人が決めるためです。
特定のファイルを触るときだけ効く規約:api-conventions
---
name: api-conventions
description: このリポジトリのREST APIの命名・エラー形式・入力検証の規約
user-invocable: false
paths: "src/api/**/*.ts"
---
APIエンドポイントを書くとき:
- パスは複数形の名詞(/users、/orders)
- エラーは { "error": { "code": string, "message": string } } で返す
- リクエストはハンドラーの先頭で検証する
コマンドとして打つものではないので user-invocable: false で隠し、paths で src/api/ 配下を扱うときだけ自動で読み込ませます。paths は旧形式のコマンドファイルでは使えません。CLAUDE.mdに書くと全作業で毎ターン読まれる規約を、関係する作業だけに絞れます。
組み込みコマンド・バンドルスキルとの関係
「スラッシュコマンド」と呼ばれるものは3種類あります。公式のコマンドリファレンスでは、バンドルスキルに「Skill」の印が付いています。
| 種類 | 例 | 中身 | 同名の自作スキル |
|---|---|---|---|
| 組み込みコマンド | /clear /compact /model /usage |
CLIの固定ロジック | ローカル端末では置き換わる(別名は除く) |
| バンドルスキル | /code-review /debug /loop |
Claudeに渡すプロンプト | 置き換わる(別名は除く) |
| 自作スキル・コマンド | /fix-issue など |
あなたが書いたプロンプト | — |
公式の衝突表は、組み込みコマンドについても「In a local terminal session, your skill replaces the built-in command, but not its aliases」としています。プロジェクトに usage スキルを置くと /usage は自作版になり、別名の /cost は組み込みのまま動きます。/code-review を自作で置き換えても、別名の /review はバンドル版を呼びます。チームのリポジトリに組み込みと同じ名前のスキルがあると、普段の /usage が別物に変わるということです。
バンドルスキルをまとめて止めるのは disableBundledSkills ですが、/doctor だけは残ります。/simplify と /code-review の使い分けはClaude Codeの/simplifyとは?/code-reviewとの違いと/batchの使い方にまとめています。組み込みコマンドの全体像と初日の進め方はClaude Codeの使い方|インストールから権限・CLAUDE.md設定、初日の進め方までが扱います。
自分の環境で使えるものは、/ を打って出るメニューが正です。スキルの一覧と表示状態は /skills(t でトークン数順)、使われていないスキルとそのコストは /skill-doctor で確認できます。ネット上の「コマンド一覧」は版によって実在しない項目を含むので、手元で確かめてください。
チーム配布時の説明文予算・名前衝突・権限リスク
1つ目は説明文の予算です。 スキルの名前と説明文(description+when_to_use)は、Claudeが使えるものを知るために毎ターンコンテキストに載ります。この一覧の予算はモデルのコンテキストウィンドウの1%で、あふれると使用頻度の低いスキルから説明文が落ちます。名前は残りますが、照合に使う語が消えるため「作ったのに呼ばれない」状態になります。descriptionとwhen_to_useの合計は既定で1,536字に制限されるので、主な用途を先頭に書きます。この上限はskillListingMaxDescCharsで変更できます。今のコストは /doctor で概算できます。枠を広げるなら skillListingBudgetFraction(0.02 で2%)、優先度の低いものは skillOverrides で "name-only" にします。
2つ目は名前の衝突です。 個人の ~/.claude/skills/deploy/ を持つ人だけ、リポジトリの /deploy が動かないという事故が起きます。パーソナルがプロジェクトに勝つからです。前章のとおり組み込みコマンドも置き換わるので、チームで配るものはプロジェクト固有の接頭辞を付けるか、プラグインにして名前空間を分けます。
3つ目はリポジトリ由来の権限です。 公式は「Workspace trust doesn’t gate this field」と書き、プロジェクトのスキルの allowed-tools は、一度も信頼していないフォルダでの -p 実行でも適用されるとしています。スキルは自分に広いツール権限を与えられ、!`コマンド` はClaudeが読む前に走ります。外部のリポジトリをcloneしてClaude Codeを起動する前に .claude/ 配下を目視してください。組織で止めるなら管理設定の allowManagedPermissionRulesOnly(v2.1.282以降)で、プロジェクトと個人のスキルの allowed-tools を無視させられます。全体の守り方はClaude Codeのセキュリティ設定|権限ルール・サンドボックス・管理設定で守る実装手順で扱っています。社内向けにスキルやエージェントの仕組みをまとめて設計する場合は、AIエージェント開発の支援も行っています。
作らない判断も要ります。1回きりの指示はプロンプトで足り、全作業に常に効かせたい事実はCLAUDE.mdに書きます。公式は「CLAUDE.mdの一節が事実ではなく手順に育ったとき」をスキル化の目安にしています。毎回必ず守らせたいルール(編集のたびにテストを走らせる等)は、スキルではなくClaude Code Hooksにします。スキルは会話が長くなると守られなくなることがありますが、フックはイベントごとに必ず実行されます。
動かないときの切り分け
/メニューに出ない:既存の~/.claude/skills/や.claude/skills/の中の追加・編集はセッション中に反映される。セッション開始時に無かったトップレベルのskillsディレクトリを作った場合は/reload-skillsを実行する(そのディレクトリは以後の変更のたびに必要)。名前に使えない文字が入っていないかも見る。/名前では動くのにClaudeが自動で使わない:YAMLが壊れていると、メタデータ空のまま本文だけが読み込まれる。claude plugin validate .claude/skills(v2.1.233以降)でパースエラーのあるSKILL.mdを探せる。壊れていなければ、descriptionにユーザーが実際に言う語が入っているかを見直す。paths付きのスキルが起動しない:パターンは作業ディレクトリからの相対で、その外のファイル(別のworktreeなど)には当たらない。- 差し込みでエラーになる:
Shell command failed for patternは終了コード、Shell command permission check failedは権限ルール。前者は出力を見て原因を直し、非ゼロ終了が想定内のコマンドにだけ|| trueを付ける。後者はallowed-toolsで事前承認するが、明示的なask・denyルールはそれより優先される。 - 途中から指示に従わなくなった:自動圧縮の後は、各スキルの先頭5,000トークン・合計25,000トークンまでしか再添付されず、古く呼んだものから落ちる。呼び直すか、重要な指示をSKILL.mdの先頭に置く。
- 意図と違う版が動く:同名の優先順位(エンタープライズ>パーソナル>プロジェクト、スキル>コマンドファイル)を疑う。
よくある質問
claude.aiの「カスタム指示」はどこで設定しますか?
Claude Codeのカスタムコマンドとは別の機能です。claude.aiでは左下のイニシャルから「Settings」→「Your Claude」を開き、「Instructions」に書きます(旧レイアウトでは「Account」→「Instructions for Claude」)。特定のプロジェクトだけに効かせたい場合は、プロジェクト指示を使います。プロジェクトは無料アカウントでも作れます(無料は5個まで)。開発作業の手順を / で呼びたいなら、本記事の .claude/skills/ が答えです。
既存の .claude/commands は廃止されますか?
公式は既存の .claude/commands/ のファイルは動き続けると書いており、廃止の告知はありません。ただし name・paths と付随ファイルの同梱はスキル形式にしか無いため、新しく作るならSKILL.mdです。
スキルのnameとディレクトリ名、どちらで呼べますか?
両方です。パーソナル・プロジェクトのスキルは、frontmatterの name で呼べ、ディレクトリ名でも呼べます。name と同じ名前を別のコマンドが使っている場合は name の方が効きません。プラグインのスキルでは name が最後の部分になり、/プラグイン名:name です。
引数を複数渡すとき、$1は1つ目ですか?
いいえ、$0 が1つ目です。$N は $ARGUMENTS[N] の短縮形で0始まりです。取り違えを避けたいなら、frontmatterに arguments: [issue, branch] と宣言して $issue・$branch で受けます。
Claudeに勝手に実行されたくないコマンドはどうしますか?
frontmatterに disable-model-invocation: true を付けます。ツール経由でも止めたいなら、権限設定のdenyに Skill(deploy)(完全一致)か Skill(deploy *)(引数付きを含む前方一致)を書きます。全スキルを止めるなら Skill をdenyにします。