session-recall
Slice, search, and recover Claude Code session JSONL transcripts — primarily designed to repair the most painful moment in any long Claude Code session: post-compaction amnesia.
session-recall exposes the local JSONL store at
~/.claude/projects/<encoded-cwd>/<uuid>.jsonl to a running agent (via
MCP) and to humans (via CLI). It ships two complementary surfaces over
the same Python service layer:
- MCP server (
session-recall-mcp) — 14 tools for an LLM agent to recall what happened earlier in the session, especially after the context window has been compacted into a lossy summary. - CLI (
session-recall) — the same operations one-shot from the terminal:tail,head,range,grep,info,list, plus the v0.2 recovery surface.
Why it exists
Claude Code's context-compaction step replaces older turns with a short summary. The summary is lossy: it routinely smooths away exact file edits, dispatched background agents, the literal user prompts that drove them, and errors. After compaction the agent often repeats work, picks the wrong thread, or hallucinates that something was done when it wasn't.
The fix is to read the raw JSONL on disk — every message, tool_use, and tool_result is right there — and re-derive a structured recap. That's what this tool does.
Installation
As a Claude Code plugin (recommended — MCP server + hook + skill in one)
This repo is self-hosted as its own Claude Code plugin marketplace. Installing
it wires the MCP server, the SessionStart(compact) recovery hook, and the
session-recall skill together — nothing to configure by hand:
/plugin marketplace add msrashed2018/session-recall
/plugin install session-recall@session-recall
Uses uvx --from session-recall ... under the hood (see .mcp.json /
hooks/hooks.json) — no separate pip/uv tool install step; uvx fetches
and caches the package on first use.
As a standalone CLI/MCP install
# CLI + MCP server
uv tool install --with fastmcp session-recall
# CLI only (no agent surface)
uv tool install session-recall
The two binaries land at ~/.local/bin/:
session-recall # CLI
session-recall-mcp # FastMCP stdio server
Add the MCP server to Claude Code by appending to ~/.claude.json (or run
claude mcp add if you prefer):
{
"mcpServers": {
"session-recall": {
"type": "stdio",
"command": "session-recall-mcp",
"args": [],
"env": {}
}
}
}
With this path you also need the hook wired manually — see "Automatic
recovery via hook" below — and the skill isn't installed at all (copy
skills/session-recall/SKILL.md to ~/.claude/skills/ yourself if you want
it). The plugin install above does all three in one step.
Headline workflow — post-compaction recovery (v0.2)
When a turn begins with "This session is being continued from a previous conversation that ran out of context", your first move should be:
mcp__session-recall__recall_after_compaction(cwd="/path/to/project")
You'll get a single structured payload (typically ≤ 30 KB) covering:
prompts— the verbatim user prompts since compaction.files_changed— every file touched (Write/Edit/MultiEdit/ NotebookEdit) deduplicated, with first/last touched turn.commands— everyBashinvocation, withbg_idandexit_codeparsed out of the matching tool_result.agents_dispatched— everyTask/Agentcall with its subagent type, description, and isolation mode.errors— error tool_results, interrupts, andAPI Error: 5xxin assistant text.compaction— line/byte position of the marker that anchored the slice, plus the marker's full summary text.
When a section overflows the per-section max_* cap, the response
flags it and you can drill in via the dedicated tools below.
Automatic recovery via hook (v0.3.0+) — no agent action required
Installed via the plugin above? This is already wired for you (see
hooks/hooks.json) — skip to Other recovery tools. This section is for the standalone CLI/MCP install path.
The workflow above still depends on an agent remembering to call
recall_after_compaction (or reading CLAUDE.md instructions telling it to).
session-recall session-start-hook removes that dependency: wired to
SessionStart with matcher: "compact", it runs the moment compaction
happens and injects a structured digest + the last 8 turns verbatim
straight into the new session's context, automatically, every time — no
agent cooperation needed, no pre-compaction warning to notice in time, and
no extra script to install. It's the installed session-recall binary
itself, one subcommand among the others in this README.
Add this to ~/.claude/settings.json (or a project's .claude/settings.json)
alongside whatever other SessionStart hooks you already have — Claude Code
runs every hook group whose matcher matches, so this is additive, not a
replacement:
{
"hooks": {
"SessionStart": [
// ... any hooks you already have ...
{
"matcher": "compact",
"hooks": [
{ "type": "command", "command": "session-recall session-start-hook", "timeout": 30 }
]
}
]
}
}
That's the whole install. It fails open at every step — non-compact
sources, missing session_id/cwd, an internal error resolving the session —
by printing nothing and exiting 0, so a broken hook can never block session
start. This replaces an older, informally-used pattern of nagging the
pre-compaction agent via UserPromptSubmit/PostToolUse to hand-write a
free-text handoff file: that depended on an LLM noticing a warning and
complying in time and produced unpredictable-quality prose; this pulls
deterministic, structured data straight from the transcript every time,
using the exact same service functions as every other tool in this README.
Run session-recall doctor --cwd <project> any time to validate the whole
chain end-to-end against real data: binaries on PATH, the newest session for
that project, every recovery tool, the hook itself (invoked live, against
that real session — not a fixture), whether it's actually wired in
settings.json, and its log file. Prints PASS/WARN/FAIL per check.
Other recovery tools
| Need | Tool |
|---|---|
| Just the user's prompts (the 80% case) | prompts_timeline(since_compaction=True) |
| What did the agent actually do? | tool_call_ledger(since_compaction=True) |
| Which files do I need to re-Read? | files_changed(since_compaction=True) |
| Where are the compaction events in this session? | compaction_events() |
| Find a specific symbol/path | grep_session(pattern, ...) |
| Just browse | tail_session(count=N, with_tools=False) |
Every "since_compaction" tool also accepts an explicit start_turn
and end_turn (1-based Turn.index, negatives count from the end).
CLI quickstart
# What sessions exist for this project?
session-recall list
# Stats — turn count, time span, compaction events, top tools
session-recall info
# Recover after compaction
session-recall recall-after-compaction --format md
# Compact ledger of every Bash + Task call since the compaction
session-recall tool-call-ledger --since-compaction --tool Bash --tool Task
# Files I've edited since the compaction
session-recall files-changed --since-compaction
# Just the prompts
session-recall prompts-timeline --since-compaction --text-trunc 200
# Slice — last 5 turns with full tool I/O
session-recall tail -n 5 --with-tools
# Search a session
session-recall grep "auth_service" --include-tools -C 2
The CLI takes --session-id <uuid> to target a specific session,
defaulting to the newest in the current --cwd. Cross-project
operations live in list-all, search-all, export, and
export-recent.
Output format
Every command emits Markdown by default. Pass --format json to get
a stable, machine-readable envelope:
{
"session_id": "...",
"source": "/home/u/.claude/projects/.../<uuid>.jsonl",
"mode": "tool_call_ledger",
"start_turn": 14, "end_turn": 22, "count": 41,
"entries": [
{ "turn": 14, "ts": "...", "tool": "Bash", "summary": "git status -s",
"ok": true, "bg_id": null, "exit_code": null },
// …
]
}
Tests + dev
uv sync --extra dev --extra mcp
uv run pytest -ra
uv run ruff check src/ tests/
uv run mypy src/
Project layout
src/session_recall/
├── cli.py Click entry — one subcommand per service operation
├── mcp_server.py FastMCP entry — one @mcp.tool() per service operation
├── service.py Pure orchestration; CLI + MCP both call into here
├── digest.py Per-tool summarisers + extractors (the heart of v0.2)
├── loader.py Wire-format → Message stream + compaction-event scan
├── turns.py Group messages → Turn objects (carries line numbers)
├── filters.py Time + role + turn-index filters
├── search.py Grep-with-context windows
├── stats.py Session statistics (compaction count, etc.)
├── locator.py ~/.claude/projects/<encoded-cwd>/ resolver
├── cross_session.py list-all + search-all (across project dirs)
├── exporter.py Write a session out to disk (md/html/json)
├── models.py Domain types
└── render/ md / json / html renderers
.claude-plugin/
├── plugin.json Claude Code plugin manifest
└── marketplace.json Self-hosted marketplace — this repo lists itself (source: "./")
.mcp.json MCP server entry (uvx --from session-recall session-recall-mcp)
hooks/hooks.json SessionStart(compact) hook entry
skills/session-recall/ The skill teaching Claude how to use the tools above
See CHANGELOG.md for what's new in each release.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file session_recall-0.4.1.tar.gz.
File metadata
- Download URL: session_recall-0.4.1.tar.gz
- Upload date:
- Size: 177.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4befb74bc70e7f775bf704816e42289b90b16bc43a9d0c78d4504aa5f0f52c56
|
|
| MD5 |
f86ef7434de56c3c325ad59f5e920dca
|
|
| BLAKE2b-256 |
0b613b55a04f95a31ddde4a4e285051e4b44865529285c59adbad6bd71844233
|
File details
Details for the file session_recall-0.4.1-py3-none-any.whl.
File metadata
- Download URL: session_recall-0.4.1-py3-none-any.whl
- Upload date:
- Size: 64.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d77ab30cb1b98ab62074d0248c635d2717fee04b2bf60a719f8b208239834ec
|
|
| MD5 |
c81b78647ca8b3c18e9e81575dcd8de1
|
|
| BLAKE2b-256 |
f3e37d2920cffd43d26f7dc8ee2f67fabc40684e975f8796dbabc2d994d0f8c5
|