[Go to site: main page, start]

Skip to main content

Command Palette

Search for a command to run...

Personnaliser

Hooks

Les hooks permettent d’observer, de contrôler et d’étendre la boucle de l’Agent à l’aide de scripts personnalisés. Définissez des hooks dans des fichiers hooks.json au niveau du projet ou de l’utilisateur, ou installez-les via des plugins depuis Personnaliser. Les hooks sont des processus qui communiquent via stdio à l’aide de JSON dans les deux sens. Ils s’exécutent avant ou après certaines étapes de la boucle de l’Agent et peuvent observer, bloquer ou modifier le comportement.

Les hooks permettent de :

  • Exécuter des formateurs après les modifications
  • Ajouter des analyses aux événements
  • Analyser les données personnelles ou les secrets
  • Bloquer les opérations risquées (par ex., les écritures SQL)
  • Contrôler l’exécution des sous-agents (outil Task)
  • Injecter du contexte au début d’une session

Catégories de hooks

Les hooks se répartissent en trois catégories selon l’événement qui les déclenche :

Hooks d’agent (Cmd+K/Agent Chat) s’exécutent pendant une session d’agent :

  • sessionStart / sessionEnd - Gestion du cycle de vie de la session
  • preToolUse / postToolUse / postToolUseFailure - Hooks génériques d’utilisation d’outils (s’exécutent pour tous les outils)
  • subagentStart / subagentStop - Cycle de vie des sous-agents (outil Task)
  • beforeShellExecution / afterShellExecution - Contrôler les commandes shell
  • beforeMCPExecution / afterMCPExecution - Contrôler l’utilisation des outils MCP
  • beforeReadFile / afterFileEdit - Contrôler l’accès aux fichiers et les modifications
  • beforeSubmitPrompt - Valider les prompts avant leur envoi
  • preCompact - Surveiller la compaction de la fenêtre de contexte
  • stop - Gérer la fin de l’agent
  • afterAgentResponse / afterAgentThought - Suivre les réponses de l’agent

Hooks Tab (complétions en ligne) s’exécutent lors d’opérations Tab autonomes :

  • beforeTabFileRead - Contrôler l’accès aux fichiers pour les complétions Tab
  • afterTabFileEdit - Post-traiter les modifications effectuées par Tab

Hooks du cycle de vie de l’application s’exécutent en dehors de toute session d’agent :

  • workspaceOpen - Se déclenche lorsque Cursor ouvre un espace de travail et à chaque changement de dossier dans l’espace de travail. Peut renvoyer des chemins de plugin supplémentaires à charger pour l’espace de travail actuel.

Ces différentes interfaces de hooks vous permettent d’appliquer des stratégies distinctes aux opérations Tab autonomes, aux opérations de l’Agent initiées par l’utilisateur et au démarrage de l’espace de travail.

Prise en charge des agents cloud

Les agents cloud exécutent les hooks basés sur des commandes de votre dépôt. Si des hooks sont définis dans .cursor/hooks.json à la racine de votre projet, les agents cloud les détectent et les exécutent au cours de leur travail.

Avec les forfaits Enterprise, les agents cloud exécutent également les hooks d'équipe et les hooks gérés par l'entreprise configurés via le tableau de bord web.

Les agents cloud démarrent parfois dans un environnement en lecture seule lors des premières interactions d'exploration. Les hooks ne s'exécutent pas durant ces interactions. Ils commencent à s'exécuter dès que l'agent dispose d'un environnement accessible en écriture.

Hooks pris en charge

Les hooks suivants sont exécutés dans les agents cloud :

HookPris en charge
beforeShellExecutionOui
afterShellExecutionOui
beforeReadFileOui
afterFileEditOui
preToolUseOui
postToolUseOui
postToolUseFailureOui
subagentStartOui
subagentStopOui
beforeSubmitPromptOui
preCompactOui
afterAgentResponseOui
afterAgentThoughtOui
stopOui

Hooks non disponibles dans les agents cloud

Certains hooks ne s'appliquent pas aux agents cloud en raison de différences dans l'environnement d'exécution :

HookRaison
sessionStartDifféré, car les agents cloud peuvent démarrer dans un environnement en lecture seule. Les hooks n'y sont pas chargés : un sessionStart cloud se déclencherait donc trop tard (après la première écriture), et non au véritable début de la session.
sessionEndLes agents cloud n'ont pas de limite de session liée à la durée de vie de l'Éditeur. sessionEnd est lié à la session de l'IDE, et non à un chat d'agent cloud.
beforeMCPExecution / afterMCPExecutionDifférés, car les agents cloud peuvent démarrer dans un environnement en lecture seule, où les hooks ne sont pas chargés et où le moment de déclenchement des hooks MCP n'est pas clairement défini.
beforeTabFileRead / afterTabFileEditLes complétions Tab sont une fonctionnalité de l'IDE et ne s'exécutent pas dans les agents cloud.
workspaceOpenIl s'agit d'un hook de cycle de vie de l'IDE qui ne s'applique pas aux agents cloud.

Sources de configuration

Les agents cloud chargent les hooks à partir des sources suivantes :

  • Hooks de projet (.cursor/hooks.json dans votre dépôt) : chargés et exécutés lors du travail d’un agent cloud.
  • Hooks d’équipe (Enterprise) : distribués depuis le tableau de bord et exécutés dans les agents cloud.
  • Hooks Enterprise (Enterprise) : hooks gérés à l’échelle du système et exécutés dans les agents cloud.

Les hooks au niveau utilisateur (~/.cursor/hooks.json) ne sont pas disponibles dans les agents cloud. Les VM d’agent cloud n’ont pas accès à la configuration de votre répertoire personnel local.

Limites des types d’exécution

Les agents cloud n’exécutent que des hooks basés sur des commandes. Les hooks basés sur des prompts nécessitent de relier l’authentification entre le hook et la boucle de l’agent, ce qui n’est pas possible dans l’environnement d’exécution cloud.

Démarrage rapide

Créez un fichier hooks.json au niveau du projet (<project>/.cursor/hooks.json) ou dans votre répertoire personnel (~/.cursor/hooks.json). Les hooks de projet s’appliquent uniquement à ce projet, tandis que les hooks du répertoire personnel s’appliquent globalement.

Pour créer des hooks utilisateur applicables globalement, créez ~/.cursor/hooks.json :

{  "version": 1,  "hooks": {    "afterFileEdit": [{ "command": "./hooks/format.sh" }]  }}

Créez votre script de hook dans ~/.cursor/hooks/format.sh :

#!/bin/bash# Lire l’entrée, effectuer une action, quitter avec le code 0cat > /dev/nullexit 0

Rendez-le exécutable :

chmod +x ~/.cursor/hooks/format.sh

Cursor surveille les fichiers de configuration des hooks et les recharge automatiquement. Votre hook s’exécute après chaque modification de fichier.

Types de hooks

Les hooks prennent en charge deux types d’exécution : par commande (par défaut) et par prompt (évaluée par le LLM).

Hooks basés sur des commandes

Les hooks de commande exécutent des scripts shell qui reçoivent des données JSON via stdin et renvoient des données JSON via stdout.

{  "hooks": {    "beforeShellExecution": [      {        "command": "./scripts/approve-network.sh",        "timeout": 30,        "matcher": "curl|wget|nc"      }    ]  }}

Comportement des codes de sortie :

  • Code de sortie 0 - Hook réussi, utiliser la sortie JSON
  • Code de sortie 2 - Bloquer l’action (équivaut à renvoyer permission: "deny")
  • Autres codes de sortie - Échec du hook, l’action se poursuit (ouvert par défaut en cas d’échec)

Hooks basés sur des prompts

Les hooks basés sur des prompts utilisent un LLM pour évaluer une condition en langage naturel. Ils permettent d’appliquer des politiques sans écrire de scripts personnalisés.

{  "hooks": {    "beforeShellExecution": [      {        "type": "prompt",        "prompt": "Does this command look safe to execute? Only allow read-only operations.",        "timeout": 10      }    ]  }}

Fonctionnalités :

  • Renvoie une réponse structurée { ok: boolean, reason?: string }
  • Utilise un modèle rapide pour une évaluation rapide
  • L’espace réservé $ARGUMENTS est automatiquement remplacé par le JSON d’entrée du hook
  • Si $ARGUMENTS est absent, les données d’entrée du hook sont ajoutées automatiquement
  • Champ model facultatif permettant de remplacer le modèle LLM par défaut

Exemples

{  "version": 1,  "hooks": {    "sessionStart": [      {        "command": "./hooks/session-init.sh"      }    ],    "sessionEnd": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeShellExecution": [      {        "command": "./hooks/audit.sh"      },      {        "command": "./hooks/block-git.sh"      }    ],    "beforeMCPExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterShellExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterMCPExecution": [      {        "command": "./hooks/audit.sh"      }    ],    "afterFileEdit": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeSubmitPrompt": [      {        "command": "./hooks/audit.sh"      }    ],    "preCompact": [      {        "command": "./hooks/audit.sh"      }    ],    "stop": [      {        "command": "./hooks/audit.sh"      }    ],    "beforeTabFileRead": [      {        "command": "./hooks/redact-secrets-tab.sh"      }    ],    "afterTabFileEdit": [      {        "command": "./hooks/format-tab.sh"      }    ]  }}

Hook d’automatisation stop en TypeScript

Choisissez TypeScript si vous avez besoin de JSON typé, d’E/S de fichiers persistantes et d’appels HTTP dans un même hook. Ce hook stop basé sur Bun enregistre sur disque le nombre d’échecs par conversation, transmet des données de télémétrie structurées à une API interne et peut automatiquement planifier une nouvelle tentative lorsque l’Agent échoue deux fois de suite.

{  "version": 1,  "hooks": {    "stop": [      {        "command": "bun run .cursor/hooks/track-stop.ts --stop"      }    ]  }}

Définissez AGENT_TELEMETRY_URL sur l’endpoint interne qui doit recevoir les résumés d’exécution.

Hook de protection des manifestes Kubernetes en Python

Python est idéal lorsque vous avez besoin de bibliothèques d’analyse complètes. Ce hook utilise pyyaml pour inspecter les manifestes Kubernetes avant l’exécution de kubectl apply ; Bash aurait du mal à analyser de manière fiable des fichiers YAML comportant plusieurs documents.

{  "version": 1,  "hooks": {    "beforeShellExecution": [      {        "command": "python3 .cursor/hooks/kube_guard.py"      }    ]  }}

Installez PyYAML (par exemple, pip install pyyaml) dans tous les environnements où vos scripts de hook s’exécutent afin que l’import du parseur fonctionne.

Intégrations partenaires

Nous collaborons avec des fournisseurs de l'écosystème qui ont intégré la prise en charge des hooks à Cursor. Ces intégrations couvrent l'analyse de sécurité, la gouvernance, la gestion des secrets et bien plus encore.

Gouvernance et visibilité des MCP

PartenaireDescription
MintMCPCréez un inventaire complet des serveurs MCP, surveillez l’utilisation des outils et analysez les réponses afin de détecter les données sensibles avant qu’elles n’atteignent le modèle d’IA.
Oasis SecurityAppliquez la stratégie du moindre privilège aux actions des agents IA et conservez des pistes d’audit complètes dans l’ensemble des systèmes d’entreprise.
RunlayerEncapsulez les outils MCP et intégrez-les à leur courtier MCP pour centraliser le contrôle et la visibilité des interactions entre agents et outils.

Sécurité du code et bonnes pratiques

PartenaireDescription
CorridorObtenez des retours en temps réel sur l’implémentation du code et les choix de conception en matière de sécurité, à mesure que le code est écrit.
SemgrepAnalysez automatiquement le code généré par l’IA afin d’y détecter des vulnérabilités, puis régénérez-le à l’aide de retours en temps réel jusqu’à la résolution des problèmes de sécurité.

Sécurité des dépendances

PartenaireDescription
Endor LabsInterceptez les installations de paquets et analysez les dépendances malveillantes pour prévenir les attaques de la chaîne d’approvisionnement avant qu’elles n’atteignent votre base de code.

Sécurité des agents

PartenaireDescription
SnykPassez en revue en temps réel les actions des agents avec Evo Agent Guard, qui détecte et prévient les problèmes tels que les injections de prompt et les appels d’outils dangereux.

Gestion des secrets

PartenaireDescription
1PasswordVérifiez que les fichiers d’environnement de 1Password Environments sont correctement montés avant l’exécution des commandes shell, afin d’accéder aux secrets au moment voulu sans écrire les identifiants sur le disque.

Pour en savoir plus sur nos partenaires de hooks, consultez l’article de blog Hooks pour les équipes de sécurité et de plateforme.

Configuration

Définissez des hooks dans un fichier hooks.json. La configuration peut être définie à plusieurs niveaux. Tous les hooks correspondants de chaque source sont exécutés ; en cas de conflit entre les réponses, les sources prioritaires prévalent lors de la fusion :

~/.cursor/├── hooks.json└── hooks/    ├── audit.sh    └── block-git.sh
  • Enterprise (géré par MDM, à l’échelle du système) :
    • macOS : /Library/Application Support/Cursor/hooks.json
    • Linux/WSL : /etc/cursor/hooks.json
    • Windows : C:\\ProgramData\\Cursor\\hooks.json
  • Équipe (distribué via le Cloud, Enterprise uniquement) :
    • Configuré dans le tableau de bord web et synchronisé automatiquement pour tous les membres de l’équipe
  • Projet (spécifique au projet) :
    • <project-root>/.cursor/hooks.json
    • Les hooks de projet s’exécutent dans tout espace de travail approuvé et sont ajoutés au contrôle de version avec votre projet
  • Utilisateur (spécifique à l’utilisateur) :
    • ~/.cursor/hooks.json

Ordre de priorité (du plus élevé au plus faible) : Enterprise → Équipe → Projet → Utilisateur

L’objet hooks associe des noms de hooks à des tableaux de définitions de hooks. Chaque définition prend actuellement en charge une propriété command, qui peut être une chaîne de caractères shell, un chemin absolu ou un chemin relatif. Le répertoire de travail dépend de la source du hook :

  • Hooks de projet (.cursor/hooks.json dans un dépôt) : s’exécutent depuis la racine du projet
  • Hooks utilisateur (~/.cursor/hooks.json) : s’exécutent depuis ~/.cursor/
  • Hooks Enterprise (configuration à l’échelle du système) : s’exécutent depuis le répertoire de configuration Enterprise
  • Hooks d’équipe (distribués via le Cloud) : s’exécutent depuis le répertoire des hooks gérés

Pour les hooks de projet, utilisez des chemins comme .cursor/hooks/script.sh (relatif à la racine du projet), et non ./hooks/script.sh (qui rechercherait <project>/hooks/script.sh).

Fichier de configuration

Cet exemple montre un fichier de hooks au niveau de l’utilisateur (~/.cursor/hooks.json). Pour les hooks au niveau du projet, remplacez les chemins tels que ./hooks/script.sh par .cursor/hooks/script.sh :

{  "version": 1,  "hooks": {    "sessionStart": [{ "command": "./session-init.sh" }],    "sessionEnd": [{ "command": "./audit.sh" }],    "preToolUse": [      {        "command": "./hooks/validate-tool.sh",        "matcher": "Shell|Read|Write"      }    ],    "postToolUse": [{ "command": "./hooks/audit-tool.sh" }],    "subagentStart": [{ "command": "./hooks/validate-subagent.sh" }],    "subagentStop": [{ "command": "./hooks/audit-subagent.sh" }],    "beforeShellExecution": [{ "command": "./script.sh" }],    "afterShellExecution": [{ "command": "./script.sh" }],    "afterMCPExecution": [{ "command": "./script.sh" }],    "afterFileEdit": [{ "command": "./format.sh" }],    "preCompact": [{ "command": "./audit.sh" }],    "stop": [{ "command": "./audit.sh", "loop_limit": 10 }],    "beforeTabFileRead": [{ "command": "./redact-secrets-tab.sh" }],    "afterTabFileEdit": [{ "command": "./format-tab.sh" }],    "workspaceOpen": [{ "command": "./register-workspace-plugins.sh" }]  }}

Les hooks d’agent (sessionStart, sessionEnd, preToolUse, postToolUse, postToolUseFailure, subagentStart, subagentStop, beforeShellExecution, afterShellExecution, beforeMCPExecution, afterMCPExecution, beforeReadFile, afterFileEdit, beforeSubmitPrompt, preCompact, stop, afterAgentResponse, afterAgentThought) s’appliquent aux opérations Cmd+K et Agent Chat. Les hooks Tab (beforeTabFileRead, afterTabFileEdit) s’appliquent spécifiquement aux complétions Tab en ligne. Le hook de cycle de vie de l’application (workspaceOpen) se déclenche à l’ouverture d’un espace de travail et lors de la modification des dossiers de l’espace de travail, indépendamment de toute session d’agent.

Options de configuration globales

OptionTypePar défautDescription
versionnumber1Version du schéma de configuration

Options de configuration par script

OptionTypePar défautDescription
commandstringrequisChemin du script ou commande
type"command""prompt""command"
timeoutnumbervaleur par défaut de la plateformeDélai d'exécution en secondes
loop_limitnumbernull5
failClosedbooleanfalseLorsque true, les échecs du hook (plantage, expiration du délai, JSON non valide) bloquent l'action au lieu de l'autoriser. Utile pour les hooks critiques en matière de sécurité.
matcherobject-Critères déterminant quand le hook s'exécute

Configuration du matcher

Les matchers permettent de définir quand un hook s’exécute. Le champ auquel s’applique le matcher dépend du hook :

{  "hooks": {    "preToolUse": [      {        "command": "./validate-shell.sh",        "matcher": "Shell"      }    ],    "subagentStart": [      {        "command": "./validate-explore.sh",        "matcher": "explore|shell"      }    ],    "beforeShellExecution": [      {        "command": "./approve-network.sh",        "matcher": "curl|wget|nc "      }    ]  }}
  • subagentStart : Le matcher s’applique au type de sous-agent (p. ex. explore, shell, generalPurpose). Utilisez-le pour n’exécuter des hooks que lorsqu’un type spécifique de sous-agent démarre. L’exemple ci-dessus exécute validate-explore.sh uniquement pour les sous-agents explore ou shell.
  • beforeShellExecution : Le matcher s’applique à la chaîne de caractères de la commande shell. Utilisez-le pour n’exécuter des hooks que lorsque la commande correspond à un pattern (p. ex. appels réseau, suppressions de fichiers). L’exemple ci-dessus exécute approve-network.sh uniquement lorsque la commande contient curl, wget ou nc .

Matchers disponibles par hook :

  • preToolUse / postToolUse / postToolUseFailure : Filtrez par type d’outil. Les valeurs incluent Shell, Read, Write, Grep, Delete, Task et les outils MCP au format MCP:<tool_name>.
  • subagentStart / subagentStop : Filtrez par type de sous-agent (generalPurpose, explore, shell, etc.).
  • beforeShellExecution / afterShellExecution : Filtrez par texte de commande shell ; le matcher s’applique à l’intégralité de la chaîne de commande.
  • beforeReadFile : Filtrez par type d’outil (TabRead, Read, etc.).
  • afterFileEdit : Filtrez par type d’outil (TabWrite, Write, etc.).
  • beforeSubmitPrompt : Correspond à la valeur UserPromptSubmit.
  • stop : Correspond à la valeur Stop.
  • afterAgentResponse : Correspond à la valeur AgentResponse.
  • afterAgentThought : Correspond à la valeur AgentThought.

Distribution au sein de l’équipe

Les hooks peuvent être distribués aux membres de l’équipe via des hooks de projet (par contrôle de version), des outils MDM ou le système de distribution cloud de Cursor.

Hooks de projet (contrôle de version)

Les hooks de projet constituent le moyen le plus simple de partager des hooks avec votre équipe. Placez un fichier hooks.json dans <project-root>/.cursor/hooks.json et validez-le dans votre dépôt. Lorsque les membres de l’équipe ouvrent le projet dans un espace de travail approuvé, Cursor charge et exécute automatiquement les hooks de projet.

Les agents cloud chargent également ces hooks de projet lorsqu’ils travaillent sur votre dépôt dans le cloud.

Les hooks de projet :

  • Sont stockés dans le contrôle de version avec votre code
  • Sont automatiquement chargés pour tous les membres de l’équipe dans les espaces de travail approuvés
  • Peuvent être spécifiques au projet (par exemple, imposer des normes de formatage pour une base de code donnée)
  • Nécessitent que l’espace de travail soit approuvé pour pouvoir s’exécuter (pour des raisons de sécurité)

Distribution via MDM

Distribuez des hooks au sein de votre organisation à l’aide d’outils de gestion des appareils mobiles (MDM). Placez le fichier hooks.json et les scripts de hook dans les répertoires cibles de chaque machine.

Répertoire personnel de l’utilisateur (distribution par utilisateur) :

  • ~/.cursor/hooks.json
  • ~/.cursor/hooks/ (pour les scripts de hook)

Répertoires globaux (distribution à l’échelle du système) :

  • macOS : /Library/Application Support/Cursor/hooks.json
  • Linux/WSL : /etc/cursor/hooks.json
  • Windows : C:\\ProgramData\\Cursor\\hooks.json

Remarque : la distribution via MDM est entièrement gérée par votre organisation. Cursor ne déploie ni ne gère les fichiers via votre solution MDM. Veillez à ce que votre équipe informatique ou de sécurité interne gère la configuration, le déploiement et les mises à jour conformément aux stratégies de votre organisation.

Distribution cloud (Enterprise uniquement)

Les équipes Enterprise peuvent utiliser la distribution cloud native de Cursor pour synchroniser automatiquement les hooks sur les machines de tous les membres de l’équipe. Configurez les hooks dans le tableau de bord web. Cursor distribue automatiquement les hooks configurés sur toutes les machines clientes lorsque les membres de l’équipe se connectent.

La distribution cloud offre :

  • Une synchronisation automatique pour tous les membres de l’équipe (toutes les trente minutes)
  • Un ciblage par système d’exploitation pour les hooks spécifiques à une plateforme
  • Une gestion centralisée via le tableau de bord

Les administrateurs Enterprise peuvent créer, modifier et gérer les hooks d’équipe depuis le tableau de bord, sans avoir besoin d’accéder aux machines individuelles.

Contacter le service commercial pour bénéficier de la distribution cloud de hooks Enterprise.

Référence

Schéma commun

Entrée (tous les hooks)

Tous les hooks reçoivent un ensemble de champs de base, en plus de leurs champs spécifiques :

{  "conversation_id": "string",  "generation_id": "string",  "model": "string",  "model_id": "string",  "model_params": [{ "id": "string", "value": "string" }],  "hook_event_name": "string",  "cursor_version": "string",  "workspace_roots": ["<path>"],  "user_email": "string | null",  "transcript_path": "string | null"}
ChampTypeDescription
conversation_idstringID stable de la conversation sur plusieurs tours
generation_idstringGénération actuelle, qui change à chaque message utilisateur
modelstringSlug de l'ancien modèle configuré pour le composer ayant déclenché le hook
model_idstring (optional)ID structuré du modèle sélectionné, lorsqu'il est disponible
model_paramsarray (optional)Paramètres du modèle sélectionné, tels que la réflexion, le contexte ou l'effort. Chaque élément possède un id et une value.
hook_event_namestringHook en cours d'exécution
cursor_versionstringVersion de l'application Cursor (p. ex. "1.7.2")
workspace_rootsstring[]Liste des dossiers racine de l'espace de travail (généralement un seul, mais les espaces de travail à plusieurs racines peuvent en avoir plusieurs)
user_emailstringnullAdresse e-mail de l'utilisateur authentifié, si disponible
transcript_pathstringnullChemin vers le fichier de transcription de la conversation principale (null si les transcriptions sont désactivées)

Événements des hooks

preToolUse

Appelé avant toute exécution d’outil. Ce hook générique se déclenche pour tous les types d’outils (Shell, Read, Write, MCP, Task, etc.). Utilisez des matchers pour filtrer des outils spécifiques.

// Entrée{  "tool_name": "Shell",  "tool_input": { "command": "npm install", "working_directory": "/project" },  "tool_use_id": "abc123",  "cwd": "/project",  "model": "claude-opus-4-7-thinking-max",  "model_id": "claude-opus-4-7",  "model_params": [    { "id": "thinking", "value": "true" },    { "id": "context", "value": "1m" },    { "id": "effort", "value": "max" }  ],  "agent_message": "Installing dependencies..."}// Sortie{  "permission": "allow" | "deny",  "user_message": "<message shown in client when denied>",  "agent_message": "<message sent to agent when denied>",  "updated_input": { "command": "npm ci" }}
Champ de sortieTypeDescription
permissionchaîne"allow" pour autoriser la poursuite, "deny" pour bloquer. "ask" est accepté par le schéma, mais n'est pas appliqué pour preToolUse à ce jour.
user_messagechaîne (facultatif)Message affiché à l'utilisateur lorsque l'action est refusée
agent_messagechaîne (facultatif)Message renvoyé à l'agent lorsque l'action est refusée
updated_inputobjet (facultatif)Entrée d'outil modifiée à utiliser à la place

postToolUse

Appelé après l’exécution réussie d’un outil. Utile pour l’audit, l’analyse et l’ajout de contexte.

// Entrée{  "tool_name": "Shell",  "tool_input": { "command": "npm test" },  "tool_output": "{\"exitCode\":0,\"stdout\":\"All tests passed\"}",  "tool_use_id": "abc123",  "cwd": "/project",  "duration": 5432,  "model": "claude-opus-4-7-thinking-max",  "model_id": "claude-opus-4-7",  "model_params": [    { "id": "thinking", "value": "true" },    { "id": "context", "value": "1m" },    { "id": "effort", "value": "max" }  ]}// Sortie{  "updated_mcp_tool_output": { "modified": "output" },  "additional_context": "Test coverage report attached."}
Champ d’entréeTypeDescription
durationnumberDurée d’exécution en millisecondes
tool_outputstringPayload de résultat de l’outil sérialisé en chaîne JSON (et non texte brut du terminal)
Champ de sortieTypeDescription
updated_mcp_tool_outputobject (optional)Réservé aux outils MCP : remplace la sortie de l’outil visible par le modèle
additional_contextstring (optional)Contexte supplémentaire injecté dans la conversation après le résultat de l’outil

postToolUseFailure

Appelé lorsqu’un outil échoue, expire ou est refusé. Utile pour le suivi des erreurs et la logique de reprise.

// Entrée{  "tool_name": "Shell",  "tool_input": { "command": "npm test" },  "tool_use_id": "abc123",  "cwd": "/project",  "error_message": "Command timed out after 30s",  "failure_type": "timeout" | "error" | "permission_denied",  "duration": 5000,  "is_interrupt": false}// Sortie{  // Aucun champ de sortie n’est actuellement pris en charge}
Champ d’entréeTypeDescription
error_messagestringDescription de l’erreur
failure_typestringType d’erreur : "error", "timeout" ou "permission_denied"
durationnumberTemps écoulé en millisecondes avant l’erreur
is_interruptbooleanIndique si cette erreur a été causée par une interruption ou une annulation par l’utilisateur

subagentStart

Appelé avant la création d’un sous-agent (outil Task). Peut autoriser ou refuser sa création.

// Entrée{  "subagent_id": "abc-123",  "subagent_type": "generalPurpose",  "task": "Explore the authentication flow",  "parent_conversation_id": "conv-456",  "tool_call_id": "tc-789",  "subagent_model": "claude-sonnet-4-20250514",  "is_parallel_worker": false,  "git_branch": "feature/auth"}// Sortie{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
Champ d’entréeTypeDescription
subagent_idstringIdentifiant unique de cette instance de sous-agent
subagent_typestringType de sous-agent : generalPurpose, explore, shell, etc.
taskstringDescription de la tâche confiée au sous-agent
parent_conversation_idstringID de conversation de la session de l’agent parent
tool_call_idstringID de l’appel d’outil ayant déclenché le sous-agent
subagent_modelstringModèle utilisé par le sous-agent
is_parallel_workerbooleanIndique si ce sous-agent s’exécute en tant que processus parallèle
git_branchstring (facultatif)Branche Git sur laquelle le sous-agent opérera, le cas échéant
Champ de sortieTypeDescription
permissionstring"allow" pour autoriser, "deny" pour bloquer. "ask" n’est pas pris en charge pour subagentStart et est traité comme "deny".
user_messagestring (facultatif)Message affiché à l’utilisateur lorsque le sous-agent est bloqué

subagentStop

Appelé lorsqu’un sous-agent termine son exécution, rencontre une erreur ou est interrompu. Peut déclencher des actions de suivi.

// Entrée{  "subagent_type": "generalPurpose",  "status": "completed" | "error" | "aborted",  "task": "Explore the authentication flow",  "description": "Exploring auth flow",  "summary": "<subagent output summary>",  "duration_ms": 45000,  "message_count": 12,  "tool_call_count": 8,  "loop_count": 0,  "modified_files": ["src/auth.ts"],  "agent_transcript_path": "/path/to/subagent/transcript.txt"}// Sortie{  "followup_message": "<auto-continue with this message>"}
Champ d’entréeTypeDescription
subagent_typestringType de sous-agent : generalPurpose, explore, shell, etc.
statusstring"completed", "error" ou "aborted"
taskstringDescription de la tâche confiée au sous-agent
descriptionstringBrève description du rôle du sous-agent
summarystringRésumé de la sortie du sous-agent
duration_msnumberTemps d’exécution en millisecondes
message_countnumberNombre de messages échangés durant la session du sous-agent
tool_call_countnumberNombre d’appels d’outils effectués par le sous-agent
loop_countnumberNombre de fois qu’un message de suivi subagentStop a déjà été déclenché pour ce sous-agent (à partir de 0)
modified_filesstring[]Fichiers modifiés par le sous-agent
agent_transcript_pathstringnullChemin vers le fichier de transcription propre au sous-agent (distinct de la conversation parente)
Champ de sortieTypeDescription
followup_messagestring (facultatif)Continuer automatiquement avec ce message. Utilisé uniquement lorsque status vaut "completed".

Le champ followup_message permet des flux en boucle où la finalisation d’un sous-agent déclenche l’itération suivante. Les messages de suivi sont soumis à la même limite de boucle configurable que le hook stop (5 par défaut, configurable via loop_limit).

beforeShellExecution / beforeMCPExecution

Appelé avant l’exécution d’une commande shell ou d’un outil MCP. Renvoyez une décision d’autorisation.

// entrée de beforeShellExecution{  "command": "<full terminal command>",  "cwd": "<current working directory>",  "sandbox": false}// entrée de beforeMCPExecution{  "tool_name": "<tool name>",  "tool_input": "<json params>"}// Plus l’un des champs suivants :{ "url": "<server url>" }// Ou :{ "command": "<command string>" }// Sortie{  "permission": "allow" | "deny" | "ask",  "user_message": "<message shown in client>",  "agent_message": "<message sent to agent>"}

afterShellExecution

Se déclenche après l’exécution d’une commande shell ; utile pour l’audit ou la collecte de métriques à partir de la sortie de la commande.

// Entrée{  "command": "<full terminal command>",  "output": "<full terminal output>",  "duration": 1234,  "sandbox": false}
ChampTypeDescription
commandstringCommande complète exécutée dans le terminal
outputstringSortie complète capturée dans le terminal
durationnumberDurée d'exécution de la commande shell en millisecondes (hors temps d'attente d'approbation)
sandboxbooleanIndique si la commande a été exécutée dans un environnement sandboxé

afterMCPExecution

Se déclenche après l’exécution d’un outil MCP ; inclut les paramètres d’entrée de l’outil et le résultat JSON complet.

// Entrée{  "tool_name": "<tool name>",  "tool_input": "<json params>",  "result_json": "<tool result json>",  "duration": 1234}
ChampTypeDescription
tool_namestringNom de l’outil MCP exécuté
tool_inputstringChaîne de paramètres JSON transmise à l’outil
result_jsonstringChaîne JSON de la réponse de l’outil
durationnumberDurée d’exécution de l’outil MCP, en millisecondes (hors délai d’attente d’approbation)

afterFileEdit

Se déclenche après qu’un Agent a modifié un fichier ; utile pour les outils de formatage ou pour comptabiliser le code écrit par l’Agent.

// Entrée{  "file_path": "<absolute path>",  "edits": [{ "old_string": "<search>", "new_string": "<replace>" }]}

beforeReadFile

Appelé avant que l’Agent ne lise un fichier. Permet de contrôler l’accès afin d’empêcher l’envoi de fichiers sensibles au modèle.

// Entrée{  "file_path": "<absolute path>",  "content": "<file contents>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<absolute path>"    }  ]}// Sortie{  "permission": "allow" | "deny",  "user_message": "<message shown when denied>"}
Champ d’entréeTypeDescription
file_pathstringChemin absolu du fichier en cours de lecture
contentstringContenu complet du fichier
attachmentsarrayPièces jointes de contexte associées au prompt. Chaque entrée comporte un type ("file" ou "rule") et un file_path.
Champ de sortieTypeDescription
permissionstring"allow" pour autoriser, "deny" pour bloquer
user_messagestring (facultatif)Message affiché à l’utilisateur en cas de refus

beforeTabFileRead

Appelé avant que Tab (complétions en ligne) ne lise un fichier. Activez la rédaction ou le contrôle d’accès avant que Tab n’accède au contenu du fichier.

Principales différences avec beforeReadFile :

  • Déclenché uniquement par Tab, et non par l’Agent
  • N’inclut pas le champ attachments (Tab n’utilise pas de pièces jointes dans les prompts)
  • Utile pour appliquer des stratégies différentes aux opérations autonomes de Tab
// Entrée{  "file_path": "<absolute path>",  "content": "<file contents>"}// Sortie{  "permission": "allow" | "deny"}

afterTabFileEdit

Appelé après qu’une complétion Tab (en ligne) a modifié un fichier. Utile pour les outils de formatage ou l’audit du code écrit par Tab.

Différences clés par rapport à afterFileEdit :

  • Déclenché uniquement par Tab, et non par un Agent
  • Inclut des informations détaillées sur la modification : range, old_line et new_line, pour un suivi précis des modifications
  • Utile pour le formatage ou l’analyse détaillée des modifications de Tab
// Entrée{  "file_path": "<absolute path>",  "edits": [    {      "old_string": "<search>",      "new_string": "<replace>",      "range": {        "start_line_number": 10,        "start_column": 5,        "end_line_number": 10,        "end_column": 20      },      "old_line": "<line before edit>",      "new_line": "<line after edit>"    }  ]}// Sortie{  // Aucun champ de sortie n’est actuellement pris en charge}

beforeSubmitPrompt

Appelé juste après que l’utilisateur a envoyé sa requête, mais avant la requête au backend. Peut empêcher l’envoi.

// Entrée{  "prompt": "<texte de l'invite utilisateur>",  "attachments": [    {      "type": "file" | "rule",      "file_path": "<chemin absolu>"    }  ]}// Sortie{  "continue": true | false,  "user_message": "<message affiché à l'utilisateur lorsqu'il est bloqué>"}
Champ de sortieTypeDescription
continuebooleanIndique si l'envoi du prompt est autorisé à se poursuivre
user_messagestring (optional)Message affiché à l'utilisateur lorsque le prompt est bloqué

afterAgentResponse

Appelé une fois que l’agent a terminé un message de l’assistant.

// Entrée{  "text": "<assistant final text>"}

afterAgentThought

Appelé lorsque l’agent a terminé un bloc de réflexion. Utile pour observer le raisonnement de l’agent.

// Entrée{  "text": "<fully aggregated thinking text>",  "duration_ms": 5000}// Sortie{  // Aucun champ de sortie n’est actuellement pris en charge}
ChampTypeDescription
textstringTexte de réflexion agrégé du bloc terminé
duration_msnumber (optional)Durée du bloc de réflexion, en millisecondes

stop

Appelé à la fin de la boucle de l’agent. Peut éventuellement envoyer automatiquement un message de suivi de l’utilisateur pour poursuivre l’itération.

// Entrée{  "status": "completed" | "aborted" | "error",  "loop_count": 0}
// Sortie{  "followup_message": "<message text>"}
  • Le paramètre facultatif followup_message est une chaîne de caractères. Lorsqu’il est renseigné et non vide, Cursor l’envoie automatiquement comme prochain message utilisateur. Cela permet des flux en boucle (p. ex., itérer jusqu’à ce qu’un objectif soit atteint).
  • Le champ loop_count indique le nombre de fois où le hook stop a déjà déclenché un message de suivi automatique pour cette conversation (commence à 0). La limite par défaut est de 5 messages de suivi automatiques par script, configurable via l’option loop_limit. Définissez loop_limit sur null pour supprimer cette limite. La même limite s’applique aux messages de suivi subagentStop.

sessionStart

Appelé lorsqu’une nouvelle conversation dans composer est créée. Ce hook s’exécute en mode fire-and-forget ; la boucle de l’Agent n’attend pas de réponse bloquante et ne l’impose pas. Utilisez-le pour configurer des variables d’environnement propres à la session ou injecter du contexte supplémentaire.

// Entrée{  "session_id": "<unique session identifier>",  "is_background_agent": true | false,  "composer_mode": "agent" | "ask" | "edit"}
// Sortie{  "env": { "<key>": "<value>" },  "additional_context": "<context to add to conversation>"}
Champ d’entréeTypeDescription
session_idstringIdentifiant unique de cette session (identique à conversation_id)
is_background_agentbooleanIndique s’il s’agit d’une session d’Agent en arrière-plan ou d’une session interactive
composer_modestring (facultatif)Mode dans lequel composer démarre (p. ex., "agent", "ask", "edit")
Champ de sortieTypeDescription
envobject (facultatif)Variables d’environnement à définir pour cette session. Disponibles pour toutes les exécutions de hooks ultérieures
additional_contextstring (facultatif)Contexte supplémentaire à ajouter au contexte système initial de la conversation

sessionEnd

Appelé à la fin d’une conversation composer. Ce hook fire-and-forget est utile pour les tâches de journalisation, d’analyse ou de nettoyage. La réponse est journalisée, mais n’est pas utilisée.

// Entrée{  "session_id": "<identifiant de session unique>",  "reason": "completed" | "aborted" | "error" | "window_close" | "user_close",  "duration_ms": 45000,  "is_background_agent": true | false,  "final_status": "<chaîne d'état>",  "error_message": "<détails de l'erreur si reason est 'error'>"}
// Sortie{  // Aucun champ de sortie ; exécution sans attente de réponse}
Champ d’entréeTypeDescription
session_idstringIdentifiant unique de la session qui se termine
reasonstringManière dont la session s’est terminée : "completed", "aborted", "error", "window_close" ou "user_close"
duration_msnumberDurée totale de la session en millisecondes
is_background_agentbooleanIndique s’il s’agissait d’une session d’agent en arrière-plan
final_statusstringStatut final de la session
error_messagestring (optional)Message d’erreur si la raison est "error"

preCompact

Appelé avant la compaction ou la synthèse de la fenêtre de contexte. Ce hook d’observation ne peut ni bloquer ni modifier le comportement de compaction. Utile pour consigner les opérations de compaction ou en informer les utilisateurs.

// Entrée{  "trigger": "auto" | "manual",  "context_usage_percent": 85,  "context_tokens": 120000,  "context_window_size": 128000,  "message_count": 45,  "messages_to_compact": 30,  "is_first_compaction": true | false}
// Sortie{  "user_message": "<message to show when compaction occurs>"}
Champ d’entréeTypeDescription
triggerstringÉlément ayant déclenché la compaction : "auto" ou "manual"
context_usage_percentnumberUtilisation actuelle de la fenêtre de contexte, en pourcentage (0-100)
context_tokensnumberNombre actuel de tokens dans la fenêtre de contexte
context_window_sizenumberTaille maximale de la fenêtre de contexte en tokens
message_countnumberNombre de messages dans la conversation
messages_to_compactnumberNombre de messages qui seront résumés
is_first_compactionbooleanIndique s’il s’agit de la première compaction de cette conversation
Champ de sortieTypeDescription
user_messagestring (optional)Message à afficher à l’utilisateur lors d’une compaction

workspaceOpen

Se déclenche à l’ouverture d’un espace de travail par Cursor, puis à chaque modification d’un dossier de l’espace de travail. Ignoré lorsque la fenêtre ne contient aucun dossier d’espace de travail. S’exécute dans l’application de bureau Cursor et la CLI.

// Entrée{  "hook_event_name": "workspaceOpen",  "cursor_version": "string",  "workspace_roots": ["<absolute path>"],  "user_email": "string | null"}// Sortie{  "pluginPaths": ["<absolute path>", "..."]}
Champ de sortieTypeDescription
pluginPathsstring[] (facultatif)Chemins absolus des répertoires de plugins à charger pour l’espace de travail actuel.

Variables d’environnement

Les scripts de hook reçoivent des variables d’environnement lors de leur exécution :

VariableDescriptionToujours présente
CURSOR_PROJECT_DIRRépertoire racine de l’espace de travailOui
CURSOR_VERSIONChaîne de version de CursorOui
CURSOR_USER_EMAILAdresse e-mail de l’utilisateur authentifiéSi connecté
CURSOR_TRANSCRIPT_PATHChemin du fichier de transcription de la conversationSi les transcriptions sont activées
CURSOR_CODE_REMOTEDéfini sur la chaîne "true" lors de l’exécution dans un espace de travail distantPour les espaces de travail distants
CLAUDE_PROJECT_DIRAlias du répertoire du projet (compatibilité avec Claude)Oui

Les variables d’environnement définies par les hooks sessionStart et limitées à la session sont transmises à toutes les exécutions de hook suivantes au cours de cette session.

Dépannage

Comment vérifier que les hooks sont actifs

Un onglet Hooks est disponible dans Personnaliser, ainsi qu’un canal de sortie Hooks permettant de déboguer les hooks configurés et exécutés et d’afficher les erreurs.

Si les hooks ne fonctionnent pas

  • Cursor surveille les fichiers hooks.json et les recharge à l’enregistrement. Si les hooks ne se chargent toujours pas, redémarrez Cursor.
  • Vérifiez que les chemins relatifs sont corrects pour la source de votre hook :
    • Pour les hooks de projet, les chemins sont relatifs à la racine du projet (par ex., .cursor/hooks/script.sh)
    • Pour les hooks utilisateur, les chemins sont relatifs à ~/.cursor/ (par ex., ./hooks/script.sh ou hooks/script.sh)

Blocage par code de sortie

Le code de sortie 2 des hooks de commande bloque l’action (ce qui équivaut à renvoyer permission: "deny"). Ce comportement est conforme à celui de Claude Code, par souci de compatibilité.

Hooks Enterprise et distribution

La distribution Cloud et la gestion des hooks à l’échelle de l’équipe sont disponibles avec Enterprise.

Contact Sales