akitaonrails/ai-memory
Solution for long term memory for agent coding CLIs and to facilitate handoff between different agent vendors
Long-term memory for AI coding agents. Quit Claude Code mid-task, start OpenAI Codex in the same directory, continue without re-explaining the architecture, the failed approaches, or the open questions.
Support Matrix
| Area | Status | Notes |
|---|---|---|
| Linux | Supported | Primary Docker/server target and CI platform. Published Docker images support linux/amd64 and linux/arm64. Native Arch/AUR packages include system and user systemd units. |
| macOS | Supported | Workspace tests run in CI; tagged releases publish native ai-memory-macos-aarch64.tar.gz and ai-memory-macos-x86_64.tar.gz binaries. The native binary is the recommended path on Apple Silicon. See docs/macos.md. |
| Windows via WSL2 | Supported | Use the Linux install path inside WSL2 when the agent runs there. |
| Native Windows | Experimental | Tagged releases publish ai-memory-windows-x86_64.zip with ai-memory.exe; Docker Desktop wrapper and source builds are also available. Local supported profiles default to host-native hook commands; Claude Code may use its Windows exec form, while other agents use native single command strings matching their hook schema. PowerShell/Git Bash scripts are compatibility fallbacks. See docs/windows.md. |
| Claude Code | Supported | MCP config + lifecycle hooks; native commands enforce capture exclusions. install-mcp --session-aware optionally enables per-session auto-scope isolation through a local stdio bridge. Optionally captures the assistant's final turn on Stop when installed with --capture-assistant and the server enables capture_assistant (double opt-in, off by default). |
| Codex | Supported | MCP config + lifecycle hooks; native commands enforce capture exclusions. No automatic true session-end hook, so run ai-memory finalize-session when you need a final summary/handoff. |
| Command Code | Supported | MCP config (~/.commandcode/mcp.json) + its four stable lifecycle-hook events (~/.commandcode/settings.json); native commands enforce capture exclusions and SessionStart injects handoffs. Stop is only a turn boundary, so use ai-memory finalize-session --agent command-code after the final turn. ai-memory run command-code adds exact v3 native-session resume and visible-event import; experimental unsandboxed Mods remain excluded. |
| Devin CLI | Supported | MCP config + lifecycle hooks. Hooks use Devin's PostCompaction event, inject handoffs via hookSpecificOutput.additionalContext, and omit subagent events because Devin does not expose them. |
| OpenCode | Supported | Remote MCP config + generated TypeScript plugin; generated plugin enforces capture exclusions. |
| Cursor | Supported | MCP config + lifecycle hooks. |
| Gemini CLI | Supported | MCP config + lifecycle hooks. |
| Oh My Pi / OMP | Supported | Use --client omp / --agent omp (or oh-my-pi) for native .omp MCP config + TypeScript extension; generated extension enforces capture exclusions. |
| Pi | Supported | Generated ~/.pi/agent/extensions/ai-memory.ts extension provides lifecycle capture and an HTTP MCP bridge; generated extension enforces capture exclusions. |
| Crush | Managed-only | ai-memory run crush resumes its project-local session database and supplies portable context through a temporary supported global-context file; no lifecycle-hook installer is provided. |
| Managed workstreams | Opt-in | ai-memory run provides transparent cross-harness continuity for Claude Code, Codex, OpenCode, Pi, Crush, Kimi Code, Command Code, both incompatible Kiro CLI engines, OMP, Grok Build CLI, and Antigravity CLI. Direct launches remain unchanged. See docs/managed-workstreams.md. |
| Claude Desktop | MCP-only | Uses mcp-remote; no lifecycle hooks. |
| OpenClaw | Supported | MCP config + native plugin lifecycle hooks; generated plugin enforces capture exclusions. |
| Antigravity CLI | Supported | MCP config (serverUrl) + lifecycle hooks (agy alias). Only PreInvocation with invocationNum = 0 maps to SessionStart; later model calls cannot consume a next-session handoff. No automatic true session-end hook, so run ai-memory finalize-session --agent antigravity-cli after the final turn when you need a summary, handoff, and opt-in SessionEnd consolidation. ai-memory run antigravity (aliases antigravity-cli, agy) adds managed workstream resume via --conversation; conversation text is not decoded, so the ledger for this harness comes from hook capture. |
| Grok Build CLI | Supported | MCP config (install-mcp --client grok → $GROK_HOME/config.toml, default ~/.grok/config.toml) + lifecycle hooks (install-hooks --agent grok → $GROK_HOME/hooks/ai-memory.json, default ~/.grok/hooks/ai-memory.json, Grok-specific hook bundle). Capture works; no hook handoff injection — Grok ignores SessionStart stdout, so recover handoffs via MCP memory_handoff_accept. ai-memory run grok adds managed workstream resume with the context packet delivered natively through --rules. Skills root: .grok/skills / $GROK_HOME/skills (default ~/.grok/skills). |
| Swival CLI | MCP-only | install-mcp --client swival --apply merges a native HTTP entry into the project-root .swival/mcp.json, preserving sibling servers. Lifecycle and managed-workstream support are not claimed because Swival's callback contract does not expose a stable session identifier. |
| Zero | Supported | install-mcp --client zero (native HTTP + bearer in ~/.config/zero/config.json) + lifecycle hooks via install-hooks --agent zero --apply (exec-form native commands in ~/.config/zero/hooks.json, JSON payload on stdin, no shell). Capture works incl. specialist (subagent) events; no handoff injection — Zero discards sessionStart stdout, so recover handoffs via MCP memory_handoff_accept. |
| Kimi Code | Supported | MCP config (url entry in ~/.kimi-code/mcp.json) + lifecycle hooks ([[hooks]] in ~/.kimi-code/config.toml, 10 events including subagent start/stop and PostToolUseFailure for tool-failure capture); both paths honor $KIMI_CODE_HOME. Handoffs inject via UserPromptSubmit stdout (Kimi Code discards SessionStart hook stdout); ai-memory run kimi adds managed workstream resume. |
| Kiro CLI | Supported | MCP config uses install-mcp --client kiro-cli (alias kiro) and Kiro's Bedrock-compatible schema flavor. install-hooks --agent kiro-cli merges v2 hooks into existing agent configs; the explicit --agent kiro-cli-v3 target writes the incompatible standalone v3 registration. Both preserve unrelated entries, honor $KIRO_HOME, enforce capture exclusions, and inject pending handoffs at session start. Kiro has no true SessionEnd hook; use ai-memory finalize-session --agent kiro-cli, with --session-id for concurrent sessions. ai-memory run kiro manages v2; add --v3, --mode, or --agent-engine v3 for version-safe v3 resume. |
| VS Code Copilot | MCP-only | .vscode/mcp.json for Copilot agent mode; no lifecycle hooks (Copilot does not expose them yet). |
| Zed | MCP-only | Native remote MCP under context_servers in Zed's user settings.json; no lifecycle hooks or managed-workstream support. |
| Hermes Agent | Community | Core hook ingestion recognizes agent=hermes and Hermes' documented shell-hook tool_name / tool_input payload for concrete session attribution, tool-family titles, and capture exclusions. A community-maintained ai-memory-hermes-plugin is available, but no first-party installer is shipped; review its compatibility matrix, install/uninstall scripts, and secret handling before using it. Hermes ignores session-start hook stdout, so recover handoffs through MCP. |
| LLM/auth providers | Supported | Anthropic, OpenAI, OpenAI OAuth/Codex, GitHub Copilot, Gemini, OpenCode Zen/Go, OpenAI-compatible endpoints, and generic OIDC device auth for native hooks. |
| Embedding providers | Supported | OpenAI, Voyage, Google Gemini, and keyless OpenAI-compatible endpoints such as Ollama, LM Studio, and vLLM. |
What it is
LLM coding agents lose context when a session ends. ai-memory gives them a shared, persistent wiki compiled from sanitized lifecycle observations. When a session ends, relevant observations become a coherent summary; the next agent receives a bounded handoff. Optional ai-memory run launches add a portable visible-event ledger and native per-harness resume for higher-fidelity cross-harness continuity.
The wiki is plain markdown in a git repo - grep-able, openable in Obsidian, backed up with rsync. No vector database to babysit, no write_note ceremony, no manual context-loading. The full design is in docs/ARCHITECTURE.md; the influences and priors are at the bottom.
Key features
- Zero-friction lifecycle capture. Hooks fire-and-forget bounded, sanitized prompt, tool-lifecycle, and session-boundary observations. Direct launches keep this lightweight path; it is not a complete native transcript. User prompts and post-compaction summaries retain up to 16 KiB; notifications and tool excerpts retain up to 2 KB, with a 16 KiB durable backstop for every observation body.
- Opt-in managed workstreams.
ai-memory run claude, thenai-memory run codex --yolo, thenai-memory run command-code, transparently resumes one logical workstream with native per-harness sessions, a portable visible-event ledger, and full-ledger search. Delivered packets are origin-marked; Claude transcript import rejects a packet that Claude persisted and read back through a tool.ai-memory runwith no harness continues the newest usable Claude Code, Codex, OpenCode, Pi, Crush, Kimi Code, Command Code, or Kiro CLI v2/v3 session for this checkout. On first explicit use, an interactive launcher can adopt a previous session from the same checkout; later switches cannot select unrelated native history. Native arguments pass through unchanged except the wrapper-owned--yoloand--fresh; direct commands are unaffected.kimi-codeandkimi-cliare accepted aliases for the installedkimicommand;commandcode,cmdc, andcmdselect the cross-platformcommand-codeexecutable (cmdcon native Windows); andkiro-cliselects the installedkiro-clicommand. Kiro defaults to v2;ai-memory run kiro --v3selects v3, while a returning linked v3 workstream selects its engine transparently. - Per-repository capture exclusions. A nearest-marker
[capture]ignore_pathspolicy drops matching recognized file-tool events before they reach the local spool or server. See the capture policy reference. - Optional per-operator memory slots. On shared servers,
[slots] per_user = truekeeps engine-written_slots/context in a bounded namespace derived from the authenticated operator. Session briefs and consolidation prompts receive shared slots plus the caller's own; exact wiki reads and searches remain project-wide, so this is context-injection isolation rather than RBAC. See multi-user operation. - Cross-agent handoffs. Quit Claude Code mid-task, start Codex in the same directory hours later - the next agent sees a "where you left off" block before its first prompt.
- Per-project isolation by construction. Each project lives at
///…keyed by stable UUIDs. Workspace defaults to"default". Project is derived from$cwd: CLI subcommands (bootstrap,write-page,lint, …) walk to the main git repo root so all worktrees of the same repo share one project identity; the hook router defaults tobasename($cwd)and can opt into the repo-root rule. Drop a.ai-memory.tomlmarker file in any ancestor directory to override either field explicitly — perfect for multi-client consultancies, work/personal split, mono-repos, or linked git worktrees. Same page path can exist in two projects without collision; a rename is one column update; a purge is onerm -rf. - Global preferences scope. Standing user/team context — tech choices, code style, durable personal rules — lives in the reserved
_globalscope (memory_write_pagewithscope: "global"). Defaultmemory_queryreads union it into every project asglobal_scope_hits, so preferences travel with you into new projects without naming a magic project or paying the all-projectsglobal=truefan-out. Event capture never writes there. - Entity-assisted recall. Consolidation stores up to 10 specific nouns per page in canonical
entities:frontmatter. Exact, prefix, and compound-word matches form a project-scoped RRF stream, so a query can recover a page even when its body uses different wording. The stream is lexical and adds no query-time LLM call. - Authority-aware recall. FTS5, entity-match RRF, graph-neighbor RRF, and optional vector RRF generate candidates by relevance. Before truncation, a bounded adjustment favors maintained
_rules/,decisions/,procedures/, andgotchas/pages over closely matching episodic session evidence. Tier,pinned, and explicitcanonical/active/source-of-truthorsuperseded/historical/test-fixture/do-not-answer-fromtags contribute without becoming absolute filters, so targeted history searches still find session pages. These signals affect retrieval provenance only; retrieved text remains untrusted historical evidence and never gains instruction authority from its namespace, tier, tags, pin, or rank. - Clear routing alongside code-intelligence tools. Run ai-memory beside a structural MCP server, LSP, or other live-code tool without synchronizing their stores. Use memory for prior decisions, rationale, failed attempts, procedures, and handoffs; use the current checkout and structural provider for symbols, callers, dependencies, and impact analysis. Verify historical code claims against the checkout before acting, and treat source, builds, tests, and observed runtime behavior as operational truth. See Historical memory and live code intelligence.
- Karpathy-style LLM wiki. Pages are compiled from observations at session-end (or PreCompact; clients without a true session-end event can use
ai-memory finalize-session --agentfor a manual final close), not retrieved over raw logs. Supersession chain + git-versioned markdown means you can time-travel withai-memory checkpoints,restore-page, or rawgit log. - Built-in
/webbrowser. Read-only HTML UI for the wiki - project list, folder tree, FTS5 search, markdown rendering, dark mode. Mounted on the same axum server as MCP. - Server-wide MCP client activity.
GET /admin/activity/by-client?since_days=7shows which MCP clients are calling memory tools, split into reads and writes. Counts use bounded UTC-day buckets, so arbitrary client names cannot grow the database with request volume; shared deployments keep the endpoint root-only. See MCP client activity. - Multi-agent + multi-machine ready. Supported clients: Claude Code, Codex, Command Code, Devin CLI, OpenCode, Cursor, Claude Desktop (via
mcp-remote), Gemini CLI, Antigravity CLI, Grok Build CLI, Kimi Code, OpenClaw, Oh My Pi / OMP (omp/oh-my-pi), Pi via generated bridge extension, VS Code GitHub Copilot agent mode (MCP-only, workspace.vscode/mcp.json), Kiro CLI (MCP + v2 lifecycle hooks), and Zed (MCP-only, usersettings.json). Server runs local (loopback) OR on a homelab box (LAN/VPN/cloud) with bearer-token auth. Shared servers can opt into[auto_scope]modes for per-user or session-aware current-project routing; Claude Code has a built-in opt-in bridge viainstall-mcp --session-aware. - Thin-client CLI.
ai-memory status,bootstrap,checkpoints,restore-page,purge-project,rename-project,move-project,move-session,audit-contamination,lint,curator,auto-improve,auto-improve-report,pending-writes,embed,forget-sweep,backup,finalize-sessionare all HTTP clients of the running server - never touch SQLite or wiki files directly.statusalso reports passive LLM/embedding provider health from the last real provider call. Server is the single source of truth.finalize-sessionlists matching open sessions throughGET /admin/open-sessions, then posts syntheticsession-endhooks back to the server. On shared deployments it defaults to the caller's own plus unattributed sessions; root can pass--all-ownersfor explicit cross-operator recovery. When concurrent sessions share an agent and scope, pass--session-idto target one exact open session; it cannot be combined with--all. - LLM is opt-in. Zero-LLM mode still gives you FTS5, manually declared entity, and graph-neighbor search plus rule-based summarisation. Add a provider when you want consolidated pages, lint contradictions, or staged auto-improvement proposals.
Use cases
- "Quit Claude Code and continue the same work in Codex." Use the optional managed launcher when you want native session resume plus the portable visible history, not only a summary handoff:
cd /path/to/project ai-memory run claude # Quit Claude Code, then continue the same workstream in Codex. ai-memory run codex --yolo # Continue in Command Code, preserving its own exact native session. ai-memory run command-code # Later, omit the name to resume the newest usable managed session here. ai-memory run # Start a new Codex session in the same workstream, keeping portable history. ai-memory run --fresh codex # Kiro defaults to v2; select its incompatible v3 engine explicitly once. ai-memory run kiro --v3 - "Pick the project instead of remembering where it lives." Start from a directory containing your checkouts and choose the checkout before the managed harness:
Each successfulai-memory show # Machine-readable discovery without launching anything. ai-memory show --jsonai-memory runsaves a client-local checkout link keyed by the configured server plus workspace/project.showjoins those links with the server's public activity and page-count metadata. A fast, bounded depth-1 scan of the current directory also finds new checkouts carrying a project marker (.git,Cargo.toml,package.json,go.mod,pyproject.toml, and friends), while skipping dependency and build directories. The server never exposes a checkout path, so two client machines can safely use different local paths for the same project on a remote homeserver. The list always leads with+ New project: type a name and ai-memory validates a portable directory name, stages the new checkout privately, pins its workspace and project in.ai-memory.toml, and installs the routing block and managed Agent Skills for the chosen agent. The final directory appears only after every setup step succeeds, thenshowlaunches from it. The harness menu only offers agents actually installed on the host, using the samePATHlookuprunenforces at launch.--no-scanuses only saved links;--workspacefilters both sources;--yolo,--fresh, and trailing native arguments are forwarded unchanged. Non-terminal use must pass--json; JSON mode is discovery-only and never launches a harness. The first explicit run can offer an existing session from this exact checkout or start a new one. Switching harnesses starts or resumes the native session linked to the shared workstream, so an obsolete local session cannot replace newer cross-harness history. After a normal quit, the next launch waits briefly if the previous launcher is still finalizing; handled failures release the workstream immediately. If a linked native transcript was deleted, ai-memory detects the orphan before launch and starts fresh;--freshforces that recovery for one harness. Managed mode currently covers Claude Code, Codex, OpenCode, Pi, Crush, Kimi Code, Command Code, Kiro CLI v2/v3, OMP, Grok Build CLI, and Antigravity CLI; direct harness launches remain unchanged. See Managed cross-harness workstreams. - "Just put me back where I was." From any directory, with no name to type and no list to read:
It picks the checkout whose managed launch is most recent, revalidates the path and its resolved scope, then continues there exactly as bareai-memory continueai-memory runwould. A link whose directory moved, was replaced, now resolves to a different project, or has a corrupt ordering timestamp is reported on stderr and skipped, so a resume never quietly lands in the wrong project.--workspacenarrows the search;--yoloand--freshare forwarded. - "Quit at 4 PM, pick up at 9 AM in a different agent." The classic. SessionStart hook in the next supported hook client prepends a typed handoff with open questions, next steps, and a session summary. Grok captures lifecycle events but ignores SessionStart stdout, so ask it to call
memory_handoff_acceptwhen resuming from a handoff. Zero has the same no-stdout behavior and also must callmemory_handoff_accept. - "What did we decide about X six weeks ago?" Use
memory_query Xfrom the agent for FTS5 fused with entity matches and linked-page expansion (plus vector similarity when an embedder is configured). For a quick terminal-only FTS5 lookup, useai-memory search X; that admin command does not run the hybrid streams. Pages are LLM-consolidated, so the hit is a coherent decision page, not a raw chat log. Passexplain: trueto see why each hit ranked where it did in project or explicit-scope retrieval. Cross-projectglobal: truesearch uses its separate FTS-only ranker and reports that active stream without per-hit RRF details. - "Remember this permanently." When something is worth keeping beyond auto-captured session logs - a decision, a convention, a gotcha - tell the agent "save a permanent note that we standardised on Postgres for X" or "annotate this as a project rule" and it calls
memory_write_pageto write a durable, git-versioned wiki page. From a terminal it'sai-memory write-page --path decisions/0007-db.md --body