How do I create a custom hook?
Hooks let you automate actions when events (like /new, /reset, or startup) occur.
Hooks allow you to run custom TypeScript code when specific events occur in OpenClaw. They are powerful tools for auditing commands, persisting memory snapshots, or triggering external automations (like effective zapier-style workflows) whenever a user interacts with your agent.
A hook is simply a directory containing two essential files: HOOK.md (for metadata and discovery) and handler.ts (for the executable logic).
Step 1: Create the directory
Hooks are automatically discovered from standard locations. You can place them in ~/.openclaw/hooks/ for global availability across all agents, or in <workspace>/hooks/ for agent-specific logic.
mkdir -p ~/.openclaw/hooks/my-greeter
Step 2: Define metadata (HOOK.md)
The HOOK.md file uses YAML frontmatter to tell OpenClaw's plugin system how to load your hook. The events array is critical—it defines exactly which triggers will wake up your handler.
---
name: my-greeter
description: 'Says hello when you run /new'
metadata:
openclaw:
emoji: '👋'
events: ['command:new'] # Triggers only when /new is detected
---
# My Greeter Hook
This hook sends a welcome message when a new session starts.
Docs: https://docs.openclaw.ai/hooksStep 3: Write Logic (handler.ts)
Your `handler.ts` exports a default function that receives an `event` object. This object contains all the context you need, including the session ID, the user's message, and a mutable `messages` array for sending replies.
import type { HookHandler } from "../../src/hooks/hooks.js";
const handler: HookHandler = async (event) => {
// 1. Validate the event context
// It is good practice to double-check event types, even if filtered by metadata.
if (event.type !== "command" || event.action !== "new") {
return;
}
// 2. Perform your custom logic
console.log(`[my-greeter] New session started for session: ${event.sessionKey}`);
// 3. Interact with the user
// Pushing strings to event.messages sends them back to the user immediately.
event.messages.push("👋 Hello! I am your custom greeter hook.");
};
export default handler;Step 4: Enable it
For security, new hooks are disabled by default. You must explicitly enable them via the CLI and restart the gateway for changes to take effect.
# 1. Verify the hook is discovered openclaw hooks list # 2. Enable it by name openclaw hooks enable my-greeter # 3. Restart the gateway to load the new handler openclaw gateway restart
Troubleshooting
If your hook isn't firing, check the gateway logs. OpenClaw logs hook registration at startup.
openclaw logs --follow
Look for lines like Registered hook: my-greeter -> command:new. If you don't see them, run openclaw hooks info my-greeter to check for missing requirements or syntax errors in your `HOOK.md`.
Pro Tip: Event Types
You can listen for a variety of lifecycle events to build complex workflows:
command:new- Triggered on session reset.command:stop- Triggered when a task is aborted.gateway:startup- Runs once when OpenClaw boots (useful for background jobs).tool_result_persist- Intercept and modify tool outputs before they save to memory.