> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mengram.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Code Integration

> Memory that survives /clear and auto-compaction — auto-save conversations, auto-recall context on every prompt, load your profile on session start, a policy gate that asks before Claude runs a workflow with a weak record, and a checkpoint that carries the working state through compaction. The same hooks run under Codex.

## Overview

Mengram integrates with [Claude Code](https://docs.anthropic.com/en/docs/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](#codex-the-same-hooks) with one flag.

## Quick Setup

### Option A — plugin from the marketplace (recommended)

```bash theme={null}
# 1. Save your API key once (free key at https://mengram.io)
mkdir -p ~/.mengram && echo '{"api_key": "om-your-key-here"}' > ~/.mengram/config.json

# 2. Install the plugin
claude plugin marketplace add alibaizhanov/mengram
claude plugin install mengram@mengram
```

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

```bash theme={null}
pip install mengram-ai
mengram setup
```

This creates your account (if needed), saves your API key, and installs all six hooks automatically. Restart Claude Code — done.

<Note>
  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.
</Note>

## 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:

```bash theme={null}
pip install mengram-ai
mengram import claude-code
```

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:

```
Session starts
  → mengram auto-context runs
  → Loads your Cognitive Profile from Mengram (GET /v1/profile)
  → Prints it to stdout — Claude sees it as context

Claude now knows: your name, preferences, tech stack, current projects
```

After a compaction or a `--resume`, the working state saved by the [checkpoint](#6-before-compaction-the-working-state) comes first, above the profile.

### 2. Every Prompt — Relevant Memories Recalled

When you type a prompt, the `UserPromptSubmit` hook fires **before** Claude responds:

```
You type: "how did we deploy to Railway?"
  → mengram auto-recall runs
  → Searches Mengram for relevant memories (POST /v1/search)
  → Returns additionalContext that Claude sees:

  [Mengram Memory — relevant context from past sessions]
  Railway Deployment:
    - Auto-deploys from main branch  (claude-code, 2026-09-02)
    - Uses gunicorn with 1 worker  (codex, 2026-09-11)
    - DATABASE_URL uses Session Mode port 5432  (claude-code, 2026-09-02)

Claude responds WITH context from your past sessions
```

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:

```
Claude finishes responding
  → mengram auto-save runs (background, non-blocking)
  → Every 3rd response, sends [user + assistant] to POST /v1/add
  → API extracts entities, facts, episodes, procedures
  → Memory grows over time
```

### 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:

```
Claude wants to run: git push origin main
  → mengram auto-policy runs
  → Finds the learned workflow this matches (GET /v1/procedures/search)
  → Reads its record: untested · 61% expected · 88% reliable

  88% reliable   → silent, the command runs as it would have
  untested       → "ask": you see why, Claude gets the steps on record
  61% expected   → "ask": this version has never run; 61% is inherited from the one it replaced
  58% reliable   → "ask": below the bar (default 70%)
```

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.

```
Claude ran: twine upload dist/*  → exit 0
  → mengram auto-outcome runs
  → Recognises the command as step 3 of "Release to PyPI"
  → Records that step as a success. Nothing is printed.
```

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.

<Note>
  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.
</Note>

| Setting | Default | What it does |
| - | - | - |
| `MENGRAM_POLICY_MIN_RELIABLE` | `70` | Percent below which a workflow with a record is confirmed |
| `MENGRAM_POLICY_PATTERN` | deploy / push / migrate / kubectl / … | Regex for "workflow-shaped"; `.*` gates every Bash command |
| `MENGRAM_MEMORY_DIR` | unset | Read a memfmt folder instead of the cloud (no key, no network) |
| `mengram hook install --no-policy` | — | Install the other three hooks without the gate |

### 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:

```
Context is about to be compacted (auto or /compact)
  → mengram auto-checkpoint runs
  → Reads the transcript's tail and keeps what locates the work:
      the last 4 prompts · files edited · last 8 commands · the last thing Claude said
  → Writes ~/.mengram/checkpoints/<session_id>.json   (never uploaded)

Compaction happens; the session continues
  → SessionStart fires with source: compact
  → mengram auto-context finds the checkpoint and puts it back, verbatim:

  [Mengram — working state saved before compaction (2 min ago; the host's summary may have dropped some of this)]
  Directory: /Users/you/app
  Last things the user asked, oldest first:
    - Add a PreCompact hook to the CLI
    - Also cover Codex
  Files edited this session (re-read before editing again):
    - /Users/you/app/cli.py
    - /Users/you/app/local/checkpoint.py
  Last commands run:
    $ pytest -q tests/test_checkpoint.py
  Where the assistant left off:
    Tests written; running them now.
```

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:

```
🧠 Mengram, last session: recalled memories on 4 prompts · asked before 1 workflow
   with a weak record · recorded 3 step outcomes (2 ok, 1 failed) · caught 1 failure
   the host never reported · restored the working state after 1 compaction
```

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.

```bash theme={null}
mengram receipt            # last session, and the past 7 days
mengram receipt --days 30
```

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

```
┌──────────────────────────────────────────────┐
│  Session starts                              │
│  ↓ SessionStart → profile loaded             │
│                                              │
│  You type a prompt                           │
│  ↓ UserPromptSubmit → relevant memory found  │
│                                              │
│  Claude responds (with memory context)       │
│  ↓ PreToolUse → weak workflow? ask first     │
│  ↓ PostToolUse → step outcome recorded       │
│  ↓ Stop → conversation saved (background)    │
│                                              │
│  Context fills up                            │
│  ↓ PreCompact → working state written down   │
│  ↓ SessionStart (compact) → put back, exact  │
│                                              │
│  Next prompt → recall again...               │
│  Next session → "last session: …" receipt    │
└──────────────────────────────────────────────┘
```

## 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.

```bash theme={null}
pip install mengram-ai
mengram hook install --codex
```

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):

| Event | Command | What it does |
| - | - | - |
| `SessionStart` | `mengram auto-context` | Loads your profile; after a compact or resume, the working state first |
| `UserPromptSubmit` | `mengram auto-recall` | Relevant memories on each prompt |
| `PreCompact` | `mengram auto-checkpoint --host codex` | Writes the working state down before compaction |
| `Stop` | `mengram auto-save --every 3 --host codex` | Saves the turn and writes the [task card](/cli#mengram-resume), so Claude Code can pick up a task Codex started (2.48.0+) |

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.

```bash theme={null}
mengram hook install --cursor
```

| Event | What it does |
| - | - |
| `sessionStart` | Loads your profile, plus the newest working state saved in this workspace within the last day |
| `preCompact` | Writes the working state down before Cursor summarises the context |
| `postToolUse` | Puts it back on the first tool call after compaction — Cursor opens no new session, so this is the door |
| `afterAgentResponse` | Saves the agent's answer to memory |

`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`.

```bash theme={null}
mengram hook install                    # default: save every 3rd response
mengram hook install --every 5          # save every 5th response
mengram hook install --user-id myuser   # custom user_id
mengram hook install --no-policy        # skip the policy gate
mengram hook install --codex            # Codex instead: ~/.codex/hooks.json
```

This adds the hooks to your Claude Code settings:

```json theme={null}
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [{
          "type": "command",
          "command": "mengram auto-context",
          "timeout": 15
        }]
      }
    ],
    "UserPromptSubmit": [
      {
        "hooks": [{
          "type": "command",
          "command": "mengram auto-recall",
          "timeout": 10
        }]
      }
    ],
    "Stop": [
      {
        "hooks": [{
          "type": "command",
          "command": "mengram auto-save --every 3",
          "timeout": 30,
          "async": true
        }]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": "mengram auto-policy",
          "timeout": 10
        }]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": "mengram auto-outcome",
          "timeout": 10
        }]
      }
    ],
    "PreCompact": [
      {
        "hooks": [{
          "type": "command",
          "command": "mengram auto-checkpoint",
          "timeout": 10
        }]
      }
    ]
  }
}
```

### mengram hook status

Check status of all hooks.

```bash theme={null}
mengram hook status
```

Output:

```
Mengram Hooks

  Auto-save:      installed (every 3 responses)
  Auto-recall:    installed
  Session context: installed
  Policy gate:    installed
  Run outcomes:   installed
  Checkpoint:     installed
  Codex:          installed (/Users/you/.codex/hooks.json)
  API Key:        om-...Kb8 (set)
  API:            connected (free plan)
  Settings:       /Users/you/.claude/settings.json
```

### mengram hook uninstall

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

```bash theme={null}
mengram hook uninstall
```

## Configuration

| Option | Default | Description |
| - | - | - |
| `--every N` | 3 | Save every Nth response. Lower = more memories, higher = less noise |
| `--user-id` | `"default"` | Mengram user\_id for multi-user isolation |

### Environment Variables

| Variable | Required | Description |
| - | - | - |
| `MENGRAM_API_KEY` | Yes | Your Mengram API key (starts with `om-`) |
| `MENGRAM_URL` | No | Custom API URL (default: `https://mengram.io`) |
| `MENGRAM_USER_ID` | No | Default user\_id (overridden by `--user-id`) |
| `MENGRAM_POLICY_MIN_RELIABLE` | No | Policy gate bar, percent (default `70`) |
| `MENGRAM_POLICY_PATTERN` | No | Regex for commands the policy gate looks at |
| `MENGRAM_MEMORY_DIR` | No | memfmt folder for the policy gate's offline mode |

## 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:

| Hook | What happens | Message shown |
| - | - | - |
| **Auto-recall** | Not charged since 2.44.1 — a search the hooks make carries `X-Mengram-Source: hook` and skips the search quota (still rate-limited). Older CLIs: Claude sees `[Mengram] Memory search quota exceeded — recall is disabled` | `pip install -U mengram-ai` |
| **Auto-context** | Profile load fails | Session start shows: `[Mengram] Memory profile load failed — quota exceeded` |
| **Auto-save** | Save quota exceeded | Terminal shows: `[Mengram] Memory save failed — Your conversations are NOT being saved` |

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](https://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](https://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](https://mengram.io/dashboard)

<Tip>
  Run `mengram setup` to automatically save your API key to your shell profile and install all hooks in one step.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.