Skip to main content
Les plugins sont en bêta fermée. Pour demander l’accès, contactez support@cognition.ai. Leur comportement et leur configuration peuvent changer dans de futures versions.
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>. 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 qui s’exécutent dans chaque session où le plugin est installé. Dans les sessions cloud, les hooks command s’exécutent sur la machine de la session et ne se déclenchent que tant que cette machine est active. Ils prennent en charge tous les événements sauf SessionStart et SessionEnd — y compris PreToolUse, PostToolUse, PermissionRequest, UserPromptSubmit, Stop et PostCompaction ; les hooks de type prompt sont réservés au CLI et aux environnements locaux.
  • Serveurs MCP — les plugins peuvent fournir des serveurs MCP facultatifs qui démarrent avec la session. Leurs tools sont disponibles pour Devin, bien que les serveurs MCP des plugins n’apparaissent pas encore dans l’interface Settings MCP. Une configuration MCP de plugin peut définir un Client ID OAuth et des périmètres, mais jamais un secret client — une configuration de serveur qui en contient un est rejetée lors de l’activation.

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 :
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.

Gérer les plugins

Les plugins locaux sont liés directement à leur dossier source, donc les modifications sont prises en compte immédiatement : devin plugins install ./my-plugin → modifiez skills/<name>/SKILL.md → les modifications s’appliquent dès la session suivante, sans update.

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 : 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 admin.
  2. Org — un manifeste géré au niveau de l’org, situé sous le compte dans la hiérarchie (une org peut compléter ce que son compte déclare, mais ne peut pas y déroger). Cela s’applique uniquement aux cloud Devin sessions : la CLI s’authentifie au niveau du compte et n’a aucun contexte d’org. Les plugins requis ou interdits au niveau de l’org ne s’appliquent donc pas aux utilisateurs de la CLI. Placez dans le manifeste Enterprise/compte tout ce qui doit être appliqué dans la CLI.
  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.
  4. User — les plugins que vous installez vous-même avec devin plugins install.
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.