SpyBara
Go Premium

plugins/components.md 2026-09-27 23:59 UTC to 2026-09-28 22:01 UTC

This page contains 1 addition and 1 deletion.

2026
Fri 25 23:58 Mon 28 22:59

Ajouter des composants à un plugin

Ajoutez des skills, des hooks, des serveurs MCP et tous les autres types de composants à un plugin Claude Code, avec un exemple qui valide chacun.

export const Piece = ({id, children}) =>

{children}
;

export const PluginExplorer = ({children}) => { const PIECES = [{ id: 'manifest', name: 'Manifest', path: '.claude-plugin/plugin.json', required: "Required by Anthropic's directory", lines: [{ depth: 0, kind: 'folder', text: '.claude-plugin/' }, { depth: 1, kind: 'file', text: 'plugin.json' }], href: '/en/plugins/manifest-reference#manifest-file', linkText: 'Go to the manifest reference' }, { id: 'skills', name: 'Skills', path: 'skills/review/SKILL.md', lines: [{ depth: 0, kind: 'folder', text: 'skills/' }, { depth: 1, kind: 'folder', text: 'review/' }, { depth: 2, kind: 'file', text: 'SKILL.md' }], href: '/en/plugins/components#skills', linkText: 'Go to the Skills section' }, { id: 'commands', name: 'Commands', path: 'commands/about.md', lines: [{ depth: 0, kind: 'folder', text: 'commands/' }, { depth: 1, kind: 'file', text: 'about.md' }], href: '/en/plugins/components#commands', linkText: 'Go to the Commands section' }, { id: 'agents', name: 'Agents', path: 'agents/security-reviewer.md', lines: [{ depth: 0, kind: 'folder', text: 'agents/' }, { depth: 1, kind: 'file', text: 'security-reviewer.md' }], href: '/en/plugins/components#agents', linkText: 'Go to the Agents section' }, { id: 'hooks', name: 'Hooks', path: 'hooks/hooks.json', lines: [{ depth: 0, kind: 'folder', text: 'hooks/' }, { depth: 1, kind: 'file', text: 'hooks.json' }], href: '/en/plugins/components#hooks', linkText: 'Go to the Hooks section' }, { id: 'monitors', name: 'Monitors', path: 'monitors/monitors.json', lines: [{ depth: 0, kind: 'folder', text: 'monitors/' }, { depth: 1, kind: 'file', text: 'monitors.json' }], href: '/en/plugins/components#monitors', linkText: 'Go to the Monitors section' }, { id: 'output-styles', name: 'Output styles', path: 'output-styles/terse.md', lines: [{ depth: 0, kind: 'folder', text: 'output-styles/' }, { depth: 1, kind: 'file', text: 'terse.md' }], href: '/en/plugins/components#themes-and-output-styles', linkText: 'Go to the Themes and output styles section' }, { id: 'themes', name: 'Themes', path: 'themes/dracula.json', lines: [{ depth: 0, kind: 'folder', text: 'themes/' }, { depth: 1, kind: 'file', text: 'dracula.json' }], href: '/en/plugins/components#themes-and-output-styles', linkText: 'Go to the Themes and output styles section' }, { id: 'workflows', name: 'Workflows', path: 'workflows/audit-routes.js', lines: [{ depth: 0, kind: 'folder', text: 'workflows/' }, { depth: 1, kind: 'file', text: 'audit-routes.js' }], href: '/en/workflows#distribute-a-workflow-in-a-plugin', linkText: 'Go to Distribute a workflow in a plugin' }, { id: 'bin', name: 'Executables', path: 'bin/hello-plugin', lines: [{ depth: 0, kind: 'folder', text: 'bin/' }, { depth: 1, kind: 'file', text: 'hello-plugin' }], href: '/en/plugins/components#executables', linkText: 'Go to the Executables section' }, { id: 'scripts', name: 'Scripts', path: 'scripts/format.sh', lines: [{ depth: 0, kind: 'folder', text: 'scripts/' }, { depth: 1, kind: 'file', text: 'format.sh' }], href: '/en/plugins/components#hooks', linkText: 'Go to the Hooks section' }, { id: 'settings', name: 'Default settings', path: 'settings.json', lines: [{ depth: 0, kind: 'file', text: 'settings.json' }], href: '/en/plugins/components#default-settings', linkText: 'Go to the Default settings section' }, { id: 'mcp', name: 'MCP servers', path: '.mcp.json', lines: [{ depth: 0, kind: 'file', text: '.mcp.json' }], href: '/en/plugins/components#mcp-servers', linkText: 'Go to the MCP servers section' }, { id: 'lsp', name: 'LSP servers', path: '.lsp.json', lines: [{ depth: 0, kind: 'file', text: '.lsp.json' }], href: '/en/plugins/components#lsp-servers', linkText: 'Go to the LSP servers section' }]; const [selectedId, setSelectedId] = useState('manifest'); const [isFullscreen, setIsFullscreen] = useState(false); const rootRef = useRef(null); useEffect(() => { const onFsChange = () => setIsFullscreen(!!document.fullscreenElement); document.addEventListener('fullscreenchange', onFsChange); return () => document.removeEventListener('fullscreenchange', onFsChange); }, []); const toggleFullscreen = () => { if (!rootRef.current) return; if (document.fullscreenElement) document.exitFullscreen(); else rootRef.current.requestFullscreen().catch(() => {}); }; const selected = PIECES.find(p => p.id === selectedId) || PIECES[0]; const onTreeKeyDown = e => { const keys = ['ArrowDown', 'ArrowUp', 'Home', 'End']; if (keys.indexOf(e.key) === -1) return; const i = PIECES.findIndex(p => p.id === selectedId); let next = i; if (e.key === 'ArrowDown') next = Math.min(PIECES.length - 1, i + 1); if (e.key === 'ArrowUp') next = Math.max(0, i - 1); if (e.key === 'Home') next = 0; if (e.key === 'End') next = PIECES.length - 1; e.preventDefault(); if (next === i) return; const id = PIECES[next].id; setSelectedId(id); const el = document.getElementById('pe-node-' + id); if (el) el.focus(); }; const FolderIcon = () => ; const FileIcon = () => ; return <div ref={rootRef} className={isFullscreen ? 'pe-root pe-fullscreen not-prose' : 'pe-root not-prose'} data-selected={selected.id}>

  <div className="pe-head">
    <div className="pe-head-text">
      <div className="pe-title">What goes in a plugin</div>
      <div className="pe-sub">This example plugin, <code>my-plugin</code>, has one of every kind of component, each in its default location. Select a file or folder to read what it’s for and see what goes in it.</div>
    </div>
    <button type="button" className="pe-fs-btn" onClick={toggleFullscreen} aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}>
      {isFullscreen ? '⤡' : '⛶'}
    </button>
  </div>

  <div className="pe-body">
    <div className="pe-tree-pane">
      <div className="pe-caption" id="pe-tree-caption">Plugin directory</div>
      <div role="group" aria-labelledby="pe-tree-caption" onKeyDown={onTreeKeyDown}>
        <div className="pe-rootline"><FolderIcon /><span>my-plugin/</span></div>
        {PIECES.map(p => <button key={p.id} id={'pe-node-' + p.id} type="button" className="pe-node" aria-pressed={p.id === selected.id} aria-label={p.name + ', ' + p.path} onClick={() => setSelectedId(p.id)}>
            {p.lines.map((line, i) => <span key={i} className="pe-line pe-line-tree" style={{
paddingLeft: line.depth * 18 + 'px'

}}> {line.kind === 'folder' ? : } {line.text} {p.required && i === p.lines.length - 1 ? {p.required} : null} )} {p.path} {p.required ? {p.required} : null} )}

    <div className="pe-panel" role="region" aria-labelledby="pe-panel-caption" aria-live="polite" aria-atomic="true">
      <div className="pe-caption" id="pe-panel-caption">Selected piece</div>
      <div className="pe-name">{selected.name}{selected.required ? <span className="pe-req">{selected.required}</span> : null}</div>
      <div className="pe-path">{selected.path}</div>

      <div className="pe-block">{children}</div>

      <a className="pe-link" href={selected.href}>{selected.linkText}</a>
    </div>
  </div>
</div>;

};

Un plugin Claude Code est construit à partir de composants, tels que des skills, des agents, des hooks et des serveurs MCP. Chaque composant a un dossier par défaut dans le plugin, une clé de manifeste optionnelle dans .claude-plugin/plugin.json qui remplace ou ajoute à ce dossier, et un nom que l'utilisateur voit. Pour chaque tableau complet des champs de clé, consultez la référence du manifeste.

Utilisez cette page pour ajouter un composant à un plugin qui charge déjà.

Après avoir ajouté un composant, exécutez /reload-plugins dans une session en cours ou démarrez une nouvelle session pour que Claude Code le charge. Pour vérifier le fichier du composant avant de le charger, exécutez claude plugin validate . dans votre shell à partir du répertoire du plugin.

Explorez le répertoire du plugin

L'explorateur montre un exemple de plugin, my-plugin, qui a un de chaque type de composant à son emplacement par défaut :

Chaque fichier est le plus petit exemple valide de son format, là pour montrer la forme plutôt que d'être utile : une skill ou un agent réel porte des instructions complètes et souvent des fichiers de support, et un hook ou un moniteur réel fait un vrai travail. Les sections après l'explorateur utilisent les mêmes fichiers que leurs exemples et renvoient à des versions plus complètes. Sélectionnez un fichier ou un dossier pour lire à quoi il sert, voir ce qu'il contient, et trouver la section qui le couvre.

Le [manifeste](/docs/fr/plugins/manifest-reference) est le fichier `plugin.json` dans le répertoire `.claude-plugin/` d'un plugin. Il contient les métadonnées du plugin et les valeurs `userConfig` que Claude Code demande à l'utilisateur. Seul `name` est requis. Dans celui-ci, `description` est le texte que les utilisateurs voient pour le plugin dans `/plugin`, et `version` garde les utilisateurs sur cette version jusqu'à ce que vous la changiez :
```json theme={null}
{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Review, formatting, and database tools for this team"
}
```
Une [skill](/docs/fr/skills) est un fichier `SKILL.md`. Enregistrez chaque skill dans son propre répertoire sous `skills/`. Claude lit la `description` de chaque skill, et quand ce que l'utilisateur demande correspond, comme demander à Claude de réviser une pull request ici, Claude charge les instructions de la skill et les suit. L'utilisateur peut aussi l'exécuter directement comme `/my-plugin:review` :
```markdown theme={null}
---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.
```
Une commande est un seul fichier Markdown que l'utilisateur exécute par nom. Les commandes sont le format plus ancien : une skill s'exécute par nom de la même manière et peut aussi porter des fichiers de support dans son propre répertoire, donc écrivez les nouvelles comme des skills et gardez `commands/` pour les fichiers que vous avez déjà. Ce fichier devient `/my-plugin:about` et prend le même frontmatter qu'une skill :
```markdown theme={null}
---
description: Summarize the repository
---

Summarize what this repository does in three sentences.
```
Un [sous-agent](/docs/fr/sub-agents) est un assistant séparé, avec ses propres instructions et sa propre fenêtre de contexte, que Claude peut déléguer une tâche et obtenir un résultat. Chaque fichier Markdown sous `agents/` en définit un : le frontmatter le nomme et dit quand l'utiliser, et le corps est son invite système. Celui-ci est nommé `my-plugin:security-reviewer`, et l'utilisateur peut l'invoquer avec `@agent-my-plugin:security-reviewer` :
```markdown theme={null}
---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.
```
Un [hook](/docs/fr/hooks-guide) exécute quelque chose automatiquement à un point du cycle de vie de Claude Code, comme après chaque édition de fichier : une commande shell, une requête HTTP, un appel d'outil MCP, une invite à un modèle, ou un sous-agent. Enregistrez les hooks du plugin dans `hooks/hooks.json` à la racine du plugin. Celui-ci exécute le `scripts/format.sh` du plugin après que Claude écrit ou édite un fichier :
```json theme={null}
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}
```
Un moniteur est une commande shell que Claude Code démarre en arrière-plan quand la session démarre et continue à exécuter jusqu'à ce qu'elle se termine, en utilisant l'[outil Monitor](/docs/fr/tools-reference#monitor-tool). Ce qu'il imprime atteint Claude comme des notifications. Un champ `when` peut à la place le démarrer la première fois qu'une skill nommée s'exécute. Celui-ci suit un journal d'erreurs :
```json theme={null}
[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]
```
Un plugin peut inclure des [styles de sortie](/docs/fr/output-styles), qui changent la façon dont Claude formate et formule ses réponses. Enregistrez chaque style de sortie comme `output-styles/.md`. Celui-ci apparaît dans `/output-style` comme `my-plugin:terse` :
```markdown theme={null}
---
name: terse
description: Answer in as few words as possible
keep-coding-instructions: true
---

Keep every reply short. Skip preambles and summaries.
```
Un plugin peut inclure des [thèmes de couleur](/docs/fr/terminal-config#create-a-custom-theme) pour l'interface Claude Code. Enregistrez chaque thème comme `themes/.json`. Celui-ci apparaît dans `/theme` comme `Dracula`, marqué comme provenant de `my-plugin` :
```json theme={null}
{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}
```
Le dossier `workflows/` contient des fichiers [workflow](/docs/fr/workflows) `.js` : un bloc `meta`, puis un corps de script qui orchestre plusieurs sous-agents. Celui-ci s'exécute comme `/my-plugin:audit-routes` :
```javascript theme={null}
export const meta = {
  name: 'audit-routes',
  description: 'Audit every route handler for missing auth checks',
}

const found = await agent('List every .ts file under src/routes/.', {
  schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
})

const audits = await pipeline(found.files, file =>
  agent(`Audit ${file} for missing authentication checks.`, { label: file }),
)

return audits.filter(Boolean)
```
`bin/` est la façon dont un plugin expédie un outil en ligne de commande. Tant que le plugin est activé, Claude Code met ce dossier sur le `PATH` du shell dans lequel il exécute les commandes, donc Claude, ou les instructions d'une skill, peuvent exécuter l'outil par nom sans que l'utilisateur n'installe rien. Avec cet [exécutable](#executables) en place, `hello-plugin` est une commande que Claude peut exécuter :
```bash theme={null}
#!/bin/bash
echo "hello from my-plugin"
```
Le hook dans `hooks/hooks.json` exécute un script, et ce dossier est l'endroit où l'exemple le garde. Le nom `scripts/` est une convention, pas quelque chose que Claude Code recherche : le hook pointe vers le fichier par son chemin, `${CLAUDE_PLUGIN_ROOT}/scripts/format.sh`. Un script de formatage pourrait ressembler à ceci :
```bash theme={null}
#!/bin/bash
npx prettier --write .
```
Un `settings.json` à la racine du plugin contient des [paramètres](/docs/fr/settings-reference) qui s'appliquent tant que le plugin est activé, donc un plugin peut changer le comportement de la session et non seulement ajouter des composants. Seules deux clés prennent effet à partir d'un plugin, [`agent`](/docs/fr/settings-reference#agent) et [`subagentStatusLine`](/docs/fr/settings-reference#subagentstatusline) ; toute autre clé est supprimée. Consultez [Paramètres par défaut](#default-settings).
Celui-ci définit `agent`, qui exécute le fil principal de la session comme le propre agent `security-reviewer` du plugin, donc l'invite système, les restrictions d'outils et le modèle de cet agent s'appliquent à toute la session :

```json theme={null}
{
  "agent": "security-reviewer"
}
```
Un [serveur MCP](/docs/fr/mcp) donne à Claude des outils d'un système externe. Déclarez-le dans `.mcp.json` à la racine du plugin. Celui-ci démarre un serveur local à partir d'un script à l'intérieur du plugin, et apparaît dans `/mcp` comme `plugin:my-plugin:db` :
```json theme={null}
{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}
```
Un serveur LSP donne à Claude des [diagnostics et une navigation de code](/docs/fr/plugins/code-intelligence) pour une langue. Déclarez le serveur dans `.lsp.json` à la racine du plugin. Celui-ci connecte le serveur de langage Go pour les fichiers `.go` :
```json theme={null}
{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}
```

Ajouter chaque type de composant

Chaque section ci-dessous couvre un type de composant : où ses fichiers vont dans le plugin, un exemple qui valide, ce que l'utilisateur voit une fois que le plugin charge, et la clé de manifeste qui change l'emplacement par défaut. Ajoutez ceux dont votre plugin a besoin ; aucun n'est requis.

Skills

Une skill est un fichier SKILL.md que Claude peut charger quand sa description correspond à la tâche. L'utilisateur peut aussi l'exécuter comme une commande. Enregistrez chaque skill dans son propre répertoire sous skills/ :

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

Donnez au SKILL.md une description pour que Claude sache quand l'utiliser :

---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.

Après avoir chargé le plugin, /my-plugin:review exécute la skill. Le nom de la commande et qui peut l'invoquer suivent ces règles :

Vous pouvez aussi placer des skills en dehors du répertoire par défaut skills/ :

Pour inclure des instructions dans un plugin, écrivez-les comme une skill. Claude Code ne charge pas un CLAUDE.md à la racine du plugin, et claude plugin validate avertit CLAUDE.md at the plugin root is not loaded as project context.

Pour les champs de frontmatter et les fichiers de support, consultez Skills.

Commandes

Une commande est un seul fichier Markdown que l'utilisateur exécute par nom, comme /my-plugin:about.

Enregistrez une commande à commands/<file>.md et elle devient /<plugin>:<file>. Un sous-répertoire ajoute un segment, donc commands/db/migrate.md est /my-plugin:db:migrate.

Les fichiers de commande prennent le même frontmatter que les skills.

Définir les commandes dans le manifeste

Vous n'en avez besoin que si vous voulez garder les fichiers de commande quelque part d'autre que commands/, ou pour définir une commande courte dans plugin.json sans fichier Markdown séparé. Définissez la clé de manifeste commands, et Claude Code la lit à la place de scanner commands/. La clé prend un chemin, un tableau de chemins, ou un objet qui mappe chaque nom de commande à soit un fichier source soit un content en ligne.

Ce manifeste définit /my-plugin:about en ligne, sans fichier Markdown :

{
  "name": "my-plugin",
  "commands": {
    "about": {
      "content": "Summarize what this repository does in three sentences.",
      "description": "Summarize the repository"
    }
  }
}

Chargez le plugin et exécutez /my-plugin:about dans la session pour confirmer qu'il a chargé.

Pour la syntaxe complète de la clé, consultez commands.

Agents

Un sous-agent est un assistant séparé, avec ses propres instructions et fenêtre de contexte, que Claude peut déléguer une tâche. Chaque fichier Markdown sous agents/ en définit un :

---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.

Cet agent est nommé my-plugin:security-reviewer, et l'utilisateur peut l'invoquer explicitement avec @agent-my-plugin:security-reviewer. La forme du nom est <plugin>:<name>, où <name> provient du frontmatter, ou du nom du fichier quand il n'y en a pas.

La clé de manifeste agents remplace le scan agents/.

Organiser les agents dans des sous-dossiers

Vous pouvez mettre les fichiers d'agent du plugin dans des sous-dossiers de agents/. Claude Code les charge récursivement et joint le nom du plugin, chaque nom de sous-dossier, et le nom du fichier avec des deux-points pour former le nom d'agent scopé. Par exemple, agents/review/security.md dans un plugin nommé my-plugin charge comme my-plugin:review:security. Deux paramètres changent ce nom :

Champs de frontmatter dans les agents du plugin

Le frontmatter d'un agent du plugin suit ces règles :

Pour ce que chaque champ fait et les règles de précédence, consultez Sous-agents.

Hooks

Un hook exécute quelque chose automatiquement à un point du cycle de vie de Claude Code, comme après chaque édition de fichier : une commande shell, une requête HTTP, un appel d'outil MCP, une invite à un modèle, ou un sous-agent. Enregistrez les hooks du plugin dans hooks/hooks.json à la racine du plugin, sous une clé "hooks" de niveau supérieur, dans la même forme que l'objet hooks dans settings.json. Cela vous permet de copier un hook de paramètres existant inchangé.

Ce hook exécute un script groupé après chaque Write ou Edit :

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}

Enregistrez le script à scripts/format.sh et rendez-le exécutable.

Chargez le plugin et demandez à Claude d'éditer un fichier. Un hook PostToolUse qui sort 0 ne montre rien dans la transcription, donc confirmez qu'il a exécuté avec journalisation de débogage ou par ce que le script lui-même change.

Les hooks dans hooks/hooks.json et dans la clé de manifeste hooks chargent tous les deux. Pour chaque événement et sa charge utile, consultez Événements de hook.

Quand les hooks du plugin se déclenchent

Les hooks d'un plugin n'attendent pas qu'une des skills ou commandes du plugin soit utilisée. Claude Code les enregistre quand une session charge le plugin, et ils se déclenchent sur leurs événements à partir de là. Pour limiter quand un hook s'exécute, réduisez son matcher.

Si un hook ne se déclenche jamais, consultez hooks qui ne se déclenchent pas.

Environnement, guillemets et correspondance des outils MCP

L'environnement du hook, les guillemets de ${CLAUDE_PLUGIN_ROOT}, et les matchers pour les outils MCP du plugin fonctionnent comme suit :

Serveurs MCP

Un serveur MCP donne à Claude des outils d'un système externe. Déclarez-le dans .mcp.json à la racine du plugin, dans la même forme qu'un .mcp.json de projet. Ce .mcp.json déclare un serveur nommé db :

{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}

Vous pouvez aussi omettre le wrapper mcpServers et mettre db au niveau supérieur du fichier.

Chargez le plugin et exécutez /mcp pour confirmer que le serveur apparaît comme plugin:my-plugin:db.

claude plugin validate vérifie .mcp.json et signale une entrée de serveur que Claude Code supprimerait au moment du chargement comme une erreur. Nécessite Claude Code v2.1.281 ou ultérieur.

Pour où une mauvaise entrée s'affiche au moment du chargement, consultez Serveurs MCP qui ne démarrent pas.

La clé de manifeste mcpServers prend une carte de serveur en ligne, un chemin vers un fichier JSON, ou un tableau de ceux-ci. Quand un serveur de manifeste a le même nom qu'un dans .mcp.json, le serveur de manifeste le remplace.

Atteindre les utilisateurs sur claude.ai et Cowork

Un serveur stdio local, comme le serveur db sous Serveurs MCP, s'exécute dans Claude Code et dans une session Cowork qui s'exécute sur votre machine dans l'application Claude Desktop, mais pas sur claude.ai. Pour atteindre les utilisateurs là aussi, référencez un serveur distant par son URL https://, que claude.ai et Cowork offrent à l'utilisateur comme connecteur.

Noms de serveur, noms d'outils et rechargements

Les noms du serveur, la substitution de variables, et le comportement de rechargement suivent ces règles :

Inclure un serveur MCPB emballé

La clé mcpServers accepte aussi un serveur emballé comme un fichier MCPB, dont l'extension est .mcpb ou l'ancienne .dxt. Pointez la clé vers le fichier, comme un chemin à l'intérieur du plugin ou une URL https:// :

{
  "name": "my-plugin",
  "mcpServers": "./servers/db.mcpb"
}

Le serveur prend son nom du name dans le manifeste du bundle.

Pour les transports et l'authentification, consultez MCP.

Serveurs LSP

Un serveur LSP donne à Claude des diagnostics et une navigation de code pour une langue. Si un plugin officiel de code intelligence couvre déjà votre langue, installez celui-ci à la place d'en écrire un. Sinon, déclarez le serveur dans .lsp.json à la racine du plugin :

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

Le fichier mappe chaque nom de serveur directement à sa configuration, sans objet wrapper autour de la carte. command est le nom du binaire, avec ses arguments dans args. extensionToLanguage a besoin d'au moins une extension, chacune commençant par ..

claude plugin validate ne lit pas ce fichier. Quand une entrée est invalide, le fichier entier est ignoré au chargement et Invalid LSP server config for ".lsp.json" apparaît dans l'onglet Errors de /plugin.

Votre plugin configure la connexion mais n'installe pas le binaire du serveur, et chaque extension de fichier obtient un serveur :

La clé de manifeste lspServers prend la même carte en ligne, un chemin vers un fichier JSON, ou un tableau de ceux-ci, et ses serveurs s'ajoutent à ceux dans .lsp.json. Quand un serveur de manifeste a le même nom qu'un dans .lsp.json, le serveur de manifeste le remplace.

Pour transport, les délais d'attente, les redémarrages, et les autres champs, consultez lspServers.

Envoyez la sortie du journal à stderr, pas stdout. Claude Code lit le stdout d'un serveur comme des messages de protocole seulement, et accepte les en-têtes de message jusqu'à 64 KiB et un corps de message jusqu'à 32 MiB.

Claude Code déconnecte un serveur qui dépasse l'une ou l'autre limite ou écrit une sortie non-protocole à stdout, et compte la déconnexion comme un crash pour restartOnCrash et maxRestarts. Quand vous exécutez avec --debug, Claude Code écrit une erreur nommant la cause au journal de débogage.

Exécutables

Les fichiers dans bin/ à la racine du plugin sont sur le PATH du shell de l'outil Bash tant que le plugin est activé, donc Claude peut les exécuter comme des commandes nues. Ajoutez un script exécutable :

#!/bin/bash
echo "hello from my-plugin"

Rendez-le exécutable avec chmod +x bin/hello-plugin et chargez le plugin. Quand vous demandez à Claude d'exécuter hello-plugin, le résultat de l'outil Bash montre la sortie du script.

Les répertoires bin/ du plugin viennent après les entrées PATH de l'utilisateur, donc un plugin ne peut pas masquer git, ls, ou une autre commande système.

claude.ai et Cowork n'installent pas un plugin qui a un répertoire bin/ de niveau supérieur, y compris un que vous distribuez via les paramètres d'organisation claude.ai.

Paramètres par défaut

Pour définir les paramètres par défaut qui s'appliquent tant que le plugin est activé, ajoutez un settings.json à la racine du plugin, ou mettez le même objet en ligne dans la clé de manifeste settings. Deux clés prennent effet, agent et subagentStatusLine, et toute autre clé est supprimée.

Définissez agent pour exécuter l'un des propres agents du plugin comme le fil principal :

{
  "agent": "security-reviewer"
}

Chargez le plugin et démarrez une session. Claude répond alors dans la conversation principale avec l'invite système et le modèle de l'agent security-reviewer.

Pour tout ce que la clé contrôle, consultez le paramètre agent.

Quand la même clé est définie à plus d'un endroit, ces règles décident quelle valeur s'applique :

Pour la forme subagentStatusLine, consultez lignes d'état du sous-agent.

Thèmes et styles de sortie

Un plugin peut inclure des thèmes de couleur et des styles de sortie. Les deux apparaissent dans les mêmes sélecteurs que ceux de l'utilisateur. Pour l'un ou l'autre, définir la clé de manifeste remplace le scan de dossier.

Composant Enregistrer comme Format Apparaît dans Clé de manifeste
Thème themes/<slug>.json Le format de fichier de thème personnalisé que les utilisateurs écrivent dans ~/.claude/themes/ /theme, sous le name du fichier experimental.themes
Style de sortie output-styles/<name>.md Le format de style de sortie personnalisé, avec le frontmatter name et description /output-style, comme <plugin>:<name> outputStyles

Les thèmes du plugin sont en lecture seule, donc quand un utilisateur en édite un dans /theme, l'édition est enregistrée comme une copie dans son propre répertoire de thèmes.

Ce thème recolore l'accent d'invite et le texte d'erreur sur le préréglage sombre :

{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}

Canaux

Un canal permet à un système externe tel qu'une application de chat d'envoyer des messages dans une session. Dans un plugin, un canal est l'un des serveurs MCP plus une entrée channels qui se lie à lui et peut demander sa propre configuration. Ce manifeste lie un canal à un serveur telegram et demande un jeton de bot :

{
  "name": "my-plugin",
  "mcpServers": {
    "telegram": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
      "env": { "BOT_TOKEN": "${user_config.bot_token}" }
    }
  },
  "channels": [
    {
      "server": "telegram",
      "userConfig": {
        "bot_token": {
          "type": "string",
          "title": "Bot token",
          "description": "Telegram bot token",
          "sensitive": true
        }
      }
    }
  ]
}

server doit correspondre à une clé dans mcpServers. Le userConfig par canal prend la même forme que la clé userConfig de niveau supérieur.

Pour ce que le serveur doit implémenter et comment les utilisateurs activent un plugin de canal, consultez Empaqueter comme un plugin dans la référence des canaux. Pour le tableau des champs, consultez channels.

Moniteurs

Un moniteur est une commande shell qui s'exécute en arrière-plan pour toute la session. Ce qu'il imprime atteint Claude comme des notifications, donc Claude peut réagir à un journal ou à un changement d'état sans être demandé de le surveiller. Enregistrez les entrées dans monitors/monitors.json :

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

La commande s'exécute dans un shell, dans le répertoire de travail dans lequel la session a démarré.

La commande d'un moniteur est limitée dans où elle démarre et ce qu'elle peut référencer :

La clé de manifeste experimental.monitors prend le même tableau en ligne ou un chemin vers un fichier JSON, et est lue à la place de monitors/monitors.json.

Pour le déclencheur when et les autres champs, consultez monitors.

Demander à l'utilisateur des valeurs de configuration

Déclarez les valeurs dont votre plugin a besoin de l'utilisateur dans la clé de manifeste userConfig, pour que les utilisateurs ne modifient pas settings.json eux-mêmes. Chaque option apparaît dans une boîte de dialogue avec son title comme étiquette et sa description en dessous.

Définissez "sensitive": true pour un jeton ou un mot de passe. La boîte de dialogue masque alors l'entrée, et la valeur est stockée dans un stockage sécurisé plutôt que dans settings.json.

Ce manifeste demande un point de terminaison et un jeton :

{
  "name": "my-plugin",
  "userConfig": {
    "api_url": {
      "type": "string",
      "title": "API URL",
      "description": "Base URL of your team's API"
    },
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "Token for your team's API",
      "sensitive": true
    }
  }
}

Quand la boîte de dialogue de configuration apparaît

La boîte de dialogue n'apparaît que dans l'interface interactive /plugin. Elle s'ouvre pour toute option qui n'est pas encore définie quand l'utilisateur fait l'une des choses suivantes :

Pour ouvrir la même boîte de dialogue à tout moment, l'utilisateur exécute /plugin configure <plugin>@<marketplace>.

La commande shell claude plugin install ne demande jamais les valeurs userConfig. Pour définir les valeurs à partir du shell, passez chacune comme --config KEY=VALUE. Quand les options restent non définies, la commande imprime une ligne userConfig options not yet set qui nomme les deux façons de les définir. La boîte de dialogue userConfig ne s'affiche jamais cite la ligne.

Pour les champs d'option, où chaque valeur est stockée, comment un composant référence une valeur enregistrée, et quels champs rejettent ${user_config.*}, consultez Configuration utilisateur.

Référencer les chemins du plugin et stocker les données

Vous ne savez pas où votre plugin sera installé, donc référencez ses fichiers et données via ces variables plutôt que des chemins fixes. Ils sont substitués dans le contenu des skills, commandes et agents, dans les commandes des hooks et moniteurs, et dans les configurations des serveurs MCP et LSP. Ils sont aussi exportés aux processus des hooks, MCP et LSP :

Dans le chemin du répertoire de données, <id> est l'identifiant du plugin avec chaque caractère autre que les lettres, les chiffres, _, et - remplacé par -, donc my-plugin@my-marketplace devient my-plugin-my-marketplace.

Sur Windows, les chemins substitués utilisent des barres obliques avant pour qu'un shell ne lise pas les barres obliques arrière comme des échappements.

Installer les dépendances dans le répertoire de données

Pour un plugin installé depuis la marketplace, Claude Code installe automatiquement les dépendances de package Node.js éligibles quand il met en cache le plugin, donc vous n'aurez peut-être pas besoin de les installer vous-même. Quand vous le faites, ce hook SessionStart installe node_modules dans ${CLAUDE_PLUGIN_DATA} à la première exécution et à nouveau après une mise à jour qui change package.json :

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/package.json\" \"${CLAUDE_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CLAUDE_PLUGIN_DATA}\" && cp \"${CLAUDE_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CLAUDE_PLUGIN_DATA}/package.json\""
          }
        ]
      }
    ]
  }
}

Après la première session, ~/.claude/plugins/data/<id>/node_modules existe. Un serveur MCP peut alors définir NODE_PATH à ${CLAUDE_PLUGIN_DATA}/node_modules dans son env. Pour quels champs substituent quelle variable, consultez Variables d'environnement.

Étapes suivantes