Skip to main content
Glama
marc-shade

Enhanced Memory MCP Server

by marc-shade

Erweiterter Memory MCP Server

MCP Python 3.11+ License Tools

Persistenter, durchsuchbarer Speicher für KI-Agenten über das Model Context Protocol. Entitäten und ihre Beobachtungen leben in einer komprimierten SQLite-Datenbank mit Prüfsummen und Versionsverlauf; ein gestufter Speicher und eine Multi-Strategie-Abrufpipeline sitzen oben drauf; und das Ganze wird Ihrem Client als MCP-Tools zur Verfügung gestellt.

Wie viele Tools es sind, hängt davon ab, was Sie installiert haben, und der Unterschied ist kein Fehler: Ein Tool, dessen Backend fehlt, wird gar nicht erst registriert. Eine Kerninstallation (requirements.txt) registriert 186; das Hinzufügen der optionalen Backends (requirements-optional.txt) bringt es auf 204. Wenn Sie nach einem einfachen pip install -r requirements.txt 186 gezählt haben, ist nichts kaputt.

Beide Zahlen wurden mit Python 3.11.11 über tools/list über stdio gemessen, wobei AGENTIC_SYSTEM_PATH nicht gesetzt war. Diese letzte Bedingung ist keine Pedanterie. Wenn diese Variable auf das separate System verweist, das unter GraphRAG beschrieben wird, registrieren sich sieben weitere Tools und Sie erhalten stattdessen 193 und 211. Frühere Entwürfe dieser Datei sagten 188 und 206, weil sie auf Maschinen gemessen wurden, die es exportiert hatten, und zwei von uns reproduzierten dieselbe falsche Zahl, ohne zu bemerken, dass wir die Ursache teilten. Setzen Sie sie zurück, bevor Sie erneut messen.

Alles Kern läuft lokal ohne API-Schlüssel und ohne Netzwerk. Der optionale Vektor-Stack (Qdrant plus ollama) verbessert den Abruf von Schlüsselwortübereinstimmung zu bedeutungsbasiert, und sein Fehlen verschlechtert sich elegant, anstatt zu brechen.

Das Wichtigste zuerst

Dies sind zwei Prozesse, nicht einer. Fast jede Support-Anfrage zu diesem Projekt kommt daher, dass nur die Hälfte davon ausgeführt wird.

   your MCP client  (Claude Code, Claude Desktop, an SDK, curl)
            |
            |   stdio JSON-RPC, one server process per client session
            v
   +-------------------------------------------------------+
   |  MCP server            server.py                       |
   |  start with            setup/bin/mcp-server.sh          |
   +-------------------------------------------------------+
            |
            |   JSON over a Unix socket: $MEMORY_DB_SOCKET_PATH
            |   (default /tmp/memory-db.sock)
            v
   +-------------------------------------------------------+
   |  memory-db daemon      memory_db_service.py            |
   |  start with            setup/bin/memory-db-daemon.sh    |
   |  REQUIRED. Owns the database file exclusively so that   |
   |  several clients can share it without corrupting it.    |
   +-------------------------------------------------------+
            |
            v
     memory.db   (SQLite, default ~/.claude/enhanced_memories/)


   optional, off to the side:
     Qdrant  http://localhost:6333    vector index for semantic recall
     ollama  http://127.0.0.1:11434   local embeddings that feed that index

Der Daemon ist nicht optional und wird nicht vom MCP-Server für Sie gestartet. Ohne ihn startet der Server trotzdem, antwortet trotzdem und gibt Objekte wie diese zurück:

{"query": "anything", "count": 0, "results": [],
 "error": "Memory-DB service error: [Errno 2] No such file or directory"}

{"error": "Memory-DB service error: ...", "entities": {"total": 0},
 "compression": {"ratio": "N/A"}}

Wohlgeformt, parsbar und leer. Ein Agent, der das liest, schließt daraus, dass Ihr Speicher leer ist, nicht taub. ./healthcheck.sh existiert, um die beiden zu unterscheiden.

Related MCP server: Strata Memory MCP Server

Voraussetzungen

  • Python 3.11 oder neuer. Auf manchen macOS-Maschinen ist ein bloßes python3 noch 3.9, daher sucht der Installer zuerst nach versionierten Namen.

  • git und Speicherplatz für die virtuelle Umgebung. Gemessen auf macOS arm64 mit Python 3.11: 83 MB für eine Kerninstallation, 964 MB mit den optionalen Backends, da diese sentence-transformers und torch nach sich ziehen. Auf Linux x86_64 beträgt die Kernzahl 131 MB (gemessen in einem python:3.11-slim-Container) — die Räder unterscheiden sich je nach Plattform, also erwarten Sie, dass die Zahl mit Ihrer variiert. Der Checkout selbst ist 5 MB.

  • Optional: podman oder docker, wenn Sie den Container-Pfad oder ein lokales Qdrant möchten.

  • Optional: ollama für lokale Embeddings.

Zu keinem Zeitpunkt ist sudo erforderlich. Es wird nichts systemweit installiert.

Läuft bereits ein Enhanced-Memory-System?

Lesen Sie dies vor Schritt 2 unten, wenn diese Maschine möglicherweise bereits eines hat: einen älteren Checkout, einen zweiten Klon, einen vor Monaten installierten Dienst. Standardmäßig möchte jede Installation dieselben zwei Dinge — den Socket /tmp/memory-db.sock und die Datenbank ~/.claude/enhanced_memories/memory.db — und sie können nicht gemeinsam genutzt werden.

Überprüfen Sie zuerst:

lsof /tmp/memory-db.sock        # macOS or Linux
ss -xl | grep memory-db.sock    # Linux
pgrep -af memory_db_service.py

Alles Aufgelistete bedeutet, dass eine Installation aktiv ist. Das Starten eines zweiten Daemons auf einem belegten Socket wird abgelehnt: Er beendet sich mit einem Nicht-Null-Exitcode und gibt den Socket-Pfad und die Datenbank aus, die der antwortende Daemon verwendet, anstatt den Socket zu übernehmen. Das ist eine Absicherung, keine Koexistenz — der zweite Daemon läuft überhaupt nicht.

Um zwei Installationen nebeneinander zu betreiben, geben Sie dieser in .env alles Eigene:

ENHANCED_MEMORY_DIR=/home/you/.enhanced-memory-second
MEMORY_DB_SOCKET_PATH=/tmp/memory-db-second.sock
# Only if you want the Neural Memory Fabric somewhere else again; by default it
# follows ENHANCED_MEMORY_DIR:
# NMF_SQLITE_PATH=/home/you/.enhanced-memory-second/nmf.db
# NMF_FILES_ROOT=/home/you/.enhanced-memory-second/nmf_files

ENHANCED_MEMORY_DIR ist das, was vergessen wird. Zwei Daemons auf zwei Sockets, die eine memory.db teilen, ist keine Koexistenz: Es sind zwei exklusive Besitzer einer Datei, was genau das ist, was der Daemon verhindern soll.

Schnellstart

git clone <this-repo> enhanced-memory-mcp
cd enhanced-memory-mcp

# 1. venv, dependencies, .env, database directory. Idempotent, re-runnable.
setup/setup.sh

# 2. start the daemon (foreground). Leave it running, or install it as a
#    background service: setup/service/install-services.sh
setup/bin/memory-db-daemon.sh &

# 3. prove the install works before you trust it
./healthcheck.sh

Ein gesunder Durchlauf endet mit Required checks passed. und Exit-Code 0. Alles andere ist ein echtes Problem: siehe Fehlerbehebung.

Einstellungen leben in .env, das Schritt 1 aus .env.example nur erstellt, wenn .env fehlt. Das Bearbeiten dieser Datei ist die Art und Weise, wie eine Einstellung bestehen bleibt; ein erneutes Ausführen von setup/setup.sh überschreibt sie nie.

Dann registrieren Sie den Server bei Ihrem MCP-Client. In ~/.claude.json:

{
  "mcpServers": {
    "enhanced-memory": {
      "command": "/absolute/path/to/enhanced-memory-mcp/setup/bin/mcp-server.sh"
    }
  }
}

Weisen Sie den Client auf den Launcher, nicht auf python server.py. Der Launcher wendet das .env dieses Checkouts an, was garantiert, dass der MCP-Server und der Daemon dieselbe Datenbankdatei auflösen. Ein Client, der python direkt ausführt, erbt nur die Umgebung, die dieser Client zufällig hatte, und die beiden Prozesse driften stillschweigend auseinander. Siehe die Split-Brain-Falle.

An diesem Punkt ist die Installation abgeschlossen und die Tools funktionieren, wenn sie aufgerufen werden. Nichts ruft sie von selbst auf: Jede Sitzung startet kalt, und nichts wird zurückgeschrieben, es sei denn, der Agent entscheidet sich dafür. Das ist kein Fehler und keine Prüfung meldet es, daher ist es leicht, eine funktionierende Installation mit einem funktionierenden Speicher zu verwechseln. docs/AUTOMATION.md behandelt das Schließen dieser Lücke, beginnend mit einem Recall-Hook, der bei jeder Eingabeaufforderung ausgeführt wird.

Die Alternative: ein gemeinsamer HTTP-Server

stdio erzeugt einen Serverprozess pro Client-Sitzung, was Desktop-Clients erwarten. Wenn Sie lieber einen einzelnen gemeinsamen Server über HTTP betreiben möchten, verwenden Sie den SSE-Transport:

MCP_TRANSPORT=sse setup/bin/mcp-server.sh     # or setup/bin/mcp-server-sse.sh
{
  "mcpServers": {
    "enhanced-memory": { "type": "sse", "url": "http://127.0.0.1:9106/sse" }
  }
}

Auf diesem Port gibt es keine Authentifizierung. Behalten Sie MCP_HOST bei 127.0.0.1.

Konfiguration

Konfiguration erfolgt über Umgebungsvariablen. setup/setup.sh schreibt eine .env aus .env.example, die jede Einstellung inline dokumentiert. Das Bearbeiten von .env ist der persistente Mechanismus: Das Kopieren erfolgt nur, wenn .env nicht existiert, sodass Ihre Änderungen jede erneute Ausführung des Installers überleben (und aus demselben Grund treffen die Standardwerte einer neuen Version nicht von selbst ein — vergleichen Sie die beiden Dateien nach einem Upgrade). Eine bereits in Ihrer Umgebung gesetzte Variable überschreibt die Datei für diesen einen Aufruf:

MEMORY_DB_SOCKET_PATH=/tmp/other.sock ./healthcheck.sh

Variable

Standardwert

Zweck

ENHANCED_MEMORY_DIR

~/.claude/enhanced_memories

Verzeichnis, das memory.db enthält.

ENHANCED_MEMORY_DB_PATH

(nicht gesetzt)

Vollständiger Pfad zur Datenbankdatei. Überschreibt die Verzeichniseinstellung.

MEMORY_DB_SOCKET_PATH

/tmp/memory-db.sock

Unix-Socket zwischen den beiden Prozessen. Halten Sie ihn kurz, siehe den AF_UNIX-Hinweis unten. Geben Sie einer zweiten Installation auf derselben Maschine einen eigenen.

NMF_SQLITE_PATH

$ENHANCED_MEMORY_DIR/nmf.db

Optional. Die Neural Memory Fabric-Datenbank. Sie folgt standardmäßig ENHANCED_MEMORY_DIR; setzen Sie dies nur, um sie woanders abzulegen.

NMF_FILES_ROOT

$ENHANCED_MEMORY_DIR/nmf_files

Optional. Der NMF-Dateispeicher, gleiche Regel.

MCP_TRANSPORT

stdio

stdio, sse oder streamable-http.

MCP_HOST

127.0.0.1

Nur für HTTP-Transports. Setzen Sie dies nicht einem Netzwerk aus.

MCP_PORT

9106

Nur für HTTP-Transports.

ENHANCED_MEMORY_SURFACE

frontdoor

frontdoor registriert jedes Werkzeug und markiert fünf als immer geladen (search_nodes, semantic_recall, create_entities, get_memory_status, execute_code), der Rest bleibt der Werkzeugsuche des Clients überlassen; consolidated stellt 7 bereit und versteckt den Rest hinter einem Verteiler; full registriert alles und markiert nichts.

MEMORY_PROFILE

full

minimal überspringt die optionalen Integrationen und startet schneller.

MEMORY_QDRANT_URL

http://localhost:6333

Optionaler Vektorspeicher.

MEMORY_OLLAMA_URL

http://127.0.0.1:11434

Optionaler Embedding-Anbieter.

MEMORY_EMBED_MODEL

embeddinggemma

Einbettungsmodell zum Abrufen und Verwenden.

MEMORY_LOW_CONF_THRESHOLD

0.50

Wert, unter dem ein Ergebnis als mit geringer Konfidenz gekennzeichnet wird.

MEMORY_TOOL_REGISTRY_FILE

(nicht gesetzt)

JSON-Datei, die deklariert, welche anderen MCP-Server Code innerhalb von execute_code aufrufen darf. Nicht gesetzt bedeutet, dass keine deklariert sind, was der ehrliche Standard für ein Paket ist, das nicht wissen kann, was auf Ihrem Rechner läuft.

MEMORY_LOG_STDERR

1

Sendet WARNING und höher auch an stderr sowie an die Logdatei, sodass übersprungene Werkzeuggruppen sichtbar sind. Setzen Sie 0, wenn Ihr MCP-Client stderr als Fehler behandelt.

AGENTIC_SYSTEM_PATH

(nicht gesetzt)

Aktiviert nur GraphRAG, dessen Implementierung hier nicht ausgeliefert wird. Das Setzen erhöht die Werkzeuganzahl von 186 auf 193 bzw. von 204 auf 211 mit den optionalen Backends.

EXPECTED_TOOL_COUNT

(nicht gesetzt)

Legt die Werkzeuganzahl fest, die ./healthcheck.sh erfordert.

ENHANCED_MEMORY_SURFACE und MEMORY_PROFILE ändern beide, wie viele Werkzeuge tools/list zurückgibt, und ebenso, welche optionalen Abhängigkeiten installiert sind: Werkzeuge, deren Backend fehlt, werden nicht registriert. Eine reine Kern-Installation und eine Installation mit den optionalen Erweiterungen melden unterschiedliche Anzahlen aus demselben Code. Eine erwartete Werkzeuganzahl ist nur sinnvoll in Verbindung mit allen dreien.

Optionale Dienste und was Ihnen ohne sie fehlt

Keiner ist erforderlich. Beide sind wertvoll.

Vorhanden

Nicht vorhanden

Qdrant

Die Suche bewertet nach Bedeutung: Eine Abfrage nach "Berechtigungsprüfung" kann eine Entität finden, die dieses Wort nie verwendet.

Die Suche funktioniert weiterhin und liefert Ergebnisse, aber die Bewertung fällt auf lexikalischen Abgleich zurück. Es tritt kein Fehler auf, weshalb es leicht zu übersehen ist.

ollama

Erzeugt die Embeddings, die Qdrant indiziert.

Qdrant hat nichts zu indizieren, sodass der Abruf auch mit laufendem Qdrant lexikalisch bleibt.

Stellen Sie einen oder beide bereit:

setup/setup.sh --with-qdrant     # container on 127.0.0.1:6333, named volume
setup/setup.sh --with-ollama     # verifies ollama, pulls the embedding model

./healthcheck.sh meldet beide als OPTIONAL und schlägt nie aufgrund ihrer Abwesenheit fehl. Verwenden Sie --require-optional, wenn Sie den strengeren Vertrag wünschen.

Läuft bereits ein Qdrant? Zeigen Sie MEMORY_QDRANT_URL darauf und überspringen Sie --with-qdrant vollständig; hier muss niemand die Instanz besitzen. Der unter dem Containerprofil unten diskutierte Portkonflikt ist spezifisch für dieses Profil, das seinen eigenen Container auf 6333 veröffentlicht und keinen Port binden kann, den bereits etwas anderes hält. Eine Host-Installation tätigt nur ausgehende Anfragen.

GraphRAG ist optional und extern

Die GraphRAG-Werkzeuge (graph_enhanced_search, get_entity_neighbors) werden hier nicht ausgeliefert. graphrag_tools.py lädt seine Implementierung aus $AGENTIC_SYSTEM_PATH/scripts/graph-rag.py, einer Datei, die zu einem separaten System gehört und nicht Teil dieses Pakets ist. AGENTIC_SYSTEM_PATH standardmäßig auf das übergeordnete Verzeichnis des Checkouts, sodass dieser Pfad bei einer eigenständigen Installation nicht existiert.

Nichts bricht. Die Registrierung ist gekapselt, der Server protokolliert GraphRAG integration skipped: ... und startet ohne diese Werkzeuge. Wenn Sie dieses System haben, setzen Sie AGENTIC_SYSTEM_PATH auf sein Stammverzeichnis und sie registrieren sich. Beachten Sie, dass die Überspringungsnachricht in die Logdatei geht, nicht auf Ihr Terminal, sodass fehlende Werkzeuge wie Werkzeuge aussehen, die nie da waren.

Ausführen in einem Container

Der Auslieferungspfad für gemeinsam genutzte Umgebungen. Podman zuerst, docker-kompatibel.

podman-compose up --build                              # core only
WITH_OPTIONAL=1 podman-compose --profile qdrant up     # with a USABLE vector store

WITH_OPTIONAL=1 ist maßgeblich für das qdrant-Profil. Das Standard-Image installiert nur requirements.txt, das qdrant-client nicht enthält — also --profile qdrant ohne es gibt Ihnen ein gesundes, erreichbares, völlig ungenutztes Qdrant: Der Healthcheck meldet den Dienst als erreichbar (wahr), während der Server "qdrant-client not installed - vector search disabled" protokolliert und jede Suche lexikalisch bleibt. Ein grünes Signal neben einer inaktiven Fähigkeit ist genau die Fehlerart, die dieses Projekt zu beseitigen versucht, daher wird es hier benannt und nicht Ihnen überlassen, es zu finden. WITH_OPTIONAL=1 erstellt das Image mit requirements-optional.txt und der Vektor-Pfad wird tatsächlich aktiviert. (Gemessen: Ein Kern-Image neben dem qdrant-Profil antwortete auf /readyz mit "all shards are ready" und nutzte es für nichts.)

Verwenden Sie den Bindestrich. Auf Fedora 44 übergibt podman compose (mit Leerzeichen) an einen externen Anbieter, /usr/libexec/docker/cli-plugins/docker-compose, der einen Docker-kompatiblen API-Socket benötigt. Wenn podman.socket inaktiv ist, was der Standard ist, schlägt podman compose up fehl:

failed to connect to the docker API at unix:///run/user/1000/podman/podman.sock:
  connect: no such file or directory

systemctl --user start podman.socket behebt das, oder verwenden Sie einfach podman-compose (hier 1.6.0), das podman direkt antreibt und keinen Socket benötigt. Gemessen auf Fedora 44 mit podman 5.8.4: podman compose up schlug wie oben fehl, podman-compose up -d brachte den Stack zum Laufen und der Container meldete healthy.

Das Image führt beide Prozesse unter container-entrypoint.sh aus, das den Daemon startet, auf die Antwort des Sockets wartet und erst dann den MCP-Server auf dem SSE-Transport startet. Wenn einer der Prozesse beendet wird, wird auch der Container beendet, denn ein lebender MCP-Server neben einem toten Daemon ist genau der Zustand, der auf ewig wohlgeformte Nullen zurückgibt.

Hinweise, die Ihnen Zeit sparen:

  • podman build verwirft den HEALTHCHECK. Podman verwendet standardmäßig das OCI-Image-Format, das kein Feld dafür hat. Es warnt einmalig zur Build-Zeit: GXP13 Wenn man diese Zeile in der Build-Ausgabe übersieht, erwähnt sie niemand mehr: Das Image trägt keinen Healthcheck und podman ps zeigt niemals einen Health-Status an. Gemessen auf podman 5.8.4, Fedora 44: Der .HealthCheck des OCI-Images inspiziert als nil, und ein Neubau mit podman build --format docker ergibt [CMD /app/setup/lib/container-health.sh]. Drei Auswege, alle verifiziert: Bauen mit --format docker; Compose verwenden, dessen Healthcheck auf Dienstebene in compose.yaml definiert ist und unabhängig vom Image-Format gilt (ein von Compose verwalteter Container meldet healthy vom selben Image, das als nil inspiziert); oder bei Bedarf prüfen mit podman exec <name> /app/healthcheck.sh --skip-mcp.

  • Der MCP-Port wird nur auf dem Host-Loopback veröffentlicht (127.0.0.1:9106:9106). Innerhalb des Containers bindet der Server an 0.0.0.0, was dort korrekt und auf einer Workstation falsch ist.

  • Qdrants Host-Ports sind ${QDRANT_PORT:-6333} und ${QDRANT_ADMIN_PORT:-6334}. Setzen Sie sie in .env, wenn Sie Qdrant bereits auf 6333 betreiben, da sonst ein Bind-Konflikt das Starten des Profils verhindert.

  • Das Image ist eine Kerninstallation, daher macht das qdrant-Profil allein nichts. podman-compose --profile qdrant up gibt Ihnen einen Qdrant, der startet, den Healthcheck besteht und auf seinem Port antwortet, während der Server keinen qdrant-client hat, um mit ihm zu kommunizieren. Alles sieht grün aus und nichts wird indiziert. Bauen Sie mit dem optionalen Stack, um es tatsächlich zu nutzen: GXP14 ./healthcheck.sh unterscheidet die beiden Fälle: Es meldet Qdrant nur dann als erreichbar und nutzbar, wenn die Client-Bibliothek importierbar ist, und warnt, wenn der Dienst läuft, aber nichts ihn verwenden kann.

  • Die Datenbank befindet sich im benannten Volume enhanced-memory-data. Ohne Volume stirbt Ihr Speicher mit dem Container.

  • ollama läuft auf Ihrem Host, und ein Container kann es unter 127.0.0.1 nicht erreichen. Kommentieren Sie MEMORY_OLLAMA_URL in compose.yaml aus (host.containers.internal für podman, host.docker.internal für docker).

  • Überprüfen Sie einen laufenden Container auf die gleiche Weise wie eine Host-Installation. Verwenden Sie den absoluten Pfad: Nicht jede Engine löst einen relativen Pfad relativ zum WORKDIR auf. GXP15

  • Ihre lokale .env ist keine Konfiguration für den Container. Das Image enthält absichtlich eine leere .env, und alles Reale stammt aus der Laufzeitumgebung in compose.yaml. .containerignore und .dockerignore schließen die Datei aus, aber nicht jede Engine beachtet sie (Apples container build tat es nicht, verifiziert am 14.08.2026), daher leert das Containerfile sie auch in einer verworfenen Build-Stufe und schlägt den Build fehl, wenn eine gefüllte überlebt.

Running as a background service

GXP16 launchd-Benutzer-Agents auf macOS (~/Library/LaunchAgents), systemd-Benutzer-Units auf Linux (~/.config/systemd/user). Kein Root, keine System-Units. Jeder Pfad wird vom Speicherort dieses Checkouts abgeleitet, sodass zwei Checkouts nebeneinander existieren können, wenn Sie ihnen unterschiedliche --label-prefix-Werte, unterschiedliche MEMORY_DB_SOCKET_PATH-Werte und unterschiedliche ENHANCED_MEMORY_DIR-Werte geben. Alle drei, nicht nur die ersten beiden: Getrennte Sockets allein führen dazu, dass beide Daemons dieselbe memory.db öffnen, und jeder von ihnen soll diese Datei exklusiv besitzen.

Der Installer wartet auf den Socket und schlägt mit einem Log-Auszug fehl, wenn der Dienst nicht startet. Logs landen in ~/Library/Logs/enhanced-memory oder ${XDG_STATE_HOME:-~/.local/state}/enhanced-memory/log, bewusst nicht im Checkout: launchd kann keine Log-Datei auf einem externen Volume zum Zeitpunkt des Starts erstellen, und der Auftrag stirbt mit Exit-Code 78, bevor Ihr Code jemals läuft.

Unter Linux werden Benutzer-Units beim Abmelden gestoppt, es sei denn, Sie aktivieren das Verweilen (lingering): GXP17

Überprüfen Sie Ihre Installation

Zwei Prüfungen, in dieser Reihenfolge. GXP18

Eine dritte, entwicklerorientierte Suite befindet sich unter tests/ und benötigt zuerst pip install -r dev-requirements.txt — pytest wird bewusst in keiner Laufzeit-Anforderungsdatei ausgeliefert, und die beiden obigen Prüfungen laufen ausschließlich mit der Standardbibliothek.

Bewerten Sie comprehensive_test.py anhand seines Exit-Codes, nicht anhand der Anzahl bestandener Tests. Die Anzahl der Prüfungen hängt vom ausgewählten Modus ab: Wenn keine ENHANCED_MEMORY_*- oder MEMORY_DB_*-Variablen gesetzt sind, erstellt es eine eigene Sandbox und führt alles aus; sind sie gesetzt, läuft es gegen Ihre Bereitstellung und überspringt die Prüfungen, die eine Sandbox beschreiben, die es nicht erstellt hat. Gemessen auf einer Maschine, einem Commit: 106 isolierte und 102 betreibergesteuerte Prüfungen, beide mit Exit-Code 0. Der Lauf gibt seinen eigenen Modus aus und nennt, was er übersprungen hat.

Die Installation der optionalen Backends ändert diese Zahl um null, gemessen auf beide Arten. Eine frühere Version dieser Datei gab an, die Backends seien die Ursache. Das sind sie nicht, und die gleiche falsche Vermutung wurde dem pytest-Überspringungszähler angehängt, bevor ihn jemand getestet hat; siehe den Abschnitt zur Testsuite in RELEASE_NOTES.md für das, was diesen Zähler tatsächlich bewegt.

./healthcheck.sh ist so gebaut, dass es fehlschlagen kann. Es schreibt eine Test-Entität über den Daemon-Socket, sucht sie zurück und löscht sie. Es behandelt einen error- oder daemon-Schlüssel in jeder Antwort als Fehler, unabhängig vom restlichen Payload, und vergleicht den vom Daemon gemeldeten Datenbankpfad mit dem, den Ihre Umgebung auflöst. Es prüft:

  1. venv, Interpreter-Version, .env, Socket-Pfad-Länge, vorhandene Quellen

  2. Daemon-Rundlauf (Status, Datenbankübereinstimmung, Schreiben, Zurücklesen, Bereinigung) und eine Schema-Prüfung: Jedes wörtliche INSERT in den beiden Dateien, die diese Datenbank besitzen, wird mit den Live-Tabellendefinitionen verglichen, denn eine Spalte, die das Schema nicht hat, führt bei jedem Schreibvorgang zu einem Fehler, während der Daemon den Fehler pro Zeile meldet, anstatt ihn zu werfen

  3. MCP-Handshake über stdio, Anzahl der Tools und dass nichts stdout verschmutzt hat

  4. Qdrant und ollama, als OPTIONAL gekennzeichnet, niemals fatal

Nützliche Flags: --skip-mcp für eine schnelle Daemon-nur-Prüfung, --expect-tools N zum Festlegen der Anzahl, --require-optional um den Vektor-Stack zu erzwingen.

Wo die Logs sind

/tmp/enhanced-memory-mcp.log, immer, für jede Installation auf dem Host.

Der MCP-Server löscht beim Start jeden Logging-Handler und sendet alles an diese eine rotierende Datei (50 MB, zwei Backups), denn auf dem stdio-Transport korrumpiert alles auf stdout das Protokoll. Routinemäßiges INFO lebt nur dort, und der Pfad ist fest, sodass zwei Checkouts auf einer Maschine in dieselbe Datei einsortieren, mit Zeitstempeln und PIDs als einzigen Trennzeichen.

WARNING und höher gehen zusätzlich nach stderr, es sei denn, Sie setzen MEMORY_LOG_STDERR=0. Das ist beabsichtigt: Jede ... integration skipped: <reason>-Zeile ist ein Feature, das nicht geladen wurde, und wenn diese nur in eine Datei unter /tmp geleitet werden, liest sie niemand. Wenn Ihr MCP-Client jede stderr-Ausgabe als Fehler behandelt, setzen Sie die Variable auf 0 und lesen Sie stattdessen die Datei.

./healthcheck.sh meldet diese ebenfalls, als WARN mcp-startup-Zeile, die die einzelnen Warnungen auflistet, sodass ein fehlendes Feature in der Prüfung sichtbar wird und nicht nur in einem Log. Gemessen auf diesem Branch: Eine Kerninstallation erzeugt 11 davon (numpy, qdrant-client, sentence-transformers, redis, neo4j usw.), eine Vollinstallation 3. Keine davon lässt die Prüfung fehlschlagen. Sie sind das Inventar dessen, was Ihre Installation nicht hat – lesenswert einmal und dann ignorieren.

Überprüfen der Signaturen auf diesem Release

Commits sind mit SSH signiert. Git wird sie nicht überprüfen, bis Sie ihm mitteilen, welchen Schlüsseln es vertrauen soll, und diese Konfiguration wird nicht mit einem Klon übertragen: GXP19

Ohne die erste Zeile meldet git log --format=%G? für jeden Commit N, was „kann nicht überprüft werden" bedeutet, nicht „unsigniert". Die Signaturen sind in beiden Fällen vorhanden: git cat-file commit HEAD zeigt den gpgsig-Block.

Fehlerbehebung

Jedes Tool gibt Nullen oder ein error-Feld zurück

Der Daemon läuft nicht. Das ist mit großem Abstand der häufigste Fall. GXP20 GXP21

Der Server und der Daemon sind sich über die Datenbank uneinig

Symptom: Schreibvorgänge scheinen erfolgreich zu sein, aber Suchvorgänge finden sie nie, oder get_memory_status meldet eine Anzahl, die nicht mit dem von Ihnen Gespeicherten übereinstimmt. Die beiden Prozesse haben unterschiedliche Dateien aufgelöst, und keiner von beiden gibt einen Fehler aus. ./healthcheck.sh erkennt dies direkt: GXP22

Ursache: Etwas hat einen Prozess mit einer anderen ENHANCED_MEMORY_DIR, ENHANCED_MEMORY_DB_PATH oder HOME gestartet als den anderen. Meistens ein MCP-Client, der so konfiguriert ist, dass er python server.py direkt ausführt und dabei den Launcher umgeht, der .env anwendet. Korrigieren Sie die Client-Konfiguration, um setup/bin/mcp-server.sh zu verwenden, und starten Sie dann beide Prozesse neu.

Inhaltsabfragen geben Null zurück, während Namensabfragen funktionieren

Seit e9ca30c kann dies nicht mehr still geschehen: Wenn die Suche den Inhalt der Beobachtung nicht sehen kann, sagt die Antwort dies — GXP23

degraded bedeutet, dass die Datenbank älter ist als der Volltextindex und seit dem Upgrade kein Daemon dagegen initialisiert wurde. Starten Sie den Daemon neu: init_database() erstellt nun den Index und füllt jede vorhandene Zeile nach. Der andere Wert, name-only (FTS query error), ist abfragebezogen und bedeutet, dass der Abfragetext nach der Bereinigung die FTS-Syntax verletzt hat; der Name/Typ-Abgleich lief trotzdem.

Erneutes Importieren eines Seeds fügt doppelte Beobachtungen an

Behoben in e9ca30c: create_entities überspringt Beobachtungen, deren genauer Inhalt bereits für diese Entität existiert, und meldet die Übersprünge als observations_deduped in seiner Antwort, sodass wiederholte Seed-Importe idempotent sind. Wirklich neue Beobachtungen werden weiterhin angehängt. Duplikate, die durch erneute Importe vor der Korrektur entstanden sind, werden nicht für Sie gelöscht — Issue #8 enthält das einmalige Bereinigungs-SQL.

Umformulierte Re-Importe (derselbe Seed leicht bearbeitet) werden ebenfalls erkannt, mittels deterministischem Simhash — kein LLM beteiligt. Standardmäßig werden sie in einem near_duplicates-Antwortfeld gespeichert und gemeldet, das angibt, welcher vorhandenen Zeile jede ähnelt: Eine Korrektur („62Gi" → „125Gi") ist auf dieser Ebene nicht von einer Umformulierung zu unterscheiden, und ein Speicher darf nie stillschweigend eine Korrektur verwerfen. Eine Import-Pipeline, die weiß, dass sie erneut importiert, kann ENHANCED_MEMORY_NEAR_DUP_POLICY=skip setzen, um sie stattdessen zu verwerfen; jeder andere Wert dieser Variable fällt auf das sichere Speichern-und-Melden zurück. Der Distanzschwellwert und die gemessenen Kalibrierungsbänder befinden sich in simhash_dedup.py.

OSError beim Start des Daemons ohne hilfreiche Meldung

Der Socket-Pfad ist zu lang. AF_UNIX begrenzt die Pfadzeichenfolge auf 104 Bytes unter macOS und 108 unter Linux, und bind() schlägt mit einem Fehler fehl, der weder das Limit noch den Pfad erwähnt. Tiefe Checkouts treffen darauf, sobald der Socket darin platziert wird.

Halten Sie MEMORY_DB_SOCKET_PATH kurz und außerhalb des Checkouts, zum Beispiel /tmp/em-myproject.sock. setup/setup.sh misst ihn und weigert sich fortzufahren, wenn er zu lang ist.

macOS: Der Dienst wird installiert, aber der Daemon startet nie

Wenn das Log Operation not permitted auf dem Launcher-Pfad zeigt, befindet sich das Checkout an einem Ort, von dem launchd nicht ausführen darf. Verifiziert am 14.08.2026: Ein Checkout auf einem externen Volume unter /Volumes installiert und lädt einwandfrei, dann schlägt jeder Spawn mit EPERM fehl, weil launchd ohne den Festplattenzugriff läuft, den Ihr Terminal hat.

Verschieben Sie das Checkout in Ihr Home-Verzeichnis oder einen anderen lokalen Pfad und installieren Sie es neu, oder gewähren Sie launchd vollen Festplattenzugriff, wenn der Standort nicht verhandelbar ist. Der Installer zeigt dies an, anstatt es zu verstecken: Er wartet auf den Socket, schlägt nach 30 Sekunden fehl und gibt das Ende des Fehlerprotokolls aus.

ConnectionRefusedError, obwohl die Socket-Datei existiert

Ein beendeter Daemon hat die Datei hinterlassen. Starten Sie den Daemon erneut, und er entfernt die Datei selbst und protokolliert removed stale socket <path>; der Launcher macht dasselbe, bevor er ausführt. Löschen Sie eine Socket-Datei nicht aus Gewohnheit von Hand – eine Datei, die noch bedient wird, sieht genauso aus wie eine veraltete, und das Entfernen trennt alle Clients des Daemons, dem sie gehört, ab.

A
license - permissive license
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
1hResponse time
Release cycle
Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.

  • Persistent memory and knowledge graphs for AI agents. Hybrid search, context checkpoints, and more.

  • Universal memory for AI agents and tools. Save, organize and search context anywhere.

View all MCP Connectors

Latest Blog Posts

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marc-shade/enhanced-memory-mcp'

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