---
title: "Memory hook bundle, auto-persist sessions, snapshot before compact, recall on trigger | Recipe — StudioMeyer Academy"
description: "Four mcp_tool hooks for the StudioMeyer Memory MCP that turn it from 'a tool I call manually' into 'a memory layer that always knows what I did'. Stop, PreCompact, UserPromptSubmit, SubagentStop, all idempotent, all fast."
canonical: "https://studiomeyer.academy/en/recipes/16.2-memory-hook-bundle"
language: en
markdown_versions: ["https://studiomeyer.academy/en/recipes/16.2-memory-hook-bundle.md"]
publisher: "StudioMeyer Academy, https://studiomeyer.academy (llms.txt: https://studiomeyer.academy/llms.txt)"
---

[← Alle Recipes](https://studiomeyer.academy/recipes)

Phase 16 · Claude Code Hooks·6 steps

# Memory hook bundle, auto-persist sessions, snapshot before compact, recall on trigger

Four mcp\_tool hooks for the StudioMeyer Memory MCP that turn it from 'a tool I call manually' into 'a memory layer that always knows what I did'. Stop, PreCompact, UserPromptSubmit, SubagentStop, all idempotent, all fast.

6 steps0%

Du liest ohne Account. Mit [Login](https://studiomeyer.academy/login?next=/recipes/16.2-memory-hook-bundle) speichern wir Step-Fortschritt + Notes.

# Memory hook bundle, auto-persist sessions, snapshot before compact, recall on trigger

The Memory MCP (`studiomeyer-memory`, hosted at `memory.studiomeyer.io`) has 56 tools. Without hooks, you call them manually: `nex_session_start` at the beginning, `nex_summarize` and `nex_session_end` at the end, `nex_search` when you need recall. That's a lot of clicking, and it's easy to forget the end-of-session calls.

This bundle wires four hooks that do all of it automatically. Effect: every Claude Code session is persisted to long-term memory without touching a tool by hand.

### Step 1: Stop hook → auto-summarize and end session

Add this to `~/.claude/settings.json` under `hooks.Stop`:

```json
{
  "Stop": [
    {
      "hooks": [
        {
          "type": "mcp_tool",
          "server": "studiomeyer-memory",
          "tool": "nex_summarize",
          "input": { "session_id": "${session_id}" },
          "timeout": 30,
          "statusMessage": "Memory: summarizing session..."
        },
        {
          "type": "mcp_tool",
          "server": "studiomeyer-memory",
          "tool": "nex_session_end",
          "input": { "session_id": "${session_id}" },
          "timeout": 15,
          "statusMessage": "Memory: closing session..."
        }
      ]
    }
  ]
}
```

Two hooks fire on Stop: first summarize (writes a session snapshot into the `nex_sessions` table), then close. Both are idempotent, calling them twice on the same session is a NOOP.

### Step 2: PreCompact hook → snapshot before context loss

Context compaction throws away part of the in-window history. Before that happens, snapshot:

```json
{
  "PreCompact": [
    {
      "hooks": [
        {
          "type": "mcp_tool",
          "server": "studiomeyer-memory",
          "tool": "nex_summarize",
          "input": { "session_id": "${session_id}" },
          "timeout": 30,
          "statusMessage": "Memory: snapshot before compaction..."
        }
      ]
    }
  ]
}
```

Why duplicate `nex_summarize` between Stop and PreCompact? Because Stop only fires when the session ends. If the session is long and gets compacted mid-flow, you lose the pre-compact context unless you snapshot it first. Both calls are idempotent so the duplicate is safe.

### Step 3: UserPromptSubmit hook → recall on trigger phrases

When you ask "have we discussed this before" or "what do we know about X", the assistant should consult Memory before guessing. Wire it explicitly:

```json
{
  "UserPromptSubmit": [
    {
      "hooks": [
        {
          "type": "mcp_tool",
          "server": "studiomeyer-memory",
          "tool": "nex_search",
          "input": { "query": "${user_prompt}", "limit": 5 },
          "timeout": 10,
          "statusMessage": "Memory: pre-checking..."
        }
      ]
    }
  ]
}
```

This fires on every user prompt and pre-fetches up to 5 relevant memories. The result is injected into the assistant's context as `additionalContext`. The assistant doesn't have to remember to call `nex_search` first, the hook does it transparently.

If you only want this on specific trigger phrases (to save a tool call per prompt), add a server-side `if`\-filter, but `if`\-filters only work on Tool-Events, not on `UserPromptSubmit`. Easier path: use the existing user-level `memory-first-check.sh` bash hook which already does keyword filtering, and skip this `mcp_tool` variant.

### Step 4: SubagentStop hook → ingest research reports

When you spawn a subagent (e.g. via the Task tool) and it returns a long research report, you want the key findings persisted. The SubagentStop hook fires when the subagent finishes:

```json
{
  "SubagentStop": [
    {
      "hooks": [
        {
          "type": "mcp_tool",
          "server": "studiomeyer-memory",
          "tool": "nex_learn",
          "input": {
            "category": "research",
            "insight": "${last_assistant_message}",
            "confidence": 0.6,
            "source": "subagent-stop-hook"
          },
          "timeout": 15,
          "statusMessage": "Memory: ingesting subagent report..."
        }
      ]
    }
  ]
}
```

The `last_assistant_message` substitution variable contains the subagent's final output. `nex_learn` runs the gatekeeper which deduplicates against existing learnings, so re-calling on the same content is a NOOP.

### Step 5: GDPR + idempotency notes

All four hooks satisfy the five-rule check from recipe 16.1:

- **Idempotent.** `nex_summarize` and `nex_session_end` are NOOP on duplicate. `nex_search` is read-only. `nex_learn` deduplicates via the gatekeeper.
- **Fast.** All four are typically under 2 seconds against a warm database. Cold start (first call after deploy) can hit 5-8 seconds, well under the 30s timeout.
- **Deterministic.** Same session\_id, same summary. Same query, similar (not identical, due to recency-decay) recall ranking.
- **Side-effect-free without user trigger.** `nex_search` is read-only. `nex_summarize` writes to `nex_sessions`, but the user implicitly triggered it by ending the session. `nex_learn` writes to `nex_learnings`, but the user implicitly triggered it by spawning the subagent.
- **GDPR.** All data flows from your Claude Code session to your own Memory tenant on `memory.studiomeyer.io`. No third-party sharing. Tenant data is isolated per `tenant_id`. You can delete your tenant any time via the dashboard.

### Step 6: Verify the bundle works

```bash
# Edit settings.json with all four hooks above, then:
claude
# Type a few prompts, then Ctrl-D
```

Check the Memory dashboard at `https://memory.studiomeyer.io/dashboard`, you should see the new session listed under "Sessions" with the auto-generated summary. The `nx_learnings` count should not have changed (no subagent was spawned).

Then re-run with a subagent:

```bash
claude
# Ask: "use the research subagent to find 3 articles about MCP hooks"
# After the subagent finishes and you Ctrl-D
```

The dashboard should now show 1 new learning under category=research.

## Done

Memory is fully agentic. Every session you run gets persisted automatically. Every research subagent's findings land in your knowledge base without manual `nex_learn` calls.

## Sources

- [Claude Code Hooks Reference](https://code.claude.com/docs/en/hooks)
- [StudioMeyer Memory MCP Documentation](https://memory.studiomeyer.io)

[← The mcp\_tool hook, direct MCP](https://studiomeyer.academy/recipes/16.1-mcp-tool-hook-intro) [CRM hook bundle, auto-lookup c →](https://studiomeyer.academy/recipes/16.3-crm-hook-bundle)

Phase 16

mcp\_tool hooks, Memory/CRM/GEO/Crew/Academy hook bundles

[Alle Phasen →](https://studiomeyer.academy/recipes)

Concepts

[Hooks](https://studiomeyer.academy/concepts/hooks) [Memory basics](https://studiomeyer.academy/concepts/memory_basics)

## Sitemap

Public pages of this site as Markdown: [sitemap](https://studiomeyer.academy/sitemap.md). Curated entry point: [llms.txt](https://studiomeyer.academy/llms.txt), full text: [llms-full.txt](https://studiomeyer.academy/llms-full.txt).
