License Python FastAPI Docker Pulls PyPI Downloads PyPI Version MCP Registry

Discord Publish CodeQL marm-memory MCP server

Contributions welcome! Browse open issues to contribute, or join the MARM Discord to share workflows, get setup help, and connect with other builders.

Important Messages

  • marm-console now ships as the local web app for memory, knowledge, projects, and MCP-backed memory mutation actions. Packaging and one-command startup polish are still in progress.
  • Embedding upgrade: v2.24 switches MARM to Jina v2 Small. Existing MiniLM data must be migrated before restart: stop MARM, run marm-mcp-server --migrate-embeddings, then restart. See Upgrade Existing Embeddings.
  • Concept graph rebuild: the platform-aware graph schema requires one full rebuild. After upgrading, run marm_concept_build(search_all=True) once. MARM backs up and rebuilds only the derived concept database; memories are not modified.
  • I am waiting to get access back to my PYPI account, till restored pip will be behind a few versions. I will update the README when it is back up to date.

Table of Contents

Why MARM Memory

Your AI forgets everything. MARM Memory doesn't.

marm-memory is a high-performance 3-in-1 AI Memory Framework that solves conversational drift, context pollution, and agent amnesia. Instead of juggling fragmented tools, it natively fuses three context layers into a single local runtime:

  • 🧠 Core Memory (7 Tools) — long-term episodic memory, session logs, notebooks, and intelligent summaries via local vector embeddings and deterministic exact matching
  • 💻 Code Graph (5 Tools) — instant repo indexing, symbol lookup, and tree-sitter syntax analysis, powered by the codebase-memory-mcp static binary wrapper
  • 🧩 Concept Graph (2 Tools) — extracts entities and typed relationships from stored history, linking developer decisions straight back to source code symbols

One query resolves what was decided, why, and where it lives — no traffic-cop routing across isolated tools. Claude Code, Codex, Gemini, Qwen, Cursor, and VS Code agents share the same persistent memory server across sessions and long-running multi-agent projects, with all 14 tools bundled over both HTTP and STDIO.

Under the hood: a serialized SQLite WAL write queue kills multi-agent swarm contention, write-time consolidation merges duplicates, and hybrid semantic + full-text retrieval keeps recall sharp as memory grows. Agent-assisted compaction keeps context windows clean without losing traceability, and the local marm-console web app gives you real-time visual telemetry to browse and debug your entire memory layout.

How It Works

Layer What it does Why it matters
Memory model Sessions, structured logs, notebooks, summaries, and semantic memories Keeps project history searchable instead of trapped in one chat
Scale layer SQLite WAL mode, connection pooling, serialized write queue, and HTTP rate-limit presets Lets one server support solo use, multi-agent work, and swarm-style bursts
Intelligence layer FTS filter, semantic re-rank, bounded semantic fallback, auto-classification, write-time consolidation, and compaction candidates Keeps recall useful as memory grows instead of letting duplicates pile up
Code graph layer Repo indexing, symbol lookup, call tracing, architecture overview, and change-impact analysis Gives agents project structure without rereading the whole codebase
Concept graph layer Entity and relationship extraction from stored memories, with links back into the code graph Connects decisions, errors, tools, and people across sessions instead of leaving them as flat text
Token layer Lightweight 7-tool core surface (14 total with bundled graph tools), semantic re-rank before retrieval, and write-time deduplication Reduces tokens sent to the model on every recall and cost stays predictable as memory scales
Deployment layer Pip, Docker, STDIO, HTTP, --swarm, --swarm-max, and --trusted Lets you run private local memory or shared multi-agent memory with the same MCP surface

See Performance & Scaling Benchmarks for retrieval latency, concurrency, and write-cost numbers, and Architecture & Internals for the mechanisms behind each layer.

Start Now

Recommended: guided setup with marm-init

The easiest way to install MARM is to let your agent do the setup with you. marm-init turns the usual MCP setup mess into one guided conversation: Python or Docker, HTTP or STDIO, local or remote server, API keys, config paths, server startup, and multi-agent linking for Claude, Codex, Gemini, Qwen, Cursor, VS Code, and other MCP clients. No hunting through install docs, no guessing which config file your client uses, and no rewriting the same connection by hand for every agent.

npx degit Lyellr88/marm-memory/skills

Then tell your agent: "Use the marm-init skill to set up MARM."

Manual pip install

pip install marm-mcp-server
If you are... Start the server Connect your MCP client
Solo developer / researcher python -m marm_mcp_server "agent" mcp add --transport http marm-memory http://localhost:8001/mcp
Private local STDIO user marm-mcp-stdio "agent" mcp add --transport stdio marm-memory-stdio marm-mcp-stdio
Multiple agents sharing memory python -m marm_mcp_server --swarm "agent" mcp add --transport http marm-memory http://localhost:8001/mcp
Private high-throughput swarm python -m marm_mcp_server --swarm-max "agent" mcp add --transport http marm-memory http://localhost:8001/mcp
Trusted private lab/server python -m marm_mcp_server --trusted "agent" mcp add --transport http marm-memory http://localhost:8001/mcp

Upgrade Existing Embeddings

The Jina v2 Small default uses 512-dimensional embeddings; older all-MiniLM-L6-v2 data is 384-dimensional and must be re-embedded after upgrading. Stop every MARM HTTP and STDIO process, then run:

marm-mcp-server --migrate-embeddings

The command refuses to continue when it detects a live HTTP server, but STDIO processes cannot be detected reliably and must be stopped manually. It re-embeds memory, chunk, and any existing concept-graph embeddings (notebook scratch entries no longer carry embeddings), reports batch progress, verifies both databases, and exits. It is resumable: rerun the same command after an interruption. Do not run it against a live server.

Performance & Scaling Benchmarks

MARM is tuned for fast recall first, even as memory grows and long memories are chunked behind the scenes.

These measurements use the fastembed-backed jinaai/jina-embeddings-v2-small-en encoder and a throwaway local SQLite database.

1. Retrieval Latency Scaling

Session Size ($N$) Min Latency Median Latency p95 Latency
N = 100 6.6 ms 7.4 ms 8.0 ms
N = 500 7.1 ms 8.1 ms 10.0 ms
N = 1,000 7.6 ms 8.5 ms 9.0 ms
N = 2,000 9.3 ms 10.5 ms 11.6 ms
N = 4,000 11.5 ms 12.1 ms 13.4 ms

2. Encoder + Concurrency

  • Cold model load: 887ms
  • Warm encode: median 4.0ms, p95 4.4ms
  • Concurrent recall: 10 gathered recalls completed in 616.3ms vs 440.7ms serial. The current path is intentionally serialized around shared encoder/SQLite work, so gathering calls does not create parallel speedup.

3. Write-Time Ingestion Cost

  • Consolidation off: median 6.8ms, p95 7.9ms
  • Consolidation on: median 51.3ms, p95 93.7ms
  • Tradeoff: write-time dedupe/clustering adds 7.6x median cost so recall stays fast and cleaner over time.

4. Hybrid Search Scaling

Session Size ($N$) Pure Semantic Production Hybrid FTS Filter -> Rerank Speedup vs Pure
N = 100 2.3 ms 7.9 ms 1.9 ms 1.2x
N = 1,000 23.1 ms 9.2 ms 2.5 ms 9.2x
N = 4,000 106.5 ms 13.2 ms 4.7 ms 22.8x
N = 10,000 267.1 ms 13.6 ms 5.3 ms 50.4x

These Jina v2 Small benchmarks used a throwaway real SQLite database and the live configured encoder on local hardware. Reproduce them: scripts/benchmarking/performance/bench_hotpath.py

5. LoCoMo Retrieval Accuracy

A fresh Jina v2 Small run ingested all 10 LoCoMo conversations through marm_log_entry, then scored top-5 marm_smart_recall results against 1,977 evidence-annotated questions. No answer-generation model or LLM judge was used.

Encoder Any evidence hit All evidence hit Mean evidence recall
MiniLM baseline 37.5% 29.5% not previously published
Jina v2 Small 53.0% 43.4% 47.6%

The Jina run improved both hit metrics in this benchmark. This comparison does not isolate context length as the sole cause; model quality, 512-dimensional vectors, and reranking behavior changed together. Reproduce it with scripts/benchmarking/accuracy/locomo/run_eval.py.

6. vs Competitors: Architecture

MARM targets a specific niche: local-first memory for MCP-connected coding agents, not general personalization memory or a full agent runtime. Here's how it differs architecturally from established names in AI agent memory:

MARM Mem0 Letta (MemGPT) Zep / Graphiti agentmemory
Type Memory engine, MCP-native Memory layer API Full agent runtime Temporal knowledge graph Memory engine, MCP-native
Required infrastructure No separate data service (embedded SQLite) Vector DB (Qdrant/pgvector) Postgres + vector DB Neo4j Separate iii-engine runtime
Deployment Local-first by default; Docker for shared/remote Cloud API or self-hosted Self-hosted or cloud Cloud or self-hosted Local-first
Retrieval model Hybrid: FTS5 BM25 exact lane + semantic rerank Vector + graph + key-value Vector archival store + agent-managed core memory Temporal knowledge graph (fact validity windows) BM25 + vector + graph (RRF fusion)
Write capture Explicit tool calls from the connected agent Explicit add() calls (some integrations auto-extract) Agent self-edits its own memory Explicit API calls Hook-based, automatic (no explicit calls needed)
Code structure awareness Bundled code graph + concept graph, fused with memory Not built in Not built in Not built in Not built in (pairs with a separate project)
Framework lock-in None (any MCP client) None High (must run within Letta) None None (any MCP client)

Disclaimers & Accuracy: Competitor landscapes evolve rapidly. The matrix above reflects core architectural traits as of Q3 2026, based on public documentation and READMEs, not internal testing of each system. If any data point regarding an alternative framework has changed or is misrepresented, please open an issue or submit a Pull Request to update the table. We actively welcome corrections from peer maintainers.

🚀 Quick Start for MCP (HTTP & STDIO)

Manual pip install

pip install marm-mcp-server

Use this quick rule of thumb to choose your setup

  • Local HTTP/STDIO = fastest single-machine setup.
  • Docker HTTP = shared/always-on server (key required).
  • Docker STDIO = private containerized local use (no HTTP key).

Swarm / multi-agent note: The write queue is enabled by default to serialize memory writes through one worker. For shared HTTP deployments, use --swarm (200 RPM) or --swarm-max (600 RPM) when starting the server. --trusted disables rate limiting entirely for private deployments. STDIO is still best for private single-agent/local use. See Swarm & multi-agent presets for the full table.

"agent" refers to claude, gemini, grok, qwen, or any MCP client. Codex uses --url instead of --transport to add MCP tools.

pip install marm-mcp-server
python -m marm_mcp_server
# Stuck on client setup? Open a Q&A thread: https://github.com/Lyellr88/marm-memory/discussions
# most agents use this --transport command
"agent" mcp add --transport http marm-memory http://localhost:8001/mcp
codex mcp add marm-memory --url http://localhost:8001/mcp

Default pip/local startup is zero-config: MARM binds to localhost and does not require a key unless you expose it with SERVER_HOST=0.0.0.0.

pip install marm-mcp-server
python -m marm_mcp_server.server_stdio
# most agents use this --transport command
"agent" mcp add --transport stdio marm-memory-stdio marm-mcp-stdio
codex mcp add marm-memory-stdio -- marm-mcp-stdio

Replace marm-mcp-stdio with python -m marm_mcp_server.server_stdio if using a virtualenv or a path-based setup. Works with Claude Code, Cursor, VS Code, Qwen, and Gemini CLI. STDIO stays a single local process with no port and no API key, and exposes the same 14 tools as HTTP.

Use HTTP when multiple agents need to share one live MARM server. STDIO is still best for private single-agent use because each client owns its own local process.

# HTTP shared server, normal multi-agent use
python -m marm_mcp_server --swarm

# HTTP shared server, heavier private swarm
python -m marm_mcp_server --swarm-max

# HTTP trusted private lab/server, rate limiting disabled
python -m marm_mcp_server --trusted

# STDIO remains keyless/private and does not use swarm flags
marm-mcp-stdio

Docker HTTP requires an API key because it exposes MARM as a network server; STDIO stays local to the client process and does not need one.

# Step 1: generate key (do not add < > around the key)
docker run --rm lyellr88/marm-mcp-server:latest --generate-key

# Step 2: run server
docker pull lyellr88/marm-mcp-server:latest
docker run -d --name marm-mcp-server \
  -p 127.0.0.1:8001:8001 \
  -e SERVER_HOST=0.0.0.0 \
  -e MARM_API_KEY=your-generated-key \
  -v ~/.marm:/home/marm/.marm \
  lyellr88/marm-mcp-server:latest

# Step 3: connect client
"agent" mcp add --transport http marm-memory http://localhost:8001/mcp --header "Authorization: Bearer your-generated-key"

# PowerShell: set this before starting/restarting Codex
$env:MARM_API_KEY="your-generated-key"
codex mcp add marm-memory --url http://localhost:8001/mcp --bearer-token-env-var MARM_API_KEY

# Quick auth smoke test
curl -i -H "Authorization: Bearer $env:MARM_API_KEY" http://127.0.0.1:8001/mcp

--bearer-token-env-var takes the environment variable name, not the raw key. Start or restart Codex from the same shell after setting $env:MARM_API_KEY. For local Docker smoke tests, MARM_API_KEY=test is fine and avoids shell escaping problems; use a generated key for real deployments. A 406 Not Acceptable from the smoke-test GET /mcp means auth reached the MCP endpoint; 401 Unauthorized means the key is missing or mismatched.

# --swarm: write queue on, 200 RPM - recommended for multi-agent shared servers
docker run -d --name marm-mcp-server \
  -p 127.0.0.1:8001:8001 \
  -e SERVER_HOST=0.0.0.0 \
  -e MARM_API_KEY=your-generated-key \
  -v ~/.marm:/home/marm/.marm \
  lyellr88/marm-mcp-server:latest --swarm

Docker graph tools run inside the container, so they cannot see host paths unless you mount them at docker run.

$env:MARM_API_KEY="test"

# The second -v line mounts your repo; adjust the host path to your project
docker run -d --name marm-mcp-server `
  -p 127.0.0.1:8001:8001 `
  -e SERVER_HOST=0.0.0.0 `
  -e MARM_API_KEY=$env:MARM_API_KEY `
  -v ~/.marm:/home/marm/.marm `
  -v C:\Users\lyell\Desktop\marm-memory:/workspace/marm-memory `
  lyellr88/marm-mcp-server:latest

Then index the container path, not the Windows host path:

marm_graph_index(repo_path="/workspace/marm-memory")

Graph tools must use the container path. Mounts cannot be added to an already-running container; stop and restart the container with the repo mount when you want Docker graph indexing.

Docker STDIO includes the same built-in marm-graph tools; no extra image or install step is required.

docker run --rm -i \
  -v ~/.marm:/home/marm/.marm \
  --entrypoint python \
  lyellr88/marm-mcp-server:latest \
  -m marm_mcp_server.server_stdio

  • Docker HTTP requires a key; Docker STDIO does not.
  • If you get 401, verify key match and client restart after env var changes.
  • For full key setup, rotation, and troubleshooting: INSTALL-DOCKER.md

Connect your client

Start the server (python -m marm_mcp_server), then wire up your client below. Every block assumes the default local install (no key). For Docker or exposed servers, add the Authorization: Bearer header shown in each client's collapsible.

claude mcp add --transport http marm-memory http://localhost:8001/mcp

Claude Code supports HTTP, SSE, and STDIO through claude mcp add; use HTTP for MARM. For STDIO: claude mcp add --transport stdio marm-memory-stdio marm-mcp-stdio.

Add to .vscode/mcp.json in your workspace. Use marm-memory-local for direct Python installs; marm-memory-docker for Docker or exposed/key mode.

{
  "inputs": [
    {
      "type": "promptString",
      "id": "marm-api-key",
      "description": "MARM API Key for Docker or exposed server mode",
      "password": true
    }
  ],
  "servers": {
    "marm-memory-local": {
      "type": "http",
      "url": "http://localhost:8001/mcp"
    },
    "marm-memory-docker": {
      "type": "http",
      "url": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer ${input:marm-api-key}"
      }
    }
  }
}

Open .vscode/mcp.json, click Start above the server you want, then use Copilot Agent or any extension that consumes VS Code's native MCP registry.

Add to .cursor/mcp.json in your workspace. Cursor uses mcpServers, not VS Code's servers root.

{
  "mcpServers": {
    "marm-memory-local": {
      "type": "http",
      "url": "http://localhost:8001/mcp"
    },
    "marm-memory-docker": {
      "type": "http",
      "url": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer ${env:MARM_API_KEY}"
      }
    }
  }
}

For Docker/key mode, launch Cursor with MARM_API_KEY set in the environment.

Codex uses codex mcp add or TOML config at ~/.codex/config.toml (%USERPROFILE%\.codex\config.toml on Windows).

# Direct Python install - no key needed
codex mcp add marm-memory --url http://localhost:8001/mcp

# Docker or SERVER_HOST=0.0.0.0 - key required (set MARM_API_KEY in your shell first)
codex mcp add marm-memory --url http://localhost:8001/mcp --bearer-token-env-var MARM_API_KEY
[mcp_servers."marm-memory"]
url = "http://localhost:8001/mcp"
enabled = true
bearer_token_env_var = "MARM_API_KEY"
# Direct Python install - no key needed
gemini mcp add --transport http marm-memory http://localhost:8001/mcp

# Docker or SERVER_HOST=0.0.0.0 - key required
gemini mcp add --transport http marm-memory http://localhost:8001/mcp --header "Authorization: Bearer your-generated-key"

Equivalent ~/.gemini/settings.json (user scope) or project .gemini/settings.json:

{
  "mcpServers": {
    "marm-memory": {
      "httpUrl": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer your-generated-key"
      }
    }
  }
}
# Direct Python install - no key needed
qwen mcp add --transport http marm-memory http://localhost:8001/mcp

# Docker or SERVER_HOST=0.0.0.0 - key required
qwen mcp add --transport http marm-memory http://localhost:8001/mcp --header "Authorization: Bearer your-generated-key"

Equivalent .qwen/settings.json (project) or ~/.qwen/settings.json (user):

{
  "mcpServers": {
    "marm-memory": {
      "httpUrl": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer your-generated-key"
      }
    }
  }
}

xAI connects from its own infrastructure, so localhost will not work. Expose MARM behind HTTPS and set MARM_API_KEY.

{
  "type": "mcp",
  "server_url": "https://your-marm-domain.example.com/mcp",
  "server_label": "marm-memory",
  "authorization": "Bearer your-generated-key"
}

Full platform walkthroughs, key setup, and OS-specific notes: Windows · Linux · Docker/key mode · Other platforms

Using a client that isn't listed? Open an issue and let us know; client adapters are a first-class feature request.

Requirements

  • Python: 3.10 or higher
  • SQLite3: Included with Python (no separate install needed)
  • Storage: ~100MB minimum for initial setup, scales with memory database size
  • RAM: 512MB minimum (varies by concurrent clients and database size)
  • OS: Windows, macOS, Linux

Data location

  • Location: ~/.marm/ (Linux/macOS) or %USERPROFILE%\.marm\ (Windows)
  • Contents: SQLite database with all memories, sessions, and notebooks; the concept graph lives in its own ~/.marm/index/ database
  • Backup: Copy the entire ~/.marm/ directory to preserve all data
  • Privacy: Everything stays on your machine, no cloud sync or external storage

Verify installation

Use the MCP server health endpoint for the fastest live check:

curl http://localhost:8001/health

Expected output includes server version, feature availability (semantic search status), database connection status, and service health status.

MARM Demo

https://github.com/user-attachments/assets/dabfe44f-689d-404f-a2c7-dcf8fa4ef0c1

MARM gives AI agents persistent long-term memory, shared cross-session context, write-queue safety, swarm presets, and hybrid semantic + exact recall so commands, config keys, and project meaning all stay reachable.

Complete MCP Tool Suite (14 Tools)

💡 Pro Tip: You don't need to manually call these tools! Just tell your AI agent what you want in natural language:

  • "Claude, log this session as 'Project Alpha' and add this conversation as 'database design discussion'"
  • "Remember this code snippet in your notebook for later"
  • "Search for what we discussed about authentication yesterday"

The AI agent will automatically use the appropriate tools. Manual tool access is available for power users who want direct control.

🧠 Core Memory (7 tools)

Tool What it does Key parameters
marm_smart_recall Hybrid memory recall with an additive, bounded concept/code graph sidecar when a compatible graph exists query, limit, session_name, search_all, detail=1/2/3, project, platform, exact_mode
marm_log_entry Add structured session log entries; each entry is also embedded into semantic memory so marm_smart_recall can find it entry, session_name
marm_log_show Display all entries and sessions, with filtering session_name
marm_delete Delete a log session, log entry, or notebook entry type, target, session_name, project, platform
marm_summary Cached, paste-ready session summaries with intelligent truncation session_name
marm_notebook Session-scoped scratch pad plus promotion to a permanent, graph-linked doc action="add"|"use"|"show"|"status"|"clear"|"save", name, data, session_name, project, platform
marm_compaction Agent-assisted memory cleanup with a reviewable audit trail action="status"|"candidates"|"review"|"stage"|"apply"|"discard"

🕸️ Code Graph (5 tools)

Tool What it does Key parameters
marm_graph_index Index a repo into the code-structure graph, check status, or list projects repo_path, project
marm_code_lookup Find symbols, text patterns, or a symbol's source; use instead of grep/glob kind="auto"|"symbol"|"text"|"snippet"
marm_graph_trace Trace call paths and data flow from a function direction, mode
marm_graph_architecture Architecture overview: modules, node/edge breakdown, schema project
marm_graph_impact Blast radius of code changes: git diff → affected symbols + risk since, base_branch, depth

🧩 Concept Graph (2 tools)

Tool What it does Key parameters
marm_concept_build Extract entities and typed relationships from stored memories session_name, project, or search_all=True (one required)
marm_concept_recall Explicitly query entities, relationships, and linked code symbols query, depth (1-5), direction, project, platform

All 14 tools are available on both HTTP and STDIO. Behind the tool surface, the server handles lifecycle setup, protocol refresh, docs indexing, date context, summary-cache maintenance, write queue handling, project/platform attribution, and health checks automatically; none of those consume the agent's attention or tokens. The two graph engines start lazily on first use and never block the 7 core memory tools if they fail to start. See Architecture & Internals for the mechanisms.

Using MARM: Talk, Don't Call Tools

MARM handles lifecycle work internally. Docs and session state initialize on the first real tool call, and packaged docs are indexed into the marm_system memory namespace with source-file hash tracking, so your agent can answer MARM usage questions from memory itself.

Example Workflow: Cross-AI Research Project

A realistic workflow showing MARM in action. Scenario: you're researching authentication patterns for a new project using multiple AI clients.

Phase 1: Route Session (Claude)

You: "Claude, create a MARM session called 'auth-research-2025-01'"
Claude calls: marm_log_entry(entry="Session: auth-research")
Result: Session routed to auth-research-[today]. MARM lifecycle/docs initialize automatically.

Phase 2: Capture Research (Claude)

You: "Summarize OAuth2 vs JWT for API authentication and save it"
Claude calls: marm_log_entry(entry="Research: OAuth2 is token-based with refresh cycles, better for delegated access. JWT is stateless, good for microservices...", session_name="auth-research-2025-01")
Result: Research captured in the active session log and marked for summary-cache refresh

Phase 3: Add Reusable Reference (Claude)

You: "Save a JWT validation code snippet to my notebooks as 'jwt-validation-pattern'"
Claude calls: marm_notebook(action="add", name="jwt-validation-pattern", data="def verify_jwt(token):\n  # validation logic...")
Result: Reusable snippet stored for future projects

Phase 4: Recall Context (Gemini)

You: "Gemini, what authentication approaches did we research? Activate the JWT pattern."
Gemini calls: marm_smart_recall("authentication patterns", search_all=True)
Gemini calls: marm_notebook(action="use", names="jwt-validation-pattern")
Result: Gemini sees previous research + has JWT code available as context

Phase 5: Synthesis & Summary (Qwen)

You: "Qwen, pull everything from the auth research and create a summary"
Qwen calls: marm_smart_recall("authentication", session_name="auth-research-2025-01", limit=20)
Qwen calls: marm_summary(session_name="auth-research-2025-01")
Result: Qwen generates implementation guide from all captured research

Phase 6: End Session (Claude)

You: "Log final decision - we're using JWT for APIs and OAuth2 for user auth"
Claude calls: marm_log_entry(entry="DECISION: JWT for API auth, OAuth2 for user flows. Rationale: stateless APIs + delegated user access", session_name="auth-research-2025-01")
Result: Decision logged and searchable by all future AI clients

Result: Three different AI clients collaboratively researched a topic, shared insights, and documented decisions. All without re-explaining the project to each new AI.

Advanced patterns

Project Structure:
├── project-name-planning/          # Initial design and requirements
├── project-name-development/       # Implementation details
├── project-name-testing/           # QA and debugging notes
├── project-name-deployment/        # Production deployment
└── project-name-retrospective/     # Lessons learned

Knowledge base loop:

  1. Capture: Use marm_log_entry for structured session learnings
  2. Organize: Create themed sessions for knowledge areas
  3. Synthesize: Regular marm_summary for knowledge consolidation
  4. Apply: Convert summaries to marm_notebook(action="add", ...) entries

Multi-AI collaboration: each AI works in dedicated sessions on its strengths, uses marm_smart_recall to build on the others' work, then a collaborative session combines the insights.

  • Session naming: Include the LLM name for cross-referencing
  • Strategic logging: Focus on key decisions, solutions, discoveries, configurations
  • Global search: Use search_all=True to search across all sessions
  • Natural language search: "authentication problems with JWT tokens" beats "auth error"
  • Layered recall depth: detail=1 returns a short summary view (~200 chars), detail=2 a larger context view (~500 chars), detail=3 full memory content
  • Notebook stacking: Combine multiple entries for complex workflows
  • Compaction: Let MARM surface compaction candidates, then use marm_compaction to stage, review, apply, or discard summaries
  • Session lifecycle: Start → Work → Reference → Review staged compaction when MARM asks

Understanding MARM Memory

Two searches, two very different problems, one tool:

User: "I discussed machine learning algorithms yesterday"
MARM Search: Finds related memories about "ML models", "neural networks", "AI training"

User: "What was the COMPACTION_TRIGGER_COUNT setting?"
MARM Search: Finds the exact config memory even if the rest of the text differs

The first query is about meaning, so MARM reranks candidates with local vector embeddings — RAG-style semantic search without a hosted vector database. The second is syntax-shaped (a config key), so MARM detects that automatically and routes it through deterministic exact matching instead. This exact-retrieval lane is the difference between a memory system that works in demos and one that answers the questions developers actually ask: config keys, CLI flags, file paths, API names, error strings. Pure-semantic memory systems fail at exactly those queries.

MARM uses filter→rerank hybrid recall plus an exact retrieval lane:

  1. Exact lane (exact_mode="auto", the default): config keys, CLI flags, file paths, API/tool names, dotted namespaces, HTTP routes, URLs, and quoted command strings are detected and routed through deterministic FTS5 BM25 with a LIKE fallback. No embeddings involved, so results are stable and literal.
  2. Filter→rerank lane: natural-language queries first pull a bounded candidate set from the FTS index (FTS_CANDIDATE_LIMIT, default 50), then semantic embeddings rerank those candidates by meaning. Conservative temporal weighting gives fresher memories a modest boost when matches are otherwise close.
  3. Bounded semantic fallback: when FTS coverage is weak or unusable, MARM falls back to a bounded semantic scan (RECALL_SCAN_LIMIT). If the response includes recall_scan_truncated=true, the fallback hit its cap; narrow the session/query or raise the env var for larger stores.
  4. Chunk-aware scoring: long memories (roughly 180+ words) are embedded as overlapping chunk rows internally, and recall collapses chunk scores back to one parent memory using the best-matching chunk. Both the rerank lane and the fallback lane are chunk-aware.

This is why recall latency stays nearly flat as the store grows (see benchmarks): the semantic rerank always scores a bounded set instead of scanning every embedding.

Exact recall control: exact_mode="auto" is usually right. Use exact_mode="exact" when a query must match literal text such as RECALL_SCAN_LIMIT, --generate-key, or settings.py. Use exact_mode="semantic" when a syntax-looking query should still be treated as meaning-based recall.

Memory types & classification

  1. Context Logs - Auto-classified conversation memories
  2. Manual Entries - Explicitly saved important information
  3. Notebook Entries - Reusable instructions and knowledge
  4. Session Summaries - Compressed conversation history

MARM automatically categorizes content on write: Code (programming snippets and technical discussions), Project (work conversations and planning), Book (literature, learning materials, research), and General (everything else).

Project & platform attribution

MARM stores nullable project and platform columns on memories, log entries, and notebook entries. The project is detected from the working directory and the platform from the connecting client (Claude Code, VS Code, Cursor, ...); MARM_PROJECT and MARM_PLATFORM override detection. marm_smart_recall(project=..., platform=...) scopes recall without changing the default unfiltered behavior, so one shared server can hold several projects without cross-contamination.

Knowledge Graphs: Code & Concepts

MARM ships two graph systems that complement the memory store: a code graph that understands your repository's structure, and a concept graph that understands what your stored memories are about. When both are indexed for the same project, concept entities cross-link to code symbols.

Code Graph: repo indexing and code lookup

marm-graph is bundled into both transports. It indexes a repository once, then lets agents ask code-structure questions without repeatedly scanning files:

Use marm_graph_index to index this repository.
Then use marm_code_lookup when you need symbols, files, or source snippets.
Use marm_graph_trace for call paths, marm_graph_architecture for an overview, and marm_graph_impact for change-risk checks.

The recommended agent workflow: index once, then marm_code_lookup before broad file reads, marm_graph_trace when callers/callees or data-flow context matters, marm_graph_architecture for orientation, and marm_graph_impact before risky refactors. Re-index after meaningful code changes. One graph query replaces dozens of grep/read cycles, which is where the token savings come from.

Under the hood, the engine is codebase-memory-mcp (MIT), a zero-dependency static binary that parses 158 languages through tree-sitter with Hybrid LSP type resolution for the major ones, indexes an average repository in seconds, and answers structural queries in under a millisecond. MARM pins a specific release, verifies its tool schem