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/andsrc/memos/mem_scheduler/for ingestion, retrieval, and scheduling logic. - Multi‑modal parsers –
src/memos/mem_reader/read_multi_modal/__init__.pyandsrc/memos/mem_reader/read_multi_modal/multi_modal_parser.pyturn 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/andsrc/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:
- Backend – a Django service (not listed explicitly but implied by the
Djangotag). Its entry point is the standardmanage.pycommand that loadssrc/memos/. The request handlersrc/memos/mem_scheduler/base_mixins/web_log_ops.pyreceives HTTP calls, logs them, and forwards to the scheduler core (src/memos/mem_scheduler/).
- Vector/Graph store – Neo4j and a vector DB are defined as separate services. The backend talks to them through adapters in
src/memos/types/andsrc/memos/mem_reader/.
- Frontend – the React desktop app is built from
openwork-memos-integration/apps/desktop/. The entry HTML isopenwork-memos-integration/apps/desktop/index.html; the main renderer starts inopenwork-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 todocker/.envand supplyNEO4J_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.ymlmissing). - MEDIUM – Pin Docker base image –
docker/Dockerfileuses mutablepython:3.11-slim. - MEDIUM – Add vulnerability scan – No dependency‑review or OSV scanner in CI.
- MEDIUM – Checkout without persist‑credentials –
.github/workflows/python-tests.ymlleaves token in.git/config. - MEDIUM – Run container as non‑root – No
USERdirective in Dockerfile. - LOW – Set workflow timeout –
python-release.ymllackstimeout-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.