SpyBara
Go Premium

agent-sdk/plugins.md 2026-11-10 21:57 UTC to 2026-11-11 22:59 UTC

No changes for this document in this history range.

2026
Fri 6 23:01

Plugin nell'SDK

Carica plugin personalizzati per estendere Claude Code con skills, agenti, hooks e server MCP tramite l'Agent SDK

I plugin ti permettono di estendere Claude Code con funzionalità personalizzate che possono essere condivise tra i progetti. Attraverso l'Agent SDK, puoi caricare programmaticamente i plugin da directory locali per aggiungere capacità alle tue sessioni di agente. Un plugin può includere:

  • Skills: capacità che Claude invoca autonomamente quando rilevante. Puoi anche invocare direttamente una skill del plugin con /plugin-name:skill-name.
  • Agents: subagenti specializzati per compiti specifici
  • Hooks: gestori di eventi che rispondono all'uso degli strumenti e ad altri eventi
  • MCP servers: integrazioni di strumenti esterni tramite Model Context Protocol

Per informazioni complete sulla struttura dei plugin e su come creare plugin, vedi Plugins.

Caricamento dei plugin

Carica i plugin fornendo i loro percorsi del file system locale nella configurazione delle opzioni. Il campo type deve essere "local", l'unico valore che l'SDK accetta. L'SDK supporta il caricamento di più plugin da posizioni diverse.

Per utilizzare un plugin distribuito tramite un marketplace o un repository remoto, scaricalo prima e fornisci il percorso della directory locale. Per il layout della directory di cui un plugin ha bisogno, vedi il riferimento della struttura del plugin di seguito.

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())

Specifiche dei percorsi

I percorsi dei plugin possono essere:

  • Percorsi relativi: risolti rispetto all'opzione cwd (ad esempio, "./plugins/my-plugin")
  • Percorsi assoluti: percorsi completi del file system (ad esempio, "/home/user/plugins/my-plugin")

[!NOTE]

Il percorso deve puntare alla directory radice del plugin: la directory padre di skills/, agents/, hooks/, commands/, o .claude-plugin/.

Ricaricare i plugin in una sessione in esecuzione

Per applicare una modifica alle skill, ai comandi, agli agenti o agli hook di un plugin senza avviare una nuova sessione, chiama reloadPlugins() sull'oggetto Query dell'SDK TypeScript. L'SDK Python non espone un metodo equivalente; invia invece /reload-plugins come prompt nella sessione.

Aggiungere plugin a una sessione in esecuzione

Nell'SDK TypeScript, chiama reloadPlugins() sull'oggetto Query restituito da query() ed elenca la directory del plugin nell'opzione addPlugins di quella chiamata. Ogni voce di addPlugins è un oggetto { type: "local", path } con un path assoluto. Richiede l'Agent SDK TypeScript v0.3.301 o successivo.

In questo esempio, q è l'oggetto Query restituito da query(). L'esempio aggiunge una directory di plugin alla sessione in esecuzione e, dopo che reloadPlugins() ha restituito il risultato, stampa il percorso di ogni plugin nella sessione:

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

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

Se il plugin è stato caricato, l'elenco stampato include /home/user/plugins/another-plugin. Se quel percorso manca dall'elenco, o se reloadPlugins() viene rifiutata, consulta Quando reloadPlugins() non carica le cartelle di addPlugins per conoscerne le cause.

Verifica dell'installazione del plugin

Quando i plugin si caricano correttamente, appaiono nel messaggio di inizializzazione del sistema. Puoi verificare che i tuoi plugin siano disponibili:

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())

Utilizzo delle skills dei plugin

Le skills dai plugin vengono automaticamente associate allo spazio dei nomi del plugin per evitare conflitti. Per invocare una direttamente, invia /plugin-name:skill-name come prompt.

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]

Se hai installato un plugin tramite la CLI (ad esempio, /plugin install my-plugin@marketplace), puoi comunque utilizzarlo nell'SDK fornendo il suo percorso di installazione. Controlla ~/.claude/plugins/ per i plugin installati tramite CLI.

Esempio completo

Ecco un esempio completo che dimostra il caricamento e l'utilizzo dei plugin:

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())

Riferimento della struttura del plugin

Una directory di plugin contiene tipicamente un file manifest .claude-plugin/plugin.json. Il manifest è facoltativo. Quando omesso, Claude Code scopre automaticamente i componenti dal layout della directory. La directory può includere:

my-plugin/
├── .claude-plugin/
│   └── plugin.json          # Plugin manifest (facoltativo, componenti auto-scoperti senza di esso)
├── skills/                   # Agent Skills (invocati autonomamente o via /plugin-name:skill-name)
│   └── my-skill/
│       └── SKILL.md
├── commands/                 # Skills come file .md flat
│   └── custom-cmd.md
├── agents/                   # Agenti personalizzati
│   └── specialist.md
├── hooks/                    # Gestori di eventi
│   └── hooks.json
└── .mcp.json                # Definizioni del server MCP

[!NOTE]

La directory commands/ contiene skills come file Markdown flat. Usa skills/ per i nuovi plugin. Claude Code supporta entrambe le posizioni.

Più fonti di plugin

Combina i plugin da posizioni diverse:

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]

L'SDK non espande i percorsi con tilde come ~/plugins. Se un percorso del plugin non esiste, l'SDK salta quel plugin e la sessione continua, quindi controlla l'elenco plugins nel messaggio di init per confermare che ogni plugin è stato caricato.

Troubleshooting

Plugin non caricato

Se il tuo plugin non appare nell'elenco plugins del messaggio di init, controlla il suo campo plugin_errors per il motivo, quindi procedi con questi controlli:

  1. Controlla il percorso: assicurati che il percorso punti alla directory radice del plugin, la directory padre di skills/, agents/, hooks/, commands/, o .claude-plugin/
  2. Valida plugin.json: se il tuo plugin include un manifest, assicurati che abbia una sintassi JSON valida
  3. Controlla i permessi dei file: assicurati che la directory del plugin sia leggibile
  4. Conferma che la directory esista: l'SDK salta un percorso inesistente e il plugin non appare nell'elenco plugins del messaggio di init

Skills non appaiono

Se le skills dei plugin non funzionano:

  1. Usa lo spazio dei nomi: invoca le skills dei plugin come /plugin-name:skill-name
  2. Controlla il messaggio di init: verifica che la skill appaia nell'elenco skills con lo spazio dei nomi corretto
  3. Valida i file delle skills: assicurati che ogni skill abbia un file SKILL.md nella sua sottodirectory sotto skills/, ad esempio skills/my-skill/SKILL.md

Vedi anche