Skip to main content
Un plugin est un ensemble de skills et de règles, hooks, serveurs MCP ou sous-agents personnalisés facultatifs que vous pouvez installer depuis un repo GitHub, une URL git, un sous-dossier d’un repo ou un dossier local. Les plugins fonctionnent dans les sessions Devin dans le cloud, le Devin CLI et Devin Desktop, sous réserve des limitations propres à chaque interface décrites ci-dessous. L’installation d’un plugin rend ses skills disponibles sous forme de commandes slash /<plugin>:<skill>. Cette page traite des plugins dans le CLI ; pour l’application web — la page Customize, les périmètres organisation et Enterprise, l’indexation et les connexions MCP — consultez le guide Plugins. Le plugin est l’unité d’installation. L’installation d’un plugin installe toutes ses skills et ses requiredPlugins ; vous ne pouvez pas installer de skills individuelles depuis un plugin. Pour proposer des skills séparément, répartissez-les dans des plugins distincts. Un plugin est simplement une source qui contient :
Le répertoire skills/ contient des skills ordinaires — les plugins n’introduisent aucun nouveau format de skill. Voir Créer des skills pour le format SKILL.md. Un repo (ou un sous-dossier git-subdir) correspond à un plugin. Un même repo peut héberger plusieurs plugins sous forme de sous-dossiers, chacun référencé avec sa propre source git-subdir. Au-delà des skills, un plugin peut également inclure :
  • Règles — un fichier AGENTS.md à la racine du plugin est injecté en tant que règle toujours active dans chaque session, aux côtés des règles de votre projet. Les fichiers Markdown du dossier rules/ sont également chargés, avec le même frontmatter trigger et les mêmes types d’activation que les règles Windsurf.
  • Sous-agents personnalisés — des profils agents/<name>.md ou agents/<name>/AGENT.md (le même format de sous-agent personnalisé que les sous-agents de projet), disponibles sous la forme <plugin>:<name>. Les sous-agents de plugin se chargent actuellement uniquement dans les agents Devin locaux — le CLI et Devin Desktop — et non dans les sessions Devin dans le cloud.
  • Hooks — un fichier hooks.json à la racine du plugin enregistre des hooks de cycle de vie dans les sessions Devin locales (le CLI et Devin Desktop) où le plugin est installé. Les hooks de plugin sont actuellement fournis sans garantie et ouverts en cas d’échec — si un hook ne parvient pas à se charger ou à s’exécuter, la session se poursuit sans lui — ne comptez donc pas encore sur eux pour des guardrails cruciaux.
  • Serveurs MCP — les plugins peuvent fournir des serveurs MCP facultatifs qui démarrent avec la session. Leurs tools sont disponibles pour Devin. Dans le CLI, authentifiez le serveur OAuth d’un plugin avec devin mcp login ; les sessions cloud utilisent la connexion établie dans l’application web (voir MCPs). Une configuration MCP de plugin peut définir un Client ID OAuth et des périmètres, mais jamais un Client Secret — une configuration de serveur qui en contient un est rejetée lors de l’activation. Référencez les secrets sous la forme ${NAME} ; les valeurs littérales écrites dans la configuration sont supprimées.

Formats compatibles

La structure ci-dessus est le format de plugin propre à Devin. Devin charge également les plugins empaquetés selon deux autres structures, avec la priorité suivante pour les manifestes : .devin-plugin/plugin.json > .claude-plugin/plugin.json > plugin.json à la racine :
  • Plugins Claude — en l’absence de .devin-plugin/plugin.json, Devin utilise .claude-plugin/plugin.json. Le fichier .mcp.json à la racine des plugins Claude et le champ mcpServers du manifeste sont pris en charge, et ${CLAUDE_PLUGIN_ROOT} dans les configurations de serveur est remplacé par la racine du plugin.
  • Plugins Agent — les plugins empaquetés conformément à la spécification Agent Plugins 1.0.0 (un manifeste plugin.json à la racine du plugin, des serveurs MCP dans un fichier mcp.json à la racine, des skills sous skills/) sont également chargés. Pour ces plugins, le fichier mcp.json à la racine est lu comme une source MCP standard (après .mcp.json, qui prévaut en cas de conflit de noms de serveur) — les anciens plugins utilisant les structures Devin/Claude ne le lisent jamais, sauf si leur manifeste le déclare explicitement. Les entrées MCP peuvent déclarer leur transport à l’aide du champ type de la spécification (stdio, streamable-http ou sse) au lieu de transport, et ${PLUGIN_ROOT} dans les configurations de serveur est remplacé par la racine du plugin, comme ${CLAUDE_PLUGIN_ROOT}. Une version $schema non reconnue génère un avertissement, mais le plugin est tout de même chargé dans la mesure du possible. Les serveurs MCP des plugins Agent bénéficient également des conventions d’environnement d’exécution de la spécification (celles-ci s’appliquent uniquement aux plugins dont le manifeste est le fichier plugin.json à la racine ; les structures Devin et Claude se comportent exactement comme auparavant) :
    • ${PLUGIN_DATA} dans les valeurs args, env et cwd est remplacé par un répertoire de données persistant et accessible en écriture, propre à chaque plugin. Le répertoire est associé à l’identité du plugin — et non à sa version — afin que son contenu soit conservé lors des mises à jour du plugin, et il est supprimé lors de la désinstallation du plugin.
    • Les processus serveur stdio reçoivent les variables d’environnement PLUGIN_ROOT et PLUGIN_DATA en plus des éventuelles variables env définies dans la configuration.
    • Un serveur peut définir cwd (relatif à la racine du plugin) ; par défaut, il correspond à la racine du plugin. Une command préfixée par ./ est résolue par rapport à la racine du plugin, afin que les plugins puissent fournir leurs propres exécutables. Les deux sont validés afin de rester dans la racine du plugin ou dans le répertoire de données.

Installation d’un plugin

La source d’un plugin peut être un owner/repo GitHub, une URL git ou un chemin local ; ajoutez #path/to/plugin lorsque le plugin se trouve sous la racine du repository :
Avant l’installation, Devin affiche ce que le plugin ajoute — les skills qu’il fournit, les plugins requis qui seront installés automatiquement, ainsi que toute politique qu’il introduit (par exemple, s’il interdit d’autres plugins). Passez -y / --yes pour ignorer le prompt. Les plugins sont installés au niveau de l’utilisateur et sont disponibles dans tous vos projets. Par défaut, install enregistre le plugin dans votre manifeste personnel dans Devin Cloud, de sorte que les mêmes plugins se chargent sur chaque machine sur laquelle vous vous connectez (et dans vos sessions Devin dans le cloud). Passez --local pour l’installer uniquement sur la machine actuelle. La gestion des plugins nécessite d’être connecté (devin auth login) ; une entreprise peut désactiver les plugins CLI pour ses members, auquel cas les plugins installés ne sont pas appliqués.

Gestion des plugins

remove --force supprime un plugin même si un autre plugin ou un manifeste de gouvernance en dépend encore ; un plugin requis par la gouvernance est réinstallé lors de la session suivante dans le périmètre concerné, et la CLI indique quelle configuration d’entreprise, d’organisation ou de dépôt l’exige encore. Les plugins installés depuis un dossier local sont liés directement à leur dossier source : les modifications sont donc prises en compte immédiatement. devin plugins install --local ./my-plugin → modifiez skills/<name>/SKILL.md → les modifications s’appliquent lors de la session suivante, sans update. Si la CLI dispose du plugin mais que Customize affiche un contenu manquant ou obsolète, consultez Résoudre les problèmes d’indexation. devin plugins update actualise le contenu local du plugin ; Reindex plugins dans Customize actualise la liste affichée sur le web. Une installation effectuée avec --local reste sur cet appareil.

Manifeste

.devin-plugin/plugin.json décrit le plugin. Seul name est obligatoire, et il doit être unique parmi les plugins installés (il s’agit de l’espace de noms /<name>:…). Les noms sont composés de caractères alphanumériques minuscules, avec - ou . comme séparateurs simples (par ex. review-tools, acme.tools).

Métadonnées

name, version, description, author ({ name, email }), homepage, repository, license et keywords. Seul name est utilisé pour l’identité et l’espace de noms du plugin ; les autres sont descriptifs et affichés par devin plugins info.

Skills et règles

Le champ skills définit l’emplacement de chargement des skills, en remplacement du répertoire skills/ par défaut. Il accepte un chemin unique relatif à la racine du plugin ou un tableau de chemins :
Un tableau vide ("skills": []) désactive complètement le chargement des skills. Les chemins doivent rester à l’intérieur du plugin : les chemins absolus, ~ et les parcours de répertoires avec .. sont rejetés, et une entrée non valide invalide l’ensemble du manifeste. Les règles sont chargées indépendamment des skills : un fichier AGENTS.md à la racine du plugin est toujours actif, et les fichiers Markdown du répertoire rules/ sont chargés en tant que règles déclenchées. Consultez Règles pour en savoir plus sur leur activation.

Serveurs MCP

Le champ mcpServers permet d’ajouter des déclarations de serveurs MCP. Les plugins peuvent également utiliser le fichier racine conventionnel .mcp.json (et mcp.json pour les plugins utilisant la structure de manifeste racine d’Agent Plugins). Quatre formats sont acceptés :
Les chemins déclarés suivent les mêmes règles de confinement que les skills, mais les entrées non sécurisées sont ignorées au lieu de faire échouer le plugin. Un champ mcpServers invalide désactive uniquement le chargement de MCP, tandis que les skills, les règles et les hooks restent utilisables. Un tableau vide n’ajoute aucun fichier de déclaration, mais ne désactive pas la convention racine. De même, une map inline vide laisse la convention racine activée. Lorsqu’un même nom de serveur apparaît dans plusieurs sources, la première prévaut.

Dépendances

Une entrée de dépendance est une source — soit une forme abrégée sous forme de chaîne, soit un objet : sha et ref fonctionnent avec toutes les formes objet (github, url, git-subdir) et s’excluent mutuellement : un sha épingle, un ref évolue. En l’absence des deux, la source suit la branche par défaut du dépôt. Toutes les formes GitHub pour un même repo (owner/repo, l’URL HTTPS, l’URL .git, la forme SSH) correspondent à la même identité de plugin. Un plugin peut déclarer trois listes, ce qui permet à un seul plugin de servir de collection organisée et encadrée d’autres plugins.

requiredPlugins

Installés automatiquement (de façon récursive) lors de l’installation du plugin. Si un plugin requis est bloqué par une politique, l’installation échoue dans son ensemble — il n’existe pas d’installation partielle.

optionalPlugins

Une liste d’autorisation des plugins par ce plugin. Ils ne sont pas installés automatiquement ; cette liste ne sert qu’à définir une exception pour une entrée interdite (voir ci-dessous).

forbiddenPlugins

Une liste de refus d’identités de plugin et de motifs glob. Les entrées forbiddenPlugins sont mises en correspondance avec les identités de plugin :
  • Une identité exacte, écrite sous la forme owner/repo ou d’une URL Git. Toutes les formes GitHub d’un même repo (owner/repo, l’URL HTTPS, l’URL .git, la forme SSH) renvoient à la même identité.
  • Un motif glob — toute entrée contenant *. Le * correspond à n’importe quelle séquence de caractères, y compris / : acme/* correspond à tous les repos GitHub de acme, */secrets correspond à un repo nommé secrets chez n’importe quel propriétaire, et https://gitlab.com/acme/* correspond à n’importe quel repo sous ce chemin.
  • Le simple "*", qui correspond à tout le reste (verrouillage complet).
Les listes se combinent selon une logique où l’interdiction l’emporte :
  • L’interdiction l’emporte. Un plugin est bloqué si un manifest actif ou un plugin installé l’interdit. Si rien n’interdit quoi que ce soit, rien n’est bloqué.
  • Dérogation pour soi-même. Les requiredPlugins et optionalPlugins d’un manifest (ou d’un plugin) — et, pour un plugin, le plugin lui-même — sont exemptés de leur propre liste d’interdictions. Ainsi, "forbiddenPlugins": ["*"] plus "optionalPlugins": ["acme/approved"] signifie « n’autoriser que ce que ce manifest liste ; interdire tout le reste. » Cette exception ne couvre que ces entrées directes, pas les dépendances transitives d’un plugin requis — listez-les explicitement dans le cadre d’un verrouillage.
  • Aucune réautorisation inter-périmètres. La liste des autorisations d’un manifest ou d’un plugin ne peut pas réautoriser ce qu’un autre interdit. Un verrouillage "forbiddenPlugins": ["*"] ne peut pas être contourné depuis un périmètre inférieur.
L’application des règles se fait à deux moments :
  • À l’installation — l’installation d’un plugin bloqué (ou d’un plugin dont les plugins requis ne peuvent pas être satisfaits, ou dont le nom entre en conflit avec un plugin installé) est refusée.
  • Au chargement — un plugin bloqué après avoir déjà été installé reste sur le disque, mais ses skills sont ignorées au démarrage de la session, avec un avertissement indiquant l’élément qui l’interdit.
Une identité interdite peut aussi prendre la forme d’un chemin local (pour les plugins installés à partir d’un dossier local), en plus des formes owner/repo et URL git ci-dessus.

Héritage et niveaux

Les plugins ne sont pas déclarés à un seul endroit. En plus de ceux que vous installez vous-même, des plugins peuvent être requis, approuvés ou interdits par votre repo et par l’admin de votre organisation. Chaque source constitue un niveau, et les niveaux sont classés par autorité, de la plus élevée à la plus faible :
  1. Enterprise — le manifeste géré à l’échelle du compte, configuré par un enterprise admin.
  2. Org — un manifeste géré au niveau de l’org, situé sous son enterprise dans la hiérarchie (une org peut compléter ce que son enterprise déclare, mais ne peut pas y déroger). Les sessions Devin dans le cloud utilisent le manifeste de l’organisation de la session ; la CLI et Devin Desktop utilisent le manifeste de votre organisation principale.
  3. Repo — les requiredPlugins / optionalPlugins / forbiddenPlugins dans le .devin/config.json d’un checkout, détectés en remontant depuis votre répertoire de travail (dans les sessions Devin dans le cloud, depuis chaque repository cloné).
  4. User — les plugins que vous installez vous-même avec devin plugins install (synchronisés via votre manifeste personnel) ou avec --local sur cette machine.
La CLI récupère les manifestes enterprise, org et personnel depuis Devin Cloud lorsque vous vous connectez ; les admins gèrent les deux premiers depuis la web app (voir le guide Plugins). Chaque niveau déclare les mêmes trois listes et, au sein d’un même niveau, elles se combinent selon les mêmes règles de priorité au refus et d’auto-dérogation qu’un manifeste unique. La seule règle supplémentaire apportée par les niveaux est la suivante : l’autorité supérieure l’emporte.

L’autorité supérieure prime

  • Un niveau inférieur ne peut jamais réautoriser ce qu’un niveau supérieur interdit.
  • Un niveau inférieur ne peut jamais interdire ce qu’un niveau supérieur exige — l’interdiction est ignorée et le plugin est quand même chargé.
Ainsi, un administrateur peut imposer un plugin auquel aucun repo ni utilisateur ne peut se soustraire, et interdire un plugin qu’aucun niveau inférieur ne peut réactiver.

Une liste de refus ne peut être outrepassée qu’à son propre niveau

Comme les listes d’autorisation ne s’appliquent pas d’un niveau à l’autre, la seule façon de ménager une exception à une liste de refus est de le faire au même niveau que celui qui l’a déclarée. Le forbiddenPlugins d’un niveau ne peut être outrepassé que par le optionalPlugins de ce même manifeste (ou requiredPlugins) — jamais par une liste située à un niveau inférieur. Par exemple, un manifeste géré au niveau de l’entreprise peut restreindre le compte à un seul plugin approuvé :
Cela signifie “sur l’ensemble du compte, n’autoriser que acme/approved et interdire tout autre plugin.” Aucune organisation, aucun dépôt ni aucun utilisateur ne peut élargir cette liste d’autorisation — ni en installant un plugin, ni en l’ajoutant aux optionalPlugins d’un niveau inférieur. L’exception ne couvre également que les entrées que ce manifeste liste directement ; les dépendances transitives d’un plugin requis ne sont pas exemptées, alors indiquez-les explicitement dans une configuration verrouillée.

Conflits et dépendances

  • Pour un même plugin, un require et un forbid au même niveau mais issus de manifestes différents (par exemple, deux plugins distincts installés au niveau utilisateur) donnent priorité à forbid — une liste d’autorisation n’exempte que les entrées de son propre manifeste, elle ne peut donc pas lever l’interdiction d’un plugin interdit par un autre manifeste. (Au sein d’un même manifeste, ses propres éléments requis/facultatifs restent exemptés de ses propres interdictions, comme ci-dessus.)
  • Un plugin bloqué par la gouvernance échoue de manière non bloquante : au démarrage de la session, ses skills sont ignorées avec un avertissement indiquant l’origine de l’interdiction, au lieu d’interrompre la session.
  • Le fait d’être une dépendance n’accorde aucune exemption. Un plugin inclus uniquement comme dépendance transitive reste soumis à toute interdiction qui s’applique à lui, et il hérite du niveau d’autorité le plus élevé de tout plugin qui l’exige.
  • Un conflit de pin — deux manifestes qui épinglent le même plugin sur des sha différents — doit être résolu en alignant les pins ou en laissant le pin au niveau d’autorité supérieur.
  • Lorsqu’un manifeste géré ne peut pas être récupéré au démarrage de la session, ce niveau échoue en mode ouvert : rien n’en est installé et ses interdictions ne sont pas appliquées pour cette session.