# Session checkpoint — axiom-memory MCP

**Status:** Foundation shipped on `feat/axiom-memory-mcp`, 2026-05-06
**Owner:** Ben Booth
**Resume context:** Read this first when continuing work on the axiom-memory MCP foundation. Linked artifacts are durable; this doc + the linked design notes survive session compaction.

---

## What this is

The axiom-memory MCP is the cross-tool, cross-session memory substrate for every LLM tool the user touches: Claude Code, ChatGPT, Gemini, OpenCode, `axi chat`, future tools. Conversation turns are memorable per `spec-memory.md §1` — they carry provenance, may be projected, are subject to retraction and retention. They route through `CompositionService.write` with `cognitive_type="episodic"` via a single common path so writes from any surface land in the same ledger.

User's design intent (locked 2026-05-06):

- **Shared memory across extensions.** Tool surfaces are per-extension MCPs (classroom, openmc, dendra, ...); memory is the substrate that crosses extension lines (per `feedback_axiom_mcp_always_available.md`).
- **All LLM tools converge on `CompositionService.append()`.** MCP write tools, `axi memory record` CLI, `axi memory ingest` backstop, `axi chat` direct in-process — all paths feed the same backend (per `feedback_axiom_memory_captures_all_claude_sessions.md`).
- **Always available; endures restarts; install-mode-agnostic.** PyPI-installed and editable-repo-installed axi must register the same MCP with the same backend; durable in `~/.claude.json` user-scope; self-heals via `axi dr`.

---

## What shipped on `feat/axiom-memory-mcp`

Commit `6e2e9e45` — initial foundation:

- `axiom/memory/session_capture.py` — `record_session_turn()` common path
- `axiom/extensions/builtins/memory/mcp_server.py` — read+write MCP with `instructions` driving model discipline
- `axi memory record` — flag- or stdin-driven write CLI
- `axi memory ingest <path>` — Claude Code JSONL backstop, single-pass
- Manifest 0.2.0 → 0.3.0 with `[mcp_servers.axiom-memory]` block
- Tests: 49 added; targeted memory+classroom sweep 370 passed

Subsequent commit (this session, pending) — post-Prague queue items pulled forward:

- **Idempotent re-ingest** keyed on `content.extra.source_uuid`. Re-running ingest is a no-op; appending to a transcript only writes the new turn pairs.
- **`axi memory register-mcp`** — idempotent user-scope registration to `~/.claude.json`. Uses `sys.executable` so the entry follows the venv that ran the command.
- **`axi dr` self-heal check** — `check_axiom_memory_mcp_registered` flags missing or stale registration with a `fix: axi memory register-mcp` hint.
- **`axi memory ingest --watch`** — polling-mode incremental ingest (default 5s). Idempotency makes re-runs safe; foreground only (daemon post-Prague).
- **Per-tool parser dispatch** — `--tool {claude-code|opencode|gemini|chatgpt-desktop}`. claude-code is canonical; the other three are stubs that raise `NotImplementedError` with a contributor pointer.
- **Venv design note** — `docs/working/venv-worktree-design.md` capturing the venv-vs-worktree-vs-repo problem and proposing per-worktree `.venv`s with direnv. Design only.

---

## How to verify it works (after restart)

After restarting Claude Code in any host (VS Code, Ghostty, standalone), the new session should:

1. **Auto-connect to `axiom-memory` MCP.** Run `claude mcp list` and see:
   ```
   axiom-memory: <python path> -m axiom.extensions.builtins.memory.mcp_server - ✓ Connected
   ```
2. **Have `axiom_memory_*` tools available** in-session. The model should call `axiom_memory_recent` at task start and `axiom_memory_append` after substantive turns (the MCP `instructions` field drives this).
3. **Surface no `axi dr` errors on the new check.** Run `axi dr` (or `axi doctor`) and the `axiom-memory MCP registered (user-scope)` check shows `[ok]`.

End-to-end smoke test from a shell:

```bash
# Round-trip through the common path
axi memory record --principal ben@utexas.edu --tool axi-chat \
  --user-input "checkpoint-test" --assistant-output "ok" --json
axi memory show ben@utexas.edu --json | jq '.fragment_count'

# Backstop ingest of a real Claude Code transcript (idempotent — safe to re-run)
axi memory ingest \
  /Users/ben/.claude/projects/-Users-ben-Projects-UT-Computational-NE/<session>.jsonl \
  --principal ben@utexas.edu --json

# Self-heal check (returns 0 if registered with current python, 1 if missing/stale)
axi memory register-mcp --check
```

---

## What's queued for after the restart

Per the user, the plan is:
1. Restart Claude Code so this session sees the MCP it just built.
2. Verify the smoke tests above.
3. **Return to the Classroom branch** (`feat/classroom-prague-readiness` at `axiom-classroom-prague/`) for **Canvas bi-di sync verification** — the gating Prague item that unblocks the instructor invite.

Open follow-ups (not blocking the restart):

- **Per-worktree `.venv`s with direnv** — implement `docs/working/venv-worktree-design.md`'s recommendation. Bigger lift; do when current worktree juggling becomes the bottleneck.
- **Real OpenCode / Gemini / ChatGPT-Desktop parsers** — stubs land contributor pointers; fill in when each tool's session-log format is in hand.
- **Ingest daemon** — `axi memory ingest --watch` foreground works today; daemonization (launchd/systemd unit) post-Prague.
- **`axi install` step-type integration** — auto-registration during `axi install` run, so a fresh install of axi+memory is reachable from Claude Code without a separate `axi memory register-mcp` step. Today: manual one-shot.

---

## Key files (load these as the work demands)

- **Common path:** `src/axiom/memory/session_capture.py` — `record_session_turn`, `parse_claude_code_jsonl`, `ingest_claude_code_jsonl`, `watch_ingest_claude_code_jsonl`, `ingest_session_log`, `KNOWN_TOOL_PARSERS`
- **MCP server:** `src/axiom/extensions/builtins/memory/mcp_server.py` — tool definitions, handlers, `INSTRUCTIONS`, `_initialization_options`
- **CLI:** `src/axiom/extensions/builtins/memory/cli.py` — record / ingest / register-mcp / show / migrate
- **Registration:** `src/axiom/extensions/builtins/memory/register_mcp.py` — `register_axiom_memory_mcp`, `is_axiom_memory_mcp_registered`
- **Doctor check:** `src/axiom/cli/doctor.py` — `check_axiom_memory_mcp_registered`
- **Manifest:** `src/axiom/extensions/builtins/memory/axiom-extension.toml`
- **Design notes:** `docs/working/venv-worktree-design.md`, this file

---

## Repository state at checkpoint

- **Branch:** `feat/axiom-memory-mcp`
- **Worktree:** `/Users/ben/Projects/UT_Computational_NE/axiom-memory-mcp/`
- **Editable install:** the workspace `.venv` is currently pointed at `axiom-memory-mcp/src` (so this session's tests run against the new code). To return to other axi work after restart, repoint with `pip install -e <other-worktree> --no-deps` from the workspace root.
- **MCP registration:** `axiom-memory` registered user-scope in `~/.claude.json` with command `/Users/ben/Projects/UT_Computational_NE/.venv/bin/python` — durable across restarts.
- **Smoke-test pollution:** one fragment for principal `smoketest@example.org` exists in `~/.axi/memory/` from the manual end-to-end check; harmless, can be tombstoned later.
