BETA In open beta. Install live. Lock $5/mo for your first 12 months. See pricing →
Docs / Concepts

Claude Code hooks

Hydrate plugs into Claude Code via four first-party hooks. They're wired in during hydrate setup and are invisible during normal use - you run claude exactly as you always have.

The four hooks

UserPromptSubmit - context inject

Fires the instant you hit return on a prompt, before Claude Code sends anything to the model. Hydrate queries its local SQLite store for facts scoped to the current project (plus your user- and org-scope facts) and injects the relevant ones into the context.

Relevance is scored by a blend of embedding similarity to your prompt, recency, and reinforcement (how often the fact has been confirmed or referenced). The hook has a soft budget - it will not inject more than a few hundred tokens of facts unless you override that via hydrate config set inject.max_tokens.

Stop - transcript capture

Fires when a session ends. Hydrate receives the full transcript, runs a small extractor that pulls atomic facts out of what the model and tools actually did, and stores them scoped to the project. Also writes a session summary used later for retrieval.

Extraction uses whichever LLM provider you've configured (OPENAI_API_KEY, ANTHROPIC_API_KEY, or a local HYDRATE_LLM_ENDPOINT). You bring your own key - Hydrate doesn't meter or proxy.

PreToolUse - large-file redirect

Fires before each tool call. When Claude Code is about to read a large file that Hydrate already has summarised in its store, this hook substitutes a compressed version instead - saving hundreds of input tokens per call. Disabled by default; enable with hydrate config set tool_guard.enabled=true.

PostToolUse - tool-output capture

Fires after each tool call and captures tool outputs (file reads, bash results) into Hydrate's store for future injection. Disabled by default; enable with hydrate config set tool_capture.enabled=true.

Where they live

All four hooks are registered in ~/.claude/settings.json under the hooks key. Each one runs a lightweight binary installed to ~/.local/bin/ that reads the server port from ~/.hydrate/server.port at runtime:

{
  "hooks": {
    "UserPromptSubmit": [
      {"hooks": [{"type": "command", "command": "~/.local/bin/claude-context", "timeout": 3}]}
    ],
    "Stop": [
      {"hooks": [{"type": "command", "command": "~/.local/bin/claude-capture", "timeout": 15}]}
    ],
    "PostToolUse": [
      {"hooks": [{"type": "command", "command": "~/.local/bin/claude-tool-post", "timeout": 3}]}
    ],
    "PreToolUse": [
      {"hooks": [{"type": "command", "command": "~/.local/bin/claude-tool-pre", "timeout": 3}]}
    ]
  }
}

If hydrate-server isn't running when a hook fires, the hook no-ops in under 50 ms and your Claude Code session continues normally - Hydrate is designed to fail soft.

Turning hooks off for a session

Set HYDRATE_DISABLE=1 in the environment Claude Code is launched from to skip all hooks for that invocation. Useful when you explicitly want a fresh mind: greenfield exploration, debugging Hydrate itself, or a one-off prompt where context would be noise.

Verifying they ran

hydrate facts diff --last-session

Prints the exact set of facts injected into the last session, plus any new facts extracted from it. If the output is empty, check hydrate doctor - the daemon is probably down.

The same hooks for Codex and Vibe

Claude Code is not the only runtime Hydrate hooks into. OpenAI Codex (CLI and macOS app) and Mistral Vibe each have their own per-event binary family that does the same job:

EventClaude CodeCodexVibe
SessionStartclaude-session-startcodex-session-startvibe-session-start
UserPromptSubmitclaude-contextcodex-contextvibe-context
PreCompactclaude-precompactn/avibe-precompact
PreToolUseclaude-tool-precodex-pretoolusevibe-tool-pre
PostToolUseclaude-tool-postn/avibe-tool-post
Stopclaude-capturecodex-capturevibe-capture
PermissionRequestn/acodex-permissionn/a

Internally the Claude and Codex binaries share an adapter layer (internal/runtimebridge) that translates each runtime's on-the-wire JSON to and from a single canonical event model. Vibe ships its own family of standalone binaries that read the equivalent shared helpers without going through the adapter. Either way the user-visible result is the same: a fact you capture in Claude Code is immediately retrievable from Codex, and vice versa.

The cross-runtime architecture is documented in chapter 27 of the thesis. See /integrations/claude-code, /integrations/codex, and /integrations/vibe for per-runtime install steps.