【Claude Code 連載 第61回】プラグインを作成する — 最初の1本を10分で作る

スポンサーリンク
【Claude Code 連載 第61回】プラグインを作成する — 最初の1本を10分で作る 用語解説
【Claude Code 連載 第61回】プラグインを作成する — 最初の1本を10分で作る
この記事は約18分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

スポンサーリンク

背景

この連載では、Claude Codeの公式ドキュメントを1ページずつ読み解いていきます。公式ドキュメントは情報が網羅されている分、「結局どの機能を、どんな場面で使えばいいのか」は自分で考える必要があり、読むのに意外と時間がかかります。そこで、私が実務で使うために読み込んだ内容を「使う場面→実例コード」の順に整理して残していくことにしました。専門家の解説というより、一次情報を読んだ記録です。推測や動作を確認していない部分には、その都度そう書きます。

1. 一言でいうと何か

第55回はプラグインの技術仕様、第56〜60回は配布と推奨でした。今回は実際に手を動かして作るチュートリアルです。連載の順序としては逆になりましたが、「まず動くものを1つ作る」ならここから始めるのが正解です。

そして最初に扱われるのが、地味ですが重要な判断——プラグインにすべきか、スタンドアロン設定(.claude/ ディレクトリ)で足りるか

アプローチスキル名最適な用途
スタンドアロン.claude/ ディレクトリ)/hello個人的なワークフロー、プロジェクト固有のカスタマイズ、クイック実験
プラグイン(スキル・エージェント・フック、または .claude-plugin/plugin.json マニフェストを含む自己完結型ディレクトリ)/plugin-name:helloチームとの共有、コミュニティ配布、バージョン管理されたリリース、プロジェクト横断の再利用

スタンドアロンを選ぶのは、単一プロジェクト向け、共有不要、パッケージ化前の実験段階、そして**/hello/deploy のような短いスキル名が欲しい**とき。

プラグインを選ぶのは、共有したい、複数プロジェクトで同じものを使いたい、バージョン管理と更新が要る、マーケットプレイス配布する、そして**/my-plugin:hello のような名前空間付きスキルで問題ない**とき(名前空間はプラグイン間の競合を防ぐため)。

公式の勧め方が実務的です。**.claude/ で素早く反復し、共有する準備ができたらプラグインに変換する。**変換手順もこのページに載っています(後述)。

2. どういう場面で役立つか

シーン1:チームの定型作業を1つのスキルにして配る

コードレビューの観点、コミットの作法、デプロイ前チェック——口頭やドキュメントで共有していたものを、/plugin-name:xxx として実行可能な形にする。これがプラグインの一番素直な用途です。

シーン2:スタンドアロン設定が育ちすぎたので整理する

.claude/commands/ にファイルが溜まってきて、他のプロジェクトでも使いたくなった。移行手順が用意されているので、cp で移してマニフェストを1枚書けば終わります。

シーン3:公式 LSP プラグインがない言語をサポートする

**まず「一般的な言語は公式マーケットプレイスから入れろ」と釘を刺されます。**カスタム LSP プラグインを作るのは、既に対応されていない言語が必要な場合だけです。

シーン4:プラグインが有効な間だけ Claude の振る舞いを変える

settings.jsonagent キーで、**プラグインのカスタムエージェントをメインスレッドとしてアクティブにできます。**そのシステムプロンプト、ツール制限、モデルが適用される——プラグインを有効にするだけで Claude Code の動き方が変わるわけです。

不要・向かないケース

  • 短いスキル名が欲しいプラグインスキルは常に名前空間が付きます。/hello にしたいならスタンドアロンです。
  • 1プロジェクト限定の実験。マニフェストを書く手間の分だけ損です。
  • .claude/ から移行したのに元ファイルを消していない。**プロジェクトとユーザーの .claude/agents/ 定義は、同名のプラグインエージェントをオーバーライドします。**消さないとプラグイン版が効きません(スキルは名前空間が違うので共存します)。
  • ~/.claude/ をプラグインルートと勘違いするプラグインルートは .claude-plugin/plugin.json を含むディレクトリであって ~/.claude/ ではありません。~/.claude/.mcp.json に置いた .mcp.json は読み込まれません。
  • 信頼していない .zip--plugin-url で読み込むプラグインソースには通常のインストールと同じ信頼上の考慮が適用されます。制御下にあるか信頼できるアーカイブだけを指すこと。

3. 手を動かす

クイックスタート:最初のプラグイン

前提は Claude Code がインストール・認証済みであることだけ。/plugin コマンドが見当たらないなら最新版に更新します。

まずディレクトリを作ります。mkdir my-first-plugin で作り、その中に mkdir my-first-plugin/.claude-plugin を作る。テストでは --plugin-dir で場所を指すので、置き場所はどこでも構いません。

マニフェストを my-first-plugin/.claude-plugin/plugin.json に書きます。

{
  "name": "my-first-plugin",
  "description": "A greeting plugin to learn the basics",
  "version": "1.0.0",
  "author": {
    "name": "Your Name"
  }
}

4フィールドの役割はこうです。name は一意の識別子であり、スキルの名前空間(スキルにこれが接頭辞として付く)。description はプラグインマネージャーで参照・インストールするときに表示される。version はオプションで、設定するとこのフィールドをバンプしたときだけユーザーが更新を受け取り、省略して git 配布なら全コミットが新バージョン扱い(第55・56回で繰り返された話です)。author もオプション

次にスキル。mkdir -p my-first-plugin/skills/hello を作り、SKILL.md を置きます。フォルダ名がスキル名になり、プラグインの名前空間が接頭辞として付きます——my-first-plugin の中の hello//my-first-plugin:hello になる。

---
description: Greet the user with a friendly message
disable-model-invocation: true
---
Greet the user warmly and ask how you can help them today.

テストは --plugin-dir で読み込むだけです。

claude --plugin-dir ./my-first-plugin

起動したら実行します。

/my-first-plugin:hello

/help を実行すると、プラグイン名前空間の下にスキルがリストされているのが確認できます。

名前空間を変えたい場合は plugin.jsonname を変更します。

引数を受け取る

$ARGUMENTS プレースホルダーでユーザー入力を拾えます。SKILL.md をこう書き換えます。

---
description: Greet the user with a personalized message
---
# Hello Skill
Greet the user named "$ARGUMENTS" warmly and ask how you can help them today. Make the greeting personal and encouraging.

/reload-plugins で変更を反映させてから実行します。

/my-first-plugin:hello Alex

ここまでで押さえた要素は3つ——マニフェスト(.claude-plugin/plugin.json)、スキルディレクトリ(skills/)、スキル引数($ARGUMENTS

毎回 --plugin-dir を渡さずに開発する

スキルディレクトリに置けば自動で読み込まれます。スキャフォルドコマンドがあります。

claude plugin init my-tool

~/.claude/skills/my-tool/.claude-plugin/plugin.json とスターター SKILL.md が作られ、次のセッションからマーケットプレイスもインストール手順もなしに my-tool@skills-dir として読み込まれます(第55回で扱った skills ディレクトリプラグイン)。

プラグイン構造の全体像

最頻出のミスが Warning として明記されています。commands/agents/skills/hooks/.claude-plugin/ の中に置かないでください。.claude-plugin/ に入るのは plugin.json だけです。

そして前述の補足——プラグインルートは .claude-plugin/plugin.json を含むディレクトリであって ~/.claude/ ではない。~/.claude/.mcp.json は読み込まれません。

ディレクトリ目的
.claude-plugin/plugin.json マニフェスト(デフォルト位置を使うならオプション)
skills/<name>/SKILL.md 形式のスキル
commands/フラットな Markdown としてのスキル。新しいプラグインには skills/ を使う
agents/カスタムエージェント定義
hooks/hooks.json のイベントハンドラー
.mcp.jsonMCP サーバー設定
.lsp.jsonLSP サーバー設定
monitors/monitors.json のバックグラウンドモニター設定
bin/プラグインが有効な間、Bash ツールの PATH に追加される実行可能ファイル
settings.jsonプラグイン有効化時に適用されるデフォルト設定

スキルがちょうど1つなら、skills/ を作らずプラグインルートに SKILL.md を直接置けます。その場合はフロントマターの name が呼び出し名になります。複数に育つ可能性があるなら skills/ レイアウトを使ってください。

スキルを足す

skills/ の下にフォルダを作り、SKILL.md を置くだけです。

my-plugin/
├── .claude-plugin/
│   └── plugin.json
└── skills/
    └── code-review/
        └── SKILL.md

スキルはモデル呼び出し型——**Claude がタスクの文脈に基づいて自動的に使います。**だから description が肝で、いつ使うべきかを Claude に伝える必要があります。

---
description: Reviews code for best practices and potential issues. Use when reviewing code, checking PRs, or analyzing code quality.
---
When reviewing code, check for:
1. Code organization and structure
2. Error handling
3. Security concerns
4. Test coverage

description“Use when reviewing code, checking PRs, or analyzing code quality.” と発火条件を書き込んでいるのが手本です。単なる説明ではなく、トリガー条件を含める。

LSP サーバーを足す

前述のとおりまず公式マーケットプレイスを確認。無い言語だけ自分で作ります。.lsp.json を置くだけです。

{
  "go": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}

プラグインをインストールするユーザー側に、言語サーバーのバイナリが必要な点は第55・57回と同じです。

バックグラウンドモニターを足す

プラグインがアクティブなら Claude Code が各モニターを自動的に開始するので、Claude に「モニターを起動して」と指示する必要はありません。

[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]

command の stdout の各行が、セッション中に Claude への通知として配信されます。

デフォルト設定を配布する

プラグインルートの settings.json で、プラグイン有効化時に適用される設定を配れます。現在サポートされるのは agentsubagentStatusLine の2キーのみ。

{
  "agent": "security-reviewer"
}

これは**プラグインの agents/ で定義した security-reviewer エージェントをメインスレッドとしてアクティブにします。**そのシステムプロンプト・ツール制限・モデルが適用される。

優先順位も明記されています。settings.json の設定は plugin.json で宣言された settings より優先し、不明なキーは無視されます。

ローカルでテストする

開発中は --plugin-dir が基本ですが、いくつかバリエーションがあります。

方法用途
claude --plugin-dir ./my-pluginディレクトリを直接読み込む(インストール不要)
claude --plugin-dir ./my-plugin.zip.zip アーカイブも受け付ける(v2.1.128 以降)
claude --plugin-dir ./plugin-one --plugin-dir ./plugin-twoフラグを繰り返して複数読み込み
claude --plugin-url https://example.com/my-plugin.zipURL でホストされた .zip(CI ビルド成果物など)を起動時にフェッチし、そのセッションのみ読み込む
claude --plugin-url "https://example.com/a.zip https://example.com/b.zip"スペース区切りの URL を1つの引用符付き引数で渡す

--plugin-dir には便利な優先規則があります。インストール済みのマーケットプレイスプラグインと同名なら、そのセッション中はローカルコピーが優先されます。つまり先にアンインストールしなくても、既存プラグインへの変更をテストできる。唯一の例外は管理設定で強制的に有効化されたマーケットプレイスプラグインで、これはオーバーライドできません。

--plugin-url の失敗時の挙動も明示されています。フェッチが失敗するかアーカイブが無効なら、Claude Code はプラグイン読み込みエラーを報告して、それなしで起動します。

変更を加えたら /reload-plugins で再起動なしに反映。プラグイン・スキル・エージェント・フック・プラグイン MCP サーバー・プラグイン LSP サーバーが再読み込みされます。

コンポーネント別の確認方法が具体的です。スキルは /plugin-name:skill-name で試す。エージェントは /context でカスタムエージェントの下に表示されるか確認するか、スコープ付き名で @-mention する。フックは期待どおり動くか確認する。

うまく動かないときの順序も3ステップで示されています。構造を確認する(ディレクトリが .claude-plugin/ の中でなくプラグインルートにあるか)、コンポーネントを個別にテストする検証とデバッグツールを使う

スタンドアロン設定を移行する

.claude/ に既にあるものをプラグインにする手順です。

まず mkdir -p my-plugin/.claude-plugin を作り、マニフェストを書きます。既存の .claude/ フォルダの隣に置くと、次のステップの相対パスが解決します。

そしてコピー。

# Copy commands
cp -r .claude/commands my-plugin/
# Copy agents (if any)
cp -r .claude/agents my-plugin/
# Copy skills (if any)
cp -r .claude/skills my-plugin/

フックがあるなら mkdir my-plugin/hooks を作り、.claude/settings.jsonsettings.local.jsonhooks オブジェクトをコピーします。形式は同じです。

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npm run lint:fix" }]
      }
    ]
  }
}

この例のコマンドが jq を使っている理由も説明されています——フックコマンドはフック入力を stdin で JSON として受け取るため、jq でファイルパスを抽出します。

テストは claude --plugin-dir ./my-plugin で。

移行で何が変わるかの対照はこうです。

スタンドアロン(.claude/プラグイン
1つのプロジェクトでのみ利用可能マーケットプレイス経由で共有可能
.claude/commands/ 内のファイルplugin-name/commands/ 内のファイル
settings.json のフックhooks/hooks.json のフック
共有するには手動コピーが必要/plugin install でインストール

そして移行後の後始末が重要です。重複を避けるため .claude/ から元ファイルを削除してください。理由は非対称です——エージェントは、プロジェクトとユーザーの .claude/agents/ 定義が同名のプラグインエージェントをオーバーライドするので、消さないとプラグイン版が効きません。一方スキルは /plugin-name:skill-name と名前空間化されるので、元の /skill-name とプラグイン版が共存します(どちらかが上書きするのではなく両方使える)。

共有と、コミュニティマーケットプレイスへの送信

共有の準備は4つ——README.md を用意するバージョン管理戦略を決める(明示的な version か git コミット SHA か)、マーケットプレイスを作るか使う他のユーザーにテストしてもらう。チーム内に留めたいならプライベートリポジトリでマーケットプレイスをホストします(第56回)。

そして第57回で触れた2つの公開マーケットプレイスについて、ここに最も詳しい説明があります。

claude-plugins-officialAnthropic 管理のキュレーションされたセットで、初めて Claude Code をインタラクティブに起動したときに自動登録されます。ただし注意点があり、最初の起動前に実行される非インタラクティブスクリプトは、claude plugin marketplace add anthropics/claude-plugins-official で明示的に追加する必要があります。CI で使うなら知っておくべき挙動です。

claude-communityレビュー後にサードパーティの送信が登録される公開マーケットプレイス。ユーザーは /plugin marketplace add anthropics/claude-plugins-community で追加し、@claude-community としてインストールします。

送信フォームは2つあり、使い分けの条件が明確です。claude.ai のフォーム(claude.ai/admin-settings/directory/submissions/plugins/new)は Team または Enterprise 組織とディレクトリ管理アクセスが必要(組織の所有者はデフォルトで保有)。組織に属していない個人の作成者は Console のフォーム(platform.claude.com/plugins/submit)を使えます。

送信前に claude plugin validate をローカルで実行してください。レビューパイプラインは全送信に同じチェックを実行し、加えて自動セーフティスクリーニングも行います。

承認後の流れも書かれています。承認されたプラグインは anthropics/claude-plugins-community カタログ内の特定のコミット SHA にピン留めされ、CI がリポジトリへの新規コミットごとに自動でピンをバンプします。公開カタログはレビューパイプラインから毎晩同期されるので、承認から marketplace.json に現れるまで遅延が生じうる——インストール可能かはコミュニティカタログで名前を検索して確認します。

最後にもう一度、公式マーケットプレイスは別途キュレーションされ、Anthropic が裁量で決める。申請プロセスはなく、送信フォームは公式には追加しません。そして公式に載っていれば、CLI からインストールを促せる(第60回の plugin-hints)。

4. まとめ + 次回予告

  • 共有しないならスタンドアロン、共有するならプラグイン。.claude/ で反復して、あとから変換するのが公式の勧め。
  • 最小構成は .claude-plugin/plugin.jsonskills/<name>/SKILL.mdフォルダ名がスキル名になり、plugin.jsonname が名前空間になる。
  • **$ARGUMENTS でユーザー入力を受け取る。**変更後は /reload-plugins
  • claude plugin init なら ~/.claude/skills/ にスキャフォルドされ、--plugin-dir なしで自動読み込みされる。
  • **.claude-plugin/ に入るのは plugin.json だけ。**他は全部プラグインルート。プラグインルートは ~/.claude/ ではない。
  • **スキルの description には発火条件を書く。**モデル呼び出し型だから。
  • settings.jsonagent キーで、プラグインのエージェントをメインスレッドにできる(サポートは agentsubagentStatusLine のみ)。
  • テストは --plugin-dir.zip も可、複数指定も可)。同名のインストール済みプラグインより優先されるので、アンインストールせずに検証できる。URL 配布の .zip--plugin-url(そのセッション限り、失敗しても起動はする)。
  • **移行後は .claude/ の元ファイルを消す。**エージェントは .claude/agents/ が優先されるが、スキルは名前空間が違うので共存する。
  • コミュニティ送信は claude.ai(Team/Enterprise)か Console(個人)のフォームから。**送信前に claude plugin validate。**承認後もカタログ反映は毎晩の同期待ち。
  • **公式マーケットプレイスに申請プロセスはない。**Anthropic の裁量。

第54回から8本続いたプラグイン系は、これで完結です。作る・包む・配る・受け取る・依存・推奨(2種)・そして作成チュートリアル。

次回予告(暫定):**ツールリファレンス(tools-reference)**を取り上げ、第55回で参照した Monitor tool を含む、Claude Code が持つツール群の仕様を扱う予定です。


よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました