Recursive Language Models for Claude Code - Infinite memory solution inspired by MIT CSAIL paper
39
stars
2
commits
Python
primary language
Aug 1, 2026
updated
Your Claude Code sessions forget everything after
/compact. RLM fixes that.
Claude Code has a context window limit. When it fills up:
/compact wipes your conversation historyRLM is an MCP server that gives Claude Code persistent memory across sessions:
You: "Remember that the client prefers 500ml bottles"
→ Saved. Forever. Across all sessions.
You: "What did we decide about the API architecture?"
→ Claude searches its memory and finds the answer.
3 lines to install. 14 tools. Zero configuration.
Requirements: Python 3.10+ (download), Claude Code CLI
pip install mcp-rlm-server[all]
The hooks and templates ship inside the package. Since a pip install gives you no repo checkout, ask the package where they landed:
python -m mcp_server --hooks-dir # e.g. .../site-packages/mcp_server/hooks
python -m mcp_server --templates-dir
Point your ~/.claude/settings.json hook commands at that path (see
Hook Configuration), or copy them to ~/.claude/rlm/hooks/.
uv tool install mcp-rlm-server[all] --python 3.12
git clone https://github.com/EncrEor/rlm-claude.git
cd rlm-claude
./install.sh
docker build -t rlm-server .
# Or pull from registry (when published):
# docker pull ghcr.io/encreor/rlm-claude
Then configure Claude Code to use the Docker container (see Docker setup below).
Restart Claude Code. Done.
v0.9.1 moved the source code from mcp_server/ to src/mcp_server/ (PyPA best practice). A compatibility symlink is included so existing installations keep working, but we recommend re-running the installer:
cd rlm-claude
git pull
./install.sh # reconfigures the MCP server path
Your data (~/.claude/rlm/) is untouched. Only the server path is updated.
┌─────────────────────────┐
│ Claude Code CLI │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ RLM MCP Server │
│ (14 tools) │
└────────────┬────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌─────────▼────────┐ ┌──────▼──────┐ ┌──────────▼─────────┐
│ Insights │ │ Chunks │ │ Retention │
│ (key decisions, │ │ (full conv │ │ (auto-archive, │
│ facts, prefs) │ │ history) │ │ restore, purge) │
└──────────────────┘ └─────────────┘ └────────────────────┘
RLM hooks into Claude Code's /compact event. Before your context is wiped, RLM automatically saves a snapshot. No action needed.
| System | What it stores | How to use |
|---|---|---|
| Insights | Key decisions, facts, preferences | rlm_remember() / rlm_recall() |
| Chunks | Full conversation segments | rlm_chunk() / rlm_peek() / rlm_grep() |
rlm_remember - Save decisions, facts, preferences with categories and importance levelsrlm_recall - Search insights by keyword (multi-word tokenized), category, or importance
critical rule outranks today's medium noterlm_forget - Remove an insightrlm_status - System overview (insight count, chunk stats, access metrics)rlm_chunk - Save conversation segments with typed categorization (snapshot, session, debug; insight redirects to rlm_remember)rlm_peek - Read a chunk (full or partial by line range)rlm_grep - Regex search across all chunks (+ fuzzy matching for typo tolerance)rlm_search - Hybrid search: BM25 + semantic cosine similarity (FR/EN, accent-normalized, chunks + insights)rlm_list_chunks - List all chunks with metadatarlm_sessions - Browse sessions by project or domainrlm_domains - List available domains for categorizationrlm_retention_preview - Preview what would be archived (dry-run)rlm_retention_run - Archive old unused chunks, purge ancient onesrlm_restore - Bring back archived chunksrlm_search still matches them by summary and tags and returns them under archived_matches — rlm_peek(chunk_id) restores one in full/compact or auto-compact| Model2Vec (default) | FastEmbed | |
|---|---|---|
| Model | potion-multilingual-128M | paraphrase-multilingual-MiniLM-L12-v2 |
| Dimensions | 256 | 384 |
| Embed 108 chunks | 0.06s | 1.30s |
| Search latency | 0.1ms/query | 1.5ms/query |
| Memory | 0.1 MB | 0.3 MB |
| Disk (model) | ~35 MB | ~230 MB |
| Semantic quality | Good (keyword-biased) | Better (true semantic) |
| Speed | 21x faster | Baseline |
Top-5 result overlap between providers: ~1.6/5 (different results in 7/8 queries). FastEmbed captures more semantic meaning while Model2Vec leans toward keyword similarity. The hybrid BM25 + cosine fusion compensates for both weaknesses.
Recommendation: Start with Model2Vec (default). Switch to FastEmbed only if you need better semantic accuracy and can afford the slower startup.
# Model2Vec (default) — fast, ~35 MB
pip install mcp-rlm-server[semantic]
# FastEmbed — more accurate, ~230 MB, slower
pip install mcp-rlm-server[semantic-fastembed]
export RLM_EMBEDDING_PROVIDER=fastembed
# Compare both providers on your data
python3 scripts/benchmark_providers.py
# Backfill existing chunks (run once after install)
python3 scripts/backfill_embeddings.py
Embedding is best-effort: a chunk is always written, even when the provider is unavailable. That chunk is then invisible to semantic search until it gets a vector, so the gap is reported rather than left to be discovered later.
rlm_status warns whenever coverage is incomplete, names the reason when the
provider failed to load, and echoes the most recent entries of rlm.log (an
append-only log in your context directory). To heal a gap:
# Dry-run first: lists chunks that would be embedded
python3 scripts/reconcile_stores.py
# Re-embed everything missing, with timestamped backups
python3 scripts/reconcile_stores.py --apply
Both honour RLM_CONTEXT_DIR. Use the same RLM_EMBEDDING_PROVIDER as your
server — the script refuses to mix vector dimensions.
/rlm-analyze - Analyze a single chunk with an isolated sub-agent/rlm-parallel - Analyze multiple chunks in parallel (Map-Reduce pattern from MIT RLM paper)| Feature | Raw Context | Letta/MemGPT | RLM |
|---|---|---|---|
| Persistent memory | No | Yes | Yes |
| Works with Claude Code | N/A | No (own runtime) | Native MCP |
| Auto-save before compact | No | N/A | Yes (hooks) |
| Search (regex + BM25 + semantic) | No | Basic | Yes |
| Fuzzy search (typo-tolerant) | No | No | Yes |
| Multi-project support | No | No | Yes |
| Smart retention (archive/purge) | No | Basic | Yes |
| Sub-agent analysis | No | No | Yes |
| Zero config install | N/A | Complex | 3 lines |
| FR/EN/JA support | N/A | EN only | 3 languages |
| Cost | Free | Self-hosted | Free |
# Load universal rules (apply regardless of topic).
# Pass a limit above your critical count — the default is 10, and a recall
# that returns 10 of 34 rules looks exactly like a complete one.
rlm_recall(importance="critical", limit=50)
# Load context for current topic
rlm_recall(query="deployment")
# Check memory status
rlm_status()
# Save a universal rule (loaded every session)
rlm_remember("Always deploy LOCAL → VPS, never direct",
category="decision", importance="critical",
tags="deploy,workflow")
# Save a topic-specific insight
rlm_remember("WeasyPrint requires inline CSS for PDF rendering",
category="finding", importance="high",
tags="weasyprint,pdf")
# Find insights later
rlm_recall(query="source of truth")
rlm_recall(category="decision")
rlm_recall(importance="critical", limit=50) # all universal rules (mind the default limit of 10)
| Level | When to use | Loaded |
|---|---|---|
critical | Universal rules (apply regardless of topic) | Every session |
high | Topic-specific rules | When working on that topic |
medium | Useful info, not blocking | On explicit search |
Test: "Does this rule apply even when working on a completely different topic?" If yes → critical.
# Save important discussion (typed)
rlm_chunk("Discussion about API redesign... [long content]",
summary="API v2 architecture decisions",
tags="api,architecture",
chunk_type="session") # or "snapshot", "debug"
# Search across all history
rlm_search("API architecture decisions") # BM25 ranked
rlm_grep("authentication", fuzzy=True) # Typo-tolerant
# Read a specific chunk
rlm_peek("2026-01-18_MyProject_001")
# Filter by project
rlm_search("deployment issues", project="MyApp")
rlm_grep("database", project="MyApp", domain="infra")
# Browse sessions
rlm_sessions(project="MyApp")
rlm-claude/
├── src/mcp_server/
│ ├── server.py # MCP server (14 tools)
│ └── tools/
│ ├── memory.py # Insights (remember/recall/forget)
│ ├── navigation.py # Chunks (chunk/peek/grep/list)
│ ├── search.py # BM25 search engine
│ ├── tokenizer_fr.py # FR/EN tokenization
│ ├── sessions.py # Multi-session management
│ ├── retention.py # Archive/restore/purge lifecycle
│ ├── embeddings.py # Embedding providers (Model2Vec, FastEmbed)
│ ├── vecstore.py # Vector store (.npz) for semantic search
│ ├── diagnostics.py # Warning log (rlm.log) — degraded ops stay visible
│ └── fileutil.py # Safe I/O (atomic writes, path validation, locking)
│
├── hooks/ # Claude Code hooks
│ ├── i18n.py # Translations (EN/FR/JA) for hook messages
│ ├── pre_compact_chunk.py # Auto-save before /compact (PreCompact hook)
│ ├── memory_write_redirect.py # Redirect auto-memory writes to RLM (PostToolUse hook)
│ └── reset_chunk_counter.py # Stats reset after chunk (PostToolUse hook)
│
├── templates/
│ ├── hooks_settings.json # Hook config template
│ ├── CLAUDE_RLM_SNIPPET.md # CLAUDE.md instructions
│ └── skills/ # Sub-agent skills
│
├── context/ # Storage (created at install, git-ignored)
│ ├── session_memory.json # Insights
│ ├── index.json # Chunk index
│ ├── chunks/ # Conversation history
│ ├── archive/ # Compressed archives (.gz)
│ ├── embeddings.npz # Semantic vectors (Phase 8)
│ └── sessions.json # Session index
│
├── install.sh # One-command installer
└── README.md
The installer automatically configures hooks in ~/.claude/settings.json:
{
"hooks": {
"PreCompact": [
{
"matcher": "manual",
"hooks": [{ "type": "command", "command": "python3 ~/.claude/rlm/hooks/pre_compact_chunk.py" }]
},
{
"matcher": "auto",
"hooks": [{ "type": "command", "command": "python3 ~/.claude/rlm/hooks/pre_compact_chunk.py" }]
}
],
"PostToolUse": [{
"matcher": "mcp__rlm-server__rlm_chunk",
"hooks": [{ "type": "command", "command": "python3 ~/.claude/rlm/hooks/reset_chunk_counter.py" }]
}]
}
}
Hook messages default to English. Set RLM_LANG=fr for French or RLM_LANG=ja for Japanese:
# Option 1: Set globally in your shell profile (~/.zshrc, ~/.bashrc)
export RLM_LANG=fr # or ja
# Option 2: Set per-hook in ~/.claude/settings.json
# Replace the command with:
"command": "RLM_LANG=fr python3 ~/.claude/rlm/hooks/pre_compact_chunk.py"
Supported languages: en (default), fr, ja.
RLM stores data in ~/.claude/rlm/context/ by default. Override with RLM_CONTEXT_DIR:
export RLM_CONTEXT_DIR=/path/to/custom/storage
This is particularly useful for Docker deployments (see below).
Organize chunks by topic with custom domains:
{
"domains": {
"my_project": {
"description": "Domains for my project",
"list": ["feature", "bugfix", "infra", "docs"]
}
}
}
Edit context/domains.json after installation.
pip install -e ".[all]"
claude mcp add rlm-server -- python3 -m mcp_server
uv tool install mcp-rlm-server[all] --python 3.12
claude mcp add rlm-server -- ~/.local/bin/mcp-rlm-server
The ./install.sh script handles this automatically. For manual installs:
# Get hook scripts from the repo
git clone https://github.com/EncrEor/rlm-claude.git /tmp/rlm-setup
# Install hooks and i18n
mkdir -p ~/.claude/rlm/hooks
cp /tmp/rlm-setup/hooks/pre_compact_chunk.py ~/.claude/rlm/hooks/
cp /tmp/rlm-setup/hooks/reset_chunk_counter.py ~/.claude/rlm/hooks/
cp /tmp/rlm-setup/hooks/memory_write_redirect.py ~/.claude/rlm/hooks/
cp /tmp/rlm-setup/hooks/i18n.py ~/.claude/rlm/hooks/
chmod +x ~/.claude/rlm/hooks/*.py
# Install skills (optional)
mkdir -p ~/.claude/skills/rlm-analyze ~/.claude/skills/rlm-parallel
cp /tmp/rlm-setup/templates/skills/rlm-analyze/skill.md ~/.claude/skills/rlm-analyze/
cp /tmp/rlm-setup/templates/skills/rlm-parallel/skill.md ~/.claude/skills/rlm-parallel/
# Cleanup
rm -rf /tmp/rlm-setup
Then configure hooks in ~/.claude/settings.json (see Hook Configuration above).
Build the image:
git clone https://github.com/EncrEor/rlm-claude.git
cd rlm-claude
docker build -t rlm-server .
Configure Claude Code MCP to use Docker:
claude mcp add rlm-server -- docker run -i --rm -v ~/.claude/rlm/context:/data rlm-server
Or manually in ~/.claude/settings.json:
{
"mcpServers": {
"rlm-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "~/.claude/rlm/context:/data", "rlm-server"]
}
}
}
The Docker image uses RLM_CONTEXT_DIR=/data internally, and the volume mount maps it to your local storage.
./uninstall.sh # Interactive (choose to keep or delete data)
./uninstall.sh --keep-data # Remove RLM config, keep your chunks/insights
./uninstall.sh --all # Remove everything
./uninstall.sh --dry-run # Preview what would be removed
RLM includes built-in protections for safe operation:
[a-zA-Z0-9_.-&]), and resolved paths are verified to stay within the storage directoryfcntl.flock exclusive locksAll I/O safety primitives are centralized in mcp_server/tools/fileutil.py.
claude mcp list # Check servers
claude mcp remove rlm-server # Remove if exists
claude mcp add rlm-server -- python3 -m mcp_server
cat ~/.claude/settings.json | grep -A 10 "PreCompact" # Verify hooks config
ls ~/.claude/rlm/hooks/ # Check installed hooks
chunk_type parameter (snapshot/session/debug/insight redirect)The repository is maintained in English. User-facing files can be translated to your language:
| File | Purpose | Translations welcome |
|---|---|---|
README.md | Main documentation | README.xx.md (e.g., README.fr.md, README.ja.md) |
templates/CLAUDE_RLM_SNIPPET.md | CLAUDE.md instructions | CLAUDE_RLM_SNIPPET.xx.md |
Code, comments, and commit messages stay in English.
MIT License - see LICENSE
Python
91.9%
Shell
8.0%
Recursive Language Models for Claude Code - Infinite memory solution inspired by MIT CSAIL paper
39
stars
2
commits
Python
primary language
Aug 1, 2026
updated
Your Claude Code sessions forget everything after
/compact. RLM fixes that.
Claude Code has a context window limit. When it fills up:
/compact wipes your conversation historyRLM is an MCP server that gives Claude Code persistent memory across sessions:
You: "Remember that the client prefers 500ml bottles"
→ Saved. Forever. Across all sessions.
You: "What did we decide about the API architecture?"
→ Claude searches its memory and finds the answer.
3 lines to install. 14 tools. Zero configuration.
Requirements: Python 3.10+ (download), Claude Code CLI
pip install mcp-rlm-server[all]
The hooks and templates ship inside the package. Since a pip install gives you no repo checkout, ask the package where they landed:
python -m mcp_server --hooks-dir # e.g. .../site-packages/mcp_server/hooks
python -m mcp_server --templates-dir
Point your ~/.claude/settings.json hook commands at that path (see
Hook Configuration), or copy them to ~/.claude/rlm/hooks/.
uv tool install mcp-rlm-server[all] --python 3.12
git clone https://github.com/EncrEor/rlm-claude.git
cd rlm-claude
./install.sh
docker build -t rlm-server .
# Or pull from registry (when published):
# docker pull ghcr.io/encreor/rlm-claude
Then configure Claude Code to use the Docker container (see Docker setup below).
Restart Claude Code. Done.
v0.9.1 moved the source code from mcp_server/ to src/mcp_server/ (PyPA best practice). A compatibility symlink is included so existing installations keep working, but we recommend re-running the installer:
cd rlm-claude
git pull
./install.sh # reconfigures the MCP server path
Your data (~/.claude/rlm/) is untouched. Only the server path is updated.
┌─────────────────────────┐
│ Claude Code CLI │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ RLM MCP Server │
│ (14 tools) │
└────────────┬────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌─────────▼────────┐ ┌──────▼──────┐ ┌──────────▼─────────┐
│ Insights │ │ Chunks │ │ Retention │
│ (key decisions, │ │ (full conv │ │ (auto-archive, │
│ facts, prefs) │ │ history) │ │ restore, purge) │
└──────────────────┘ └─────────────┘ └────────────────────┘
RLM hooks into Claude Code's /compact event. Before your context is wiped, RLM automatically saves a snapshot. No action needed.
| System | What it stores | How to use |
|---|---|---|
| Insights | Key decisions, facts, preferences | rlm_remember() / rlm_recall() |
| Chunks | Full conversation segments | rlm_chunk() / rlm_peek() / rlm_grep() |
rlm_remember - Save decisions, facts, preferences with categories and importance levelsrlm_recall - Search insights by keyword (multi-word tokenized), category, or importance
critical rule outranks today's medium noterlm_forget - Remove an insightrlm_status - System overview (insight count, chunk stats, access metrics)rlm_chunk - Save conversation segments with typed categorization (snapshot, session, debug; insight redirects to rlm_remember)rlm_peek - Read a chunk (full or partial by line range)rlm_grep - Regex search across all chunks (+ fuzzy matching for typo tolerance)rlm_search - Hybrid search: BM25 + semantic cosine similarity (FR/EN, accent-normalized, chunks + insights)rlm_list_chunks - List all chunks with metadatarlm_sessions - Browse sessions by project or domainrlm_domains - List available domains for categorizationrlm_retention_preview - Preview what would be archived (dry-run)rlm_retention_run - Archive old unused chunks, purge ancient onesrlm_restore - Bring back archived chunksrlm_search still matches them by summary and tags and returns them under archived_matches — rlm_peek(chunk_id) restores one in full/compact or auto-compact| Model2Vec (default) | FastEmbed | |
|---|---|---|
| Model | potion-multilingual-128M | paraphrase-multilingual-MiniLM-L12-v2 |
| Dimensions | 256 | 384 |
| Embed 108 chunks | 0.06s | 1.30s |
| Search latency | 0.1ms/query | 1.5ms/query |
| Memory | 0.1 MB | 0.3 MB |
| Disk (model) | ~35 MB | ~230 MB |
| Semantic quality | Good (keyword-biased) | Better (true semantic) |
| Speed | 21x faster | Baseline |
Top-5 result overlap between providers: ~1.6/5 (different results in 7/8 queries). FastEmbed captures more semantic meaning while Model2Vec leans toward keyword similarity. The hybrid BM25 + cosine fusion compensates for both weaknesses.
Recommendation: Start with Model2Vec (default). Switch to FastEmbed only if you need better semantic accuracy and can afford the slower startup.
# Model2Vec (default) — fast, ~35 MB
pip install mcp-rlm-server[semantic]
# FastEmbed — more accurate, ~230 MB, slower
pip install mcp-rlm-server[semantic-fastembed]
export RLM_EMBEDDING_PROVIDER=fastembed
# Compare both providers on your data
python3 scripts/benchmark_providers.py
# Backfill existing chunks (run once after install)
python3 scripts/backfill_embeddings.py
Embedding is best-effort: a chunk is always written, even when the provider is unavailable. That chunk is then invisible to semantic search until it gets a vector, so the gap is reported rather than left to be discovered later.
rlm_status warns whenever coverage is incomplete, names the reason when the
provider failed to load, and echoes the most recent entries of rlm.log (an
append-only log in your context directory). To heal a gap:
# Dry-run first: lists chunks that would be embedded
python3 scripts/reconcile_stores.py
# Re-embed everything missing, with timestamped backups
python3 scripts/reconcile_stores.py --apply
Both honour RLM_CONTEXT_DIR. Use the same RLM_EMBEDDING_PROVIDER as your
server — the script refuses to mix vector dimensions.
/rlm-analyze - Analyze a single chunk with an isolated sub-agent/rlm-parallel - Analyze multiple chunks in parallel (Map-Reduce pattern from MIT RLM paper)| Feature | Raw Context | Letta/MemGPT | RLM |
|---|---|---|---|
| Persistent memory | No | Yes | Yes |
| Works with Claude Code | N/A | No (own runtime) | Native MCP |
| Auto-save before compact | No | N/A | Yes (hooks) |
| Search (regex + BM25 + semantic) | No | Basic | Yes |
| Fuzzy search (typo-tolerant) | No | No | Yes |
| Multi-project support | No | No | Yes |
| Smart retention (archive/purge) | No | Basic | Yes |
| Sub-agent analysis | No | No | Yes |
| Zero config install | N/A | Complex | 3 lines |
| FR/EN/JA support | N/A | EN only | 3 languages |
| Cost | Free | Self-hosted | Free |
# Load universal rules (apply regardless of topic).
# Pass a limit above your critical count — the default is 10, and a recall
# that returns 10 of 34 rules looks exactly like a complete one.
rlm_recall(importance="critical", limit=50)
# Load context for current topic
rlm_recall(query="deployment")
# Check memory status
rlm_status()
# Save a universal rule (loaded every session)
rlm_remember("Always deploy LOCAL → VPS, never direct",
category="decision", importance="critical",
tags="deploy,workflow")
# Save a topic-specific insight
rlm_remember("WeasyPrint requires inline CSS for PDF rendering",
category="finding", importance="high",
tags="weasyprint,pdf")
# Find insights later
rlm_recall(query="source of truth")
rlm_recall(category="decision")
rlm_recall(importance="critical", limit=50) # all universal rules (mind the default limit of 10)
| Level | When to use | Loaded |
|---|---|---|
critical | Universal rules (apply regardless of topic) | Every session |
high | Topic-specific rules | When working on that topic |
medium | Useful info, not blocking | On explicit search |
Test: "Does this rule apply even when working on a completely different topic?" If yes → critical.
# Save important discussion (typed)
rlm_chunk("Discussion about API redesign... [long content]",
summary="API v2 architecture decisions",
tags="api,architecture",
chunk_type="session") # or "snapshot", "debug"
# Search across all history
rlm_search("API architecture decisions") # BM25 ranked
rlm_grep("authentication", fuzzy=True) # Typo-tolerant
# Read a specific chunk
rlm_peek("2026-01-18_MyProject_001")
# Filter by project
rlm_search("deployment issues", project="MyApp")
rlm_grep("database", project="MyApp", domain="infra")
# Browse sessions
rlm_sessions(project="MyApp")
rlm-claude/
├── src/mcp_server/
│ ├── server.py # MCP server (14 tools)
│ └── tools/
│ ├── memory.py # Insights (remember/recall/forget)
│ ├── navigation.py # Chunks (chunk/peek/grep/list)
│ ├── search.py # BM25 search engine
│ ├── tokenizer_fr.py # FR/EN tokenization
│ ├── sessions.py # Multi-session management
│ ├── retention.py # Archive/restore/purge lifecycle
│ ├── embeddings.py # Embedding providers (Model2Vec, FastEmbed)
│ ├── vecstore.py # Vector store (.npz) for semantic search
│ ├── diagnostics.py # Warning log (rlm.log) — degraded ops stay visible
│ └── fileutil.py # Safe I/O (atomic writes, path validation, locking)
│
├── hooks/ # Claude Code hooks
│ ├── i18n.py # Translations (EN/FR/JA) for hook messages
│ ├── pre_compact_chunk.py # Auto-save before /compact (PreCompact hook)
│ ├── memory_write_redirect.py # Redirect auto-memory writes to RLM (PostToolUse hook)
│ └── reset_chunk_counter.py # Stats reset after chunk (PostToolUse hook)
│
├── templates/
│ ├── hooks_settings.json # Hook config template
│ ├── CLAUDE_RLM_SNIPPET.md # CLAUDE.md instructions
│ └── skills/ # Sub-agent skills
│
├── context/ # Storage (created at install, git-ignored)
│ ├── session_memory.json # Insights
│ ├── index.json # Chunk index
│ ├── chunks/ # Conversation history
│ ├── archive/ # Compressed archives (.gz)
│ ├── embeddings.npz # Semantic vectors (Phase 8)
│ └── sessions.json # Session index
│
├── install.sh # One-command installer
└── README.md
The installer automatically configures hooks in ~/.claude/settings.json:
{
"hooks": {
"PreCompact": [
{
"matcher": "manual",
"hooks": [{ "type": "command", "command": "python3 ~/.claude/rlm/hooks/pre_compact_chunk.py" }]
},
{
"matcher": "auto",
"hooks": [{ "type": "command", "command": "python3 ~/.claude/rlm/hooks/pre_compact_chunk.py" }]
}
],
"PostToolUse": [{
"matcher": "mcp__rlm-server__rlm_chunk",
"hooks": [{ "type": "command", "command": "python3 ~/.claude/rlm/hooks/reset_chunk_counter.py" }]
}]
}
}
Hook messages default to English. Set RLM_LANG=fr for French or RLM_LANG=ja for Japanese:
# Option 1: Set globally in your shell profile (~/.zshrc, ~/.bashrc)
export RLM_LANG=fr # or ja
# Option 2: Set per-hook in ~/.claude/settings.json
# Replace the command with:
"command": "RLM_LANG=fr python3 ~/.claude/rlm/hooks/pre_compact_chunk.py"
Supported languages: en (default), fr, ja.
RLM stores data in ~/.claude/rlm/context/ by default. Override with RLM_CONTEXT_DIR:
export RLM_CONTEXT_DIR=/path/to/custom/storage
This is particularly useful for Docker deployments (see below).
Organize chunks by topic with custom domains:
{
"domains": {
"my_project": {
"description": "Domains for my project",
"list": ["feature", "bugfix", "infra", "docs"]
}
}
}
Edit context/domains.json after installation.
pip install -e ".[all]"
claude mcp add rlm-server -- python3 -m mcp_server
uv tool install mcp-rlm-server[all] --python 3.12
claude mcp add rlm-server -- ~/.local/bin/mcp-rlm-server
The ./install.sh script handles this automatically. For manual installs:
# Get hook scripts from the repo
git clone https://github.com/EncrEor/rlm-claude.git /tmp/rlm-setup
# Install hooks and i18n
mkdir -p ~/.claude/rlm/hooks
cp /tmp/rlm-setup/hooks/pre_compact_chunk.py ~/.claude/rlm/hooks/
cp /tmp/rlm-setup/hooks/reset_chunk_counter.py ~/.claude/rlm/hooks/
cp /tmp/rlm-setup/hooks/memory_write_redirect.py ~/.claude/rlm/hooks/
cp /tmp/rlm-setup/hooks/i18n.py ~/.claude/rlm/hooks/
chmod +x ~/.claude/rlm/hooks/*.py
# Install skills (optional)
mkdir -p ~/.claude/skills/rlm-analyze ~/.claude/skills/rlm-parallel
cp /tmp/rlm-setup/templates/skills/rlm-analyze/skill.md ~/.claude/skills/rlm-analyze/
cp /tmp/rlm-setup/templates/skills/rlm-parallel/skill.md ~/.claude/skills/rlm-parallel/
# Cleanup
rm -rf /tmp/rlm-setup
Then configure hooks in ~/.claude/settings.json (see Hook Configuration above).
Build the image:
git clone https://github.com/EncrEor/rlm-claude.git
cd rlm-claude
docker build -t rlm-server .
Configure Claude Code MCP to use Docker:
claude mcp add rlm-server -- docker run -i --rm -v ~/.claude/rlm/context:/data rlm-server
Or manually in ~/.claude/settings.json:
{
"mcpServers": {
"rlm-server": {
"type": "stdio",
"command": "docker",
"args": ["run", "-i", "--rm", "-v", "~/.claude/rlm/context:/data", "rlm-server"]
}
}
}
The Docker image uses RLM_CONTEXT_DIR=/data internally, and the volume mount maps it to your local storage.
./uninstall.sh # Interactive (choose to keep or delete data)
./uninstall.sh --keep-data # Remove RLM config, keep your chunks/insights
./uninstall.sh --all # Remove everything
./uninstall.sh --dry-run # Preview what would be removed
RLM includes built-in protections for safe operation:
[a-zA-Z0-9_.-&]), and resolved paths are verified to stay within the storage directoryfcntl.flock exclusive locksAll I/O safety primitives are centralized in mcp_server/tools/fileutil.py.
claude mcp list # Check servers
claude mcp remove rlm-server # Remove if exists
claude mcp add rlm-server -- python3 -m mcp_server
cat ~/.claude/settings.json | grep -A 10 "PreCompact" # Verify hooks config
ls ~/.claude/rlm/hooks/ # Check installed hooks
chunk_type parameter (snapshot/session/debug/insight redirect)The repository is maintained in English. User-facing files can be translated to your language:
| File | Purpose | Translations welcome |
|---|---|---|
README.md | Main documentation | README.xx.md (e.g., README.fr.md, README.ja.md) |
templates/CLAUDE_RLM_SNIPPET.md | CLAUDE.md instructions | CLAUDE_RLM_SNIPPET.xx.md |
Code, comments, and commit messages stay in English.
MIT License - see LICENSE
Python
91.9%
Shell
8.0%