Hooks
A hook runs at a named moment in a Mercury session. It can run a shell command, have a model answer a prompt, have an agent check something, or post the moment's facts to an HTTP endpoint.
Hooks are declared under the hooks key in user, project, local or managed policy settings. A skill or an extension can declare its own hooks in its frontmatter or manifest, and /hooks lists every hook the session carries.
Hook kinds
Every hook has a type.
command: Runscommandin a shell.shellselectsbash, the default, orpowershell.async: trueruns the hook in the background, andasyncRewake: truealso wakes the model when the hook exits with the blocking status.prompt: Has a model answerprompt.$ARGUMENTSreceives the hook input JSON, andmodelselects the model.agent: Has an agent verifyprompt.$ARGUMENTSreceives the hook input JSON, and the timeout defaults to 60 seconds.http: Posts the hook input JSON tourl.headersmay reference environment variables as$VARor${VAR}; only the names listed inallowedEnvVarsare interpolated, and every other reference resolves to an empty string.
Entry fields
Each event names a list of entries.
matcher: Matches the event's tool name on the tool events. An absent or empty matcher, or*, matches everything; a plain name matches that tool;Read|Editmatches either; anything else is a regular expression. An entry whose matcher is not a valid regular expression is refused whole.hooks: Lists the hooks to run when the matcher matches.
Fields every hook kind accepts
if: A condition in permission-rule syntax, such asBash(git *), evaluated against the tool events' input. A hook whose condition does not match is skipped.timeout: The timeout in seconds.statusMessage: The text shown in the spinner while the hook runs.once: Runs the hook once, then removes it.
Declare a command hook
To declare a command hook, follow these steps:
Add an entry under the event name in the settings file's
hooksobject:{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [{ "type": "command", "command": "./scripts/check-command.sh" }] } ] } }
The command runs before each Bash tool call, subject to workspace trust and managed policy.
Event inputs
Every hook input carries hook_event_name, session_id, transcript_path, cwd and permission_mode. Each event adds its own fields.
- Tool events:
PreToolUse,PostToolUse,PostToolUseFailureandPermissionDeniedcarrytool_name,tool_inputandtool_use_id;PostToolUseaddstool_response,PostToolUseFailureaddserrorandis_interrupt, andPermissionDeniedaddsreason.PermissionRequestcarriestool_name,tool_inputandpermission_suggestions. - Prompt events:
UserPromptSubmitcarriesprompt;UserPromptExpansionaddsexpansion_type,command_name,command_argsandcommand_source. - Session events:
SessionStartcarriessource,agent_typeandmodel;SessionEndcarriesreason;Setup, fired by--init,--init-onlyor--maintenance, carriestrigger. - Turn events:
Stopcarriesstop_hook_activeandlast_assistant_message;SubagentStopaddsagent_id,agent_transcript_pathandagent_type;StopFailurecarrieserror,error_detailsandlast_assistant_message. - Agent and task events:
SubagentStartcarriesagent_idandagent_type;TeammateIdlecarriesteammate_nameandteam_name;TaskCreatedandTaskCompletedaddtask_id,task_subjectandtask_description. - Compaction events:
PreCompactcarriestriggerandcustom_instructions;PostCompactcarriestriggerandcompact_summary. - MCP events:
Elicitationcarriesmcp_server_name,message,mode,urlandelicitation_id;ElicitationResultcarriesmcp_server_name,elicitation_id,mode,actionandcontent. - Configuration and file events:
ConfigChangecarriessourceandfile_path;InstructionsLoadedcarriesfile_path,memory_type,load_reason,globsandtrigger_file_path;CwdChangedcarriesold_cwdandnew_cwd;FileChangedcarriesfile_pathandevent. - Worktree events:
WorktreeCreatecarriesname;WorktreeRemovecarriesworktree_path. Notification: Carriesmessage,titleandnotification_type.
Hook responses
A command hook answers with its exit code and its stdout. Prompt, agent and HTTP hooks answer with the same JSON object.
- Exit code
0: Success. Stdout is plain text shown as the hook's output, or one JSON object. - Exit code
2: The event is blocked, and stderr is the reason the model sees. - Any other exit code: A nonblocking error, reported to the user.
The JSON object may carry continue, where false stops the whole turn with stopReason shown to the user; suppressOutput; systemMessage; decision: "block" with reason; and hookSpecificOutput with hookEventName set to the event that ran. On PreToolUse the permission answer is permissionDecision with allow, deny or ask inside hookSpecificOutput, never the decision field; permissionDecisionReason, updatedInput and additionalContext ride beside it. PermissionRequest answers decision with behavior: "allow" or "deny", Elicitation and ElicitationResult answer action and content, SessionStart may add additionalContext, initialUserMessage and watchPaths, and WorktreeCreate answers worktreePath. A hookEventName that is not the event that ran is an error.
Policy controls
disableAllHooks: Disables every hook, managed hooks included.allowManagedHooksOnly: Restricts execution to the hooks the policy settings define.
Workspace trust keeps a project's hooks from running before the workspace is trusted.
Related pages
Workspace trust and permissions, Extensions, MCPs and skills, Permission modes