The Problem

LLM‑driven agents need a persistent, queryable store for learned skills and user‑specific context. Without a unified memory layer each task re‑learns the same information, leading to token waste, inconsistent behavior, and difficult skill evolution.

What This Does

MemOS supplies a “memory operating system” that sits between agents and their vector/graph back‑ends. The core Python package lives under src/ (≈ 357 code files) and implements:

  • Graph‑based memory API – see src/memos/mem_reader/ and src/memos/mem_scheduler/ for ingestion, retrieval, and scheduling logic.
  • Multi‑modal parsers – src/memos/mem_reader/read_multi_modal/__init__.py and src/memos/mem_reader/read_multi_modal/multi_modal_parser.py turn text, images, and tool outputs into structured nodes.
  • Persistence adapters – Docker images ship Neo4j and a vector store; the adapters are referenced from src/memos/types/ and src/memos/mem_reader/.

The front‑end integration lives in openwork-memos-integration/apps/desktop/ (React + Tailwind) and provides the UI for skill creation, inspection, and editing. Example skill bundles (ask‑user‑question, dev-browser) are under openwork-memos-integration/apps/desktop/skills/.

How It Is Wired

Execution is driven by Docker‑Compose (see docker/docker-compose.yml). The compose file starts three containers:

  1. Backend – a Django service (not listed explicitly but implied by the Django tag). Its entry point is the standard manage.py command that loads src/memos/. The request handler src/memos/mem_scheduler/base_mixins/web_log_ops.py receives HTTP calls, logs them, and forwards to the scheduler core (src/memos/mem_scheduler/).
  1. Vector/Graph store – Neo4j and a vector DB are defined as separate services. The backend talks to them through adapters in src/memos/types/ and src/memos/mem_reader/.
  1. Frontend – the React desktop app is built from openwork-memos-integration/apps/desktop/. The entry HTML is openwork-memos-integration/apps/desktop/index.html; the main renderer starts in openwork-memos-integration/apps/desktop/src/main/ipc/handlers/index.ts, which opens IPC channels to the backend API.

A typical request flow:

browser → React UI (src/renderer/components/…) → IPC handler (src/main/ipc/handlers) 
   → HTTP request → Django view → mem_scheduler/base_mixins/queue_ops.py 
   → mem_reader/read_multi_modal/multi_modal_parser.py 
   → Neo4j / vector store

The most connected production module is src/memos/types/openai_chat_completion_types/__init__.py (imports 13, imported by 1, instability 0.93), meaning changes here ripple widely. The test hub tests/utils.py (imports 26, no outgoing imports) is the only high‑impact non‑runtime module.

No circular imports were detected, and the import graph contains 304 edges across 697 internal modules, indicating a relatively flat dependency landscape.

How To Use It

# 1. Clone the repo
git clone https://github.com/moses-y/MemOS
cd MemOS

# 2. Build and start the stack
docker compose -f docker/docker-compose.yml up --build -d

# 3. Install the Python SDK (optional, for custom agents)
poetry install   # uses pyproject.toml / poetry.lock
# Or, inside the running backend container:
docker exec -it memos_backend poetry install

Configuration files:

  • docker/.env.example – copy to docker/.env and supply NEO4J_AUTH, VECTOR_DB_URL, and API keys required by the agents.
  • openwork-memos-integration/apps/desktop/.eslintrc.json – lint rules for the UI; no runtime effect.

The backend listens on the port defined in docker/docker-compose.yml (default 8000). The UI is reachable at http://localhost:3000.

Real‑World Use

An autonomous research bot can call MemoryOS.add_memory(user_id, skill_payload) (implemented in src/memos/mem_reader/). The payload is parsed by read_multi_modal_parser, stored in Neo4j, and later retrieved by mem_scheduler when the same user asks a related question, cutting token usage by ~ 70 % (as claimed in the README).

Code Health & Issues

  • MEDIUM – Enable Dependabot – 9 manifest files lack an update bot (.github/dependabot.yml missing).
  • MEDIUM – Pin Docker base image – docker/Dockerfile uses mutable python:3.11-slim.
  • MEDIUM – Add vulnerability scan – No dependency‑review or OSV scanner in CI.
  • MEDIUM – Checkout without persist‑credentials – .github/workflows/python-tests.yml leaves token in .git/config.
  • MEDIUM – Run container as non‑root – No USER directive in Dockerfile.
  • LOW – Set workflow timeout – python-release.yml lacks timeout-minutes.

Measured code‑quality findings (high/medium/low) include deep nesting (max depth 8 in several files), an oversized SettingsDialog.tsx (704 LOC), broad exception handling, and duplicated evaluation scripts. The hub module tests/utils.py imports 26 other modules; keep it stable.

The Bottom Line

MemOS offers a fairly complete stack—backend SDK, Neo4j/vector persistence, and a React UI—for building long‑term memory into LLM agents. The codebase is modular and passes basic hygiene checks, but production readiness requires tightening Docker security, adding automated dependency updates, and refactoring a few large, deeply nested files. Teams that need a plug‑and‑play memory layer and are comfortable operating Docker‑compose will find it usable with modest engineering effort.