# OpenMemory (mem0) Selbst-gehosteter Memory-Store mit MCP-Schnittstelle. Wird u. a. von Cursor und Jervais/Hermes als persistentes Gedaechtnis genutzt. ## Deployment - **Host:** CT122 auf pve-hetzner (Tailscale-Gateway `root@100.88.230.59`), interne IP `10.10.10.122`. - **Container:** Docker Compose unter `/root/mem0/openmemory/` (`docker-compose.yml`): - `openmemory-openmemory-mcp-1` (`mem0/openmemory-mcp`) — API/MCP auf Port `8765`, `uvicorn main:app --reload --workers 4`. - `openmemory-mem0_store-1` (`qdrant/qdrant`) — Vektor-Store, Collection `openmemory`. - `openmemory-openmemory-ui-1` (`mem0/openmemory-ui`) — Dashboard auf Port `3000`. - **App-Quellcode (bind-mount):** Host `/root/mem0/openmemory/api` → Container `/usr/src/openmemory`. - **Aktive Konfiguration:** NICHT `config.json`, sondern DB-Tabelle `configs` (key `main`) in `/usr/src/openmemory/openmemory.db`. LLM = `gpt-4o-mini` via OpenRouter (`OPENAI_BASE_URL=https://openrouter.ai/api/v1`), Embedder `text-embedding-3-small`. - **Zugang vom Cursor-Host:** SSH-Tunnel `openmemory-tunnel.service` (autossh) leitet `localhost:8765` → `10.10.10.122:8765`. MCP-URL in `mcp.json`: `http://localhost:8765/mcp/cursor/sse/orbitalo`. - **Logs:** `docker logs openmemory-openmemory-mcp-1` (json-file, keine Rotation konfiguriert). --- # Hotfix — 2026-05-31 Behob zwei Fehlfunktionen. ## Symptome 1. `list_memories` lieferte hart: `Error getting memories: fromisoformat: argument must be str`. 2. `add_memories` mit laengeren Texten gab still `{"results": []}` zurueck (nicht gespeichert), ohne sichtbaren Client-Fehler. ## Root Causes 1. **Gemischte Timestamp-Typen in qdrant.** 274 von 663 Punkten hatten `hash` und `created_at` als **Integer** (alte Records einer frueheren mem0-Version), neuere als String/ISO. - `mem0.memory.main._normalize_iso_timestamp_to_utc()` fing nur `ValueError`; bei int wirft `datetime.fromisoformat()` ein `TypeError` → `get_all`/`list_memories` crasht komplett. - Zusaetzlich verlangt das Pydantic-Modell `MemoryItem` Strings fuer `hash`/`created_at` → `ValidationError` bei int. 2. **Truncation des Extraktor-LLM-JSON.** `max_tokens: 2000` zu klein; beim Update-Memory-Schritt (Prompt enthaelt alle bestehenden Memories) wurde das JSON abgeschnitten → `Invalid JSON response` → leeres `results`. - Hinweis: Leeres `results` kann AUCH legitim sein (LLM-Dedup → `event: NONE`/`NOOP`). Nur das abgeschnittene JSON ist der Bug. ## Fixes (angewendet + verifiziert) 1. **qdrant-Daten normalisiert:** 274 Records, `hash` int→`str`, `created_at`/`updated_at` epoch-int→ISO-UTC. Backup: `api/qdrant_intfix_backup-20260531.json`. 2. **mem0-Library tolerant:** `site-packages/mem0/memory/main.py` `except ValueError:` → `except (ValueError, TypeError):`. Backup `.bak-tsfix-20260531` (NICHT rebuild-fest). 3. **Durabler Monkeypatch (rebuild-fest):** in `api/main.py` nach den Imports — ueberschreibt `_normalize_iso_timestamp_to_utc` so, dass Nicht-String-Werte unveraendert durchgereicht werden. Backup `api/main.py.bak-tsfix-20260531`. 4. **max_tokens erhoeht:** DB-Config `configs.main` → `mem0.llm.config.max_tokens` `2000` → `8000`. Backup `api/config_main.bak-20260531.json`. ## Verifikation - `_normalize_iso_timestamp_to_utc(1774205916)` gibt int zurueck statt Crash; ISO weiterhin korrekt. - `list_memories()` liefert JSON-Array (100), 0 verbleibende int-Records. - Langer `add_memories` → gueltiges JSON, `event: ADD` (Dedup korrekt `NONE`/`NOOP`). - Live ueber Cursor-MCP (nach Client-Reload) beide Tools ok. ## Nach Container-Rebuild beachten - Persistent: Fix 1 (qdrant-Daten), Fix 3 (Monkeypatch in `main.py`), Fix 4 (DB-Config). - Verloren bei Image-Rebuild: Fix 2 (site-packages) — durch Fix 3 abgedeckt. - Container-Neustart invalidiert MCP-Sessions → Clients muessen neu initialisieren (`-32602` = request before initialization). In Cursor: MCP `openmemory` toggeln oder Fenster neu laden.