結論から言うと、Claude Codeを毎日触るなら、カスタムスラッシュコマンドに1時間投資したほうがいいです。.claude/commands/ にMarkdownを数枚置くだけで「またこの前置きを書いている」という時間がなくなります。
ただ、いざ自作しようとすると「Skillsと何が違う?」「引数はどう渡す?」「勝手に呼ばれて困るときの対処は?」といった疑問がまとめて出てきます。2026年のアップデートで仕様が統合されたこともあり、情報がやや散らばっています。今回は自分のプロジェクトで運用しているコマンドを例に、ディレクトリ構造・$ARGUMENTS・frontmatter・Skillsとの使い分けまでを整理します。
Claude Code 2系の挙動を前提にしています。環境は macOS 14 / Claude Code 2.x で動作確認しました。
.claude/commands/の基本構造—ファイル名がそのままコマンド名になる
Claude Codeのカスタムスラッシュコマンドは、.claude/commands/<コマンド名>.md というファイルを1枚置くだけで作れます。/reviewコマンドを作りたければ.claude/commands/review.mdを用意する、それだけです。
置き場所は2種類ある
保存先は用途で使い分けます。
- プロジェクト固有:
<project>/.claude/commands/*.md— リポジトリにコミットすればチーム全員で共有できる - 個人用(全プロジェクト共通):
~/.claude/commands/*.md— 自分のマシンだけで使う
ディレクトリ構成の例を示します。
myproject/
├── .claude/
│ └── commands/
│ ├── review.md # /review
│ ├── fix-test.md # /fix-test
│ └── pr-desc.md # /pr-desc
└── src/
サブディレクトリを切ると名前空間も使えます。.claude/commands/db/migrate.mdは/db:migrateとして呼べます。プロジェクトが大きくなってコマンドが増えてきたら有効です。
最小構成のreview.md
試しに、コミット前のコード差分をレビューするコマンドを書いてみます。
# .claude/commands/review.md
git diff --stagedで出てくるコードを読み、以下の観点でレビューしてください。
- バグの可能性がある箇所
- セキュリティ上の懸念
- 命名・可読性で改善できる点
指摘は重要度順に3点まで。修正案はコードブロックで示してください。
Claude Codeを起動して/reviewと入力すると、この内容がそのままプロンプトとして実行されます。実行結果のイメージは次のとおりです。
$ claude
> /review
ステージ済みの差分を確認しました。重要度順に3点です。
1. [高] src/auth.ts:42 — bcrypt.compareの戻り値を await していません。
2. [中] src/api/user.ts:88 — 入力検証なしで req.body.id を直接クエリに渡しています。
3. [低] src/utils/log.ts:15 — 関数名 fmt は情報量が薄いです。formatRequestLog などに。
毎回「ステージ済みの差分をレビューして、観点は…」と打ち込む必要がなくなる、これだけでも体感の効率は大きく変わります。
引数を渡す—$ARGUMENTSで可変なコマンドにする
ありがちなハードコードの失敗例
最初にコマンドを作りはじめた頃、対象ファイル名をMarkdown内に直接書いてしまっていました。
# .claude/commands/summarize-auth.md (アンチパターン)
src/auth.tsを読んで、関数ごとの役割を箇条書きでまとめて。
このやり方だと、対象ファイルが変わるたびに別コマンドを作る羽目になります。気づいたらcommandsディレクトリがsummarize-auth.md、summarize-user.md、summarize-api.md…と肥大化していきました。1週間で10ファイル以上になっていた記憶があります。
$ARGUMENTSの展開と位置引数
解決策は$ARGUMENTSプレースホルダを使うこと。実行時に渡した引数が丸ごと展開されます。
# .claude/commands/summarize.md
$ARGUMENTSで指定されたファイルを読み、関数ごとの役割を箇条書きでまとめてください。
不明な部分は推測せず「不明」と書いてください。
呼び出し方はこうです。
> /summarize src/auth.ts
src/auth.ts を読みました。関数ごとの役割は以下です。
- hashPassword(plain) — bcryptでパスワードをハッシュ化する
- verifyPassword(plain, hash) — ハッシュと平文を照合する
- issueToken(userId) — JWTを発行する(有効期限24h)
- verifyToken(token) — JWTを検証し、userIdを返す
複数の引数を別々のスロットで扱いたいときは、$1, $2のような位置引数も使えます。
# .claude/commands/compare.md
$1のファイルと$2のファイルを比較し、差分の意味と影響範囲を説明してください。
> /compare src/old_api.py src/new_api.py
src/old_api.py と src/new_api.py を比較しました。
主な差分は3点です。
- レスポンス形式: {data: ...} → {data: ..., meta: {...}} に変更
- エラーハンドリング: raise → return Err(code) パターンに変更
- 依存: requests → httpx に変更(非同期対応)
影響範囲: 呼び出し側のレスポンスパースが破壊変更です。tests/api_test.py 12箇所の書き換えが必要です。
1つのコマンドが、渡した引数で振る舞いを変える汎用コマンドになりました。
frontmatterで挙動を制御する
Markdownの先頭に---で囲んだYAMLブロックを置くと、メタデータを付けられます。公式ドキュメントによると現在サポートされている主なフィールドは3つです。
---
description: ステージ済みの差分をレビュー
argument-hint: "[追加の観点]"
allowed-tools: Bash(git diff:*), Read
---
git diff --stagedの出力を読み、$ARGUMENTSの観点も踏まえてレビューしてください。
descriptionとargument-hint
- description: コマンド一覧や補完ポップアップに表示される短い説明
- argument-hint: 引数の書式ヒント。
/review <Tab>時にガイドが出る
descriptionは/helpでコマンド一覧を開いたときに表示されます。未来の自分やチームメンバーが読んで意味がわかる日本語にしておくと、あとで「このコマンド何だっけ」を防げます。
allowed-toolsで権限を絞る
allowed-toolsは、そのコマンドが使えるツールを制限するフィールドです。Bash(git diff:*)のようにサブコマンド単位で指定できます。
権限を絞る理由は2つあります。
- 安全側に倒す:
/reviewはあくまで読み取り系なので、WriteやBash(rm:*)は不要です。誤動作を防げます - 確認プロンプトを減らす: 使うツールを事前宣言しておけば、毎回の「このツールを使ってよいですか?」が出ません
バージョン間でallowed-toolsの構文が少し違うことがあります。手元のclaude --versionで確認してから使ってください。
Skillsと何が違う?統合後の使い分け
2025年末のアップデートで、カスタムスラッシュコマンドとSkillsの扱いが統合されました。公式ドキュメントによると、.claude/commands/review.mdと.claude/skills/review/SKILL.mdのどちらで定義しても/reviewという同じコマンドとして動作します。
SKILL.mdとコマンドmdの比較表
違いを整理すると次のようになります。
| 項目 | .claude/commands/<名前>.md | .claude/skills/<名前>/SKILL.md |
|---|---|---|
| ファイル構成 | Markdown1枚 | ディレクトリ+複数ファイル可 |
| frontmatter | 任意 | 必須(descriptionが必要) |
| 自動呼び出し | 原則は明示実行のみ | Claudeが判断して呼ぶことがある |
| 同梱ファイル | 不可 | 可(テンプレ・サンプル・参照ドキュメント) |
| 向く用途 | 短い定型プロンプト | 大きめのワークフロー・手順書 |
長い手順はSkills、短い定型文はコマンド
私の基準は「5行で収まる指示はcommands、20行を超える手順書やサンプルファイルを同梱したいならskills」です。
たとえば「PR説明文のテンプレで埋める」は5行で済むのでcommands。「OpenAPIスキーマから型生成→MSWのハンドラ生成→テンプレからテスト骨格を作る」のようなワークフローはSkills、みたいな使い分けです。Skillsはディレクトリなので、template.tsやreference.mdを同じフォルダに置けるのが強みですね。
関連記事として Claude CodeのMCPサーバー連携ガイド|完全な実装手順とベストプラクティス も併せて読むと、外部ツールを絡めた自動化の全体像がつかみやすいと思います。
よくあるアンチパターン
コンテキストを圧迫する巨大コマンド
1つのコマンドに「プロジェクト構成 + コーディング規約 + 禁止事項 + レビュー観点20個」を全部書き込むと、呼び出すたびに数千トークンを消費します。
# .claude/commands/review.md (アンチパターン)
# プロジェクト概要
当プロジェクトはマイクロサービス構成で、認証サービス、ユーザーサービス、...
# コーディング規約(抜粋)
- インデントは2スペース
- 命名は...(以下50行)
# レビュー観点(20項目)
1. ...
2. ...(以下続く)
対処法はシンプルで、不変のルールはCLAUDE.mdに書くです。CLAUDE.mdはセッション全体の前提として常に読み込まれるため、ここに置けばコマンド側で再記述する必要がなくなります。
# .claude/commands/review.md (改善後)
---
description: ステージ済み差分のレビュー(観点はCLAUDE.mdに準拠)
---
git diff --stagedの出力を読み、CLAUDE.mdのレビュー観点に沿ってレビューしてください。
重要度順に3点まで。
関連記事: Claude CodeのCLAUDE.md設計 — チーム開発ルールを統一する仕組み で、CLAUDE.mdに何を書いて何を書かないかを整理しています。合わせて読むとコマンドとの役割分担が見えてきます。
勝手に呼ばれて混乱するケース
Skills形式にするとClaudeが自主的にコマンドを呼び出すことがあります。「CLAUDE.mdを編集し始めたらスキルdescriptionにマッチして、頼んでもいないのにreviewが走った」みたいな混乱が起きます。
明示呼び出しだけに留めたい場合は、descriptionに「ユーザーが明示的に /xxx と入力したときのみ実行」と書いておくと判定が変わります。
---
description: ユーザーが明示的に /review と入力したときのみ実行する
---
...本文...
descriptionは「いつ使うか」をClaude自身が判断するための材料なので、ここに制約を書けば自動発火を抑えられます。
チーム共有と個人利用を分ける運用
プロジェクト共有はリポジトリにコミット
.claude/commands/をGit管理すれば、チーム全員が同じコマンドを使えます。新メンバーのオンボーディングが一気に楽になるので、最低限この3つは用意しておくと喜ばれます。
/review— PR前のセルフレビュー/test— テスト実行とカバレッジ確認/pr-desc— PR説明文の下書き
副次効果として、コマンドを読めば「このプロジェクトではこういう観点でレビューするんだな」という暗黙知が可視化されます。ドキュメントを書くより敷居が低いので、続きやすいのもポイントです。
個人用は~/.claude/commands/に置く
自分だけのワークフロー(ログ整形、コミットメッセージの下書き、Slack投稿の清書など)は~/.claude/commands/へ。チームに関係ないものをリポジトリに混ぜないほうがクリーンです。
個人用コマンドはClaude Codeを起動した場所を問わず使えるのがメリット。プロジェクト横断で使う汎用コマンドはここに置くと便利です。
実際に運用しているコマンド例
参考までに、普段使っている3つのコマンドを紹介します。いずれも20行以内の短いもので、.claude/commands/に置いています。
/pr-desc: PR説明文の下書き
---
description: コミット済みの差分からPRテンプレに沿った説明文を書く
allowed-tools: Bash(git log:*), Bash(git diff:*), Read
---
git log と git diff main..HEAD の出力を読み、以下のテンプレを埋めてください。
## 変更内容
- (箇条書き、3〜5個)
## 動作確認
- (具体的な手順)
## 懸念点
- (あれば、なければ「なし」)
実行例です。
> /pr-desc
## 変更内容
- /review コマンドで allowed-tools を指定し、Bash(git diff:*) と Read に権限を限定
- frontmatterのdescription を「明示実行のみ」に変更し、Skills自動発火を抑止
- docs/commands.md に使用例を追記
## 動作確認
- `claude /review` で意図どおり実行されることを確認
- `git diff` 以外のコマンドが提案されないことを確認
## 懸念点
- なし
/fix-test: テスト失敗の原因推定
---
description: 直近のテスト失敗ログから原因を推定し修正案を出す
argument-hint: "[テストコマンド. 省略時は pnpm test]"
---
$ARGUMENTS(省略時は pnpm test)を実行し、失敗メッセージから原因を推定してください。
推定が複数ある場合は確度の高い順に並べ、最優先の案のみ具体的な修正差分を提示してください。
/ask: 推測させずに答える
---
description: 公式ドキュメントまたはプロジェクト内コードを根拠に回答する
---
$ARGUMENTSについて答えてください。
推測で答えず、公式ドキュメントまたはプロジェクト内のコードを根拠にしてください。
根拠がない場合は「確認が必要」と答えてください。
> /ask useEffectのクリーンアップ関数はいつ呼ばれる?
公式ドキュメント(react.dev/reference/react/useEffect)によると、クリーンアップ関数は次のタイミングで実行されます。
1. 次のeffectが実行される直前(依存配列が変わったとき)
2. コンポーネントのアンマウント時
Strict Modeでは、マウント直後にも一度実行される点に注意してください。
こうしたコマンドはプロジェクトの暗黙知を共有する手段にもなります。関連記事として プロが毎日使ってるClaude Codeの隠しコマンド&ショートカットキー完全ガイド では、組み込みコマンド側の活用例もまとめています。
まとめ
カスタムスラッシュコマンドは小さく始めて、運用しながら育てるのが向いていると思います。最初は/review1つから始めて、「3回同じ説明をした」と感じた瞬間に新しいコマンドを足す、くらいのペースで十分です。
.claude/commands/<name>.mdを置くだけでカスタムコマンドが使える- 引数は
$ARGUMENTSまたは$1, $2で受け取る - frontmatterの
description・argument-hint・allowed-toolsで挙動を制御する - Skills(
SKILL.md)はディレクトリ構造で、長い手順書向け - 短い定型はcommands、大きいワークフローはSkills
- 全員で使うものはプロジェクト直下、個人用は
~/.claude/commands/ - 巨大化したらCLAUDE.mdへの分割を検討する
手元のプロジェクトで.claude/commands/を切って、レビュー用のMarkdownを1枚書くところからはじめてみてください。投資対効果は驚くほど高いはずです。

