Back to Directory/Developer Tools

io.github.Lyellr88/marm-mcp-server

Universal MCP Server with advanced AI memory capabilities and semantic search.

Developer ToolsPythonv2.60.1

License Python FastAPI Docker Pulls PyPI Downloads PyPI Version MCP Registry Updated

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

Project Status: Brief Personal Pause

I took a short personal break from active development to focus on matters outside the project. This project isn't abandoned, and I plan to return soon to keep building and refining it.

Thank you for your patience, support, and continued interest. I’ll resume work soon and share updates as progress continues.

Table of Contents

Quick Start

  1. Install and initialize with your preferred agent profiles:
pip install marm-mcp-server
marm-memory init --g-claude --g-codex --g-antigravity

Also available: --g-cursor, --g-grok, --g-hermes, --g-opencode, --g-devin, --g-cline, --g-qwen, --g-kiro and --g-zed. Run without flags to install into your current project folder instead of home

  1. Hand off to your AI companion. Tell your agent:

"Use the marm-init skill to set up MARM."

  1. Interact: Your agent will handle the entire setup (Python/Docker, HTTP/STDIO, keys, and client configs) interactively right inside your chat.

Manual setup

Prefer to wire it up yourself:

Replace "agent" with your client’s CLI command (for example, claude, agy, or qwen). For Codex, use codex mcp add marm-memory --url http://localhost:8001/mcp instead.

If you are...Start the serverConnect your MCP client
Solo developer / researchermarm-memory start"agent" mcp add --transport http marm-memory http://localhost:8001/mcp
Private local STDIO usermarm-mcp-stdio"agent" mcp add --transport stdio marm-memory-stdio marm-mcp-stdio
Multiple agents sharing memorymarm-memory start --profile swarm"agent" mcp add --transport http marm-memory http://localhost:8001/mcp
Private high-throughput swarmmarm-memory start --profile swarm-max"agent" mcp add --transport http marm-memory http://localhost:8001/mcp
Trusted private lab/servermarm-memory start --profile trusted"agent" mcp add --transport http marm-memory http://localhost:8001/mcp
  • ⚡ Fastest HTTP Startup: Run marm-memory fast-start-http to spin up the local runtime, launch the console, and open it in your browser immediately.
  • 🖥️ Web Console: Run marm-memory console to view the local UI app instantly (no Node.js required).
  • ⚙️ Lifecycle Management: Manage the background daemon using status, logs --follow, restart, and stop.
  • 💡 Quick Flags: Use --no-console or --no-browser to restrict startups. Run marm-memory --help for full command lists.

Why MARM Memory

Your AI forgets everything. MARM Memory doesn't.

marm-memory gives your agents a private, shared memory for the context that normally gets lost between chats: decisions, research, fixes, notes, and project history. Switch from Claude Code to Codex or Gemini without losing the context already gathered.

It brings three things together:

  • 🧠 Core Memory (8 tools) stores conversations, notes, notebook entries, and summaries so they stay searchable.
  • 💻 Code Graph (6 tools) maps your repository so agents can find symbols, follow code paths, and understand the project without rereading it all. Point it at a repo once and it keeps itself current as you work.
  • 🧩 Concept Graph (2 tools) connects people, decisions, errors, and ideas from your stored memories, with links back to relevant code when available. It builds itself as you store memories.

All 16 tools work over HTTP and STDIO. Your agents share the same local memory across sessions instead of starting from scratch each time. The bundled Console App provides a local control plane for memory, graphs, code context, distillation, runtime controls, and the integrated terminal. Indexing a repository creates its independent Code Graph, which you can explore from Knowledge Graph → Code Explorer even before storing any memories.

How It Works

LayerWhat it doesWhy it matters
Memory modelSessions, structured logs, notebooks, summaries, and semantic memoriesKeeps project history searchable instead of trapped in one chat
Scale layerSQLite WAL mode, connection pooling, serialized write queue, and HTTP rate-limit presetsLets one server support solo use, multi-agent work, and swarm-style bursts
Intelligence layerFTS filter, semantic re-rank, bounded semantic fallback, auto-classification, write-time consolidation, and compaction candidatesKeeps recall useful as memory grows instead of letting duplicates pile up
Code graph layerRepo indexing, symbol lookup, call tracing, architecture overview, and change-impact analysisGives agents project structure without rereading the whole codebase
Concept graph layerEntity and relationship extraction from stored memories, with links back into the code graphConnects decisions, errors, tools, and people across sessions instead of leaving them as flat text
Token layerLightweight 8-tool core surface (16 total with bundled graph tools), semantic re-rank before retrieval, and write-time deduplicationReduces tokens sent to the model on every recall and cost stays predictable as memory scales
Deployment layerPip, Docker, STDIO, HTTP, and managed swarm, swarm-max, and trusted profilesLets 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.

MARM Console: Your Local Control Plane

Run marm-memory console to open the bundled web app at http://127.0.0.1:8002. It ships with MARM, needs no Node.js installation, stays on your machine, and works with the same local stores and MCP runtime your agents use.

WorkspaceWhat it gives you
Memories and Knowledge GraphBrowse, filter, edit, and clean up memory, logs, notebooks, extracted concepts, duplicates, concept builds, and code links.
Indexed Projects and Project ExplorerIndex local repositories, inspect architecture, impact, coverage, decisions, runtime traces, symbol search, and code-graph topology.
Code ContextBuild one bounded view of task-ranked symbols, source, and related memory. An optional local model can answer from that same context, with its citations checked.
DistillTurn transcripts into durable-memory proposals. Review, apply, or discard them with duplicate evidence visible.
System and TerminalManage runtime health, indexing, local-model settings, backups, diagnostics, and maintenance. The docked terminal provides a real local shell with persistent sessions and a searchable MARM command menu.
ConnectionsSet up MARM end to end in one place. Setup connects Claude Code, Claude Desktop, Cursor, VS Code, Codex CLI, Grok Build, Hermes Agent, OpenCode, Cline, Antigravity, Qwen Code, Devin, Kiro, and Zed over HTTP, STDIO, or Docker STDIO, tests each connection, and saves server settings to ~/.marm/settings.json. Docker pulls, starts, and stops the MARM container and writes a compose file. Manual gives copy-ready config for each client and OS, every CLI command, and every HTTP endpoint.

Runtime CLI Commands

marm-memory is the local runtime manager installed with the Python package. These are the normal operational commands; use marm-memory <command> --help for flags and command-specific examples.

Daily runtime work

marm-memory fast-start-http                # start HTTP, Console, and open the browser
marm-memory fast-start-http --client cursor # also connect one client (add --transport stdio for STDIO)
marm-memory start                          # start or reuse the managed HTTP runtime
marm-memory start --profile swarm          # shared multi-agent preset
marm-memory stop                           # stop the managed runtime safely
marm-memory restart                        # restart the managed runtime
marm-memory status                         # inspect runtime, database, queue, and graph status
marm-memory logs --follow                  # follow bounded runtime logs
marm-memory console                        # start or reuse the bundled local Console

Transports and setup

marm-memory http                           # run HTTP in the foreground
marm-memory stdio                          # run the strict local MCP STDIO transport
marm-memory init                           # install the MARM skill into detected agents (project scan)
marm-memory init --g-claude                # install the skill into the home-folder claude directory
marm-memory doctor                         # diagnose the local install
marm-memory key init                       # create or reuse ~/.marm/.env without displaying the key
marm-memory key path                       # print the managed key-file path
marm-memory key reveal                     # explicitly display the managed key
marm-memory console --import-key           # open an authenticated local Console session
marm-memory upgrade --check                # compare the installed package with PyPI
marm-memory uninstall                      # preview package removal; always preserves ~/.marm

Knowledge, projects, and maintenance

marm-memory knowledge status               # Indexers, models, and how far behind automatic indexing is
marm-memory knowledge build --all          # Rebuild the whole concept graph (new memories index themselves)
marm-memory knowledge auto off             # Stop indexing memories automatically (on, off, status)
marm-memory projects list                  # List all tracked workspaces
marm-memory projects index <path>          # Add a repo to the code graph (kept current after that)
marm-memory projects status                # Inspect target repo graph readiness
marm-memory projects auto off              # Stop re-indexing repos automatically (on, off, status)
marm-memory maintenance status             # Check internal database optimization state
marm-memory maintenance embeddings migrate # Upgrade old 384-dim vectors to 512-dim
marm-memory maintenance chunks rechunk     # Recalibrate long memory text splits

Docker commands are documented separately below because they require explicit data mounts, network exposure, and key-handling choices.

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. Every timed path calls the shipped MARMMemory code, not a benchmark-local reimplementation. Sections 1-4 are timings from a single run of scripts/benchmarking/performance/bench_hotpath.py on local hardware; absolute milliseconds vary by machine, so treat the scaling shape as the signal. Section 5 is a separate accuracy benchmark (run_eval.py) measuring retrieval rather than speed, and its latest row is a controlled before and after, explained there.

1. Retrieval Latency Scaling

End-to-end recall_similar latency (includes query encoding).

Session Size ($N$)Min LatencyMedian Latencyp95 Latency
N = 1007.4 ms7.9 ms9.4 ms
N = 25011.9 ms13.5 ms15.4 ms
N = 50010.9 ms11.8 ms13.4 ms
N = 1,00013.3 ms13.5 ms15.6 ms
N = 2,00017.5 ms18.2 ms19.6 ms
N = 4,00023.8 ms25.9 ms30.9 ms

Run-to-run variance at small $N$ is larger than the gap between adjacent sizes, which is why N = 250 reads slower than N = 500 here. Treat the trend from N = 1,000 upward as the real signal.

2. Encoder + Concurrency

  • Cold model load: 893ms
  • Warm encode: median 3.8ms, p95 4.3ms
  • Concurrent recall: 10 gathered recalls completed in 151.5ms vs 176.0ms serial (gather/serial = 0.86). Do not read that as parallelism: repeated runs of this same benchmark land anywhere from 0.63 to 0.86, so the ratio is not stable enough to claim a speedup. The path is serialized around shared encoder and SQLite work by design, and any apparent gain is measurement noise.

3. Write-Time Ingestion Cost

  • Consolidation off: median 6.5ms, p95 7.6ms
  • Consolidation on: median 58.1ms, p95 106.5ms
  • Tradeoff: write-time dedupe/clustering adds 9.0x median cost so recall stays fast and the store stays cleaner over time. Consolidation is off by default.

4. Recall Scaling: Full Scan vs Production Hybrid

Why recall stays flat as memory grows: Instead of scanning every vector, production recall uses an FTS keyword pre-filter to narrow the candidate pool, then re-ranks using a blended semantic + BM25 + temporal score. Both benchmark columns represent authentic asynchronous code paths timed with precomputed vectors to isolate retrieval speed from raw encoding overhead. Tests alternate execution to ensure completely unbiased cache conditions.

Session Size ($N$)Full Semantic ScanProduction HybridSpeedupFTS candidates
N = 1003.3 ms6.6 ms0.5x85 / 200
N = 50016.3 ms11.6 ms1.4x200 / 200
N = 1,00031.1 ms14.7 ms2.1x200 / 200
N = 2,00063.5 ms19.0 ms3.3x200 / 200
N = 4,000127.2 ms29.1 ms4.4x200 / 200
N = 10,000316.7 ms53.8 ms5.9x200 / 200

The full scan grows roughly linearly with $N$ while hybrid recall grows far more slowly, so the advantage still widens with session size. At very small $N$ the pre-filter is not worth its overhead and hybrid is slower.

5. LoCoMo Retrieval Accuracy

All 10 LoCoMo conversations are ingested through marm_log_entry (5,882 memories), then top-5 marm_smart_recall results are scored against 1,977 evidence-annotated questions. No answer-generation model or LLM judge is involved, so this measures whether the right memory is retrieved, not whether an agent answers correctly with it.

ConfigurationAny evidence hitAll evidence hitMean evidence recall
MiniLM baseline37.5%29.5%not published
Jina v2 Small (v2.29.0)53.0%43.4%47.6%
v2.33.1 through v2.44.362.9 - 63.5%53.1 - 53.5%57.4 - 57.9%
v2.44.4 (log lane fix)69.1 - 69.6%58.2 - 58.6%63.0 - 63.5%

The last row is a controlled comparison, same build and data with the log lane as the only variable. That lane previously substring-matched the whole query against log topics and summaries, so a natural-language question never matched and it scored 0.0% on all 1,977 questions. It now tokenizes the query and reaches 53.3% on its own. Ranges rather than single figures because the semantic lane varies about half a point between runs, so a sub-point difference is not a result.

Multi-hop remains the weakest category at 44.9%, and single-hop evidence recall is 36.6% against a 66.2% any-hit rate, so the lane often surfaces some of a question's evidence rather than all of it. Reproduce with run_eval.py. It also reports MRR and nDCG@k for the ranked semantic lane; set MARM_RECALL_REFERENCE_TIME on the server so two runs rank near-ties identically.

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:

MARMMem0Letta (MemGPT)Zep / Graphitiagentmemory
TypeMemory engine, MCP-nativeMemory layer APIFull agent runtimeTemporal knowledge graphMemory engine, MCP-native
Required infrastructureNo separate data service (embedded SQLite)Vector DB (Qdrant/pgvector)Postgres + vector DBNeo4jSeparate iii-engine runtime
DeploymentLocal-first by default; Docker for shared/remoteCloud API or self-hostedSelf-hosted or cloudCloud or self-hostedLocal-first
Retrieval modelHybrid: FTS5 BM25 exact lane + semantic rerankVector + graph + key-valueVector archival store + agent-managed core memoryTemporal knowledge graph (fact validity windows)BM25 + vector + graph (RRF fusion)
Write captureExplicit tool calls from the connected agentExplicit add() calls (some integrations auto-extract)Agent self-edits its own memoryExplicit API callsHook-based, automatic (no explicit calls needed)
Code structure awarenessBundled code graph + concept graph, fused with memoryNot built inNot built inNot built inNot built in (pairs with a separate project)
Framework lock-inNone (any MCP client)NoneHigh (must run within Letta)NoneNone (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.

MCP Client Setup for 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 marm-memory start --profile swarm (200 RPM) or --profile swarm-max (600 RPM). --profile 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.

Local pip HTTP

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

pip install marm-mcp-server
marm-memory start
# 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.

Local pip STDIO
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 Antigravity. STDIO stays a single local process with no port and no API key, and exposes the same 16 tools as HTTP.

Local Python swarm modes (HTTP & STDIO)

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
marm-memory start --profile swarm

# HTTP shared server, heavier private swarm
marm-memory start --profile swarm-max

# HTTP trusted private lab/server, rate limiting disabled
marm-memory start --profile trusted

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

Docker HTTP (key required)

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.

If you installed MARM through pip, the product CLI can safely preview or run the same setup. It uses a loopback port by default, preserves ~/.marm, stores the generated key in ~/.marm/.env rather than shell history, and refuses to replace an existing container.

marm-memory docker command                 # preview the exact HTTP command
marm-memory docker run                     # create the managed HTTP container
marm-memory docker stdio-command           # print a Docker STDIO client command
marm-memory docker status
marm-memory docker logs --follow
marm-memory docker stop

# Optional: mount repositories read-only for code indexing.
marm-memory docker run --repo /absolute/path/to/repository

# Optional: preview or explicitly write a Compose configuration.
marm-memory docker compose
marm-memory docker compose --yes

The HTTP run, command, and compose commands accept the same operational flags:

FlagPurpose
--data-dir <absolute path>Persistent host directory mounted at /home/marm/.marm. Defaults to ~/.marm; this holds memory, indexes, logs, and the managed key file.
--env-file <path>Explicit Docker env file. It must already contain MARM_API_KEY; without this flag, MARM uses ~/.marm/.env and creates a key there only when docker run or docker compose --yes needs one.
--port <number>Host HTTP port. Default: 8001.
--expose-networkBind the host port to 0.0.0.0 instead of loopback. This is deliberate network exposure; configure a firewall and TLS proxy.
--profile standard|swarm|swarm-max|trustedSelect the same write-queue and rate-limit preset as native HTTP startup.
--rate-limit-rpm <number>Override the selected profile's HTTP rate limit. 0 disables rate limiting.
--repo <absolute path>Repeatable read-only repository mount for code indexing. MARM reports each corresponding /workspace/repo-N path to index inside the container.
--tag <tag>Official image tag. Default: latest.
--pullPull the selected image before creating a new HTTP container.
--name <name>Managed container name. MARM refuses to replace an existing container with that name.
--memory <limit> / --cpus <limit>Optional Docker resource limits.
--dry-rundocker run only: print the planned command without creating a container or key file. docker command is always a preview.

For example:

# Shared local server with a custom data path and two repositories for indexing.
marm-memory docker command \
  --profile swarm \
  --data-dir /srv/marm-data \
  --repo /srv/projects/api \
  --repo /srv/projects/web

# Execute the reviewed command, pulling the image first.
marm-memory docker run --profile swarm --data-dir /srv/marm-data --pull

Docker STDIO is separate from Docker HTTP: marm-memory docker stdio-command uses docker run -i --rm, has no port and no bearer key, but still mounts the data directory so SQLite memory persists after the short-lived container exits. Use --data-dir and --tag with that command when needed. There are no separate docker key or docker mount commands; --env-file and --data-dir make those choices explicit in the generated HTTP command.

marm-memory docker pull only downloads an image. marm-memory docker maintenance embeddings migrate runs against the same data mount and refuses while the managed HTTP container is running. The helper is available only with the pip-installed marm-memory command; Docker-only users can use the raw commands below.

# 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.

Docker HTTP swarm mode
# --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 indexing: mount the repo

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 (no HTTP key)

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

Support notes
  • 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 Code
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.

VS Code / GitHub Copilot Agent

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.

Cursor

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.

The Cursor CLI (agent) reads the same mcp.json files, so a server added for the editor is already available there. Run agent mcp list to check. A server in the global ~/.cursor/mcp.json loads without approval. A server in a project's .cursor/mcp.json asks you to trust the folder and approve it on first use, and headless runs need --trust --approve-mcps. If it lists no servers, look in mcp.json for an entry with an unknown type such as streamable-http: the CLI drops the whole file when one entry fails to parse. Install it with curl https://cursor.com/install -fsS | bash on macOS, Linux and WSL, or irm 'https://cursor.com/install?win32=true' | iex in Windows PowerShell.

Codex CLI

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"
Grok Build

Grok Build (grok), xAI's terminal coding agent, supports STDIO and HTTP MCP servers and reads ~/.grok/config.toml. MARM sets bearer_token_env_var, so the key stays in your environment and never lands in the file.

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

Docker or SERVER_HOST=0.0.0.0 (key required): set MARM_API_KEY, then add this to ~/.grok/config.toml (or .grok/config.toml for one project):

[mcp_servers.marm-memory]
url = "http://localhost:8001/mcp"
bearer_token_env_var = "MARM_API_KEY"

Grok Build also reads MCP servers from ~/.claude.json, .cursor/mcp.json, and project .mcp.json, so MARM may already load if Claude Code or Cursor has it. Run grok mcp list to see what it loaded.

Hermes Agent

Hermes Agent (hermes) by Nous Research reads MCP servers from mcp_servers in config.yaml: ~/.hermes/config.yaml on macOS and Linux, %LOCALAPPDATA%\hermes\config.yaml on native Windows, or $HERMES_HOME/config.yaml if you set it. It supports STDIO and HTTP and expands ${VAR} in headers, so the key stays in your environment or ~/.hermes/.env and never lands in the file.

# STDIO - no key needed
hermes mcp add marm-memory --command marm-mcp-stdio

# HTTP, direct Python install - no key needed
hermes mcp add marm-memory --url http://localhost:8001/mcp

Docker or SERVER_HOST=0.0.0.0 (key required): set MARM_API_KEY, then add this under mcp_servers in config.yaml:

mcp_servers:
  marm-memory:
    url: "http://localhost:8001/mcp"
    headers:
      Authorization: "Bearer ${MARM_API_KEY}"

Run /reload-mcp in Hermes, or start a new session, to load it.

OpenCode

OpenCode (opencode, installed with npm install -g opencode-ai) reads MCP servers from mcp in opencode.json or opencode.jsonc: ~/.config/opencode/ on every platform including Windows (%USERPROFILE%\.config\opencode), or $XDG_CONFIG_HOME/opencode/ if you set it, and opencode.json in a project root for one project. It supports STDIO (type: local) and HTTP (type: remote) and expands {env:VAR} in headers, so the key stays in your environment and never lands in the file. Remote servers try OAuth by default, so MARM writes oauth: false. OpenCode 2 nests servers under mcp.servers and still reads the layout below, and MARM writes into whichever layout the file already uses. Connecting from the Console rewrites the file as plain JSON, so comments in a .jsonc file are not kept, and the original is saved beside it as .marm-backup. Start a new OpenCode session to load it, and run opencode mcp list to check.

STDIO, no key needed:

{
  "mcp": {
    "marm-memory": {
      "type": "local",
      "command": ["marm-mcp-stdio"]
    }
  }
}

HTTP, direct Python install (no key needed):

{
  "mcp": {
    "marm-memory": {
      "type": "remote",
      "url": "http://localhost:8001/mcp",
      "oauth": false
    }
  }
}

Docker or SERVER_HOST=0.0.0.0 (key required): set MARM_API_KEY, then add the same HTTP entry with a header:

{
  "mcp": {
    "marm-memory": {
      "type": "remote",
      "url": "http://localhost:8001/mcp",
      "oauth": false,
      "headers": {
        "Authorization": "Bearer {env:MARM_API_KEY}"
      }
    }
  }
}
Devin

Devin CLI (devin) and the Devin Local agent in Devin Desktop, the IDE formerly called Windsurf, read MCP servers from the same mcp_config.json: ~/.config/devin/mcp_config.json on macOS and Linux (or $XDG_CONFIG_HOME/devin/mcp_config.json if you set it), %APPDATA%\devin\mcp_config.json on Windows. Connecting once covers both. The older Cascade agent in Devin Desktop keeps its MCP servers in its own file under ~/.codeium, which MARM does not write. Devin CLI v3000.3 or later reads this dedicated file, and older builds keep mcpServers in config.json and migrate it on startup. devin mcp add saves to a gitignored project file unless you pass -s user.

# STDIO - no key needed
devin mcp add -s user marm-memory -- marm-mcp-stdio

# HTTP, direct Python install - no key needed
devin mcp add -s user marm-memory http://localhost:8001/mcp

Docker or SERVER_HOST=0.0.0.0 (key required): MARM has not confirmed that Devin expands environment variables in headers, so use STDIO, or add the key by hand under mcpServers in that file:

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

Zed reads MCP servers from context_servers in its user settings.json: ~/.config/zed/settings.json on macOS and Linux (or $XDG_CONFIG_HOME/zed/settings.json on Linux), %APPDATA%\Zed\settings.json on Windows. Run zed: open settings file from the command palette to open it. Zed has no add command, and MARM has not confirmed that Zed expands environment variables in headers, so keyed setups use STDIO. Connecting from the Console edits only the marm-memory entry as text, so comments and the rest of your settings stay as they were, and it restores the file if anything else changed. Zed lists the server under Settings, AI, MCP Servers, with a green dot when it is running. Zed's own agent reads the MARM skill from ~/.agents/skills once you install it from the Console.

STDIO, no key needed:

{
  "context_servers": {
    "marm-memory": {
      "command": "marm-mcp-stdio",
      "args": []
    }
  }
}

HTTP, direct Python install (no key needed):

{
  "context_servers": {
    "marm-memory": {
      "url": "http://localhost:8001/mcp"
    }
  }
}

Docker or SERVER_HOST=0.0.0.0 (key required): use STDIO, or paste the key into the entry by hand. Zed keeps it as plain text in settings.json:

{
  "context_servers": {
    "marm-memory": {
      "url": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer your-generated-key"
      }
    }
  }
}
Cline CLI

Cline CLI (cline, installed with npm install -g cline) reads MCP servers from ~/.cline/data/settings/cline_mcp_settings.json, the same file the Cline extensions in VS Code and JetBrains use (%USERPROFILE%\.cline on Windows, or $CLINE_DATA_DIR/settings if you set it). Cline's own MCP page still says ~/.cline/mcp.json, but the CLI never reads that file. HTTP entries need "type": "streamableHttp": leaving type out selects the legacy SSE transport. The extensions in VS Code and JetBrains show the server in their MCP Servers panel. Cline 4.x or later shares this file and moves an older file from VS Code's extension storage into it on first launch. Older builds keep reading their own file, so upgrade Cline first.

# STDIO - no key needed
cline mcp install marm-memory --yes -- marm-mcp-stdio

# HTTP, direct Python install - no key needed
cline mcp install marm-memory --yes --transport http http://localhost:8001/mcp

Docker or SERVER_HOST=0.0.0.0 (key required): MARM has not confirmed that Cline CLI expands environment variables in headers, so use STDIO, or add the key by hand under mcpServers in that file:

{
  "mcpServers": {
    "marm-memory": {
      "type": "streamableHttp",
      "url": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer your-generated-key"
      }
    }
  }
}
Antigravity CLI

Antigravity CLI (agy) replaced Gemini CLI in June 2026. It supports STDIO and HTTP MCP servers. Use HTTP for MARM. The Antigravity IDE and 2.0 app read this same file (in the IDE, open "..." then MCP Servers, then Manage MCP Servers). Antigravity 2.x or later reads it. Older IDE builds used ~/.gemini/antigravity/mcp_config.json, and MARM writes that file only when it is the only one present.

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

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

Equivalent ~/.gemini/config/mcp_config.json (user scope) or project .agents/mcp_config.json. Antigravity reads serverUrl, not url or httpUrl, and does not expand ${VAR} in this file, so paste the real key:

{
  "mcpServers": {
    "marm-memory": {
      "serverUrl": "http://localhost:8001/mcp",
      "headers": {
        "Authorization": "Bearer your-generated-key"
      }
    }
  }
}
Qwen Code
# 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"
      }
    }
  }
}
Grok app and API

The Grok app (grok.com, iOS, Android) supports custom MCP servers: open grok.com/connectors, click New Connector, choose Custom, and enter your MARM URL. The xAI API supports Remote MCP Tools over Streamable HTTP or SSE only.

Both run on xAI's infrastructure, so localhost will not work. Expose MARM behind HTTPS (a tunnel or your own domain) and set MARM_API_KEY. MARM has not been tested through the app's connector form. For the API, send this tool payload:

{
  "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 · macOS · 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.

System requirements, data location & backup

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
  • Knows which memories go unused: each memory records how often recall returned it and when, and the Console lists cold memories (GET /api/memories/cold?days=30) so old, never-recalled entries can be reviewed. Counting never slows or fails a recall and does not change ranking
  • Credentials are redacted before storage: API keys, tokens, private keys and NAME=value secrets (a metadata field is read with its name, and a quoted value may hold spaces) in anything written to memory, the log, the notebook, or a review queue, and in every prompt sent to a local model, are replaced with [redacted:<kind>]; names and templates stay. A write that redacted something says so in its response as redacted: {count, kinds}, never the values. An identifier holding a credential (a session, project or platform name, a Session: marker, a notebook entry name) is refused rather than redacted, because a renamed identifier could not be looked up again. This is high-precision protection for common credential formats, not a guarantee that every secret is caught, and it applies to new writes only: existing data is not scanned or rewritten

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.

Complete MCP Tool Suite (16 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 (8 tools)

ToolWhat it doesKey parameters
marm_smart_recallHybrid memory recall with an additive, bounded concept/code graph sidecar when a compatible graph existsquery, limit, session_name, search_all, detail=1/2/3, project, platform, exact_mode
marm_log_entryAdd structured session log entries; each entry is also embedded into semantic memory so marm_smart_recall can find itentry, session_name, project (optional; defaults to the server's detected project)
marm_log_showDisplay all entries and sessions, with filteringsession_name
marm_deleteDelete a log session, log entry, or notebook entrytype, target, session_name, project, platform
marm_summaryCached, paste-ready session summaries with intelligent truncationsession_name
marm_notebookSession-scoped scratch pad plus promotion to a permanent, graph-linked docaction="add"|"use"|"show"|"status"|"clear"|"save", name, data, session_name, project, platform
marm_compactionAgent-assisted memory cleanup with a reviewable audit trailaction="status"|"candidates"|"review"|"stage"|"apply"|"discard"
marm_distillTurn raw conversation into memory proposals, each resolved against the store as new, duplicate, or near. Selects sentences verbatim by default; with use_llm=true and local generation enabled, writes self-contained facts with a local model instead, keeping the verbatim span each came from. Staged for review; applied unattended only under review_mode="guardrails" with the operator's auto-apply switch on, and then only proposals that pass every deterministic checkaction="propose"|"review"|"apply"|"discard", text, session_name, proposal_id, use_llm, review_mode (manual|guardrails)

🕸️ Code Graph (6 tools)

ToolWhat it doesKey parameters
marm_graph_indexIndex a repo into the code-structure graph, check status, list projects, or turn automatic re-indexing on and offrepo_path, project, action
marm_code_lookupFind symbols, text patterns, or a symbol's source; use instead of grep/globkind="auto"|"symbol"|"text"|"snippet"
marm_code_contextComposed context for a task in one call: symbols ranked by personalised PageRank, their source read from disk, and what memory records about themtask, project, cwd, budget, detail (0-3; 0 uses MARM_CODE_CONTEXT_DETAIL, the server default), include_graph (default false)

Installation

Source-derived launch command. Check the maintainer’s required arguments and credentials before running:

bash
uvx marm-mcp-server

Set up in your AI client

Merge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.

json
{
  "mcpServers": {
    "io-github-lyellr88-marm-mcp-server": {
      "command": "uvx",
      "args": [
        "marm-mcp-server"
      ]
    }
  }
}

Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.

Claude Desktop setup reference

Package

marm-mcp-serverpypi

Compatible MCP Clients

io.github.Lyellr88/marm-mcp-server works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.

  • Claude Desktop~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.
  • Cursor~/.cursor/mcp.jsonRestart Cursor for changes to take effect.
  • VS Code.vscode/mcp.jsonReload VS Code window for changes to take effect.
  • Windsurf~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect.
  • Claude Code.mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.

Learn More