Learn Claude Code Subagents: Multi-Agent Orchestration Agent Lifecycle Hooks: Automating Around Your Agents

Agent Lifecycle Hooks: Automating Around Your Agents

Intermediate 🕐 13 min Lesson 9 of 15
What you'll learn
  • Use the hooks frontmatter field to scope lifecycle hooks to a single subagent definition
  • Configure SubagentStart and SubagentStop hook events with matchers that filter by agent type name
  • Build practical automation patterns using command, http, and mcp_tool hook handlers triggered by agent lifecycle events

Hooks Scoped to Agents

The Claude Code hooks system fires on lifecycle events — when a tool is called, when a session starts, when a file changes. By default, hooks configured in settings files apply globally to everything in the session.

The hooks frontmatter field in a subagent definition is different. Hooks defined there are active only while that specific agent is running. When the agent finishes, those hooks deactivate. This lets you attach automation directly to specific agent types without affecting the rest of your session.

---
name: database-migration-agent
description: Runs database migrations safely. Logs all operations.
tools: Bash, Read
hooks:
  PreToolUse:
    - matcher: Bash
      hooks:
        - type: command
          command: "echo "Migration agent executing: $TOOL_INPUT" >> ~/.claude/migration-audit.log"
---

This hook fires every time the agent runs a Bash command, appending an audit log entry. It only fires when this specific agent is active — not for other agents or the main session.

SubagentStart and SubagentStop Events

Two hook events are specifically designed for subagent lifecycle automation:

SubagentStart: fires when a subagent is about to begin its first turn. Useful for setup work, notifications, and logging that a specific type of agent has started.

SubagentStop: fires when a subagent has finished and is about to terminate. Useful for cleanup, notifications, and capturing the agent's output for downstream processing.

Both events support matchers that filter by agent type name:

"hooks": {
  "SubagentStart": [
    {
      "matcher": "database-migration-agent",
      "hooks": [
        {
          "type": "http",
          "url": "https://hooks.slack.com/...",
          "timeout": 10
        }
      ]
    }
  ]
}

This configuration (in a settings file, not in the agent definition) sends a Slack notification whenever the database migration agent starts. The matcher "database-migration-agent" matches the agent's name field exactly.

Practical Automation Patterns

Three patterns cover most subagent hook use cases:

Pattern 1: Audit logging. Use SubagentStart and SubagentStop to log when agents of a specific type run, what they were given, and when they finished. Invaluable for debugging and compliance in automated pipelines.

Pattern 2: Notifications. Use SubagentStop with an http handler to post to Slack, send a webhook, or trigger a downstream service when an agent completes. Useful for long-running agents where you want to know when the result is ready.

Pattern 3: Quality gates. Use SubagentStop with a command handler that runs a validation script and exits with code 2 to prevent the agent from being considered complete if its output fails validation. If the hook exits with code 2, Claude reads the stderr and continues the agent's turn rather than reporting it as done.

Hook Handler Types

Three handler types are most useful in agent lifecycle hooks:

command: Runs a shell command. Receives hook context as JSON on stdin. Exit code 0 = success, exit code 2 = blocking error (stops the action), any other code = non-blocking error.

- type: command
  command: "python3 ~/.claude/scripts/validate-output.py"
  timeout: 30

http: Makes a POST request to an HTTP endpoint. Useful for webhooks, external logging services, and triggering downstream automation.

- type: http
  url: "https://api.myservice.com/agent-events"
  headers:
    Authorization: "Bearer $MY_TOKEN"
  allowedEnvVars: ["MY_TOKEN"]

mcp_tool: Calls a tool on a connected MCP server. Useful when your logging or notification infrastructure is already exposed through an MCP server.

- type: mcp_tool
  server: my_logging_server
  tool: log_agent_event
  input:
    agent_type: "database-migration-agent"

Exit Code Behavior

The exit code from a command hook controls what happens next:

  • Exit 0: Success. Parse stdout for JSON output if present.
  • Exit 2: Blocking error. Claude reads stderr and blocks the action. This is how you enforce quality gates.
  • Any other code (including 1): Non-blocking error. Shows in output but does not stop execution.

Note that exit code 1 is not blocking. If you want to stop an action on failure, your script must exit with code 2 specifically.

Key takeaways
  • The <code>hooks</code> frontmatter field in an agent definition scopes hooks to that agent only — they activate when the agent starts and deactivate when it finishes
  • <code>SubagentStart</code> fires when an agent begins its first turn; <code>SubagentStop</code> fires when it terminates — both support matchers that filter by agent type name
  • Three practical patterns: audit logging (capture all agent starts/stops), notifications (http handler posts to Slack on completion), quality gates (command handler exits 2 to block completion if output fails validation)
  • Exit code 2 is the blocking exit code — use it explicitly in validation scripts; exit code 1 is non-blocking and will NOT stop execution
  • Three handler types for agent hooks: <code>command</code> (shell scripts), <code>http</code> (webhooks and APIs), <code>mcp_tool</code> (tools on a connected MCP server)