claude-session-continuity-mcp
About
Zero-config session continuity for Claude Code. Auto-captures context via Claude Hooks, provides 24 tools for memory, tasks, solutions, and knowledge graph. Multilingual semantic search (94+ languages).
Details
- Author
- leesgit
- Categories
- Developer Tools, AI, Knowledge Base, Productivity
Jump to
Alternative: Local Install (Not Recommended)
If you really want per-project install (e.g., locked version for one project):
cd <project> && npm install passbaton
Drawback: you must install separately in every project, andnpm execmay not find the local copy reliably from hook context (cwd-dependent). Stick with-gunless you have a specific reason.
{ "mcpServers": { "project-manager": { "command": "npx", "args": ["passbaton"] } } }
Claude Hooks(in~/.claude/settings.json):
{ "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-session-start" }] }], "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-user-prompt" }] }], "PostToolUse": [{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-post-tool" }] }, { "matcher": "Write", "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-post-tool" }] }], "PreCompact": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-pre-compact" }] }], "Stop": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-session-end" }] }] } }
Note (v1.5.0+):Full lifecycle coverage with 5 hooks. Usesnpm exec --which finds localnode_modules/.binfirst.
# Check hook status npx passbaton-hooks status # Reinstall hooks npx passbaton-hooks install # Remove hooks npx passbaton-hooks uninstall
After installation, restart Claude Code to activate the hooks.
(v2.1.0+)Five behaviours are individually toggleable; the rest are shown for transparency but arealways on(a hook's mere existence is controlled by yoursettings.json, not by config) ornot yet wired. Config lives in a plain, hand-editable JSON file (~/.claude/passbaton.config.json) — separate from your data, so it survives a db reset. No file = today's defaults (nothing changes for existing users).
passbaton config # grouped table; ●/○ = toggleable, · = always on passbaton config set solutionCapture off # flip a toggleable feature passbaton config set strictSolutionGate on # opt into the strict error→fix filter passbaton config preset minimal # minimal | default | everything passbaton config reset # back to defaults passbaton config path # print the active config file path
Trying tosetan always-on / not-yet-wired feature is rejected with a clear message. Each toggleable feature also has an env override for one-off/CI use:PASSBATON_<FEATURE>=0(e.g.PASSBATON_SOLUTIONCAPTURE=0) wins over the config file.
On-by-default rule:a feature shipsononly if it'ssilent, safe, and universally useful. Anything that speaks unprompted, guesses, or writes speculative rows shipsoff.
Legend:●/○= toggleable (on/off) ··= always on, not a config toggle ·⋯= not yet wired.
sessionStart/sessionEndare "always on" because a hook either runs or it doesn't — that's controlled by the hook registration in~/.claude/settings.json, not by config. To disable them, remove the hook there.
The only genuinely user-flippable flags today arecompactionHandover,hotPathPrewarm,verificationLedger,solutionCapture(on) andstrictSolutionGate(opt-in).
SessionStart Hook(npx passbaton-hook-session-start):
- Auto-detects project: monorepo (apps/project-name/) or single project (package.jsonroot folder name)
- Loads context from.claude/sessions.db
- Injects: Current state,3 recent sessionswith commits/decisions, directives, pending tasks, filtered key memories
- Auto-cleans stale noise memories (3d+ auto-tracked, 14d+ auto-compact)
UserPromptSubmit Hook(npx passbaton-hook-user-prompt):
- Runs on every prompt submission
- (v1.11.0)No longer calls loadContext() — saves 24-60K tokens/session
- Injects relevant context (filtered: decisions, learnings, errors only)
PostToolUse Hook(npx passbaton-hook-post-tool):
- Tracks hot file paths and updatesactive_context.recent_files
- (v1.12.0)Auto-detects Bash errors → searches solutions DB → injects past solutions into context
- No longer creates observation memories(v1.10.0 — eliminates[File Change]noise)
PreCompact Hook(npx passbaton-hook-pre-compact):
- Builds structured handover context: work summary, active file, pending action, key facts, recent errors
- No longer stores auto-compact memories(v1.10.0)
Stop Hook(npx passbaton-hook-session-end):
- Extracts commit messages from JSONL transcript (git commit -mpatterns)
- Extracts error-fix pairs (error → resolution within 3 messages)
- (v1.12.0)Auto-records error→fix pairs to solutions table for future reuse
- Extracts decisions ("because", "instead of", "chose" patterns)
- (v1.11.0)Single-pass transcript parsing (4 JSONL reads → 1)
- Stores structured metadata insessions.issuescolumn as JSON
# my-app - Session Resumed 📍 State: Implementing signup form 🚧 Blocker: OAuth callback URL issue ## Recent Sessions ### 2026-02-28 Work: Completed OAuth integration Commits: feat: add OAuth handler; fix: redirect config Decisions: Use Server Actions over API routes Next: Implement form validation ## Directives - 🔴 Always use Zod for validation ## Pending Tasks - 🔄 [P8] Implement form validation - ⏳ [P5] Add error handling ## Key Memories - 🎯 Decided on App Router, using Server Actions - ⚠️ OAuth redirect_uri mismatch → check env file
# Check status npx passbaton-hooks status # Reinstall npx passbaton-hooks install # Remove npx passbaton-hooks uninstall # Temporarily disable export MCP_HOOKS_DISABLED=true
When you ask about past work, theUserPromptSubmithook automatically searches the database:
You: "저번에 인앱결제 어떻게 했어?" → Hook detects "저번에" + extracts keyword "인앱결제" → Searches sessions, memories (FTS5), and solutions → Injects matching results into context automatically
Supported patterns (Korean & English):
## Related Past Work (auto-detected from your question) ### Sessions - [2/14] 카카오 로그인 앱키 수정, 인앱결제 IAP 플로우 수정 ### Memories - 🎯 [decision] 테스트: 인앱결제 상품 등록 완료 ### Solutions - IAP_BILLING_ERROR: StoreKit 2 migration으로 해결
Previous versions used absolute paths ornpx:
// v1.3.x - absolute paths (broke on multi-project) "command": "node \"/path/to/project-a/node_modules/.../session-start.js\"" // v1.4.0-1.4.2 - npx (required global install or hit npm registry) "command": "npx passbaton-hook-session-start"
"command": "npm exec -- passbaton-hook-session-start"
npm exec --finds localnode_modules/.binfirst, then falls back to global. Works with both local and global installation without hitting npm registry.
// Start of session - auto-loads context session_start({ project: "my-app", compact: true }) // End of session - auto-saves context session_end({ project: "my-app", summary: "Completed auth flow", modifiedFiles: ["src/auth.ts", "src/login/page.tsx"] }) // View session history session_history({ project: "my-app", limit: 5 }) // Semantic search past sessions search_sessions({ query: "auth work", project: "my-app" })
// Get project status with task stats project_status({ project: "my-app" }) // Initialize new project project_init({ project: "my-app" }) // Analyze project tech stack project_analyze({ project: "my-app" }) // List all projects list_projects()
// Add a task task_add({ project: "my-app", title: "Implement signup", priority: 8 }) // Update task status task_update({ taskId: 1, status: "done" }) // List tasks task_list({ project: "my-app", status: "pending" }) // Suggest tasks from TODO comments task_suggest({ project: "my-app" })
// Record an error solution solution_record({ errorSignature: "TypeError: Cannot read property 'id'", solution: "Use optional chaining: user?.id" }) // Find similar solutions (keyword or semantic) solution_find({ query: "TypeError property", semantic: true }) // AI-powered solution suggestion solution_suggest({ errorMessage: "Cannot read property 'email'" })
// Run build verify_build({ project: "my-app" }) // Run tests verify_test({ project: "my-app" }) // Run all (build + test + lint) verify_all({ project: "my-app" })
// Store a classified memory memory_store({ content: "State management with Riverpod makes testing easier", type: "learning", // observation, decision, learning, error, pattern project: "my-app", tags: ["flutter", "state-management"], importance: 8, relatedTo: 23 // Connect to existing memory }) // Search memories — returns index (id, type, tags, score) for token efficiency memory_search({ query: "state management test", type: "learning", semantic: true, // Use embedding similarity limit: 10 }) // Get full memory content by ID (v1.11.0) memory_get({ memoryId: 23 }) // Find related memories (graph + semantic) memory_related({ memoryId: 23, includeGraph: true, includeSemantic: true }) // Get memory statistics memory_stats({ project: "my-app" })
// Connect two memories with a typed relation graph_connect({ sourceId: 23, targetId: 25, relation: "solves", // related_to, causes, solves, depends_on, contradicts, extends, example_of strength: 0.9 }) // Explore knowledge graph graph_explore({ memoryId: 23, depth: 2, relation: "all", // or specific relation type direction: "both" // outgoing, incoming, both })
SQLite database at~/.claude/sessions.db:
Zero-config session continuity for Claude Code. Auto-captures context via Claude Hooks, provides 24 tools for memory, tasks, solutions, and knowledge graph. Multilingual semantic search (94+ languages).
Session continuity for AI coding agents.Your agent picks up where it left off — never re-explain your project again. Persistent memory forClaude Code, OpenAI Codex CLI & Google Gemini CLI, sharing one local db: auto context injection, compaction handover, semantic search, and error→solution recall. Zero config, zero API cost, 100% local.
⚡ One install → context auto-loads every session · 🧩 survives compaction (0 re-explaining) · 🔒 100% local, $0 API
Renamed (v2.0.0):this project was previouslyclaude-session-continuity-mcp. The old name suggested it was Claude-only — it never was.Claude Code, Codex CLI, and Gemini CLI are all first-class and share one local memory.Existing installs keep working: the oldclaude-hook-commands still ship as aliases. SeeMigrating from v1.
Every new session — whether you're in Claude Code, Codex CLI, or Gemini CLI:
"This is a Next.js 15 project with App Router..." "We decided to use Server Actions because..." "Last time we were working on the auth system..." "The build command is pnpm build..."
5 minutes of context-setting. Every. Single. Time.
Fully automatic.Lifecycle hooks handle everything without manual calls — onClaude Code,OpenAI Codex CLI, andGoogle Gemini CLI, sharing one local memory so context carries across all three:
# Session start → Auto-loads relevant context + recent session history # When asking → Auto-injects relevant memories/solutions # During conversation → Tracks active files + auto-injects error solutions # On compact → Structured handover context for continuity # On exit → Extracts commits, decisions, error-fix pairs from transcript
← Auto-output on session start: # my-app - Session Resumed 📍 State: Implementing signup form ## Recent Sessions ### 2026-02-28 Work: Completed OAuth integration with Google provider Commits: feat: add OAuth callback handler; fix: redirect URI config Decisions: Use Server Actions instead of API routes ### 2026-02-27 Work: Set up authentication foundation Next: Implement signup form validation ## Directives - 🔴 Always use Zod for form validation - 📎 Prefer Server Components by default ## Key Memories - 🎯 Decided on App Router, using Server Actions - ⚠️ OAuth redirect_uri mismatch → check env file
Most Claude memory tools rely onexplicit tool calls("remember this"), acloud API, or abackground AI worker. This one is deliberately different:
If you want zero-config, offline, no-cost memory that justhappenswhile you work — this is it.
There's also a great class oflocal searchtools (e.g.ctx) that index your agent history so you canqueryit (search "failed migration"). That's complementary, not the same job:
Use search when you want tolook something up. Use this when you want your context tofollow youwithout asking.
Beyond Claude Code, this also supportsOpenAI Codex CLI. If~/.codexexists, the installer registers the same hooks in~/.codex/hooks.json(SessionStart, UserPromptSubmit, PreCompact, Stop), and the hooks auto-detect the host and emit the right output format (Codex'shookSpecificOutput.additionalContext).
The same localsessions.dbis shared, so context carries across both agents: what you did in Codex is available in Claude Code and vice versa.
Scope:session save + context injection work on both. Codex file-change tracking (PostToolUse) isn't wired yet — session save already covers most of it via transcript parsing. Codex'stranscript_pathis treated as an unstable interface (it can be null at startup), so host detection uses an installer-injected--codexmarker rather than relying on the path.
Also supportsGoogle Gemini CLI. If~/.geminiexists, the installer registers the hooks in~/.gemini/settings.json(SessionStart, BeforeAgent, PreCompress, SessionEnd — Gemini's event names), preserving your other settings. Same shared localsessions.db, so context carries across all three agents.
Gemini's transcript format was verified against real~/.gemini/tmp/.../chats/.jsonlfiles — it usestwo shapes(a flat{type, content}line and an older{"$set":{"messages":[…]}}diff line); the parser handles both. Like Codex,transcript_pathcan be null at startup, so host detection uses a--geminimarker.
Honest scope note:session save (SessionEnd) and context output are verified working. Gemini'sSessionStartcontext injection is documented asadvisory-onlyupstream (gemini-cli#15413) — if your Gemini build doesn't render the injected context on startup, that's an upstream limit, not this tool. Session continuity still works via the saved history.
If you installed this asclaude-session-continuity-mcp(v1.x),nothing breaks— the v1claude-hook-commands still ship as aliases in v2.
npm install -g passbaton # installs the new package npm uninstall -g claude-session-continuity-mcp # optional: drop the old one
The installer rewrites your hook entries topassbaton-hook-and removes the oldclaude-hook-lines — it matches on both names, so you won't end up with duplicates. Your existingsessions.dbis untouched:all past sessions, memories, and solutions carry over.
Nothing else changes — same hooks, same database, same behavior.
Requires Node.js 22+.The nativebetter-sqlite3dependency only ships prebuilt binaries for Node 22, 24, and 26 (the currently supported lines — Node 18 and 20 are both end-of-life). On older Node it falls back to compiling from source, which fails without build tools. Node 22 and up install cleanly with no compiler needed.
That's it!The postinstall script automatically:
- Registers MCP server in~/.claude.json
- Installs Claude Hooks in~/.claude/settings.json
This tool is designed to trackall your Claude Code projectsin a single unified database. Global installation is strongly recommended because:
Important: Even with global install, you can stilldisable the hook for specific projects(see below). Global ≠ forced on every project.
Global install doesnotmean "always on everywhere". You have three layers of control:
To disable hooks in a specific project, create the override file with empty hook arrays:
// <project>/.claude/settings.json (or settings.local.json for personal-only) { "hooks": { "SessionStart": [], "UserPromptSubmit": [], "PostToolUse": [], "PreCompact": [], "Stop": [] } }
Empty arrays override the global setting → that project's sessions are no longer tracked.
That's the only step — all projects pick up the new binary on next Claude Code restart. No need to reinstall in each project.
Alternative: Local Install (Not Recommended)
If you really want per-project install (e.g., locked version for one project):
cd <project> && npm install passbaton
Drawback: you must install separately in every project, andnpm execmay not find the local copy reliably from hook context (cwd-dependent). Stick with-gunless you have a specific reason.
{ "mcpServers": { "project-manager": { "command": "npx", "args": ["passbaton"] } } }
Claude Hooks(in~/.claude/settings.json):
{ "hooks": { "SessionStart": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-session-start" }] }], "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-user-prompt" }] }], "PostToolUse": [{ "matcher": "Edit", "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-post-tool" }] }, { "matcher": "Write", "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-post-tool" }] }], "PreCompact": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-pre-compact" }] }], "Stop": [{ "hooks": [{ "type": "command", "command": "npm exec -- passbaton-hook-session-end" }] }] } }
Note (v1.5.0+):Full lifecycle coverage with 5 hooks. Usesnpm exec --which finds localnode_modules/.binfirst.
# Check hook status npx passbaton-hooks status # Reinstall hooks npx passbaton-hooks install # Remove hooks npx passbaton-hooks uninstall
After installation, restart Claude Code to activate the hooks.
(v2.1.0+)Five behaviours are individually toggleable; the rest are shown for transparency but arealways on(a hook's mere existence is controlled by yoursettings.json, not by config) ornot yet wired. Config lives in a plain, hand-editable JSON file (~/.claude/passbaton.config.json) — separate from your data, so it survives a db reset. No file = today's defaults (nothing changes for existing users).
passbaton config # grouped table; ●/○ = toggleable, · = always on passbaton config set solutionCapture off # flip a toggleable feature passbaton config set strictSolutionGate on # opt into the strict error→fix filter passbaton config preset minimal # minimal | default | everything passbaton config reset # back to defaults passbaton config path # print the active config file path
Trying tosetan always-on / not-yet-wired feature is rejected with a clear message. Each toggleable feature also has an env override for one-off/CI use:PASSBATON_<FEATURE>=0(e.g.PASSBATON_SOLUTIONCAPTURE=0) wins over the config file.
On-by-default rule:a feature shipsononly if it'ssilent, safe, and universally useful*. Anything that speaks unprompted, guesses, or writes speculative rows shipsoff.
Legend:●/○= toggleable (on/off) ··= always on, not a config toggle ·⋯= not yet wired.
sessionStart/sessionEndare "always on" because a hook either runs or it doesn't — that's controlled by the hook registration in~/.claude/settings.json, not by config. To disable them, remove the hook there.
The only genuinely user-flippable flags today arecompactionHandover,hotPathPrewarm,verificationLedger,solutionCapture(on) andstrictSolutionGate(opt-in).
SessionStart Hook(npx passbaton-hook-session-start):
- Auto-detects project: monorepo (apps/project-name/) or single project (package.jsonroot folder name)
- Loads context from.claude/sessions.db
- Injects: Current state,3 recent sessionswith commits/decisions, directives, pending tasks, filtered key memories
- Auto-cleans stale noise memories (3d+ auto-tracked, 14d+ auto-compact)
UserPromptSubmit Hook(npx passbaton-hook-user-prompt):
- Runs on every prompt submission
- (v1.11.0)No longer calls loadContext() — saves 24-60K tokens/session
- Injects relevant context (filtered: decisions, learnings, errors only)
PostToolUse Hook(npx passbaton-hook-post-tool):
- Tracks hot file paths and updatesactive_context.recent_files
- (v1.12.0)Auto-detects Bash errors → searches solutions DB → injects past solutions into context
- No longer creates observation memories(v1.10.0 — eliminates[File Change]noise)
PreCompact Hook(npx passbaton-hook-pre-compact):
- Builds structured handover context: work summary, active file, pending action, key facts, recent errors
- No longer stores auto-compact memories(v1.10.0)
Stop Hook(npx passbaton-hook-session-end):
- Extracts commit messages from JSONL transcript (git commit -mpatterns)
- Extracts error-fix pairs (error → resolution within 3 messages)
- (v1.12.0)Auto-records error→fix pairs to solutions table for future reuse
- Extracts decisions ("because", "instead of", "chose" patterns)
- (v1.11.0)Single-pass transcript parsing (4 JSONL reads → 1)
- Stores structured metadata insessions.issuescolumn as JSON
# my-app - Session Resumed 📍 State: Implementing signup form 🚧 Blocker: OAuth callback URL issue ## Recent Sessions ### 2026-02-28 Work: Completed OAuth integration Commits: feat: add OAuth handler; fix: redirect config Decisions: Use Server Actions over API routes Next: Implement form validation ## Directives - 🔴 Always use Zod for validation ## Pending Tasks - 🔄 [P8] Implement form validation - ⏳ [P5] Add error handling ## Key Memories - 🎯 Decided on App Router, using Server Actions - ⚠️ OAuth redirect_uri mismatch → check env file
# Check status npx passbaton-hooks status # Reinstall npx passbaton-hooks install # Remove npx passbaton-hooks uninstall # Temporarily disable export MCP_HOOKS_DISABLED=true
When you ask about past work, theUserPromptSubmithook automatically searches the database:
You: "저번에 인앱결제 어떻게 했어?" → Hook detects "저번에" + extracts keyword "인앱결제" → Searches sessions, memories (FTS5), and solutions → Injects matching results into context automatically
Supported patterns (Korean & English):
## Related Past Work (auto-detected from your question) ### Sessions - [2/14] 카카오 로그인 앱키 수정, 인앱결제 IAP 플로우 수정 ### Memories - 🎯 [decision] 테스트: 인앱결제 상품 등록 완료 ### Solutions - IAP_BILLING_ERROR: StoreKit 2 migration으로 해결
Previous versions used absolute paths ornpx:
// v1.3.x - absolute paths (broke on multi-project) "command": "node \"/path/to/project-a/node_modules/.../session-start.js\"" // v1.4.0-1.4.2 - npx (required global install or hit npm registry) "command": "npx passbaton-hook-session-start"
"command": "npm exec -- passbaton-hook-session-start"
npm exec --finds localnode_modules/.binfirst, then falls back to global. Works with both local and global installation without hitting npm registry.
// Start of session - auto-loads context session_start({ project: "my-app", compact: true }) // End of session - auto-saves context session_end({ project: "my-app", summary: "Completed auth flow", modifiedFiles: ["src/auth.ts", "src/login/page.tsx"] }) // View session history session_history({ project: "my-app", limit: 5 }) // Semantic search past sessions search_sessions({ query: "auth work", project: "my-app" })
// Get project status with task stats project_status({ project: "my-app" }) // Initialize new project project_init({ project: "my-app" }) // Analyze project tech stack project_analyze({ project: "my-app" }) // List all projects list_projects()
// Add a task task_add({ project: "my-app", title: "Implement signup", priority: 8 }) // Update task status task_update({ taskId: 1, status: "done" }) // List tasks task_list({ project: "my-app", status: "pending" }) // Suggest tasks from TODO comments task_suggest({ project: "my-app" })
// Record an error solution solution_record({ errorSignature: "TypeError: Cannot read property 'id'", solution: "Use optional chaining: user?.id" }) // Find similar solutions (keyword or semantic) solution_find({ query: "TypeError property", semantic: true }) // AI-powered solution suggestion solution_suggest({ errorMessage: "Cannot read property 'email'" })
// Run build verify_build({ project: "my-app" }) // Run tests verify_test({ project: "my-app" }) // Run all (build + test + lint) verify_all({ project: "my-app" })
// Store a classified memory memory_store({ content: "State management with Riverpod makes testing easier", type: "learning", // observation, decision, learning, error, pattern project: "my-app", tags: ["flutter", "state-management"], importance: 8, relatedTo: 23 // Connect to existing memory }) // Search memories — returns index (id, type, tags, score) for token efficiency memory_search({ query: "state management test", type: "learning", semantic: true, // Use embedding similarity limit: 10 }) // Get full memory content by ID (v1.11.0) memory_get({ memoryId: 23 }) // Find related memories (graph + semantic) memory_related({ memoryId: 23, includeGraph: true, includeSemantic: true }) // Get memory statistics memory_stats({ project: "my-app" })
// Connect two memories with a typed relation graph_connect({ sourceId: 23, targetId: 25, relation: "solves", // related_to, causes, solves, depends_on, contradicts, extends, example_of strength: 0.9 }) // Explore knowledge graph graph_explore({ memoryId: 23, depth: 2, relation: "all", // or specific relation type direction: "both" // outgoing, incoming, both })
SQLite database at~/.claude/sessions.db:
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





