# How Claude Code Hooks Integrate with MemPalace: Complete Technical Guide

> Discover how Claude Code hooks integrate with MemPalace using Bash scripts. Learn to auto-ingest conversation transcripts by parsing JSON payloads from Stop and PreCompact events. A complete technical guide.

- Repository: [MemPalace/mempalace](https://github.com/MemPalace/mempalace)
- Tags: how-to-guide
- Published: 2026-06-06

---

**Claude Code hooks integrate with MemPalace through Bash scripts that intercept `Stop` and `PreCompact` events, parsing JSON payloads from stdin to trigger automatic ingestion of conversation transcripts into the MemPalace data store.**

The MemPalace repository provides a seamless bridge between Anthropic’s Claude Code and its long-term memory system through custom hook scripts. These hooks automatically capture conversation transcripts and project files before they disappear from the context window. This integration ensures verbatim preservation of raw tool output without requiring manual intervention.

## Hook Registration and Configuration

Users register MemPalace hooks by adding shell command entries to Claude Code’s [`settings.local.json`](https://github.com/MemPalace/mempalace/blob/main/settings.local.json) or to [`.codex/hooks.json`](https://github.com/MemPalace/mempalace/blob/main/.codex/hooks.json) for the Codex CLI. According to [`hooks/README.md`](https://github.com/MemPalace/mempalace/blob/main/hooks/README.md) (lines 18-33), the configuration points to the shell scripts in the `hooks/` directory:

```json
{
  "hooks": {
    "Stop": [{
      "matcher": "*",
      "hooks": [{
        "type": "command",
        "command": "/absolute/path/to/hooks/mempal_save_hook.sh",
        "timeout": 30
      }]
    }],
    "PreCompact": [{
      "hooks": [{
        "type": "command",
        "command": "/absolute/path/to/hooks/mempal_precompact_hook.sh",
        "timeout": 30
      }]
    }]
  }
}

```

When Claude Code fires the `Stop` event after each assistant response, it executes [`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh). The `PreCompact` hook runs when the context window is about to be compacted.

## How the Save Hook Works

The Save Hook script located at [`hooks/mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/hooks/mempal_save_hook.sh) (lines 4-8) performs four critical operations when triggered:

1. **Payload ingestion**: Reads JSON from stdin containing `session_id`, `stop_hook_active`, and `transcript_path` (lines 38-42)
2. **Sanitization**: An embedded Python snippet validates fields and returns a sentinel value `__MEMPAL_PARSE_OK__` plus safe values (lines 52-66)
3. **Interval checking**: Counts human messages and compares against `SAVE_INTERVAL` (default 15, configurable on line 55)
4. **Blocking decision**: If the threshold is reached, returns a JSON block instruction forcing Claude to invoke the MemPalace CLI before stopping

When blocking occurs, the script returns a JSON object with a `reason` field asking the AI to "save tool output verbatim". This forces the AI to execute `mempalace mine` before Claude Code can terminate the session.

## The Pre-Compact Hook

The [`mempal_precompact_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_precompact_hook.sh) script follows the same parsing logic but behaves differently regarding timing. As documented in [`hooks/README.md`](https://github.com/MemPalace/mempalace/blob/main/hooks/README.md) (lines 33-40), this hook **always** triggers a save operation when the context window is about to be compacted, regardless of message count. This ensures no conversation data is lost during context compression.

## Auto-Mining Implementation

When the Save Hook decides to persist data, it invokes the MemPalace CLI through the `mempalace mine` command. The entry point in [`mempalace/cli.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/cli.py) handles two distinct modes:

- **Conversations**: `mempalace mine <transcript-dir> --mode convos` ingests the JSONL transcript into the conversations wing
- **Projects**: If `MEMPAL_DIR` is set, the hook also runs `--mode projects` to scan the project directory via [`mempalace/project_scanner.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/project_scanner.py)

The mined data is stored in the core palace data structure implemented in [`mempalace/palace.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/palace.py), creating searchable drawers of conversation history.

## Preventing Hook Recursion

The implementation includes safeguards against infinite loops. After Claude Code performs a save operation, it re-fires the `Stop` hook with `stop_hook_active` set to `true` in the JSON payload.

In [`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh) (lines 40-46), the script detects this flag and simply echoes `{}` to stdout, allowing the AI to stop normally. Without this guard, the hook would block indefinitely, creating a recursion where each save attempt triggers another save attempt.

## Configuration Options

Users can customize hook behavior through environment variables or the `~/.mempalace/config.json` file. As implemented in [`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh) (lines 86-90) and documented in the README (lines 70-88), the following options are available:

- **`SAVE_INTERVAL`**: Adjust the number of human messages required to trigger a save (default 15)
- **`MEMPAL_DIR`**: Enable automatic mining of project files alongside transcripts
- **`MEMPALACE_HOOKS_AUTO_SAVE`** or `hooks.auto_save`: Set to `false` to completely disable automatic saving

Example configuration:

```bash
export SAVE_INTERVAL=30
export MEMPALACE_HOOKS_AUTO_SAVE=false

```

## Debugging Hook Execution

When troubleshooting integration issues, examine the hook state directory at `~/.mempalace/hook_state/`. According to [`hooks/README.md`](https://github.com/MemPalace/mempalace/blob/main/hooks/README.md) (lines 55-62), this directory contains count tracking and error logs, while `hook.log` provides detailed execution traces.

For manual backfill of historical transcripts that were not captured by hooks, run:

```bash
mempalace mine ~/.claude/projects/ --mode convos

```

## Summary

- **Hook registration** requires adding command entries to [`settings.local.json`](https://github.com/MemPalace/mempalace/blob/main/settings.local.json) pointing to scripts in `hooks/`
- **Save Hook** ([`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh)) blocks the `Stop` event based on `SAVE_INTERVAL` threshold (line 55)
- **Pre-Compact Hook** always saves before context compaction to prevent data loss
- **Auto-mining** relies on `mempalace mine --mode convos` (and optionally `--mode projects` via [`mempalace/project_scanner.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/project_scanner.py))
- **Recursion prevention** uses the `stop_hook_active` flag (lines 40-46) to distinguish initial saves from completion signals
- **Configuration** supports environment variables and `~/.mempalace/config.json` for threshold adjustment and opt-out

## Frequently Asked Questions

### Where do I configure Claude Code hooks for MemPalace?

Register the hooks in Claude Code’s [`settings.local.json`](https://github.com/MemPalace/mempalace/blob/main/settings.local.json) file (or [`.codex/hooks.json`](https://github.com/MemPalace/mempalace/blob/main/.codex/hooks.json) for Codex CLI) by adding command entries that point to [`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh) and [`mempal_precompact_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_precompact_hook.sh) in the repository’s `hooks/` directory, as documented in [`hooks/README.md`](https://github.com/MemPalace/mempalace/blob/main/hooks/README.md) lines 18-33.

### How does MemPalace prevent duplicate saves during the Stop event?

The hook checks the `stop_hook_active` boolean in the JSON payload from stdin. When this flag is `true`, indicating Claude Code already performed a save, the script returns empty JSON `{}` to allow normal termination rather than blocking again, preventing infinite loops as implemented in lines 40-46 of [`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh).

### Can I adjust how frequently the Save Hook triggers?

Yes. Set the `SAVE_INTERVAL` environment variable to change the number of human messages required to trigger a save. The default value is 15, configurable on line 55 of [`mempal_save_hook.sh`](https://github.com/MemPalace/mempalace/blob/main/mempal_save_hook.sh). You can also completely disable auto-save by setting `MEMPALACE_HOOKS_AUTO_SAVE=false`.

### What files are actually ingested when the hook runs?

The hook executes `mempalace mine <transcript-dir> --mode convos` to ingest JSONL conversation transcripts into [`mempalace/palace.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/palace.py). If `MEMPAL_DIR` is configured, it additionally mines project files using [`mempalace/project_scanner.py`](https://github.com/MemPalace/mempalace/blob/main/mempalace/project_scanner.py) with the `--mode projects` flag.