Skip to main content
Mnemo logo

Mnemo

One memory for all your coding agents.

Your agents can recall every Claude Code, Codex, OpenCode and Pi session you've ever run, on this machine and your devboxes, just by asking.

Python 3.7+ Zero dependencies SQLite FTS5 MCP License: MIT

Website · Docs · Changelog

English · 简体中文

you ▸ test_backoff_is_bounded is failing again. Didn't we fix this before?

claude ▸ search_sessions(query="backoff flaky")
         1 hit · codex · devbox-b · 2026-09-26 · /home/alex/relay
           "CI is red on main: test_[[backoff]]_is_bounded is [[flaky]]. Investigate."

       ▸ get_context(path=…/rollout-2026-09-26….jsonl, line=2, host="devbox-b")
           tool  1 failed, 199 passed … assert 30.000000000000004 <= 30.0
           codex A floating-point edge case … I'll clamp explicitly in backoff()
           codex apply_patch: return min(cap, random.uniform(0, base * 2 ** attempt))

claude ▸ Yes. Codex fixed this on devbox-b on Sep 26: the jittered delay could
         exceed the 30s cap by float error, so the clamp moved after the jitter.
         That fix isn't on this branch. Want me to apply the same patch?

Illustrative session with trimmed output. See the recall loop for what each call returns.

Why Mnemo

Every coding agent already writes its full working memory to disk: prompts, reasoning, tool calls, tool output. But each agent keeps its own logs, and each machine keeps its own. The result is a set of islands:

  • Claude Code can't see what you worked out in Codex yesterday.
  • The agent on your laptop can't see last week's session on the devbox.
  • Handoff notes and shared MEMORY.md files only help if every agent keeps them up to date, and they don't.

Mnemo indexes the logs your agents already produce and gives every agent the same tools to search and read them. Your agents don't have to change how they work, and you don't write any notes.

How agents use Mnemo

Just ask

With the MCP server and the skill installed, you don't have to name the tool. Questions like these send the agent to its history:

You say The agent
"How did we fix the OOM on the GPU box last week?" Searches all devices, then reads the fix in context
"Did Codex ever try sqlite-vec for this?" Searches source=codex, then summarizes what was tried and why it was dropped
"Pick up where the devbox session left off yesterday." Finds the session and reads its tail with get_session(tail=…)
"What was the exact command we used to rebuild the index?" Searches kind=tool_call and quotes the command verbatim
"上次那个连接池超时是怎么解决的?" Chinese matches by substring, so 连接池超时 works too

The recall loop

Every lookup follows the same three steps, and each step reads more than the one before it. The agent stops as soon as it has what it needs, so it pays only for that:

search_sessions ──▶ get_context ──▶ get_session
 ~1.8k–3.9k tokens   a few k tokens     only when the whole arc matters
 "where is it?"      "what happened?"   "walk me through it"
  1. search_sessions returns {hits, coverage, warnings}. Coverage reports device failures, index refresh and the indexed-body cap. Each hit carries host, source, cwd, ts, role, kind, a snippet with the matched terms marked, and path + lineno. Keywords are ANDed, and filters narrow by agent, device, directory, date or message kind.
  2. get_context reads the messages around a hit: the prompt that led up to it, the tool calls and results, and the conclusion. The agent passes back the hit's host, and the read runs on that device.
  3. get_session reads a session in pages (limit, cursor, anchor_line) or as a whole. head/tail fetch only the selected indexed bodies, and raw: true reads the original JSONL when an indexed body was truncated at 20k characters.

Snippets are deliberately short. The skill tells the agent to call get_context before quoting or reusing anything from a hit.

Tools

MCP Pi CLI Purpose
search_sessions search_sessions mnemo search … --json Ranked keyword search across all agents and devices
get_context get_session_context mnemo context <path> <line> Messages around a hit
get_session get_full_session mnemo session <path> The whole session, optionally head/tail/raw
list_recent_sessions — mnemo recent Recently started sessions with their first task as title
reindex — mnemo index Incremental sync of local logs

Parameters, output shapes and token costs: Agent tools.

Codex completed-item events and compressed .jsonl.zst rollouts are supported. Compressed reads require the optional zstd executable on the device holding the file; missing decoders preserve existing rows for affected compressed files and report a coverage warning while plain sessions still sync. See bounded retrieval.

Make it a habit

The skill covers "look it up when the user asks." To have agents check history before they start work, add a rule to your AGENTS.md or CLAUDE.md:

## Past sessions
Before non-trivial work, and whenever I refer to earlier work ("last time", "like before",
"did we ever…"), search past agent sessions with mnemo (`search_sessions`, or
`mnemo search … --json`). Read promising hits with `get_context` before relying on them,
and say which session (agent, device, date) you are drawing on.

Highlights

  • Cross-agent. A single index covers Claude Code, Codex (including archived sessions), OpenCode and Pi, all normalized to one message schema.
  • Cross-device. Queries fan out over SSH to your devboxes and merge by rank. Session bodies never leave the machine that produced them.
  • Cheap for agents. A search returns ranked snippets, not raw logs: ~1.9k tokens for 10 hits. In a controlled test, agents used 23% fewer tokens and 52% fewer tool calls than with grep (benchmarks).
  • Good at CJK. English uses prefix matching and Chinese uses substring matching (unigram + bigram), all ranked with BM25.
  • Fast. Searches take about 60–100 ms on a 236k-message index and an idle incremental sync about 0.1 s. Opening a long session reads one page around the hit (133 KB) instead of the whole transcript (19 MB).
  • Zero dependencies. Mnemo needs only the Python 3.7+ standard library and SQLite FTS5. It installs with git clone and needs no daemon.
  • A dashboard for humans. A local browser UI to search, read sessions on a timeline and manage devices.

Install

curl -fsSL https://szupzj18.github.io/mnemo/install.sh | sh

One command: it checks Python 3.7+ and SQLite FTS5, clones to ~/mnemo, links mnemo into ~/.local/bin, builds the index, and runs mnemo setup, which connects every agent it finds (Claude Code MCP + skill, Codex MCP, OpenCode MCP, Pi extension; anything already configured is left alone). Run it again to upgrade. Prefer a Python tool manager? uv tool install mnemo-search && mnemo setup (or pipx install mnemo-search; the command is mnemo).

Then try mnemo search "retry budget", or ask an agent about something only an old session would know.

Manual install
git clone https://github.com/szupzj18/mnemo.git ~/mnemo
ln -s ~/mnemo/bin/mnemo ~/.local/bin/mnemo    # any directory on PATH
mnemo index                                   # first full index; later runs are incremental
mnemo setup                                   # connect agents (or configure them by hand below)

To connect agents by hand:

Claude Code
claude mcp add --scope user mnemo -- mnemo mcp

For better triggering, also install the skill. It tells the agent when to reach for past sessions:

ln -s ~/mnemo/integrations/skills/mnemo ~/.claude/skills/mnemo
Codex

~/.codex/config.toml:

[mcp_servers.mnemo]
command = "/Users/you/.local/bin/mnemo"   # absolute path
args = ["mcp"]
startup_timeout_sec = 120
Pi
ln -s ~/mnemo/integrations/pi/mnemo.ts ~/.pi/agent/extensions/mnemo.ts

The extension calls the mnemo CLI. It looks for ~/mnemo/bin/mnemo first, then PATH, and MNEMO_BIN overrides both.

Any other MCP client

Register the stdio command mnemo mcp. For agents that support skills but not MCP, symlink integrations/skills/mnemo/ into their skills directory. The skill uses the CLI.

See Getting started for keeping the index fresh and troubleshooting.

Dashboard

For you rather than your agents: mnemo dashboard opens a local web UI (127.0.0.1, token-gated) with the same search, across every device.

Mnemo dashboard: one search across Claude Code, Codex and Pi sessions

Click a hit to open the full session as a chat thread. Matches are highlighted and you can jump between them. Tool calls fold away. A timeline rail marks each turn, idle gaps, day changes and how long each tool call took.

Session view with a timeline rail, highlighted matches and tool-call durations

The dashboard also covers index stats, per-device health, device add/update/remove, a topology map of every device reachable through relays, and search diagnostics (latency and hits per device). It has light and dark themes.

Multiple machines

mnemo remote add devbox-b          # rsync-installs mnemo over SSH and builds its index
mnemo search "sglang oom"            # now searches local + devbox-b in parallel
flowchart LR
  A["Agent on laptop"] -->|search| L["mnemo (laptop)"]
  L -->|local query| LI[("laptop index")]
  L -->|ssh: mnemo search --host local| R1["mnemo (devbox-a)"]
  L -->|ssh: mnemo search --host local| R2["mnemo (devbox-b)"]
  R1 --> I1[("devbox-a index")]
  R2 --> I2[("devbox-b index")]
  R1 -. ranked hits .-> L
  R2 -. ranked hits .-> L
  L -->|RRF merge| A

The design is message passing, not shared storage. Each machine indexes only its own logs, a search is a message sent to every device, and results come back as ranked hits merged with Reciprocal Rank Fusion. context and session reads are routed to the device that holds the session, so no central database collects everyone's transcripts. Each device lists only its direct neighbors; turn on mnemo node --forward on on a device and searches relay through it, so any topology works (chains, trees, meshes) with loops and duplicates handled. Hits carry their route, e.g. devbox-a/devbox-b. Unreachable devices are skipped with a warning.

Details: Multi-device.

Benchmarks

Measured on 2026-10-01 (0.4.1 + current main) on a real corpus of 872 sessions and 235,602 messages (4.14 GB of logs):

Full index build 48.4 s (one-time)
Incremental sync, nothing changed 90 ms
Search (CLI end-to-end) 60–97 ms
context lookup, largest session (27k messages) 12.5 ms (vs 385 ms re-parsing the file)
Opening that session in the dashboard 26 ms, 133 KB (vs 62 ms, 19.3 MB for the whole transcript)
Index size 1.30 GB (31% of raw; was 1.84 GB before message text was stored once)

Reproduce on your own history with python3 scripts/benchmark-real.py. It prints no session text or paths.

In a controlled experiment on 2026-09-24, fresh agents answered four "what did we do back then" questions, once with Mnemo and once with only grep/rg over the raw logs. Both groups got every answer right. With Mnemo they used 23% fewer tokens, 52% fewer tool calls and 40% less wall time. The gain grows with the size of the search space. When the answer sat in a small, guessable directory, plain grep was just as good. Methodology and caveats: Benchmarks.

Privacy & security

  • Everything runs locally. Mnemo makes no network calls except SSH to devices you registered yourself.
  • Session bodies are read on the device that produced them. A cross-device query returns only the hits and the messages you asked to read.
  • The dashboard listens on 127.0.0.1 only. API calls require a random per-launch token and a local Host header.
  • The index at ~/.mnemo/index.db holds your transcripts in plaintext. Treat it like the logs themselves.

See SECURITY.md to report a vulnerability.

Documentation

Getting started Install, connect each agent, keep the index fresh
Agent tools MCP / Pi tool schemas and the search → context → session workflow
CLI reference Every command and flag
Multi-device Remotes, relays and topologies, SSH and Kerberos notes
Architecture Index schema, CJK matching, sync, federation
Benchmarks Latency, token cost, end-to-end experiment

Roadmap

  • More agents: Gemini CLI (bodies live in protobuf SQLite blobs), Cursor
  • Hybrid semantic search (sqlite-vec + local embeddings) alongside keyword search
  • Length caps on tool_result in context responses to bound per-call token cost
  • Store message text once (index 1.84 → 1.30 GB on the corpus above)
  • Compressed verbatim bodies for injected content

Contributing

Issues and PRs are welcome, especially new agent adapters (each is about 100 lines). Start with CONTRIBUTING.md. Coding agents working in this repo should read AGENTS.md.

License

MIT

Metadata

Release files for mnemo-search 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mnemo-search 0.5.0
File Size Uploaded
mnemo_search-0.5.0.tar.gz 475.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mnemo-search 0.5.0
File Interpreter ABI Platform
mnemo_search-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 972.9 kB

Release files / mnemo_search-0.5.0.tar.gz

Download URL mnemo_search-0.5.0.tar.gz
Size 475.7 kB
Tags Source
SHA-256 checksum
How to use checksums
7a47e4437ae1d655b3134a60bf748f4a8dc91ecd32423b2526bb639447411f23
BLAKE2b-256 checksum
How to use checksums
71610fecaa6d91984315f7f0c775a9e595c14ba43ecd9eb1a1893ad4a5dd8e20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release files / mnemo_search-0.5.0-py3-none-any.whl

Download URL mnemo_search-0.5.0-py3-none-any.whl
Size 497.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
526e3db0cc6b002413a4e2bcb66c4e9a8e62c6f7d9353ae82c3b0aca54db9d5b
BLAKE2b-256 checksum
How to use checksums
eb209eeb450aa3b143388900ebec6fea3b5abda034ba62d4c610d5ea68906d29
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page