Introduction

Hooks in OpenClaw let you run custom code at specific points in the agent's lifecycle. There are five event types, each firing at a different moment: when commands are issued, when agents bootstrap, when the gateway starts, when messages flow, and when tool results are persisted. Mastering these events lets you customize every stage of the agent pipeline.

Key Concepts

  • command hook: Fires on command lifecycle events: new, reset, and stop
  • agent hook: Fires during agent lifecycle, specifically at bootstrap when the agent initializes before workspace files are injected
  • gateway hook: Fires at startup when the Gateway process begins
  • message hook: Fires when messages are received from users or sent by the agent
  • tool_result_persist hook: Fires when a tool result is saved to the session history

Real World Context

A platform team runs OpenClaw for their organization. They use a gateway:startup hook to verify that all required environment variables are present before the Gateway accepts connections. An agent:bootstrap hook injects organization-specific system instructions into every agent. A message:received hook logs all incoming messages to an audit database for compliance. These hooks let them customize the platform without modifying OpenClaw's source code.

Deep Dive

Command Hooks

Command hooks fire when users issue session management commands:

json
{
  "hooks": {
    "command": {
      "new": "./hooks/on-new-session.sh",
      "reset": "./hooks/on-reset.sh",
      "stop": "./hooks/on-stop.sh"
    }
  }
}

The new event fires when a new session is created. The reset event fires when a session is reset (clearing history). The stop event fires when a session is terminated. Each hook points to a script that runs when the event occurs.

Agent Hooks

The agent:bootstrap hook fires during agent initialization, before workspace files like HEARTBEAT.md are injected:

json
{
  "hooks": {
    "agent": {
      "bootstrap": "./hooks/on-agent-bootstrap.js"
    }
  }
}

This hook is ideal for injecting custom instructions, loading environment-specific configuration, or performing setup tasks that must complete before the agent starts processing messages.

Gateway Hooks

The gateway:startup hook fires once when the Gateway process begins:

json
{
  "hooks": {
    "gateway": {
      "startup": "./hooks/on-gateway-startup.sh"
    }
  }
}

This hook runs before the Gateway starts accepting connections. It is perfect for validating configuration, checking dependencies, or initializing shared resources.

Message Hooks

Message hooks fire on the message lifecycle:

json
{
  "hooks": {
    "message": {
      "received": "./hooks/on-message-received.js",
      "sent": "./hooks/on-message-sent.js"
    }
  }
}

The received event fires when a message arrives from a user before the agent processes it. The sent event fires after the agent generates a response. These hooks enable logging, content filtering, message transformation, and analytics.

Tool Result Persist Hook

This hook fires when a tool's output is saved to the session:

json
{
  "hooks": {
    "tool_result_persist": "./hooks/on-tool-result.js"
  }
}

This hook is useful for monitoring tool usage patterns, sanitizing sensitive data from tool outputs before they enter session history, or triggering follow-up actions based on specific tool results.

Common Pitfalls

  • Confusing agent:bootstrap with gateway:startup: The bootstrap hook fires per-agent during initialization, while gateway:startup fires once for the entire Gateway process.
  • Blocking hooks with long-running operations: Hooks are synchronous by default. A slow hook in the message:received pipeline delays the agent's response.
  • Not handling hook errors gracefully: A hook that throws an unhandled exception can crash the agent or prevent message processing.

Best Practices

  • Keep hooks lightweight by delegating heavy work to background processes or queues.
  • Use gateway:startup for one-time setup and agent:bootstrap for per-agent configuration.
  • Always add error handling in hook scripts to prevent unhandled exceptions from disrupting the pipeline.

Summary

  • Five hook event types cover the complete lifecycle: command, agent, gateway, message, and tool_result_persist
  • agent:bootstrap fires before workspace files are injected, ideal for pre-initialization setup
  • gateway:startup fires once when the Gateway process begins, before accepting connections
  • message hooks cover both received and sent events for logging, filtering, and transformation
  • tool_result_persist fires when tool outputs are saved to session history
✓ Completed