الصفحات · Zekra
Capture hook
An opt-in Claude Code Stop hook that retains durable decisions and facts from each assistant turn, with private-span and secret redaction.
The capture hook fills a brain automatically while you work. It is a Claude Code Stop
hook: at the end of each assistant turn it reads the turn, keeps it only if it states
something durable, redacts it, and sends it to POST /api/brain/retain.
It lives in the Zekra server repository at .claude/hooks/capture-mode.py. It needs Python 3
and no extra packages.
Authentication: the hook sends your access token as
X-Zekra-Token(fromZEKRA_TOKEN, or the legacyCABRAIN_TOKEN) and posts to app.zekra.dev by default. The token needs write access on the target brain. Without a token it works only against a self-hosted instance that accepts requests without one (see Security).
What it captures
The hook keeps a turn only if it looks like a conclusion, not chatter:
- It must be at least 40 characters long.
- It must contain a decision or fact marker, such as decided, chose, because, instead of, rather than, turns out, the root cause, should use or should not, constraint, gotcha, note that, important, prefer, corrected, endpoint, schema, contract or convention.
Routine turns, such as file listings, status updates and acknowledgements, are skipped. The server's write decision then drops anything already known.
Privacy
- Any
<private>…</private>span is removed before the request is sent. If nothing is left, the turn is dropped. - If a turn contains something shaped like a credential (an AWS access key, a private-key
block, or
password=,secret:,token=orapi_key=followed by a value), the whole turn is dropped. - The server also moves any secrets it detects into the brain's vault.
Enable it
Capture is opt-in and does nothing unless ZEKRA_CAPTURE=1. Add the hook to
.claude/settings.json in your project, or to ~/.claude/settings.json for all projects:
| Variable | Default | Meaning |
|---|---|---|
ZEKRA_CAPTURE | off | Must be 1 to capture anything |
ZEKRA_API_URL | https://app.zekra.dev | Your Zekra instance (self-hosted: your URL) |
ZEKRA_TOKEN | none (falls back to CABRAIN_TOKEN) | Sent as X-Zekra-Token; needs write on the brain |
ZEKRA_NAMESPACE | lower-cased name of the working directory | Brain to write to |
ZEKRA_AGENT_ID | none | Sent as X-Agent-Id |
Each captured memory is stored with sourceKind: "claude_code" and sourceRef set to the
Claude Code session id, so you can trace a memory back to the session it came from.
Behavior
- Never blocks. The request times out after 2 seconds, and any failure (server down, turn not worth keeping, everything private) exits silently with status 0.
- Importance is computed on the server. The hook only decides whether a turn is worth sending.