
Cursor のプラグインシステムは、公式ドキュメントを読んだだけでは「なんとなく分かった気がする」で止まりがちです。
でも cursor/plugins リポジトリを実際に開いてコードを読むと、構造はかなりシンプルで、自社業務向けのカスタムプラグインを書くハードルが一気に下がります。
公式リポジトリのディレクトリ構成・マニフェストの型定義・スキルとルールの宣言パターンを順番に読み解きながら、最小のカスタムプラグインを自分で書けるようになることをゴールに置きます。
型定義を読んでいないと踏む地雷や、ローカルテストのつまずきポイントも具体的に触れるので、公式プラグインを改造する際の判断軸として使ってください。
Cursor プラグインとは何をしている仕組みか
Cursor プラグインを一言で言うと、「エージェントが何をできるかを宣言するパッケージ」です。
スキル・ルール・MCP サーバー定義をひとまとめにして配布できる単位、と考えると分かりやすいです。
重要なのは、これが Cursor 独自の仕様ではない点です。
Agent Plugins 1.0 という業界横断の共通仕様に乗っており、OpenAI・AWS・Cursor・GitHub・Vercel が合意した形式として策定されています。
今この仕様を読んでおくと、将来的に他のエージェントランタイムに横展開しやすい知識になります。
.claude/ のスキルファイルや agent-skills と概念的に近い部分はありますが、Cursor プラグインは plugin.json を中心としたマニフェスト駆動の構造を持ち、マーケットプレイス配布やチームへの一括展開まで視野に入れた設計になっています。
そこが本記事で踏み込む差別化ポイントです。
エージェントはプラグインをインストールすることで、宣言されたスキルを呼び出し可能なツールとして認識し、ルールをコンテキストとして取り込み、MCP サーバー経由で外部システムへアクセスできるようになります。
「エージェントに何かを覚えさせる」というより、「エージェントが使える道具と振る舞いのセットを定義する」というイメージが正確です。
cursor/plugins リポジトリの構造をコードから読む
リポジトリを開くと、まずこのディレクトリ構成が目に入ります。
cursor/plugins/
├── .cursor-plugin/
│ └── marketplace.json # マーケットプレイス全体のマニフェスト(プラグイン一覧)
├── gmail/
│ ├── .cursor-plugin/
│ │ └── plugin.json # プラグイン個別のマニフェスト
│ ├── skills/ # エージェントスキル(SKILL.md をサブディレクトリに配置)
│ ├── rules/ # Cursor ルール(.mdc ファイル)
│ ├── mcp.json # MCP サーバー定義
│ ├── README.md
│ ├── CHANGELOG.md
│ └── LICENSE
├── google-drive/
│ └── ...
├── orchestrate/
│ └── ...
└── cursor-sdk/
└── ...
ルート直下の .cursor-plugin/marketplace.json がプラグイン一覧を管理する「目次」で、各プラグインディレクトリの .cursor-plugin/plugin.json が個別の仕様書にあたります。
skills/・rules/・mcp.json は全部オプションで、必要なものだけ置けばいい構成です。
公式プラグインのラインナップを見ると、粒度の感覚がつかめます。
gmail や google-drive は特定 SaaS との連携を担い、orchestrate は並列エージェントのタスク分散を管理し、cursor-sdk は TypeScript SDK の操作スキルをまとめています。
「一つのサービスや一つのワークフロー」を単位にプラグインが切られているイメージです。
single plugin と multi-plugin の選択は、用途で判断します。
自社業務向けに一つのプラグインを作るだけなら single が楽です。
リポジトリルートに plugin.json を置き、marketplace.json は不要になります。
チームで複数のプラグインをまとめて管理・配布したい場合は multi を選び、公式リポジトリと同じ構成にします。
最初は single から始めて、増えてきたら multi に移行するのが現実的な流れです。
マニフェスト(plugin.json)の型定義を正確に読む
plugin.json は closed-schema です。
許可されているトップレベルフィールドは厳密に10個だけで、それ以外のフィールドを書いてもクライアントは「報告して無視する」義務があります。
バリデーションは厳格で、知らずに独自フィールドを足しても動作はしますが、仕様上は未定義の動作として扱われます。
許可されている10フィールドのうち、必須は $schema と name の2つだけです。
残りの version・description・author・homepage・repository・license・keywords・extensions はすべて任意です。
まず最小有効マニフェストはこれだけです。
{
"$schema": "https://cursor.com/schemas/plugin/1.0.0/plugin.schema.json",
"name": "my-plugin"
}
$schema を省略するとバリデーターが仕様バージョンを特定できないため、必ず入れます。
name の命名規則は意外と厳格で、小文字の英数字・ハイフン・ピリオドのみ使用可能、先頭と末尾は英数字、-- や .. の連続は禁止、64文字以内という制約があります。
My-Plugin や my_plugin はその時点でバリデーションエラーになります。
業務プラグイン向けに主要フィールドを埋めた実用例はこうなります。
{
"$schema": "https://cursor.com/schemas/plugin/1.0.0/plugin.schema.json",
"name": "internal-api-tools",
"version": "0.1.0",
"description": "社内 API 呼び出しと業務ファイル操作のスキルセット",
"author": {
"name": "Your Team"
},
"license": "MIT",
"keywords": ["internal", "api", "workflow"],
"extensions": {
"skills": [
{ "path": "skills/fetch-order" },
{ "path": "skills/export-csv" }
],
"rules": [
{ "path": "rules/api-conventions.mdc" }
]
}
}
extensions フィールドがスキル・ルール・MCP などの拡張点をまとめる場所です。
ここに列挙したパスがエージェントに読み込まれます。
一つ踏みやすい地雷として、sessionStart フィールドがあります。
Agent Plugins 1.0 の仕様ドキュメントには記載があるのですが、現時点の Cursor バリデーターはこれを弾きます。
「仕様書に書いてあるから使える」と思って入れると、ロードに失敗するので注意してください。
スキルとルールの宣言パターンを公式コードから逆引きする
skills/ 配下の構造は、スキル名のサブディレクトリを作り、その中に SKILL.md を置く形です。
ファイル本体はマークダウンですが、先頭に YAML フロントマターでエージェントへの呼び出し方を宣言します。
---
description: 受注番号を指定して社内 API から注文情報を取得する
globs:
- "**/*.ts"
- "**/*.py"
alwaysApply: false
---
# fetch-order スキル
受注番号(order_id)を引数に取り、社内受注管理 API の /orders/{order_id} エンドポイントを呼び出して結果を返す。
レスポンスは JSON 形式で、items・status・customer_id を含む。
description がエージェントにとっての「このスキルを呼ぶべき状況の説明」になります。
ここが曖昧だとエージェントがスキルを呼ばない原因になるので、「何を入力として何を返すか」を具体的に書くのがコツです。
rules/ 配下の .mdc ファイルは、エージェントの振る舞いを制約するルールです。
フロントマターで alwaysApply: true にすると常時適用され、globs でファイルパターンを指定するとそのファイルを操作するときだけ適用されます。
API の命名規則や禁止操作を書いておくのが典型的な使い方です。
mcp.json は MCP サーバーの接続定義を書く場所です。
社内 API を MCP サーバーとして立てている場合、こんな形で宣言します。
{
"mcpServers": {
"internal-api": {
"command": "node",
"args": ["./mcp-server/index.js"],
"env": {
"API_BASE_URL": "https://api.internal.example.com",
"API_KEY": "${INTERNAL_API_KEY}"
}
}
}
}
環境変数は ${VAR_NAME} 形式で参照できます。
シークレットをファイルにハードコードせず .env から渡す運用が基本です。
「業務フロー固有の操作をどこに書くか」の判断軸はシンプルです。
エージェントに手順を教えたいなら スキル、エージェントの振る舞いを制約したいなら ルール、外部システムへのアクセスを与えたいなら MCP です。
この三つを組み合わせると、「社内 API から情報を取ってきて、特定のフォーマットで出力する」という業務フローをプラグインとして完結させられます。
ローカルで動かしながら最小プラグインを育てる
ローカルテストは ~/.cursor/plugins/local/ にプラグインディレクトリを置くだけで読み込まれます。
Cursor を再起動するか、プラグイン設定を再読み込みすると反映されます。
公式プラグインを起点にスケルトンを作るなら、orchestrate か cursor-sdk あたりが参考にしやすいです。
構造がシンプルで、スキルとルールの両方が入っているので削ぎ落としやすいです。
やることは「自分のユースケースに関係ないスキルを全部消して、plugin.json の name と extensions を書き直す」だけです。
最初は skills/ 一つ・rules/ なし・mcp.json なしの最小構成から始めて、動作確認しながら足していくのが安全です。
つまずきやすいポイントと切り分け方をまとめます。
- バリデーションエラーが出る: まず name の命名規則を疑います。大文字・アンダースコア・-- の連続が混入していないか確認してください。次に $schema の URL が正しいかを確認します。Cursor のバリデーターはスキーマ URL でバージョンを判定するので、古い URL や typo があるとエラーになります。
- スキルがエージェントに呼ばれない: SKILL.md の description が曖昧な可能性が高いです。「どんな状況でこのスキルを使うべきか」を具体的に書き直してみてください。extensions.skills のパスが実際のディレクトリと一致しているかも確認します。
- mcp.json の接続が失敗する: command に指定したプロセスが起動できているか、ポートやパスが正しいかを先に確認します。環境変数が未定義のまま ${VAR_NAME} を参照していると、サーバー起動時にエラーになります。
- name 命名規則違反: エラーメッセージに「invalid plugin name」が含まれていたら命名規則違反です。lowercase kebab-case に統一して、先頭・末尾が英数字になっているか確認してください。
最小プラグインが動いたら、スキルの description を育てるのが一番効果的な改善です。
エージェントがスキルを選ぶ判断はほぼ description の質で決まります。
実際にエージェントに使わせてみて、呼ばれなかったケースの状況を description に追記していくサイクルが、実務では一番早く精度が上がります。
Agent Plugins 1.0 という共通仕様に乗っているので、一度書いた知識は他のエージェントランタイムにも転用できます。
今のうちにリポジトリを手元で動かしておく価値は十分あります。
株式会社ホコサキは山口県宇部を拠点に、Web 制作・業務システム開発・AI 活用支援を手がけています。
Cursor プラグインのような開発ツール活用から、業務フローへの AI 組み込みまで、実務に即した支援が得意です。
興味があればお気軽に お問い合わせ ください。

