プラグイン開発スキル
新しいプラグインの雛形(スキャフォールド)を生成する開発者向けスキルです。スキルを実行すると、対話形式で必要な情報を収集し、ファイル生成からデプロイテンプレートへの登録までを一括で行います。
nagi には以下の 3 種類のプラグインがあり、それぞれ専用のスキャフォールドスキルが用意されています。
| スキル | 用途 | 配置先 |
|---|---|---|
/create-plugin-channel | メッセージングプラットフォームとの接続 | host/plugins/channel-{name}/ |
/create-container-plugin-mcp | コンテナ内で動作する MCP ツール | container/plugins/mcp-{name}/ |
/create-container-plugin-agent-hooks | エージェント実行時の通知フック | container/{agent}/plugins/agent-hooks-{name}/ |
/create-plugin-channel --- チャンネルプラグイン作成
新しいチャンネルプラグインの雛形を生成します。Slack や Discord のように、外部メッセージングプラットフォームと nagi を接続するためのプラグインです。
トリガー: create channel plugin, new channel, scaffold channel, add channel plugin
対話で聞かれる項目
- チャンネル名(小文字。例:
telegram,whatsapp,line) - 一行の説明(例: "Telegram bot channel via grammy library")
- 使用する SDK / ライブラリ(例:
grammy,whatsapp-web.js) - 必要な認証情報と環境変数名(例:
TELEGRAM_BOT_TOKEN) - JID プレフィックス(例: Telegram なら
tg:、WhatsApp ならwa:)
生成されるファイル構造
host/plugins/channel-{name}/
package.json # @nagi/channel-{name} パッケージ定義
tsconfig.json # TypeScript コンパイル設定
vitest.config.ts # テスト設定
src/
{name}-channel.ts # Channel インターフェースの実装(メインロジック)
index.ts # 公開エクスポート
__tests__/
{name}-channel.test.ts # ユニットテスト上記に加えて、以下の既存ファイルも更新されます。
deploy/templates/host/entry.template.ts--- チャンネル登録ブロックの追加- ルートの
package.json--- ワークスペース依存の追加
主要な設計ルール
チャンネルプラグインを実装する際は、以下のルールに従ってください。
- JID フォーマット:
{prefix}:{platformId}の形式で、すべてのチャンネルを通じて一意である必要があります ownsJid(): 自プラグインの JID プレフィックスだけにtrueを返しますsendMessage(): 例外を投げてはいけません。エラーはログに記録してreturnしますonMessage(): 登録済みグループ(opts.registeredGroups()[jid])からのメッセージだけを通知しますonChatMetadata(): すべてのメッセージに対して呼び出します(グループ検出に使用)- メンション変換: プラットフォーム固有のメンション形式(例:
<@BOT_ID>)をトリガーパターン(@AssistantName)に変換します
スキャフォールド後のカスタマイズ手順
- Channel インターフェースの実装 ---
src/{name}-channel.tsのTODOコメント箇所を埋めますconnect()--- SDK クライアントの初期化、メッセージハンドラの登録sendMessage()--- JID からチャンネル ID を抽出してメッセージ送信setTyping()--- 入力中インジケータの送信(未対応なら no-op)syncGroups()--- グループメタデータの検出(任意)
- SDK の追加 ---
pnpm --filter @nagi/channel-{name} add {sdk-package} - エントリファイルの同期 ---
/deployスキルを実行して Host を選択 - 認証情報の設定 ---
.envにトークンを追加 - テスト実行 ---
pnpm --filter @nagi/channel-{name} test - 再起動 ---
/nagi-restartを実行
参考になる既存プラグイン
host/plugins/channel-slack/--- Socket Mode、スレッド返信、メッセージキューイング、ユーザー名キャッシュhost/plugins/channel-discord/--- Gateway intents、スレッド作成、添付ファイル処理、2000 文字分割
/create-container-plugin-mcp --- MCP プラグイン作成
新しい MCP(Model Context Protocol)プラグインの雛形を生成します。コンテナ内で stdio MCP サーバーとして動作し、エージェントに外部サービスへのアクセス手段を提供します。
トリガー: create mcp plugin, new mcp plugin, add mcp, scaffold mcp
対話で聞かれる項目
- プラグイン名(小文字、
mcp-プレフィックスは不要。例:youtube,github,notion) - 一行の説明(例: "YouTube analytics and video search")
- API トークン / キーの要否と環境変数名(例:
YOUTUBE_API_KEY) - 対象エージェント(Claude Code / Open Code / 両方)
生成されるファイル構造
container/plugins/mcp-{name}/
package.json # @nagi/mcp-{name} パッケージ定義
tsconfig.json # TypeScript コンパイル設定
src/
index.ts # MCP サーバー本体(ツール定義を含む)上記に加えて、以下の既存ファイルも更新されます。
- 選択したエージェントの
Dockerfile--- COPY + ビルドステップの追加 deploy/templates/host/entry.template.ts---registerMcpPluginブロックの追加
MCP サーバーの仕組み
生成される src/index.ts は、@modelcontextprotocol/sdk を使った stdio トランスポートの MCP サーバーです。プレースホルダーとして {name}_hello ツールが含まれており、実際のツールに置き換えて開発を進めます。
環境変数は entry.ts の registerMcpPlugin で env オプションとして渡され、コンテナ内で process.env から読み取れます。API トークンが不要な場合は env オプションが省略されます。
スキャフォールド後のカスタマイズ手順
- ツールの実装 ---
src/index.tsのプレースホルダーツールを実際の機能に置き換えます。server.tool()で複数のツールを登録できます - Docker イメージの再ビルド ---
./container/claude-code/build.shや./container/open-code/build.shを実行 - エントリファイルの同期 ---
/deployスキルを実行して Host を選択 - 認証情報の設定(必要な場合)---
.envに{ENV_VAR}=...を追加 - 再起動 ---
/nagi-restartを実行 - 動作確認 --- Slack や Discord でエージェントに新しいツールの使用を依頼
参考になる既存プラグイン
container/plugins/mcp-ollama/--- API トークン不要。host.docker.internal経由でローカルサービスに接続container/plugins/mcp-vercel/---VERCEL_API_TOKENが必要。外部 REST API を呼び出す
/create-container-plugin-agent-hooks --- エージェントフックプラグイン作成
新しいエージェントフックプラグインの雛形を生成します。エージェントがツールを実行したときやセッションを開始したときに、チャットチャンネルへ通知を送るための仕組みです。
トリガー: create agent hooks plugin, new agent hooks, scaffold agent hooks
対話で聞かれる項目
- プラグイン名(小文字。例:
open-code,cursor,windsurf) - 一行の説明(例: "Tool execution and session notifications for Open Code")
- サポートするフック種別(PostToolUse / SessionStart / 両方)
- 対象エージェント(Claude Code / Open Code / 両方)
生成されるファイル構造
container/{agent}/plugins/agent-hooks-{name}/
index.mjs # フックファクトリ関数(純粋な ES Module)上記に加えて、以下の既存ファイルも更新されます。
deploy/templates/container/{agent}/entry.template.ts--- プラグイン読み込みブロックの追加
エージェントフックの特徴
チャンネルプラグインや MCP プラグインとは異なり、エージェントフックには以下の特徴があります。
- 純粋な JavaScript --- TypeScript ではなく
.mjsファイル 1 つだけで構成されます。ビルドステップもpackage.jsonも不要です - IPC メッセージング ---
/workspace/ipc/messages/に JSON ファイルを書き込むことで、ホストプロセスと通信します - アトミック書き込み ---
.tmpファイルに書き込んでからrenameすることで、部分読み取りを防ぎます - 例外を投げない --- フックのロジックは try/catch で囲み、エラーはログに記録して
{}を返します - 内部ツールのスキップ ---
mcp__nagi__send_messageなど、通知ループを引き起こすツールは自動的にスキップされます
サポートされるフック種別
| フック | タイミング | 用途の例 |
|---|---|---|
PostToolUse | エージェントがツールを実行した後 | 実行したツール名をチャットに通知 |
SessionStart | エージェントセッションの開始時 | "Thinking..." メッセージの送信 |
スキャフォールド後のカスタマイズ手順
- フックのカスタマイズ ---
index.mjsの通知フォーマットや動作条件を編集します - コンテナエントリの同期 ---
/deployスキルを実行して対象エージェントを選択 - Docker イメージの再ビルド ---
./container/claude-code/build.shや./container/open-code/build.shを実行 - 再起動 ---
/nagi-restartを実行 - 動作確認 --- Slack や Discord でツールの実行を伴うメッセージを送信
参考になる既存プラグイン
container/claude-code/plugins/agent-hooks/--- PostToolUse(ツールアイコンとサマリー)と SessionStart("Thinking...")を実装
開発ワークフローのまとめ
3 種類のプラグインに共通する開発の流れは以下のとおりです。
- スキャフォールド --- 上記いずれかのスキルを実行して雛形を生成
- 実装 --- 生成されたファイルの
TODOコメントやプレースホルダーを実際のロジックに置き換え - ビルド / テスト ---
pnpm buildとpnpm test(エージェントフックはビルド不要) - デプロイテンプレートの同期 ---
/deployスキルでentry.tsを更新 - Docker 再ビルド(コンテナプラグインの場合)---
build.shを実行 - 再起動と動作確認 ---
/nagi-restartで反映を確認
スキャフォールド後に手動で生成内容を修正しても問題ありません。スキルは初回の雛形生成のみを担当し、その後の変更は通常の開発フローで管理します。