Skip to main content
Glama
siosig

mcp-chest-memory

by siosig

mcp-chest-memory

English | 日本語

Persistent, cross-session memory for Claude Code — a lightweight, local-only MCP server. Add the MCP and it works anywhere. The MCP process runs in-process: it owns the SQLite store and runs recall directly, and delegates only embedding to a separate, locally-running embedding-daemon that is shared across all your sessions and projects. No network backend, no Docker, no API key for the interactive tools.

Implemented in Rust. Japanese full-text search uses an embedded dictionary. The embedding model (BGE-M3, ~1.7 GB) lives in the external embedding-daemon, which chest reaches over a local Unix-domain socket (preferred) or loopback TCP — so the model is loaded once per host, not once per session. The only network use is the optional background Gemini Batch API (classifier + consolidation summarizer); interactive memory is fully local and offline.

Table of contents

Related MCP server: UseCortex MCP Server

How it works

chest_remember ──► staging table (recall can't see it)
                        │  background batch (systemd timer)
                        ▼  classify each item with Gemini → promote / reject
                    memories (searchable)  ◄── chest_recall (hybrid search)
  • chest_remember never filters or blocks. It appends your submission to a staging area and returns immediately — embedding and classification are deferred.

  • A background batch (run by a systemd timer) classifies staged items with the Gemini Batch API (batched for low cost) and promotes the useful ones into searchable memories, rejecting noise.

  • chest_recall searches the promoted memories with a hybrid of dense (semantic) embeddings and FTS5 full-text search, fused by Reciprocal Rank Fusion and weighted by recency and importance.

  • Background maintenance consolidates cold clusters (summarized by Gemini Batch), archives near-duplicates (supersession), and expires TTL memories.

  • In-process, with a shared embedding-daemon. The MCP server owns the SQLite store and runs recall in-process — no chest process loads the embedding model. Embedding is delegated to a separate embedding-daemon (a gemini-embedding-001-compatible local service) over a Unix-domain socket or loopback TCP, so one model instance is shared by every session, the maintenance timers, and any other project. Writes stay single-writer: the in-process server and the timer-run maintenance CLI serialize via an OS file lock (plus WAL).

Install

Clone the repo, cd into it, and run the installer. It builds the Rust binaries, puts them on your PATH, checks the embedding-daemon is reachable, and installs the Claude Code plugin.

git clone https://github.com/siosig/mcp-chest-memory.git
cd mcp-chest-memory
./install_claude_plugin.sh        # build + install
# restart Claude Code

Prerequisites: cargo (https://rustup.rs), claude (https://claude.ai/code), and a running embedding-daemon reachable over its Unix-domain socket or 127.0.0.1:18181 — install and start it separately (it is the one process that loads the embedding model). Uninstall with ./install_claude_plugin.sh -d (your memories in ~/.chest-memory are kept).

Background classifier + maintenance (optional)

To auto-classify and maintain memories on a schedule, deploy the systemd timers via Ansible (A-phase embed, B-phase classify, C-phase consolidate — each runs every 5 minutes):

cd ansible
ansible-playbook site.yml

Requires Ansible ≥ 2.15. See deploy/systemd/README.md for details.

Without GEMINI_API_KEY, chest-index up promotes everything (fail-open) and falls back to a simple join-based consolidation. With the key, both classification and consolidation use the Gemini Batch API automatically — no extra flags needed.

MCP tools

Tool

Purpose

chest_remember

Stage a memory (classified + made searchable by the batch).

chest_recall

Hybrid dense-semantic + FTS5 search over promoted memories.

chest_update_memory

Edit a memory's content / importance / layer (re-embeds).

chest_list_entities

List subjects with their memory counts.

chest_forget

Archive a memory (protected / high-importance ones are kept).

chest_read_smart

Read a file, returning "unchanged" when it hasn't changed since last read (saves tokens).

chest_recommend

Recommend next actions to work on, ranked from accumulated memory (goals, momentum, time-decayed work transitions).

chest_record_recommendation_feedback

Record accept/reject/ignore feedback so future recommendations improve.

Lifecycle hooks (automatic)

The plugin wires Claude Code hooks so memory works without you thinking about it:

  • UserPromptSubmit → fast FTS-only recall injects relevant memories into the prompt (no model load, sub-second).

  • SessionStart → injects your most active memory topics, and (read-only, no model) proactively offers next-action candidates when you start with no explicit task — cooldown-gated so it never nags.

  • PreCompact / Stop → captures your turns into staging before compaction so nothing memory-worthy is lost; the batch later triages them.

Next-action recommendation

Ask the assistant what to do next and it ranks candidates from your accumulated knowledge — open goals, the topics you're actively working on (momentum), and a time-decayed model of which topic you tend to move to next — then offers 2–4 concrete next actions as a selection. Picking one starts that task and records feedback so the ranking improves over time.

  • /recommend — the deterministic path: gathers candidates via chest_recommend and presents a selection.

  • Proactive — at session start, the chest-memory-recommend hook may offer candidates when you have no explicit task (cooldown + per-session cap).

The score layers an additive term on top of the unchanged recall composite (0.4·composite + 0.3·transition + 0.2·goal + 0.1·momentum); the transition term uses a smoothed Markov model that gracefully falls back to associative ranking until enough history accrues. Algorithm details: specs/master/recommend_algorithm.md.

CLI reference

chest-index — maintenance CLI

chest-index is the maintenance binary run by the systemd timer (or on demand).

chest-index <subcommand> [flags]

Subcommand

Key flags

What it does

classify

--offline, --limit N

Classify pending staged memories. Without --offline, submits a Gemini Batch API job and harvests the previous one; --offline promotes everything locally with no network.

up

--no-classify, --offline, --classify-limit N, --embed-limit N

Full maintenance cycle: classify → consolidate → embed backfill → activation decay → supersession → expiry.

consolidate

--min-age-days N

Merge cold, old memory clusters into learning summaries using local join (no network).

import

--path PATH

Import Claude Code conversation history from ~/.claude/projects/ (or a given path) into staging for batch classification.

analyze

--days N

Compute IR quality metrics (precision / recall / F1 / F2 / accuracy) from recall events and print JSON.

usage

--days N, --all, --json

Show Gemini Batch API token usage with cost. Default: last 24 h hourly table. --days N / --all switch to daily buckets; --json outputs backward-compatible JSON.

fetch-model

Verify the external embedding-daemon is reachable (first-run check).

Examples:

# classify on demand (Gemini Batch API, async)
chest-index classify

# classify with no network (promote everything)
chest-index classify --offline

# full maintenance cycle
chest-index up

# show token usage for the last 7 days
chest-index usage --days 7

# IR quality report for the last 30 days
chest-index analyze --days 30

# import past Claude Code sessions
chest-index import --path ~/.claude/projects/

Hook binaries (internal)

These binaries are invoked automatically by Claude Code hooks; you rarely need to call them directly.

Binary

Trigger

What it does

chest-memory-user-prompt-submit

UserPromptSubmit

Fast FTS-only recall over the prompt; injects matching memories as context (no model load, sub-second).

chest-memory-session-start

SessionStart

Injects the most active memory topics to seed a new session.

chest-memory-recommend

SessionStart

Read-only, no model load: proactively offers next-action candidates when you start with no explicit task (cooldown + per-session cap).

chest-memory-precompact

PreCompact

Captures recent turns into staging before compaction so nothing memory-worthy is lost.

chest-memory-import <file.jsonl>

Manual / Stop hook

Ingests a Claude Code transcript JSONL into staging (file argument).

chest-memory-sync

Stop hook (stdin)

Same as import but reads the transcript from stdin (pipe-friendly).

chest-memory-stats

Manual

Prints a privacy-safe health report: memory counts, staging backlog, recall hit-rate.

Check memory health:

chest-memory-stats

/chest-memory skill

The plugin ships a /chest-memory Claude Code skill that lets you trigger memory operations interactively from the chat prompt.

Invocation

What it does

/chest-memory

Analyze the recent conversation, auto-classify the most valuable fact, save it, and report the rationale.

/chest-memory status

Show memory store health (total memories, embedding status, whether chest-index reembed is needed).

/chest-memory analyze [--days N]

Show IR quality metrics as a formatted Markdown table (precision / recall / F1 / F2 / accuracy).

/chest-memory <free text>

Save the given text, still auto-classifying the layer.

Memory layers (auto-selected by the skill):

Layer

Saved when

realize

An error, trap, or failure that must never recur (protected from auto-forgetting).

learning

A new insight, decision, or technique that worked.

goal

A stated objective for the project.

context

Background / timing facts ("demo on Friday").

implementation

Code or config that worked or failed, with specifics.

emotion

User's emotional state worth calibrating tone to.

The skill also fires automatically at key moments without being invoked explicitly: when a new task starts, before editing a file with history, right after resolving a bug, and whenever you say "remember this" or "did we do this before?".

Configuration

Env var

Default

Meaning

CHEST_DB

~/.chest-memory/chest.db

SQLite database path.

CHEST_EMBED_SOCK / EMBED_SOCK

~/.embedding-daemon/embedding.sock, then /var/lib/embedding-daemon/embedding.sock

embedding-daemon Unix-domain socket (preferred when it exists).

CHEST_EMBED_ADDR / EMBED_ADDR

127.0.0.1:18181

embedding-daemon loopback TCP address (used when no socket is reachable).

GEMINI_API_KEY

Enables Gemini Batch API for classification and consolidation (else promote-all / join fallback).

CHEST_GEMINI_MODEL

gemini-3.1-flash-lite

Classification model.

CHEST_CONSOLIDATE_MODEL

gemini-3.1-flash-lite

Consolidation summarizer model.

GEMINI_BATCH_SIZE

1000

Items per Gemini batch submit (inline limit is a 20 MB payload, not a count).

EMBED_PARALLELISM

4

Texts per embed() call during backfill (batched internally; not OS threads).

EMBED_RETRY_MAX

3

Embed attempts before a memory is marked failed (recover with chest-index reset-failed).

CHEST_HIT_SCORE_THRESHOLD

0.5

Recall hit threshold for quality stats.

chest-memory-stats prints a privacy-safe report (memory counts, staging backlog, recall hit-rate). Usage metrics record only lengths, hashes, counts, and scores — never raw queries or paths.

Single-writer

Exactly one user is assumed. The in-process MCP server serializes its writes (remember / update / forget), and the timer-run maintenance CLI serializes against it with an OS file lock plus WAL + busy_timeout; with one user, contention is rare and the brief WAL wait is acceptable.

License

MIT.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/siosig/mcp-chest-memory'

If you have feedback or need assistance with the MCP directory API, please join our Discord server