# Claude Code Hooks Setup
This guide explains how to configure Claude Code hooks for aggressive memory capture, context injection, and automated learning with Recall.
## Overview
Recall provides **15 hooks** for Claude Code, plus a background daemon for fast operations:
| Hook | File | Purpose | Hook Type |
|------|------|---------|-----------|
| **Session Start** | `recall-session-start.py` | Record session initiation | SessionStart |
| **Context Loader** | `recall-context.py` | Load relevant memories at session start | SessionStart |
| **User Prompt** | `recall-prompt.py` | Inject context based on prompt content | UserPromptSubmit |
| **Pre-Tool Context** | `recall-precontext.py` | Inject memories before tool calls | PreToolUse |
| **Security Validator** | `recall-security.py` | Block dangerous bash patterns | PreToolUse |
| **Permissions** | `recall-permissions.py` | Automate learned permission decisions | PermissionRequest |
| **File Tracker** | `recall-track.py` | Track file Read/Write/Edit operations | PostToolUse |
| **Session Capture** | `recall-capture.py` | Summarize session, store memories | SessionEnd |
| **Compaction Guard** | `recall-compact.py` | Preserve context before compaction | PreCompact |
| **Monitor** | `recall-monitor.py` | Health check and deep analysis | PostSessionEnd |
| **Notification** | `recall-notify.py` | Handle notification events | Notification |
| **Stop Hook** | `recall-stop.py` | Capture learnings when agent stops | Stop |
| **Subagent Tracker** | `recall-subagent.py` | Track Task/subagent results | SubagentStop |
**Background Services:**
| Service | File | Purpose |
|---------|------|---------|
| **Daemon** | `recall-daemon.py` | Fast IPC server (<10ms operations) |
| **Daemon Control** | `recall-daemon-ctl.py` | CLI for daemon lifecycle management |
These hooks are **optional** - Recall works as a standard MCP server without them. The hooks enhance the experience by automating memory capture, context injection, and learning.
## Daemon Architecture (Fast Path)
The recall daemon is the key to fast memory operations. Without it, each store operation blocks for embedding generation (10-60s with Ollama, <100ms with MLX). With the daemon, operations complete in <10ms.
```
┌─────────────────────────────────────────────────────────────────┐
│ Hook calls memory_store │
│ │ │
│ ▼ │
│ ┌─────────────────────┐ │
│ │ Daemon socket exists?│ │
│ └──────────┬──────────┘ │
│ YES │ NO │
│ │ └────────────────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ FAST PATH │ │ SYNC PATH │ │
│ │ Queue to daemon │ │ MLX: <100ms │ │
│ │ <10ms response │ │ Ollama: 10-60s │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
```
### Daemon Components
- **Unix Socket**: `/tmp/recall-daemon.sock` for fast IPC
- **StoreQueue**: SQLite-backed queue for pending memories
- **EmbedWorker**: Background embedding processing (MLX on Apple Silicon, Ollama fallback)
- **ClassificationWorker**: Async LLM classification for edge types
### Daemon Performance
| Path | Response Time | Use Case |
|------|---------------|----------|
| Fast (daemon) | <10ms | Normal operation when daemon running |
| Sync + MLX | <100ms | Apple Silicon without daemon |
| Sync + Ollama | 10-60s | Non-Apple platforms without daemon |
---
## Quick Start
### 1. Install the Daemon (Recommended)
```bash
# From the recall directory
./hooks/install-daemon.sh
```
This will:
1. Copy hook scripts to `~/.claude/hooks/`
2. Install the launchd plist to `~/Library/LaunchAgents/`
3. Start the daemon automatically
### 2. Configure Claude Code Hooks
Add hooks to `~/.claude/settings.json`:
```json
{
"hooks": {
"SessionStart": [
{
"command": "~/.claude/hooks/recall-session-start.py",
"timeout": 5000
},
{
"command": "~/.claude/hooks/recall-context.py",
"timeout": 10000
}
],
"UserPromptSubmit": [
{
"command": "~/.claude/hooks/recall-prompt.py",
"timeout": 5000
}
],
"PreToolUse": [
{
"matcher": "Bash|Write|Edit",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/recall-precontext.py",
"timeout": 3000
},
{
"type": "command",
"command": "~/.claude/hooks/recall-security.py",
"timeout": 2000
}
]
}
],
"PermissionRequest": [
{
"command": "~/.claude/hooks/recall-permissions.py",
"timeout": 5000
}
],
"PostToolUse": [
{
"matcher": "Read|Write|Edit|MultiEdit|Glob|Grep|WebFetch|Task",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/recall-track.py",
"timeout": 5000
}
]
}
],
"SessionEnd": [
{
"command": "~/.claude/hooks/recall-capture.py",
"timeout": 30000
}
],
"PreCompact": [
{
"command": "~/.claude/hooks/recall-compact.py",
"timeout": 10000
}
],
"PostSessionEnd": [
{
"command": "~/.claude/hooks/recall-monitor.py",
"timeout": 30000
}
],
"Notification": [
{
"command": "~/.claude/hooks/recall-notify.py",
"timeout": 5000
}
],
"Stop": [
{
"command": "~/.claude/hooks/recall-stop.py",
"timeout": 30000
}
],
"SubagentStop": [
{
"command": "~/.claude/hooks/recall-subagent.py",
"timeout": 10000
}
]
}
}
```
---
## Prerequisites
- Claude Code installed and configured
- Recall MCP server set up (see main README)
- Python 3.11+ with `uv` package manager
- **For Apple Silicon (recommended)**: MLX embeddings work automatically
- **For other platforms**: Ollama with required models
### Install Ollama (if not using MLX)
```bash
# macOS
brew install ollama
# Linux
curl -fsSL https://ollama.com/install.sh | sh
# Pull required models
ollama pull mxbai-embed-large # For embeddings
ollama pull llama3.2 # For session summarization (optional)
```
---
## Hook Details
### Session Lifecycle Hooks
#### SessionStart - Session Recording
**File:** `recall-session-start.py`
Records every session start. This is mandatory for session tracking and enables correlation between sessions and memories.
#### SessionStart - Context Injection
**File:** `recall-context.py`
Loads relevant memories at the start of each Claude Code session.
**How it works:**
1. Detects the current project from working directory
2. Calls `memory_context` to fetch relevant memories
3. Uses Ollama for intelligent curation (optional)
4. Outputs context as markdown for Claude to ingest
#### SessionEnd - Memory Capture
**File:** `recall-capture.py`
Summarizes session transcripts and stores important information as memories.
**How it works:**
1. Reads session transcript from `CLAUDE_TRANSCRIPT_PATH`
2. Sends to Ollama `llama3.2` for summarization
3. Extracts structured memories (preferences, decisions, patterns)
4. Stores each memory via `memory_store`
#### Stop - Learning Capture
**File:** `recall-stop.py`
Captures learnings when the agent finishes responding. Analyzes the conversation for important patterns, decisions, or issues.
---
### Tool Interception Hooks
#### UserPromptSubmit - Prompt Context
**File:** `recall-prompt.py`
Injects relevant memory context based on the user's prompt content before processing.
#### PreToolUse - Context Injection
**File:** `recall-precontext.py`
Injects relevant memory reminders BEFORE certain operations.
**Example Output:**
```markdown
# Memory Reminder
*Before running: `npm install express...`*
- [GOLDEN RULE] You MUST use pnpm. You MUST NOT use npm.
- [PREFERENCE] This project uses TypeScript strict mode
```
#### PreToolUse - Security Validation
**File:** `recall-security.py`
Validates commands for security risks before execution. Blocks dangerous bash patterns (exit code 2).
#### PermissionRequest - Learned Automation
**File:** `recall-permissions.py`
Automates approval/denial based on stored memory patterns. Learns from user decisions and builds up a permission memory.
#### PostToolUse - File Activity Tracking
**File:** `recall-track.py`
Tracks every file Read/Write/Edit/MultiEdit operation for "recently touched files" queries.
---
### Specialized Hooks
#### PreCompact - Context Preservation
**File:** `recall-compact.py`
Runs BEFORE a compact operation (context window compression). Extracts and stores important information that might be lost during compaction.
#### PostSessionEnd - Health Monitoring
**File:** `recall-monitor.py`
Fast health check with background deep analysis that survives hook cancellation. Uses double-fork daemon pattern for reliable background execution.
#### Notification - Event Handling
**File:** `recall-notify.py`
Handles notification events from Claude Code. Informational only - cannot block notifications.
#### SubagentStop - Subagent Tracking
**File:** `recall-subagent.py`
Tracks Task/subagent results. Captures subagent work for memory context, enabling better coordination between main agent and subagents.
---
## Daemon Management
### Starting the Daemon
```bash
# Using launchd (auto-start on boot)
launchctl load ~/Library/LaunchAgents/com.recall.daemon.plist
# Manual start
~/.claude/hooks/recall-daemon.py
# Using control script
~/.claude/hooks/recall-daemon-ctl.py start
```
### Checking Status
```bash
# Via socket
echo '{"cmd": "status"}' | nc -U /tmp/recall-daemon.sock | jq
# Using control script
~/.claude/hooks/recall-daemon-ctl.py status
# Via MCP tool
# Use daemon_status_tool in your MCP client
```
### Stopping the Daemon
```bash
# Using launchd
launchctl unload ~/Library/LaunchAgents/com.recall.daemon.plist
# Using control script
~/.claude/hooks/recall-daemon-ctl.py stop
```
### Viewing Logs
```bash
tail -f ~/.claude/hooks/logs/recall-daemon.log
```
---
## Troubleshooting
### Hook Not Running
1. Check file path is correct and absolute
2. Verify Python/uv is in PATH
3. Check file permissions: `chmod +x ~/.claude/hooks/recall-*.py`
4. Check hook logs: `~/.claude/hooks/logs/`
### Daemon Not Starting
1. Check socket doesn't already exist: `rm /tmp/recall-daemon.sock`
2. Verify PID file: `cat /tmp/recall-daemon.pid`
3. Check daemon logs: `tail -f ~/.claude/hooks/logs/recall-daemon.log`
### No Context Loaded (SessionStart)
1. Verify Recall MCP server starts without errors
2. Check you have stored memories: `memory_list_tool()`
3. Increase timeout if needed
### Session Not Captured (SessionEnd)
1. Verify Ollama is running: `ollama serve`
2. Check model is installed: `ollama pull llama3.2`
3. Verify `CLAUDE_TRANSCRIPT_PATH` is set
### Debug Mode
Test hooks manually:
```bash
# Test session start
~/.claude/hooks/recall-session-start.py
# Test context hook
~/.claude/hooks/recall-context.py
# Test file tracking (with mock input)
echo '{"tool_name": "Write", "tool_input": {"file_path": "/tmp/test.py"}}' | \
~/.claude/hooks/recall-track.py
```
---
## Performance
| Hook | Typical Time | Notes |
|------|--------------|-------|
| Session Start | ~100ms | Records session |
| Context Loader | ~1-2s | Direct tool call |
| User Prompt | ~200ms | Quick memory lookup |
| Pre-Tool Context | ~200ms | Quick memory lookup |
| Security Validator | ~50ms | Pattern matching |
| Permissions | ~100ms | Memory lookup |
| File Tracker | ~100ms | Very fast with daemon |
| Session Capture | ~5-15s | Depends on transcript length |
| Compaction Guard | ~1-2s | Extracts important context |
| Monitor | ~5-30s | Deep analysis takes longer |
| Notification | ~50ms | Informational only |
| Stop Hook | ~5-15s | Captures learnings |
| Subagent Tracker | ~100ms | Records subagent results |
All hooks run asynchronously and don't block Claude Code operations.
---
## Security Notes
- Hooks run with your user permissions
- All data stays local (processed by local Ollama/MLX)
- Memories are stored in local SQLite database
- No data is sent to external services (unless you enable Anthropic API for monitoring)
- Security hook blocks dangerous bash patterns before execution
---
## See Also
- [Recall Usage Guide](./recall.md) - How to use recall (slash commands, MCP tools, hooks)
- [Main README](../README.md) - General Recall documentation