SpyBara
Go Premium

agent-sdk/plugins.md 2026-11-05 23:03 UTC to 2026-11-06 23:01 UTC

This page contains 4 additions and 0 deletions.

2026
Fri 6 23:01

SDK のプラグイン

Agent SDK を通じてカスタムプラグインを読み込み、スキル、エージェント、フック、MCP サーバーで Claude Code を拡張します

プラグインを使用すると、Claude Code をカスタム機能で拡張でき、プロジェクト全体で共有できます。Agent SDK を通じて、ローカルディレクトリからプログラムでプラグインを読み込み、エージェントセッションに機能を追加できます。プラグインには以下を含めることができます:

  • Skills: Claude が関連する場合に自律的に呼び出す機能。/plugin-name:skill-name でプラグインスキルを直接呼び出すこともできます。
  • Agents: 特定のタスク用の専門的なサブエージェント
  • Hooks: ツール使用およびその他のイベントに応答するイベントハンドラー
  • MCP servers: Model Context Protocol 経由の外部ツール統合

プラグイン構造とプラグインの作成方法に関する完全な情報については、Plugins を参照してください。

プラグインの読み込み

オプション設定でローカルファイルシステムパスを指定してプラグインを読み込みます。type フィールドは "local" である必要があります。これは SDK が受け入れる唯一の値です。SDK は複数の場所から複数のプラグインを読み込むことをサポートしています。

マーケットプレイスまたはリモートリポジトリを通じて配布されているプラグインを使用するには、まずダウンロードしてローカルディレクトリパスを指定してください。プラグインが必要とするディレクトリレイアウトについては、以下のプラグイン構造リファレンスを参照してください。

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Hello",
  options: {
    plugins: [
      { type: "local", path: "./my-plugin" },
      { type: "local", path: "/absolute/path/to/another-plugin" }
    ]
  }
})) {
  // Plugin commands, agents, and other features are now available
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions


async def main():
    async for message in query(
        prompt="Hello",
        options=ClaudeAgentOptions(
            plugins=[
                {"type": "local", "path": "./my-plugin"},
                {"type": "local", "path": "/absolute/path/to/another-plugin"},
            ]
        ),
    ):
        # Plugin commands, agents, and other features are now available
        pass


asyncio.run(main())

パス指定

プラグインパスは以下のいずれかです:

  • 相対パス: cwd オプションを基準に解決されます(例:"./plugins/my-plugin")
  • 絶対パス: 完全なファイルシステムパス(例:"/home/user/plugins/my-plugin")

[!NOTE]

パスはプラグインのルートディレクトリ(skills/、agents/、hooks/、commands/、または .claude-plugin/ の親ディレクトリ)を指す必要があります。

実行中のセッションでプラグインを再読み込みする

新しいセッションを開始せずにプラグインのスキル、コマンド、エージェント、またはフックへの変更を適用するには、TypeScript SDK の Query オブジェクトで reloadPlugins() を呼び出します。Python SDK には同等のメソッドがないため、代わりにセッション内でプロンプトとして /reload-plugins を送信してください。

実行中のセッションにプラグインを追加する

TypeScript SDK では、query() が返した Query オブジェクトで reloadPlugins() を呼び出し、その呼び出しの addPlugins オプションにプラグインディレクトリを指定します。各 addPlugins エントリは、絶対パスの path を持つ { type: "local", path } オブジェクトです。TypeScript Agent SDK v0.3.301 以降が必要です。

この例では、q は query() が返した Query オブジェクトです。この例では、実行中のセッションにプラグインディレクトリを 1 つ追加し、reloadPlugins() が返った後に、セッション内のすべてのプラグインのパスを出力します:

const result = await q.reloadPlugins({
  addPlugins: [{ type: "local", path: "/home/user/plugins/another-plugin" }]
});

console.log(result.plugins.map((plugin) => plugin.path));

プラグインが読み込まれた場合、出力されたリストに /home/user/plugins/another-plugin が含まれます。そのパスがリストにない場合、または reloadPlugins() が reject された場合は、reloadPlugins() が addPlugins のフォルダを読み込まない場合で原因を確認してください。

プラグインインストールの確認

プラグインが正常に読み込まれると、システム初期化メッセージに表示されます。プラグインが利用可能であることを確認できます:

import { query } from "@anthropic-ai/claude-agent-sdk";

for await (const message of query({
  prompt: "Hello",
  options: {
    plugins: [{ type: "local", path: "./my-plugin" }]
  }
})) {
  if (message.type === "system" && message.subtype === "init") {
    // Check loaded plugins
    console.log("Plugins:", message.plugins);
    // Example: [{ name: "my-plugin", path: "/absolute/path/to/my-plugin" }]

    // Plugin skills appear with the plugin name as a prefix
    console.log("Skills:", message.skills);
    // Example: ["my-plugin:greet"]

    // Plugin commands use the same prefix, and skills appear here too
    console.log("Commands:", message.slash_commands);
    // Example: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage


async def main():
    async for message in query(
        prompt="Hello",
        options=ClaudeAgentOptions(
            plugins=[{"type": "local", "path": "./my-plugin"}]
        ),
    ):
        if isinstance(message, SystemMessage) and message.subtype == "init":
            # Check loaded plugins
            print("Plugins:", message.data.get("plugins"))
            # Example: [{"name": "my-plugin", "path": "/absolute/path/to/my-plugin"}]

            # Plugin skills appear with the plugin name as a prefix
            print("Skills:", message.data.get("skills"))
            # Example: ["my-plugin:greet"]

            # Plugin commands use the same prefix, and skills appear here too
            print("Commands:", message.data.get("slash_commands"))
            # Example: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]


asyncio.run(main())

プラグインスキルの使用

プラグインのスキルは競合を避けるためにプラグイン名で自動的に名前空間化されます。直接呼び出すには、プロンプトとして /plugin-name:skill-name を送信してください。

import { query } from "@anthropic-ai/claude-agent-sdk";

// Load a plugin with a custom /greet skill
for await (const message of query({
  prompt: "/my-plugin:greet", // Use plugin skill with namespace
  options: {
    plugins: [{ type: "local", path: "./my-plugin" }]
  }
})) {
  // Claude executes the custom greeting skill from the plugin
  if (message.type === "assistant") {
    console.log(message.message.content);
  }
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock


async def main():
    # Load a plugin with a custom /greet skill
    async for message in query(
        prompt="/my-plugin:greet",  # Use plugin skill with namespace
        options=ClaudeAgentOptions(
            plugins=[{"type": "local", "path": "./my-plugin"}]
        ),
    ):
        # Claude executes the custom greeting skill from the plugin
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(f"Claude: {block.text}")


asyncio.run(main())

[!NOTE]

CLI 経由でプラグインをインストールした場合(例:/plugin install my-plugin@marketplace)、SDK でそのインストールパスを指定することで引き続き使用できます。CLI でインストールされたプラグインについては ~/.claude/plugins/ を確認してください。

完全な例

プラグインの読み込みと使用を示す完全な例を以下に示します:

import { query } from "@anthropic-ai/claude-agent-sdk";
import { fileURLToPath } from "node:url";

async function runWithPlugin() {
  const pluginPath = fileURLToPath(new URL("./plugins/my-plugin", import.meta.url));

  console.log("Loading plugin from:", pluginPath);

  for await (const message of query({
    prompt: "What custom commands do you have available?",
    options: {
      plugins: [{ type: "local", path: pluginPath }],
      maxTurns: 3
    }
  })) {
    if (message.type === "system" && message.subtype === "init") {
      console.log("Loaded plugins:", message.plugins);
      console.log("Available skills:", message.skills);
      console.log("Available commands:", message.slash_commands);
    }

    if (message.type === "assistant") {
      console.log("Assistant:", message.message.content);
    }
  }
}

runWithPlugin().catch(console.error);
#!/usr/bin/env python3
"""Example demonstrating how to use plugins with the Agent SDK."""

import asyncio
from pathlib import Path

from claude_agent_sdk import (
    AssistantMessage,
    ClaudeAgentOptions,
    SystemMessage,
    TextBlock,
    query,
)


async def run_with_plugin():
    """Example using a custom plugin."""
    plugin_path = Path(__file__).parent / "plugins" / "my-plugin"

    print(f"Loading plugin from: {plugin_path}")

    options = ClaudeAgentOptions(
        plugins=[{"type": "local", "path": str(plugin_path)}],
        max_turns=3,
    )

    async for message in query(
        prompt="What custom commands do you have available?", options=options
    ):
        if isinstance(message, SystemMessage) and message.subtype == "init":
            print(f"Loaded plugins: {message.data.get('plugins')}")
            print(f"Available skills: {message.data.get('skills')}")
            print(f"Available commands: {message.data.get('slash_commands')}")

        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    print(f"Assistant: {block.text}")


if __name__ == "__main__":
    asyncio.run(run_with_plugin())

プラグイン構造リファレンス

プラグインディレクトリには通常、.claude-plugin/plugin.json マニフェストファイルが含まれています。マニフェストはオプションです。省略した場合、Claude Code はディレクトリレイアウトからコンポーネントを自動検出します。ディレクトリには以下を含めることができます:

my-plugin/
├── .claude-plugin/
│   └── plugin.json          # Plugin manifest (optional, components auto-discovered without it)
├── skills/                   # Agent Skills (invoked autonomously or via /plugin-name:skill-name)
│   └── my-skill/
│       └── SKILL.md
├── commands/                 # Skills as flat .md files
│   └── custom-cmd.md
├── agents/                   # Custom agents
│   └── specialist.md
├── hooks/                    # Event handlers
│   └── hooks.json
└── .mcp.json                # MCP server definitions

[!NOTE]

commands/ ディレクトリはスキルをフラットな Markdown ファイルとして保持しています。新しいプラグインには skills/ を使用してください。Claude Code は両方の場所をサポートしています。

複数のプラグインソース

異なる場所からプラグインを組み合わせます:

import * as os from "node:os";
import * as path from "node:path";

plugins: [
  { type: "local", path: "./local-plugin" },
  {
    type: "local",
    path: path.join(os.homedir(), ".claude", "custom-plugins", "shared-plugin")
  }
];

[!NOTE]

SDK はチルダパス(~/plugins など)を展開しません。プラグインパスが存在しない場合、SDK はそのプラグインをスキップしてセッションは続行されるため、初期化メッセージの plugins リストを確認して各プラグインが読み込まれたことを確認してください。

トラブルシューティング

プラグインが読み込まれない

プラグインが初期化メッセージの plugins リストに表示されない場合は、その plugin_errors フィールドで理由を確認してから、以下のチェックを実行してください。

  1. パスを確認する: パスがプラグインルートディレクトリ(skills/、agents/、hooks/、commands/、または .claude-plugin/ の親)を指していることを確認してください
  2. plugin.json を検証する: プラグインにマニフェストが含まれている場合、有効な JSON 構文を持っていることを確認してください
  3. ファイルパーミッションを確認する: プラグインディレクトリが読み取り可能であることを確認してください
  4. ディレクトリが存在することを確認する: SDK は存在しないパスをスキップし、プラグインは初期化メッセージの plugins リストに表示されません

スキルが表示されない

プラグインスキルが機能しない場合:

  1. 名前空間を使用する: /plugin-name:skill-name としてプラグインスキルを呼び出してください
  2. 初期化メッセージを確認する: スキルが正しい名前空間で skills リストに表示されることを確認してください
  3. スキルファイルを検証する: 各スキルが skills/ の下の独自のサブディレクトリに SKILL.md ファイルを持っていることを確認してください(例:skills/my-skill/SKILL.md)

関連項目