Skip to main content

Overview

Mengram integrates with Claude Code hooks to create a full memory loop that survives /clear, auto-compaction, machine switches, and team handoffs — the SessionStart hook fires after every compact and re-injects your context:
  1. Session context — loads your cognitive profile when a session starts, so Claude knows who you are
  2. Auto-recall — searches relevant memories on every prompt and injects them as context
  3. Auto-save — captures conversations in the background to build up memory over time
  4. Policy gate — before a workflow-shaped Bash command runs, checks it against the workflows memory has learned; if the match has a weak record, Claude has to ask you first
  5. Compaction checkpoint — before the context is compacted, writes the working state down (last prompts, files edited, last commands, where Claude left off) and puts it back verbatim after; the host’s summary can drop it, the checkpoint can’t
Zero manual effort. One command to install. The same hooks install under Codex with one flag.

Quick Setup

The plugin ships the hooks, the MCP server (30 tools), and a skill. Hooks read the key from ~/.mengram/config.json (an exported MENGRAM_API_KEY env var wins if set). First-run self-check: until the plugin verifies one successful API round-trip, failures show a one-line message telling you exactly what’s broken. After the first success, failures are silent — an outage never spams you or blocks Claude Code.

Option B — CLI hooks

This creates your account (if needed), saves your API key, and installs all six hooks automatically. Restart Claude Code — done.
The compaction checkpoint (v2.44+) ships with the CLI hooks only. If you use the plugin, run mengram hook install as well — the two coexist.

Skip the cold start — import your history

Your past Claude Code sessions are already on disk. Feed them in and memory starts full, not empty:
Secrets (API keys, tokens) are redacted client-side before upload. Then ask Claude: “what do you know about my projects?”

How It Works

1. Session Start — Profile Loaded

When you open Claude Code (or after context compaction), the SessionStart hook fires:
After a compaction or a --resume, the working state saved by the checkpoint comes first, above the profile.

2. Every Prompt — Relevant Memories Recalled

When you type a prompt, the UserPromptSubmit hook fires before Claude responds:
The tag after each fact says which tool wrote it and when (since 2.46.0). The hook also tells the server which OS and tool it runs under, so a workspace path recorded on your Mac never reaches a session on a Linux box, and a Cursor settings fact never reaches Claude Code — the server leaves those out and counts them in facts_left_out_for_host.

3. After Response — Conversation Saved

After Claude responds, the Stop hook fires asynchronously in the background:

4. Before a Bash command — the policy gate

Outcome history should change what the agent is allowed to do, not only how results rank. When Claude is about to run a command that looks like a workflow (git push, deploy, migrate, kubectl, terraform, rm -rf …), the PreToolUse hook fires:
The prompt you see is a normal Claude Code permission prompt, labelled [settings], with the reason: “Mengram: learned workflow ‘deploy to Railway’ has never been run. Review the plan before it runs.” Claude receives the workflow’s steps, preconditions and last failure as context, so if you decline it can show you the plan instead of guessing. The gate never denies. Memory can ask; it does not get to forbid. Commands that are not workflow-shaped (ls, cat, grep) never trigger a lookup, so the hook costs nothing on ordinary work.

5. After a Bash command — the record

A gate is only as good as the counts behind it, and until 2.38 nothing produced them: extraction wrote workflows, nobody wrote down whether they worked, and every procedure stayed untested forever. The PostToolUse hook closes that loop.
It is deliberately reluctant, because a wrong record is worse than none:
  • One command credits one step, never the whole workflow. A run of twine upload is evidence about uploading and about nothing else.
  • It writes only when the command is the step. The command has to cover at least half the step’s words, and normally has to name the same tool. Sharing a single word is a coincidence, not a match.
  • An unclear outcome records nothing. No exit code, or an interrupted command, means silence. A non-empty stderr is not a failure: plenty of healthy tools write there.
  • Heredoc bodies are ignored. A cat >> notes.md whose text happens to mention pip install did not install anything.
A workflow whose steps have been watched working then reads as reliable instead of untested, and the weakest watched step is the one that sets the number: a chain is exactly as trustworthy as the link most likely to break.
Run outcomes are recorded in folder mode (--memory ./memory). The cloud endpoint records whole runs only, so writing a single command there would inflate the record the gate reads; a step-scoped write for the API is next.

6. Before compaction — the working state

A compaction keeps the conversation but not the work. The host writes a summary for itself, and what the summary drops is invisible from inside the session: which files were just edited, what you asked three prompts ago, where Claude left off. Claude carries on from the summary as if nothing were missing — and edits a file from a stale idea of it, or does a finished step twice. The PreCompact hook fires before the summary is written, with the transcript path in hand:
Nothing is extracted or rewritten: the value is that the record is exact. It is restored once — the file is consumed, so a later /clear in the same session does not replay old work — and it is restored with or without an account, and through a cloud outage, because it never left the machine. A --resume whose session id changed finds the newest checkpoint written from the same directory (up to 7 days old). A fresh startup or /clear never sees one.

7. What it did — the receipt

A hook that works is invisible. The recalled fact goes into the prompt, the gate’s question looks like any other permission prompt, the recorded outcome is a number in a file nobody opens. So each hook leaves one line behind, and the next session opens with the sum:
Shown once, at session start — never on a resume or after compaction, which are the same session continuing — and not at all when nothing happened. When the gate fires, Claude also says so in one line before it goes on (“Mengram flagged this: ‘deploy to Railway’ is 43% reliable (2✓/3✗); last failure 2026-07-30: the pool was cold.”), so the moment is attributed to memory rather than passing as an ordinary prompt.
The ledger is ~/.mengram/receipts.jsonl, whichever mode the hooks run in. It is bounded and append-only; delete it to start over.

Full Loop

Codex — the same hooks

Codex fires the same lifecycle events (SessionStart, UserPromptSubmit, PreCompact, …) and its hooks file has the same shape as Claude Code’s, so the handlers are shared — one memory across both tools, and a working state that survives compaction in either.
This writes ~/.codex/hooks.json (merged if it already exists; nothing else in ~/.codex is touched — inside Orca too, which rebuilds its own Codex home from that file): The policy gate is not installed under Codex yet. Installed before 2.48.0? Run mengram hook install --codex again to add the Stop hook; Codex asks you to trust it. mengram hook uninstall removes the hooks from both Claude Code and Codex. Restart Codex after installing.

Cursor — the same hooks, one door fewer

Cursor has lifecycle hooks too (~/.cursor/hooks.json, flat {"version": 1, "hooks": {event: [{command, timeout}]}}). A hook may answer {"additional_context": ...} on sessionStart and postToolUse; beforeSubmitPrompt can only allow or block, so there is no per-prompt recall — mid-conversation, recall in Cursor is on request via the MCP tools.
mengram setup finds Cursor on the machine and installs these on its own. Restart Cursor after installing. Cursor’s transcript format is not documented; the checkpoint reader accepts plain {"role", "content"} lines and says “nothing to keep” rather than guess.

Commands

mengram hook install

Installs all six hooks into ~/.claude/settings.json.
This adds the hooks to your Claude Code settings:

mengram hook status

Check status of all hooks.
Output:

mengram hook uninstall

Remove all Mengram hooks — from Claude Code and, if installed there, from Codex.

Configuration

Environment Variables

Filtering

Auto-save skips:
  • Short responses (< 100 characters) — trivial confirmations
  • Interrupted requests
  • Responses when no API key is set
Auto-recall skips:
  • Very short prompts (< 10 characters)
  • Slash commands (/help, /clear, etc.)
  • Simple confirmations (yes, no, ok)
Checkpoint skips:
  • A compaction with no transcript on disk, or a transcript with nothing to keep
  • A startup or /clear — the checkpoint is only offered after compact or resume
  • Anything older than 7 days when a resumed session has a new id
Policy gate skips:
  • Any tool other than Bash
  • Commands that are not workflow-shaped (ls, cat, grep, python -c …) — no lookup, no cost
  • Matches whose record is at or above the bar — the command runs untouched
  • Semantic near-misses: a matched workflow must share at least one real word with the command before it can interrupt you

Quota Limits

When you hit your monthly plan limits, each hook surfaces a clear warning instead of failing silently: All messages include an upgrade link. Claude Code is never blocked — hooks continue gracefully. Non-quota errors (network timeouts, transient failures) are silently swallowed so they never interrupt your workflow. To check your current usage: mengram stats or visit mengram.io/dashboard.

Debugging: verbose markers and heartbeat

Verbose markers (CLI hooks): add --verbose to any hook command in your hooks config and every exit path emits a one-line status marker — [mengram:auto-recall] found 3 memories, [mengram:auto-save] throttled (2/3). Answers “is it working?” in one session restart. Off by default (byte-for-byte silent). Heartbeat (plugin): set MENGRAM_HEARTBEAT=25 (env) or "heartbeat": 25 in ~/.mengram/config.json and every 25th successful save shows one line: [mengram] heartbeat: 150 conversations saved to memory so far. With the heartbeat on, silence means something is wrong.

Troubleshooting

Hooks not firing?
  • Restart Claude Code after installing
  • Check mengram hook status to verify the hooks are installed
  • Keys are read from MENGRAM_API_KEY env or ~/.mengram/config.json (env wins) — check cat ~/.mengram/config.json
Memories not appearing?
  • Auto-save processes in the background — check after ~30 seconds
  • Verify API connectivity: mengram hook status
  • Check your memories at mengram.io/dashboard
Recall seems slow?
  • Auto-recall has a 10-second timeout — if the API is slow, it’s skipped gracefully
  • Claude Code continues normally even if a hook fails
Seeing quota warnings?
  • You’ve hit your monthly plan limit — memory is disabled until the limit resets or you upgrade
  • Run mengram stats to check usage
  • Upgrade at mengram.io/dashboard
Run mengram setup to automatically save your API key to your shell profile and install all hooks in one step.