Skip to main content

Hooks

Run custom logic before or after tool execution via hooks.json

Hooks let you trigger external scripts, audit logs, or security checks whenever OpsCode runs a tool. You can use hooks to log every shell command, send Slack alerts for infrastructure operations, or auto-format files after the agent modifies them.


Configuration

Hooks are declared in JSON files at two scopes:

LocationScopeTrust
~/.opscode/hooks.jsonGlobal (all sessions)Always trusted
.opscode/hooks.jsonProject-levelRequires --trust-project-hooks or interactive approval

Both global and project hooks run simultaneously.


Format

{
"hooks": {
"Bash": {
"command": "echo 'Shell: ${input.command}' >> /tmp/opscode-audit.log"
},
"Write": {
"command": "echo 'File created: ${input.file_path}' >> /tmp/opscode-audit.log"
},
"Edit": {
"command": "echo 'File edited: ${input.file_path}' >> /tmp/opscode-audit.log"
}
}
}

Each key is a tool name, and command is the shell command that runs when that tool is invoked. You can use ${input.field} to reference the tool's input values.


Tool names

OpsCode maps its internal tools to these names for hooks:

Tool nameTriggered byAvailable input fields
BashShell commandscommand, timeout
WriteFile creation/overwritefile_path, content
EditFile editsfile_path, old_string, new_string, replace_all
ReadFile readsfile_path, offset, limit
GlobPattern searchespattern, path
GrepContent searchespattern, path, glob, output_mode
LSDirectory listingpath

MCP tools use their standard mcp__{server}__{tool} name:

{
"hooks": {
"mcp__kubernetes__get_pods": {
"command": "echo 'Kubernetes cluster inspected' >> ~/.opscode/audit.log"
}
}
}

Examples

Audit logging

Log all shell commands and file changes:

{
"hooks": {
"Bash": {
"command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) EXEC: ${input.command}\" >> ~/.opscode/audit.log"
},
"Write": {
"command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) WRITE: ${input.file_path}\" >> ~/.opscode/audit.log"
},
"Edit": {
"command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) EDIT: ${input.file_path}\" >> ~/.opscode/audit.log"
}
}
}

Slack alerts for infrastructure plans

Notify the team when infrastructure operations are planned:

{
"hooks": {
"Bash": {
"command": "if echo '${input.command}' | grep -qE '(terraform|tofu) plan'; then curl -s -X POST -H 'Content-type: application/json' --data '{\"text\":\"OpsCode running infrastructure plan\"}' $SLACK_WEBHOOK_URL; fi"
}
}
}

Auto-format on save

Automatically format Terraform files after the agent creates or edits them:

{
"hooks": {
"Write": {
"command": "if echo '${input.file_path}' | grep -qE '\\.(tf|tofu)$'; then tofu fmt '${input.file_path}' 2>/dev/null || terraform fmt '${input.file_path}' 2>/dev/null || true; fi"
}
}
}

Trust and security

Project-level hooks (.opscode/hooks.json) can run arbitrary shell commands and require explicit trust:

ops --trust-project-hooks

Global hooks (~/.opscode/hooks.json) are always trusted since they're in your home directory.