概要
Cluade CodeのSkill、みなさん使っていますか?
Claude CodeのSkillとは「よく使う手順や知識をフォルダにまとめておき、必要なときだけClaudeに読み込ませる仕組み」です。
この記事では、Skillの概念から作成・活用までをDockerコンテナ上でClaude Codeを動かす構成を前提に解説します。
普段これまでSkillを使ってこなかったのですが、直近で触れる機会があり知ってみると目的に沿う形であれば使わない道はないということを学んだので、今回勉強も兼ねて記事にしたいと思いました。
対象読者
- Claude Codeは触ったことがあるが、Skillはまだ使っていない(なんとなく使っている)人
- CLAUDE.mdが肥大化してきて整理したい人
- Claude Codeをホストに直接入れず、Dockerコンテナで隔離して使いたい人
この記事のゴール
- Skillが何で、CLAUDE.mdなどと何が違うのかを説明できる
- Docker運用で「どこにSkillを置けばコンテナから見えるか」を理解する
前提環境
| 項目 | 内容 |
|---|---|
| Claude Code | v2.1系(2026年10月時点の公式ドキュメントに準拠) |
| 実行場所 | Dockerコンテナ内(ホストにはインストールしない) |
| プロジェクト | ホストのディレクトリをコンテナの /workspace にbind mount |
| ホストOS | macOS / Linux / Windows(WSL2), (筆者はmacOSです) |
本題
Skillとは
SKILL.md というファイルを入れたフォルダ です。
SKILL.md に「いつ使うか」と「何をするか」を書いておくと、Claudeはそれを自分の道具箱に加え、関係のある依頼が来たときに自動で取り出して使います。
/skill-name と打って明示的に呼び出すこともできます。
公式ドキュメントでは、次のようなときにSkillを作るのが良いとされています。
• 同じ指示・チェックリスト・手順を何度もチャットに貼り付けている
• CLAUDE.mdの一部が「事実」ではなく「手順書」になってきた
CLAUDE.mdは毎回全文を読まれるため、書けば書くほどコンテキスト(Claudeの作業メモリ)を圧迫します。
一方でSkillは、普段は名前と説明文だけが読み込まれ、本文は使うときに初めて読み込まれます。分厚いマニュアルも、背表紙だけ棚に並べておくイメージです。
Claude Code起動時の挙動としては以下のような流れでやりとりが開始されます
※ちなみに、SkillはAnthropic独自の形式ではなく Agent Skills というオープン標準に沿っています。
Claude Codeはそこに「誰が呼び出せるかの制御」「サブエージェントでの実行」「動的なコンテキスト注入」といった独自機能を上乗せしています。
Skillの構造
フォルダ構成
1つのSkillは1つのフォルダです。必須なのは SKILL.md(大文字)だけで、それ以外は必要に応じて追加します。
my-skill/
├── SKILL.md # 必須:概要と手順(本体)
├── reference.md # 任意:詳細資料(必要なときだけ読まれる)
├── examples.md # 任意:使用例
└── scripts/
└── helper.py # 任意:実行用スクリプト(読まれずに実行される)
SKILL.md は500行以内に収め、詳しい資料は別ファイルに逃がすのが公式の推奨です。
SKILL.mdの中身
SKILL.md は「YAMLフロントマター」と「Markdown本文」の2部構成です。
---
name: api-conventions
description: このリポジトリのAPI設計規約。APIエンドポイントを新規作成・修正するときに使う。
---
APIエンドポイントを書くときは次を守ること:
- RESTfulな命名にする
- エラーレスポンスは共通フォーマットで返す
- リクエストのバリデーションを必ず入れる
- フロントマター(--- で囲まれた部分):Claudeが「いつ使うか」を判断する材料
- 本文:Skillが発動したときにClaudeが従う指示
フロントマターの開始 「---」 はファイルの1行目に置く必要があります。
また、YAMLの書式が壊れていると、Skill自体は読み込まれるものの説明文が空扱いになり、自動発動しなくなります。
主なフロントマター項目
すべて省略可能ですが、description だけは実質必須です。
| 項目 | 役割 | 使いどころ |
|---|---|---|
name |
/ メニューに出るコマンド名。省略時はフォルダ名 |
フォルダ名と別名にしたいとき |
description |
何をするSkillで、いつ使うか | 最重要。自動発動の判定に使われる |
when_to_use |
発動のきっかけになる言い回しや例 | description を補足したいとき |
argument-hint |
引数の入力ヒント(例:[issue-number]) |
引数を取るSkill |
disable-model-invocation |
true でClaudeが自動では呼べなくなる |
デプロイなど副作用のある操作 |
user-invocable |
false で / メニューから隠す |
Claudeだけが参照する背景知識 |
allowed-tools |
Skill実行中、許可確認なしで使えるツール | git や自作スクリプトの実行 |
paths |
特定のファイルを扱うときだけ発動させるglob |
src/api/** 専用の規約など |
context / agent
|
fork でサブエージェントとして隔離実行 |
調査系など重い作業 |
model / effort
|
Skill実行中のモデルや思考量を指定 | 軽作業を速く、難しい作業を深く |
description と when_to_use は、合わせて1,536文字を超えると一覧表示で切り詰められます。大事な用途を先頭に書きましょう。
誰が呼び出せるかの制御
| 設定 | ユーザーが / で呼ぶ |
Claudeが自動で呼ぶ | 例 |
|---|---|---|---|
| 既定 | できる | できる | コミットメッセージ作成 |
disable-model-invocation: true |
できる | できない | 本番デプロイ、Slack送信 |
user-invocable: false |
できない | できる | レガシーシステムの解説 |
「コードが良さそうだからデプロイしておきました」とClaudeに判断されたくない操作には、disable-model-invocation: true を付けておくのが鉄則です。
Skillの配置場所
通常利用の場合
まずはホストに直接Claude Codeを入れる「通常利用」での配置を押さえます。
どこに置くかで、どのセッションから使えるかが決まります。
| 種類 | パス | 使える範囲 |
|---|---|---|
| 個人(Personal) | ~/.claude/skills/<skill-name>/SKILL.md |
そのマシンの全プロジェクト |
| プロジェクト(Project) | <リポジトリ>/.claude/skills/<skill-name>/SKILL.md |
そのリポジトリ。gitにコミットすればチームで共有できる |
| ネスト(Nested) | <サブディレクトリ>/.claude/skills/... |
そのサブディレクトリで作業するとき(モノレポ向け) |
| 追加ディレクトリ |
--add-dir で渡したディレクトリの .claude/skills/
|
そのセッションのみ |
| プラグイン | <plugin>/skills/<skill-name>/SKILL.md |
プラグインを有効化した環境(/plugin名:skill名 で呼ぶ) |
| エンタープライズ | 管理設定ディレクトリ内の .claude/skills/
|
組織が配布した全ユーザー |
- 同じ名前のSkillがあるときの優先順位
- エンタープライズ > 個人 > プロジェクト の順で優先されます。たとえば
deployというSkillが 「~/.claude/skills/」 とプロジェクトの 「.claude/skills/」 の両方にあると、/deployで実行されるのは個人のホームディレクトリになります。
プラグインのSkillは/プラグイン名:skill名という名前空間付きになるので衝突しません。
- エンタープライズ > 個人 > プロジェクト の順で優先されます。たとえば
- 編集はその場で反映される
- Claude Codeは 「~/.claude/skills/」 やプロジェクトの 「.claude/skills/」 を監視しており、セッション中にSkillを追加・編集・削除しても再起動なしで反映されます。
ただし、セッション開始時に存在しなかったトップレベルのskillsディレクトリを新しく作った場合は、/reload-skillsを実行する必要があります。
- Claude Codeは 「~/.claude/skills/」 やプロジェクトの 「.claude/skills/」 を監視しており、セッション中にSkillを追加・編集・削除しても再起動なしで反映されます。
Docker運用でのSkill配置
記事の本題である、Docker環境を構築してサンドボックス環境として隔離したいケースです
結論から言うと、プロジェクトSkillはbind mountでそのまま動きますが、個人Skillはひと工夫しないとコンテナから見ることができません。
通常利用からの変更点・注意点としては以下の通りになります
- Claude Codeをコンテナで動かすと、Claude Codeから見えるのは「コンテナの中のファイルシステム」だけです。
- プロジェクトの 「.claude/skills/」 は、プロジェクトごと /workspace にマウントしているのでそのまま見える
- 個人Skillの置き場 「~/.claude/skills/」 は、コンテナ内では 「/home/node/.claude/skills/」 を指す。ホストの 「~/.claude/skills/」 はマウントしない限り見えない
- コンテナ内で直接作ったSkillは、ボリュームに載せていないとコンテナの再作成で消える
| 観点 | 通常利用(ホストに直接インストール) | Docker運用(本記事の構成) |
|---|---|---|
~ が指す場所 |
ホストのホーム | コンテナ内のホーム(例:/home/node) |
| プロジェクトSkill | そのまま使える | bind mount経由でそのまま使える |
| 個人Skill |
~/.claude/skills/ に置くだけ |
ホストのディレクトリをbind mountする必要がある |
| 認証情報・設定 | ホストの ~/.claude に残る |
ボリュームで永続化しないと再作成のたびに消える |
| Skill内スクリプトの実行環境 | ホストのツール | コンテナにインストールしたツール |
| Skillに書くパス | ホストのパス | コンテナ内のパス |
個人的に利用している構成
ポイントは、/home/node/.claude 全体はnamed volume(認証や履歴の永続化用)にし、その中の skills/ だけをホストのディレクトリでbind mountして上書きしている点です。
Dockerはこうした入れ子のマウントを扱えるので、「認証情報はボリュームに閉じ込めつつ、Skillはホストのエディタで編集する」が両立できます。
ホストの ~/.claude 全体をマウントしない理由
ホストの ~/.claude を丸ごとマウントする例もよく見かけます。
手軽ですが、認証トークンや会話履歴がホストとコンテナで混ざり、コンテナ内で動くClaudeから認証情報へアクセスできる状態にもなります。
公式ドキュメントも、ホストの秘密情報をコンテナにマウントしないよう注意しています。
本記事では、Skillだけを選んでマウントする構成をおすすめします。
環境構築:Skillを使えるClaude Codeコンテナを作る
~/claude-docker/
└── Dockerfile
FROM node:22-bookworm-slim
ARG USER_UID=1000
ARG USER_GID=1000
ARG CLAUDE_CODE_VERSION=latest
# Skill内のスクリプトが使うツールもここでインストールする
RUN apt-get update && apt-get install -y --no-install-recommends \
git ca-certificates curl jq ripgrep python3 less procps tzdata \
&& rm -rf /var/lib/apt/lists/*
# ホストのユーザーとUID/GIDを揃える(Linuxホストで重要)
RUN groupmod -o -g ${USER_GID} node \
&& usermod -o -u ${USER_UID} -g ${USER_GID} node
# バージョンを固定したい場合は CLAUDE_CODE_VERSION に指定する
RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
# コンテナ内のClaude Codeの設定
# CLAUDE_CONFIG_DIR : .claude.json もボリューム内に保存させる
# DISABLE_AUTOUPDATER : 更新はイメージの再ビルドで行う
ENV CLAUDE_CONFIG_DIR=/home/node/.claude \
DISABLE_AUTOUPDATER=1 \
TZ=Asia/Tokyo
USER node
# マウント先を node ユーザー所有で先に作っておく
RUN mkdir -p /home/node/.claude/skills \
&& git config --global --add safe.directory /workspace
WORKDIR /workspace
CMD ["claude"]
- Skillのスクリプトが使うツールはイメージに入れる:Skill内のスクリプトはコンテナ内で実行されます。ホストにPythonがあっても、イメージに python3 がなければ動きません。
- UID/GIDをホストに揃える:揃えないと、Claudeがコンテナ内で作成・編集したファイル(Skill含む)がホスト側で別ユーザーの所有になり、編集できなくなることがあります。
- 「/home/node/.claude」 を先に作る:named volumeは、イメージ内にあるマウント先ディレクトリの所有者を引き継いで初期化されます。先に作っておかないとroot所有になり、Claude Codeが設定を書き込めません。
-
CLAUDE_CONFIG_DIRをボリュームのパスに合わせる:Claude Codeは認証情報などを 「~/.claude/」 に、アカウント情報やプロジェクトの信頼設定を別ファイルの 「~/.claude.json」 に保存します。このパスを指定しておくと 「.claude.json」 もボリューム内に保存され、コンテナを作り直しても初回セットアップが繰り返されません。
イメージのビルド
cd ~/claude-docker
docker build -t claudecode-sandbox .
- Linuxホストでは、--build-arg でホストのUID/GIDを渡してください。
- Claude Codeのバージョンを固定したい場合は --build-arg CLAUDE_CODE_VERSION=<バージョン> を追加します。最新版に更新したいときは --no-cache を付けて再ビルドします。
開発ディレクトリのコンテナ起動
mkdir -p ~/claude-skills # 個人Skillの置き場(初回のみ)
cd ~/projects/my-app # 開発したいディレクトリへ移動
docker run -it --rm \
-v "$(pwd)":/workspace \
-v claude-config:/home/node/.claude \
-v "$HOME/claude-skills":/home/node/.claude/skills \
claudecode-sandbox
| オプション | 意味 |
|---|---|
-it |
対話的に操作できるようにする |
--rm |
終了時にコンテナを削除する。認証や設定はボリュームに残るので問題ない |
-v "$(pwd)":/workspace |
今いるディレクトリを作業場所としてマウント。プロジェクトSkill(.claude/skills/)もここに含まれる |
-v claude-config:/home/node/.claude |
認証・設定・会話履歴を named volume に永続化する。初回実行時に自動で作成される |
-v "$HOME/claude-skills":/home/node/.claude/skills |
個人Skillをホストからマウントする。ホストで編集した内容がコンテナにすぐ反映される |
claude-code-local |
ビルドしたイメージ名。後ろにコマンドを書かなければ claude が起動する |
- 初回起動時はログインを求められます。ブラウザでのログインが完了してもコンテナに戻ってこない場合は、ブラウザに表示されたコードをターミナルの
Paste code here if promptedに貼り付けてください。 - APIキーで使う場合は、ホストで
ANTHROPIC_API_KEYを設定したうえでdocker runに -eANTHROPIC_API_KEYを追加します。
Skillの使い方
Skillの呼び出し方は「Claudeに任せる」「自分で呼ぶ」の2通りです。
(1) Claudeに任せる(自動呼び出し)
普段どおりに依頼するだけです。
依頼内容が description に合っていれば、Claudeが自分でSkillを読み込みます。
(2) 自分で呼ぶ(スラッシュコマンド)
メッセージの先頭に /skill名 を書くと、そのSkillが直接実行されます。
/summarize-changes
文中に /deploy と書いた場合は直接は実行されず、「このメッセージ内でClaudeがそのSkillを使ってよい」という許可の意味になります。
引数を渡す
Skill名の後ろに書いた内容は、本文中の $ARGUMENTS に置き換えられます。位置ごとに取り出したいときは $0、$1 を使います。
---
name: fix-issue
description: GitHub Issueを番号指定で修正する
disable-model-invocation: true
argument-hint: [issue-number]
---
GitHub Issue #$ARGUMENTS をコーディング規約に沿って修正してください。
1. Issueの内容を読む
2. 修正を実装する
3. テストを書く
上記のSkill実行例
> /fix-issue 123
Skill関連でよく使うコマンド
| コマンド | 用途 |
|---|---|
/skills |
読み込まれているSkillの一覧と、表示・非表示の切り替え |
/reload-skills |
新しく作ったskillsディレクトリを読み込み直す |
/context |
Skill一覧がどれだけコンテキストを使っているか確認 |
/skill-doctor |
使われていないSkillとそのコストを確認 |
claude --debug |
Skillが読み込まれない原因(YAMLエラーなど)を調べる |
Docker運用での「編集→反映」の流れ
bind mountしているので、ホストのエディタ(VS Codeなど)でSKILL.mdを保存すれば、コンテナ内のClaude Codeにそのまま反映されます。コンテナに入ってvimで編集する必要はありません。
Docker運用でのハマりどころ
| 症状 | 主な原因 | 対処 |
|---|---|---|
ホストの ~/.claude/skills/ に置いたSkillが出てこない |
コンテナからホストのホームは見えない | 個人Skillのディレクトリを /home/node/.claude/skills にbind mountする |
| コンテナを作り直したらSkillやログイン状態が消えた | コンテナ内に直接作っていた/ボリューム未設定 | Skillはbind mount、認証は named volume + CLAUDE_CONFIG_DIR で永続化 |
| 毎回初回セットアップ画面が出る |
~/.claude.json がボリューム外に保存されている |
CLAUDE_CONFIG_DIR をボリュームのパスに合わせる |
Skillのスクリプトが command not found
|
イメージに必要なツールがない | Dockerfileでインストールしてイメージを再ビルド |
Skillのスクリプトが No such file or directory
|
SKILL.mdにホストのパスを書いている |
${CLAUDE_SKILL_DIR} や ${CLAUDE_PROJECT_DIR} を使う |
./script.sh が Permission denied や bad interpreter
|
実行権限が落ちている/改行コードがCRLF |
bash script.sh や python3 script.py の形で呼ぶ。.gitattributes で eol=lf を指定 |
| シンボリックリンクしたSkillが読み込まれない | リンク先がホストの絶対パス | リンクではなく実体のディレクトリをマウントする |
| Claudeが作ったSkillをホストで編集できない | コンテナとホストのUID/GIDが違う |
docker build に --build-arg USER_UID=$(id -u) --build-arg USER_GID=$(id -g) を付けて再ビルド |
gitが dubious ownership で止まり、Skillが失敗する |
リポジトリの所有者がコンテナのユーザーと違う | git config --global --add safe.directory /workspace |
Shell command failed for pattern ... |
注入コマンドが0以外で終了した、または許可されていない |
allowed-tools で許可する。失敗しうるコマンドは || true を付ける |
| ホストで編集した内容が反映されない | ファイル変更の通知がマウント越しに届いていない |
/reload-skills を実行するか、セッションを再起動 |
| 同じ名前のSkillで意図しないほうが動く | 個人Skillがプロジェクトより優先される | 名前を変えるか、片方を /skills でオフにする |
| Skillが自動で発動しない |
description が依頼の言い回しと合っていない |
利用者が実際に使う言葉を description の先頭に入れる。/skill名 で直接呼んで動作確認 |
おわりに
ということで一通りのSkillので説明となります。
claude codeで何かをしてもらうために道具を作ってあげる&使ってもらうというイメージですね。
活用できれば、いろいろな定型的な作業を任せることができて効率化につながる将来が見えます。
チーム内での共有も上手くやることで共有ナレッジとして伝播させやすいかなといった印象でした。