Skip to main content
Glama

OptChat — one memory for all your coding agents

OptChat gives every Claude Code and Codex session, on every machine you use, the same long-term memory. Each message (your words, the agent's replies, its tool calls and results) is kept forever, word for word, and folded into a binary tree of one-line summaries. An agent starting a fresh session reads a fixed-size view of the whole history: recent messages one line each, older ones many per line. When a line is too vague, it zooms into the lines it was made from, down to the original message.

OptChat is an MCP server written in plain Python (3.11+, no dependencies). It never runs a model and needs no API key. Summaries are written by your own agents: when work is pending, the agent hands it to a small subagent that claims jobs through MCP tools, writes the summary lines and submits them.

The design follows the OptChat idea of a chat whose memory is its own compressed history, which grew out of OptMem. The original specification is not included here.

How it works

  • Log. Every message is appended, with one write and fsync per record, to ~/.local/share/optchat/chat. Nothing is edited or deleted.

  • Tree. Message i gets a one-line summary of at most 512 bytes. Two adjacent lines merge into one, two of those into one, and so on. Short messages and short pairs need no model; they are their own line.

  • View. A list of tree lines that covers the whole history in about 128 KB. New messages append at the end, and the most overdue old pair merges, so detail fades with age.

  • Compaction jobs. Lines are summarized strictly in order, and each job carries the view before it as context. A worker subagent calls compact_next, reads the job with compact_read, and submits with compact_submit. If a line is too long, the server says by how much.

  • Recording. Claude Code hooks record every session automatically. Codex agents record user messages and their final replies with append.

Related MCP server: contextos-memory

Several machines, no owner

Machines share one memory through a folder they can all reach, for example an encrypted rclone remote. Each machine runs its own OptChat service and writes only its own files:

<shared folder>/machines/<machine-id>/messages/<first>-<last>.jsonl.gz   its messages, gzip
<shared folder>/machines/<machine-id>/summaries/<first>-<last>.jsonl.gz  summaries its agents wrote
<shared folder>/machines/<machine-id>/heartbeat.json                     "everything I wrote up to T is uploaded"

Because no file has two writers, a file-level sync can never lose data.

  • One order, no owner. Every machine orders messages by time once the heartbeats of all active machines have passed them, so machines online together compute the same order on their own.

  • Offline is fine. A machine silent for 10 minutes is skipped. What it records while away is placed after the others notice it again. Only that stretch may be grouped differently on each machine; the orders line up again after it.

  • Shared summaries. A summary is filed under the exact messages it covers. When one machine's agent writes it, the others reuse it instead of summarizing again.

  • Reading the folder. The rclone remote is read directly, not through a mount, so mount caches don't delay the exchange. The folder holds the complete history, compressed. With an encrypted remote it is encrypted at rest.

Keep the machines' clocks synchronized (NTP). A large clock skew only delays ordering, or groups a short stretch differently.

Install

On each machine, from a clone of this repository:

./run install --machine laptop --remote my-crypt:optchat      # dry run: shows every change
./run install --machine laptop --remote my-crypt:optchat --apply

This writes ~/.config/optchat/config.json and starts the service at login (launchd on macOS, a systemd user unit on Linux). It also registers the optchat MCP server with Claude Code and Codex, adds the recording hooks and the optchat-compactor subagent to Claude Code, and appends a short OptChat section to ~/.claude/CLAUDE.md and ~/.codex/AGENTS.md. Every edited file keeps a timestamped backup. ./run uninstall --apply removes all of it and keeps the memory.

Without --remote settings (no config file), OptChat is a single-machine memory.

MCP tools

Tool

Purpose

view

Read the current view in pages (follow next_offset with the same snapshot).

zoom(id, n)

Open line id+n into its two halves; n = 1 returns the original message.

read_message(id, offset)

Page through a long original.

date(id)

When message id was written.

append(event_id, kind, text, origin)

Record a message (kinds user, talk, tool, echo, note).

status

Backlog, failures, hook queue and replication state.

compact_next, compact_read, compact_submit, compact_release, compact_resume

The compaction job protocol used by the worker subagent.

Commands

./run status
./run view
./run zoom 0 1
./run append note 'A durable decision.'
./run import old-notes.txt          # or a .jsonl of {kind, text, date}
./run export memory.html            # every original, summary and tree level
./run backup memory.tar.gz
./run stop                          # the history stays on disk
./run serve                         # foreground service

Data and durability

~/.local/share/optchat/chat/
  main/  tree/          the local order of messages and their summaries (append-only JSONL)
  own/  remote/         this machine's messages and those received from others
  pool/  outsum/        summaries received from others and written here
  delivery.sqlite3      event ids for idempotent hook delivery and crash recovery
  jobs.json  sync.json  job progress and replication state
  spool/                hook events, written to disk before delivery

A flock makes one service the only writer of a chat directory, and it is released automatically if the process dies. Torn lines from a crash are skipped and reported. Any gap or conflict stops startup instead of guessing. Hook events are written to disk before delivery and replayed after a restart; invalid ones are kept in spool/failed/. Job leases expire after five minutes. Explicit failures pause a line after three attempts, until compact_resume.

Limits

  • Your normal Claude and Codex sessions own their context and caching. Clear a session to start fresh; the memory is read again at the start.

  • Summary quality is up to the worker subagent. The server enforces order, size and completeness, not meaning.

  • Recording is as complete as the hooks or explicit appends. Tool results are capped at 30,000 characters (start and end kept).

  • The log is permanent by design. Don't paste secrets into sessions that are recorded.

Tests

python3 -m unittest

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Persistent, shared memory for Claude across sessions and clients (Code, Desktop, Cowork) — deterministic diff reads, checkpoints, cross-client task handoff, and project-wide search. 100% local and deterministic, no API keys, no LLM summarization.
    4
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    One local memory every coding agent on your machine shares — Claude Code, Cursor, Claude Desktop, OpenCode. Answers from past sessions, commits, CLAUDE.md/AGENTS.md and ADRs with the exact source, and withholds work another agent has claimed so two agents don't rewrite the same thing.
    3
    1
    MIT
  • A
    license
    C
    quality
    B
    maintenance
    Enables Claude Code agents and sub-agents to share a persistent, compiled memory of project state, decisions, tasks, and facts across sessions instead of re-reading transcripts. Provides token-efficient bootstrap, search, commit, leased task claiming, and task-specific context compilation so parallel agents can coordinate without clobbering each other.
    5
    7 npm
    MIT