selfhost.directory

The index of self-hostable projects — ranked, categorized and served with live updates.
Own your data and stop giving it to big tech.

marm-memory logo

Self-host marm-memory

v2.60.1

Local-first AI memory layer and MCP server for coding agents

ReleaseOpen SourceApache-2.0
Updated5 days ago
LanguagePython
Setup difficultyModerate
MobileResponsive
Stars
424
Ports
8001 (HTTP MCP server), 8002 (Web Console)
Docker
lyellr88/marm-mcp-server
Install with Docker Compose

What is marm-memory?

marm-memory is a self-hosted persistent memory layer for AI coding agents implementing the Model Context Protocol. It gives agents like Claude Code, Codex, Cursor, and VS Code a shared private memory that persists across sessions. The server stores conversations, notes, and summaries in a local SQLite database with semantic embeddings and full-text search for fast hybrid recall. It also indexes codebases to build a code graph for symbol lookup and architecture analysis, and extracts a concept graph linking decisions, errors, and ideas across sessions. All 16 MCP tools work over both HTTP and STDIO transports. Installation options include pip, Docker, and Docker Compose, with managed profiles for solo, multi-agent swarm, and trusted deployments. A bundled web console offers a local UI for memory inspection, graph exploration, and client setup. The project is open source under Apache 2.0.

Should you self-host marm-memory?

marm-memory scores 53/100 on selfhost.directory (how scoring works) and ranks #26 of 120 in AI Assistant. It has 424 GitHub stars.

It shipped 10 stable releases in the past year. The latest, v2.60.1, came out on 12 October 2026. New versions land roughly every 1 days.

Setup is moderate: expect some configuration beyond a single command. An official Docker image is available. It is Apache-2.0-licensed and written mostly in Python.

Its closest alternative on selfhost.directory is hermes-agent (89/100, 257 989 stars). It scores higher overall, so compare the two before you pick. See marm-memory vs hermes-agent side by side.

Features

  • Automatic Indexing
  • Code Graph
  • Concept Graph
  • Cross-Client Memory Sharing
  • Distillation
  • Hybrid Recall
  • Local LLM integrationOptional, disabled by default
  • MCP protocol support
  • MCP Tools Suite
  • Memory CompactionOptional, disabled by default
  • Multi-Agent Swarm Support
  • Notebook System
  • Persistent memory
  • Session Management
  • Web Console

marm-memory README

How to install marm-memory

Install marm-memory with Docker Compose

Docker Compose
Environment variables
MARM_API_KEY, SERVER_HOST, SERVER_PORT, MARM_DB_PATH, MARM_CONCEPT_DB_PATH, MARM_RATE_LIMIT_RPM, WRITE_QUEUE_ENABLED

marm-memory docker compose --yes

Generates and writes a Docker Compose configuration file

How to configure marm-memory

  • COMPACTION_ENABLED0Background cluster detection + agent-assisted compaction

    Background cluster detection + agent-assisted compaction

  • COMPACTION_MAX_CLUSTER_SIZE8Most memories one compaction may fold into a summary. A discarded cluster is not offered again as it grows

    Most memories one compaction may fold into a summary. A discarded cluster is not offered again as it grows

  • COMPACTION_MIN_CONTAINMENT0.9Share of the shorter text's Unicode casefolded word set repeated by the other memory before clustering (character length selects the shorter text; equal lengths use the larger token set). The threshold constrains only that shorter side, not the longer memory's extra content. All short words are retained; empty/unrecognized token sets fail closed, trading recall for safety when a restatement cannot

    Share of the shorter text's Unicode casefolded word set repeated by the other memory before clustering (character length selects the shorter text; equal lengths use the larger token set). The threshold constrains only that shorter side, not the longer memory's extra content. All short words are retained; empty/unrecognized token sets fail closed, trading recall for safety when a restatement cannot

  • COMPACTION_SIMILARITY_THRESHOLD0.88 / 3 / 24Cluster detection gates

    Cluster detection gates

  • COMPACTION_STAGING_TTL_HOURS168How long staged summaries wait before expiring

    How long staged summaries wait before expiring

  • COMPACTION_TRIGGER_COUNT5Writes per session before a compaction pass. A maintenance pass also runs on the scheduler interval, so a session that stops being written to is still scanned once its memories age past `COMPACTION_MIN_AGE_HOURS`

    Writes per session before a compaction pass. A maintenance pass also runs on the scheduler interval, so a session that stops being written to is still scanned once its memories age past `COMPACTION_MIN_AGE_HOURS`

  • CONCEPT_AUTO_INDEXtrueAutomatic concept indexing of new memories. `false`, `0`, `no`, or `off` stops the worker and leaves builds manual. Writes still record queue rows either way

    Automatic concept indexing of new memories. `false`, `0`, `no`, or `off` stops the worker and leaves builds manual. Writes still record queue rows either way

  • CONCEPT_BUILD_ROW_CAP500Memory rows read per page during a concept-graph build. Not a cap on the build: every memory in scope is read either way

    Memory rows read per page during a concept-graph build. Not a cap on the build: every memory in scope is read either way

  • CONCEPT_INDEX_BATCH_PAUSE_MS250Pause between batches while clearing a backlog. Cuts worst-case recall during indexing from ~270ms to ~80ms for about 18% longer drain. `0` disables it

    Pause between batches while clearing a backlog. Cuts worst-case recall during indexing from ~270ms to ~80ms for about 18% longer drain. `0` disables it

  • CONCEPT_INDEX_BATCH_SIZE20Memories indexed per batch, capped at 500. Lowering it does not reduce contention; it measured slightly worse

    Memories indexed per batch, capped at 500. Lowering it does not reduce contention; it measured slightly worse

  • CONCEPT_INDEX_DEBOUNCE_SECONDS30Quiet period after a write before indexing starts, so a burst becomes one pass

    Quiet period after a write before indexing starts, so a burst becomes one pass

  • CONCEPT_INDEX_LEASE_SECONDS300How long a claimed indexing task stays owned once nothing is renewing it. Work in progress renews its own lease, so this bounds how long a *killed* process holds tasks, not how long a batch may take. Reclaimed tasks spend no attempt

    How long a claimed indexing task stays owned once nothing is renewing it. Work in progress renews its own lease, so this bounds how long a *killed* process holds tasks, not how long a batch may take. Reclaimed tasks spend no attempt

  • CONCEPT_INDEX_MAX_ATTEMPTS3Failed attempts before a memory is parked with its error instead of retried

    Failed attempts before a memory is parked with its error instead of retried

  • CONSOLIDATION_ENABLED0Write-time dedup + semantic merge

    Write-time dedup + semantic merge

  • CONSOLIDATION_THRESHOLD0.92Cosine similarity needed to merge near-duplicates. Compared against meaning-similarity alone, not the blended ranking score

    Cosine similarity needed to merge near-duplicates. Compared against meaning-similarity alone, not the blended ranking score

  • FTS_CANDIDATE_LIMIT200BM25 candidates fetched before semantic reranking; raise for stores with weak keyword overlap, lower to tighten results to the closest keyword matches

    BM25 candidates fetched before semantic reranking; raise for stores with weak keyword overlap, lower to tighten results to the closest keyword matches

  • FTS_EXTRA_STOPWORDS*(empty)*Comma-separated extra words to ignore when building keyword queries, for terms so common in your store they carry no signal

    Comma-separated extra words to ignore when building keyword queries, for terms so common in your store they carry no signal

  • FTS_LONE_HIT_SCORE1.0Keyword score used when only one memory matches, or when every match ties. Lower it on small stores if a single keyword match should not count as a perfect one.

    Keyword score used when only one memory matches, or when every match ties. Lower it on small stores if a single keyword match should not count as a perfect one.

  • FTS_QUERY_MODEor_nostopHow semantic recall builds its keyword query: `or_nostop` ignores filler words then matches any remaining term, `or` matches any term, `and` requires every term (the pre-2.31.0 behavior). The exact/lexical lane always requires every term.

    How semantic recall builds its keyword query: `or_nostop` ignores filler words then matches any remaining term, `or` matches any term, `and` requires every term (the pre-2.31.0 behavior). The exact/lexical lane always requires every term.

  • GRAPH_AUTO_INDEXtrueAutomatic re-indexing of repos already in the code graph. A saved switch from `projects auto off` or `marm_graph_index(action="auto_off")` overrides this, so a value set here cannot re-enable what a user turned off

    Automatic re-indexing of repos already in the code graph. A saved switch from `projects auto off` or `marm_graph_index(action="auto_off")` overrides this, so a value set here cannot re-enable what a user turned off

  • GRAPH_AUTO_INDEX_DEBOUNCE_SECONDS2Quiet period after a watcher event before a repo is evaluated, so a burst of saves becomes one re-index. Minimum 0.5

    Quiet period after a watcher event before a repo is evaluated, so a burst of saves becomes one re-index. Minimum 0.5

  • GRAPH_AUTO_INDEX_LEASE_SECONDS120How long the indexing gate stays owned once nothing is renewing it. A running index renews its own lease, so this bounds how long a *killed* process blocks indexing, not how long an index may take

    How long the indexing gate stays owned once nothing is renewing it. A running index renews its own lease, so this bounds how long a *killed* process blocks indexing, not how long an index may take

  • GRAPH_AUTO_INDEX_MODEmoderateIndex depth for automatic re-indexes: `full`, `moderate`, or `fast`. Anything else warns and falls back

    Index depth for automatic re-indexes: `full`, `moderate`, or `fast`. Anything else warns and falls back

  • GRAPH_AUTO_INDEX_PROJECT_TTL300How long the list of watched projects is trusted before it is re-read from the engine

    How long the list of watched projects is trusted before it is re-read from the engine

  • GRAPH_AUTO_INDEX_RECONCILE_SECONDS300Fallback pass that catches a missed watcher event, covers a filesystem that cannot be watched, and is the only trigger for a directory that is not a git repo. Minimum 60. Replaces the deprecated `GRAPH_AUTO_INDEX_FULL_INTERVAL`, whose value carries over automatically if this is unset. `GRAPH_AUTO_INDEX_INTERVAL` (the old fixed poll) is deprecated and no longer read for anything but a warning

    Fallback pass that catches a missed watcher event, covers a filesystem that cannot be watched, and is the only trigger for a directory that is not a git repo. Minimum 60. Replaces the deprecated `GRAPH_AUTO_INDEX_FULL_INTERVAL`, whose value carries over automatically if this is unset. `GRAPH_AUTO_INDEX_INTERVAL` (the old fixed poll) is deprecated and no longer read for anything but a warning

  • GRAPH_ENABLEDtrueKill switch for the 6 code-graph tools

    Kill switch for the 6 code-graph tools

  • HYBRID_SEARCH_TEXT_WEIGHT0.05How much the keyword score influences ranking. Set from a benchmark sweep; accuracy peaks across `0.04`-`0.08` and falls off sharply above `0.10`. At `0.0`, keyword matching narrows which memories are considered but does not reorder them.

    How much the keyword score influences ranking. Set from a benchmark sweep; accuracy peaks across `0.04`-`0.08` and falls off sharply above `0.10`. At `0.0`, keyword matching narrows which memories are considered but does not reorder them.

  • MARM_ANALYST_AUTO_APPLYunset (off)Default for the guardrails auto-apply switch: exactly `1` turns it on, anything else (including `true`) leaves every proposal pending. A choice saved in System > Controls (Automated Guardrails) wins, so a container cannot re-enable a saved off; "Use environment" returns to this variable. Even on, only mechanically provable claims are applied

    Default for the guardrails auto-apply switch: exactly `1` turns it on, anything else (including `true`) leaves every proposal pending. A choice saved in System > Controls (Automated Guardrails) wins, so a container cannot re-enable a saved off; "Use environment" returns to this variable. Even on, only mechanically provable claims are applied

  • MARM_ANALYST_PROFILEgeneralAnalyst profile: `general`, `small` or `large`. A choice saved in System > Controls wins

    Analyst profile: `general`, `small` or `large`. A choice saved in System > Controls wins

  • MARM_ANALYST_REASONING_TOKENSprofile (0/0/8192)Extra tokens per call a reasoning model may spend before answering, up to 32768. Added to the answer tokens in the requested cap

    Extra tokens per call a reasoning model may spend before answering, up to 32768. Added to the answer tokens in the requested cap

  • MARM_ANALYST_TIME_BUDGETprofile (90/60/180)Seconds an analyst answer may take, 5 to 600. No model call starts after it

    Seconds an analyst answer may take, 5 to 600. No model call starts after it

  • MARM_API_KEY*(empty)*Bearer key for network-exposed deployments

    Bearer key for network-exposed deployments

  • MARM_CODE_CONTEXT_ANSWER_TOKENS900Answer tokens per call for the `general` profile, 64 to 8192. The structured profiles are sized to their schemas

    Answer tokens per call for the `general` profile, 64 to 8192. The structured profiles are sized to their schemas

  • MARM_CODE_CONTEXT_DETAIL1Default `detail` for `marm_code_context` when a caller passes `0`. Clamped to 1-3. Raising it is the lever for a client that renders the structured parts itself; leaving it at `1` keeps the response to the markdown block, which is what most agents read

    Default `detail` for `marm_code_context` when a caller passes `0`. Clamped to 1-3. Raising it is the lever for a client that renders the structured parts itself; leaving it at `1` keeps the response to the markdown block, which is what most agents read

  • MARM_CONCEPT_DB_PATH~/.marm/index/marm_index.dbConcept graph database location

    Concept graph database location

  • MARM_DB_PATH~/.marm/marm_memory.dbMemory database location

    Memory database location

  • MARM_DISTILL_INJECTION_BYTES1536Byte budget for the nudge injected into the agent's context

    Byte budget for the nudge injected into the agent's context

  • MARM_DISTILL_MAX_NUDGES3Times a single proposal may be asked about before it is marked `nudge_exhausted` and stops being offered

    Times a single proposal may be asked about before it is marked `nudge_exhausted` and stops being offered

  • MARM_DISTILL_NUDGE1Whether MARM may attach a review request for one waiting proposal to a tool response, asking the agent to `apply` or `discard` it. Set `0` to never ask

    Whether MARM may attach a review request for one waiting proposal to a tool response, asking the agent to `apply` or `discard` it. Set `0` to never ask

  • MARM_DISTILL_NUDGE_COOLDOWN900Seconds between review requests. Server-wide, not per proposal or per session

    Seconds between review requests. Server-wide, not per proposal or per session

  • MARM_LLM_ALLOW_REMOTEunsetMust be the exact string `i-understand-this-leaves-my-machine` to permit a non-loopback endpoint. Anything else, including `1` or `true`, is refused

    Must be the exact string `i-understand-this-leaves-my-machine` to permit a non-loopback endpoint. Anything else, including `1` or `true`, is refused

  • MARM_LLM_ENABLEDunset (off)Switch optional local generation on. A choice saved from the Console overrides it in either direction. Finding a running model does not turn generation on

    Switch optional local generation on. A choice saved from the Console overrides it in either direction. Finding a running model does not turn generation on

  • MARM_LLM_MAX_RETRY_TOKENS8192Ceiling for the single wider retry issued when a model spends its whole budget without producing content (never used by the analyst, whose cap is hard)

    Ceiling for the single wider retry issued when a model spends its whole budget without producing content (never used by the analyst, whose cap is hard)

  • MARM_LLM_TIMEOUT120Seconds to wait for a completion. Generous on purpose: a shared GPU makes a slow answer normal rather than broken

    Seconds to wait for a completion. Generous on purpose: a shared GPU makes a slow answer normal rather than broken

  • MARM_LLM_URLhttp://127.0.0.1:18080Local OpenAI-compatible endpoint for optional generation. A stated address wins over discovery, so one that is dead surfaces rather than being silently replaced

    Local OpenAI-compatible endpoint for optional generation. A stated address wins over discovery, so one that is dead surfaces rather than being silently replaced

  • MARM_PROJECT*(auto-detected)*Override project/platform attribution

    Override project/platform attribution

  • MARM_RATE_LIMIT_RPM80Requests per minute per IP (presets override)

    Requests per minute per IP (presets override)

  • MARM_RECALL_REFERENCE_TIMEunsetISO 8601 instant to score recency against instead of now, so benchmark runs are reproducible

    ISO 8601 instant to score recency against instead of now, so benchmark runs are reproducible

  • RECALL_SCAN_LIMIT10000Cap on the semantic fallback scan; `recall_scan_truncated=true` in responses means it was hit

    Cap on the semantic fallback scan; `recall_scan_truncated=true` in responses means it was hit

  • SEMANTIC_SEARCH_ENABLED1Set to `0` to run without the embedding model: nothing is loaded, no embeddings are written, and recall falls back to keyword matching. Useful on low-memory hosts, or to see how recall behaves when the model is unavailable. `marm-memory doctor` reports when it is off.

    Set to `0` to run without the embedding model: nothing is loaded, no embeddings are written, and recall falls back to keyword matching. Useful on low-memory hosts, or to see how recall behaves when the model is unavailable. `marm-memory doctor` reports when it is off.

  • SERVER_HOST127.0.0.1Bind address; `0.0.0.0` exposes the server and makes `MARM_API_KEY` mandatory

    Bind address; `0.0.0.0` exposes the server and makes `MARM_API_KEY` mandatory

  • SERVER_PORT8001HTTP port

    HTTP port

  • TEMPORAL_WEIGHT0.1 / 30Strength and decay of the recency boost

    Strength and decay of the recency boost

  • WRITE_QUEUE_ENABLED1Serialize writes through one worker

    Serialize writes through one worker

marm-memory releases & version history

FAQ

Can I back up my MARM memory?

Yes. The Console's System page takes point-in-time snapshots of the memory database while the server runs. For a full filesystem copy, stop MARM first, then back up the ~/.marm/ directory which holds databases and local state.

How does recall work?

MARM uses filter→rerank hybrid recall: FTS keyword/BM25 search handles exact terms first, semantic embeddings rerank those candidates by meaning, and a conservative temporal weighting step gives newer memories a modest boost when scores are close.

What is the concept graph and how do I use it?

The concept graph turns stored memories into a queryable knowledge graph. marm_concept_build extracts typed entities and relationships from memory content, and marm_concept_recall answers direct lookups or multi-hop traversals up to depth 5. Indexing is automatic with a 30-second debounce.

Can MARM use a local model?

Yes, optionally. MARM can send distillation proposals and code context answers to a local OpenAI-compatible model server. It is off by default, each request must opt in, and endpoints are loopback-only unless deliberately overridden.

What MCP tools does MARM provide?

MARM exposes 16 MCP tools on both HTTP and STDIO: 8 core memory tools (smart recall, logging, notebook, delete, summary, compaction, distillation), 6 code-graph tools (index, lookup, context, trace, architecture, impact), and 2 concept-graph tools (build, recall).

Does Docker require an API key?

Docker HTTP mode should use MARM_API_KEY because the server listens through a container network bridge. Docker STDIO mode does not need a key because it communicates over local process stdin/stdout.

What is the difference between HTTP and STDIO transports?

HTTP is better for shared memory servers with multiple agents and requires an API key when exposed through Docker or 0.0.0.0. STDIO is simpler for private local agent connections with no network port or API key required.

Which AI platforms work with MARM MCP?

MARM has been tested with Claude Code, Codex, Antigravity, Qwen CLI, Grok Build, Hermes, VS Code, Devin, Kiro, and Cursor. Any client supporting standard MCP HTTP or STDIO transports should be able to connect.

How is MARM different from built-in AI memory?

MARM provides user-owned SQLite database storage, works across MCP-compatible clients, offers explicit hybrid recall with structured logs, enables multiple agents to share the same memory store, and treats retrieved memory as context rather than higher-priority instruction.

More in Knowledge Management

Rate this project

Click to rate — no account needed.

0 comments

Posting as guest
Loading comments…