convo-mem
One memory bank distilled from every coding agent's session history, served over MCP.
convo-mem reads the transcripts your coding agents already write — Claude
Code, Codex and Gemini CLI, into a single bank — extracts the decisions,
failures, knowledge and open threads buried in them, and files each one as a
record that cites the exact turn it came from. The bank is plain Markdown on
disk — greppable, diffable, and readable without this tool.
One bank across agents is the point. The reason you rejected an approach in
Codex last week is a record you can still be stopped by in Claude Code today,
and every record carries the agent whose session it came from, so you can
tell which one you were talking to.
The CLI is the product. The MCP server and the skills are shells over it.
Install
pip install convo-mem # the pipeline
pip install "convo-mem[mcp]" # ...plus the retrieval server
The command and the distribution are both convo-mem. The command used to be
memtool; the distribution never could be, because an unrelated package holds
memtool on PyPI along with the memtool import name, and sharing either
would collide in site-packages.
From a checkout, for development:
pip install -e ".[mcp]"
Use
convo-mem status # what project, sessions and bank this dir resolves to
convo-mem search "postgres" # which conversation was that? (no model call)
convo-mem search "postgres" --agent codex --session 1a2b3c4d
convo-mem init --dry-run # price the run before it spends anything
convo-mem init # build a bank from session history
convo-mem init --resume # continue an interrupted one from what is on disk
convo-mem usage # what the rolling 5h / 7d windows have actually cost
convo-mem lint # nightly sweep: revisit triggers, clustering, views
convo-mem verify --calibrate 20 # model triage of the review queue
convo-mem mcp # the MCP retrieval server (stdio; blocks)
convo-mem skills install # put the six skills where your agent looks
convo-mem vault-init # open the bank as an Obsidian vault, in place;
# then obsidian://open?path=<url-encoded bank path>
convo-mem obsidian link # print that link again; writes nothing
convo-mem <command> --help
Every command derives its project from the current directory (the git root, or
the main repo when you are in a worktree) and its bank from
<project>/memory, prints what it resolved and where each value came from, and
accepts --project PATH to operate on another project. .memconfig.yaml
overrides any of it and is never required.
Work directories (.memtool-init/, .memtool-verify/, …), the stripped
transcript corpus and the chunk corpus live under the current directory.
MEMTOOL_HOME overrides that if you want them somewhere fixed.
Sources
Three agents are read today, into one bank:
| agent | read from | override | exercised on real sessions |
|---|---|---|---|
claude_code |
~/.claude/projects/<munged cwd>/*.jsonl |
CLAUDE_CONFIG_DIR |
yes — 109 sessions across two projects |
codex |
~/.codex/sessions/**/rollout-*.jsonl |
CODEX_HOME |
yes — 83 rollouts, one project, end to end |
gemini |
~/.gemini/tmp/<slug>/chats/*.json |
GEMINI_CLI_HOME |
not yet — see below |
That last column is not decoration. gemini is implemented and tested, but
the only Gemini CLI session on the machine it was written on holds 7
records, all of them harness notices, and 0 conversational turns — so the
reader has never yet been handed a real Gemini conversation to parse. Its
record shapes were ported from the installed 0.49.0 bundle's own source
rather than confirmed against parsed messages, and both on-disk shapes (the
legacy single JSON object and the current append-only JSONL with $rewindTo
replay) are covered by unit tests. Treat it as ready to try and worth
reporting on, not as proven the way the other two are.
convo-mem status lists every folder each adapter resolves for this project
and how many sessions are in it, so an agent you use but that shows 0
sessions is visible rather than silently absent. Each record and each
manifest row carries the agent it came from; session ids are unique only
within an agent, so every agent but Claude Code gets a namespaced short id.
Surfaces that keep no readable transcript on this machine are listed by name
with the reason (sources.EXCLUDED) — cloud-hosted agents that never write
locally, and Windsurf and Antigravity, whose on-disk conversations are
encrypted. They are refused with that explanation rather than reading as "not
built yet".
MCP
Any MCP client can read the bank. Four tools: list_sessions,
search_session, read_session, get_record — every response capped at ~4k
estimated tokens, paging anchors instead of silent truncation.
convo-mem mcp list # what each client would get, and its current state
convo-mem mcp register # write it into Claude Code, Gemini CLI and Cursor's own config
convo-mem mcp register --client claude --dry-run
register writes into each client's project-scoped config — Claude
Code's .mcp.json, Cursor's .cursor/mcp.json, Gemini CLI's
.gemini/settings.json — merging in only mcpServers.convo-mem and backing
up whatever was there first. Codex is not covered yet (TOML, no confirmed
project-scope file); mcp list says so rather than pretending it doesn't
exist.
The entry it writes carries no absolute path, so all three files are safe to
commit: the server derives its project from where it is launched, and a
project-scoped config is already sitting in the project it configures. This
repo commits its own three. To register by hand instead, or for a client
register doesn't cover:
{
"mcpServers": {
"convo-mem": {
"command": "convo-mem",
"args": ["mcp"],
"_comment": "or zero-install: uvx --from 'convo-mem[mcp]' convo-mem mcp"
}
}
}
A global config is the one case that does need the project spelled out —
there is no project directory for it to sit in, so add
"env": { "MEMTOOL_PROJECT": "/path/to/your/project" }, and accept that it
binds every client session to that one project.
--project, --bank and --stripped work as flags too; MEMTOOL_PROJECT,
MEMTOOL_BANK and MEMTOOL_STRIPPED are the environment equivalents, since
clients configure servers through either. Resolution is reported on stderr —
stdout is the protocol.
Skills
Six Agent Skills ship in the package: recall, related, remember,
status, unblock, update. recall is the guardrail — it checks the bank
before you explore an idea, rather than after.
convo-mem skills list # where each client looks, what is there
convo-mem skills install # -> .agents/skills (Cursor reads it too)
convo-mem skills install --client claude # or claude | cursor | codex | all
convo-mem skills install --client all --global
One source, copied on demand. list distinguishes current from stale,
because a drifted copy an agent still follows is the failure worth catching.
Running from a checkout without installing
PYTHONPATH=src python -m convo_mem.cli <command>
Requirements
Python 3.11+, PyYAML and zstandard (pruned sessions are read back through the
zstd archive). The [mcp] extra takes mcp>=1.2 and works on both SDK major
versions: 2.x renamed FastMCP to MCPServer and removed the old import
path, so the server accepts either. Verified against 1.29.1 and 2.1.0.
The extraction pipeline calls Claude models and is calibrated against specific ones; reading a bank over MCP has no such dependency.
Metadata
Release files for convo-mem 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| convo_mem-0.2.0.tar.gz | 556.3 kB | Without provenance | Details for convo_mem-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| convo_mem-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for convo_mem-0.2.0-py3-none-any.whl |
Total release size: 933.4 kB
Release files / convo_mem-0.2.0.tar.gz
| Download URL | convo_mem-0.2.0.tar.gz |
|---|---|
| Size | 556.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6d9f39caffec6add53299f27b30262ab3a2b7ecd786a47d84a7df609d6bfc104
|
|
BLAKE2b-256 checksum How to use checksums |
2218762fa2e8c28f3a894b8de85c95eb91aa287ae6cf20e7ce3e705d498e0da7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Release files / convo_mem-0.2.0-py3-none-any.whl
| Download URL | convo_mem-0.2.0-py3-none-any.whl |
|---|---|
| Size | 377.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e64f7484abb8af25f6c4ad7dc7eebe6793bfc641e881e41e14e4c73b0331c938
|
|
BLAKE2b-256 checksum How to use checksums |
6dc14d5309dfd12e39b6da925beed2405c1719bc86e42afae495dd1d40134121
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for convo-mem 0.2.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.