Architecture
How MemexAI is deployed, how tools flow, and where memory lives.
MemexAI has two runtime modes that share the same Postgres schema. The recommended default is the containerized service. Direct Postgres runtime is available for apps that intentionally own database credentials.
The product flow to keep in mind:
agent / SDK / MCP -> MemexAI service -> PostgresThe service path keeps database credentials out of your app, gives every tenant/user the same path isolation rules, and exposes the admin console for inspecting memory files, revisions, access logs, observability, and background dreaming.
Containerized service mode
Use service mode when teams or production apps should not hold database credentials.
TypeScript app -> @memexai/sdk -> MemexAI service -> Postgres
Python app -> memexai.MemexAI -> MemexAI service -> Postgres
MCP client -> MemexAI service -> PostgresThe service handles:
- API key verification.
- Path validation and virtual-to-physical translation.
- SQL reads and writes to
mx_file,mx_revision, andmx_access_log. - The admin UI at
/admin. - MCP transport over SSE and stdio.
- BM25-first memory search, with optional pgvector hybrid search when embeddings are configured.
- Optional background memory consolidation.
Advanced: direct Postgres runtime mode
Use direct Postgres mode only when your application should own database access.
Your JavaScript app -> @memexai/core -> Postgres
Your Python app -> memexai Python SDK -> PostgresThere is no HTTP layer, no service auth, and no separate MemexAI container. Your app passes a Postgres URL, calls migrate() on startup or during deploy, then executes memory tools in-process.
Tool layers
Agentic tools
| Tool | What it does |
|---|---|
memory_memorize | Feeds raw text to an inner model that decides what durable facts should be written or patched. |
memory_search | Recalls relevant memory with BM25-first search, optional pgvector hybrid candidates, and model-backed answer synthesis when configured. |
Raw tools
| Tool | What it does |
|---|---|
memory_list | Lists visible files for a user. |
memory_read | Reads one file by virtual path. |
memory_write | Creates or overwrites a user file. |
memory_patch | Appends under a heading or replaces exact text. |
memory_smart_read | Builds one bounded context block from visible files. |
Background dreaming
Service mode can run an opt-in background memory consolidation loop. It is invisible to end users during chat: after a user's memory has been quiet for a configured grace period, the service reads that user's user/ files and asks a consolidation agent to merge duplicate facts, clean up fragmented notes, resolve direct contradictions, and keep long-running memory files readable for the next agent trajectory.
Dream writes use the same memory_write and memory_patch path as normal tools, so revisions and access logs still work. The actor is dream-agent. Dream reads exclude user/log.md, user/dream-log.md, files ending in -log.md, and files ending in .log.
Each scheduler tick only selects users who have non-excluded file writes newer than their last dream. If a tick finds no qualifying users it logs a skip message to stdout and returns immediately — no LLM calls are made. When the agent runs but determines nothing needs merging, files_touched in mx_dream_run is 0 and no dream-log.md entry is written. The agent only writes to dream-log.md when it actually consolidates something, keeping user memory free of no-op noise.
The operator UX is available both via API and the admin Dreams panel:
| Endpoint | Purpose |
|---|---|
GET /v1/admin/dream/config | Read dream_* settings. |
PUT /v1/admin/dream/config | Update cadence, grace period, write budget, and concurrency. |
GET /v1/admin/dream/users | List dream status, pause flags, errors, and run counts. |
PUT /v1/admin/dream/users/:userId/paused | Pause or resume dreaming for one user. |
Enable the scheduler with MEMEX_DREAM_ENABLED=true. The database dream_enabled key remains the runtime master switch.
See Background Dreaming for skip behavior, no-op runs, pause controls, and deployment guidance.
Tool call flow
- The AI model emits a tool call.
- A framework adapter receives the call.
- MemexAI validates the tool name, arguments, and context.
- Virtual paths like
user/profile.mdare translated to physical paths likeusers/user_123/profile.md. - Reads and writes execute against Postgres.
- Writes create revision snapshots, and reads/writes create access log entries.
- The result returns to the model or application.
Every step after tool execution is shared by the containerized service, MCP, and in-process runtimes.
Search and storage flow
MemexAI stores the current memory record in mx_file, full write snapshots in mx_revision, and every read/write event in mx_access_log.
Search starts with Postgres full-text search over the search_vector column. In hybrid mode, the service also stores embeddings in Postgres with pgvector and merges lexical and semantic candidates. BM25 remains the default; pgvector is an optional enhancement, not a separate vector database requirement.