Quickstart
From nothing to an agent storing and finding a record, on one machine, in ten steps.
Before you start
- A container engine with Docker Compose 2.24.4 or later (
docker compose version): Docker Engine on Linux, or Docker Desktop or Colima on macOS. It is the only thing to install; the stack and its tools all run as containers. - Resources given to the container engine (on macOS, the Docker Desktop or Colima VM settings): enough for the stack — sizing gives the memory each service is allowed and what the stack uses.
opensslandpython3for minting keys.
Steps
-
Get the stack files. Download the latest release of everythingmemory/home and unpack it, or clone the repository, and run every step from its folder. It holds the compose files and
local.env.template. Nothing is built: the compose file pulls the eMemory images fromghcr.io/everythingmemory, each pinned to the release by digest, and the third-party images (Postgres, the archive store, the job queue, the model gateway) from their own publishers, pinned the same way. -
Create the settings file.
cp local.env.template local.envln -s local.env .env -
Set the database password. Put the output in
local.envasPOSTGRES_PASSWORD=.openssl rand -hex 24 -
Set the job queue password and the archive settings. The archive is on by default, in the stack's own store on this machine, written to a folder you name. Make the folder, set
ARCHIVE_DIRinlocal.envto its absolute path, then mint the queue password, the archive store's key pair and the archive's encryption key, and put each inlocal.env:mkdir -p "$HOME/ememory-data/archive" # ARCHIVE_DIR (an absolute path)openssl rand -hex 24 # REDIS_PASSWORDopenssl rand -hex 20 # S3_ACCESS_KEYopenssl rand -hex 32 # S3_SECRET_KEYopenssl rand -base64 32 # ARCHIVE_KEYThe folder must exist before the stack starts; a missing one is refused, never created empty. On macOS with Docker Desktop, keep it under your home folder, which Docker Desktop shares by default. The folder survives
docker compose down -v, and you back it up and move it with your own tools.Keep a copy of
ARCHIVE_KEYin your password manager, never beside the archive folder: every archive object is encrypted with it, a lost key is an unreadable archive, and a key stored with the archive protects nothing. The S3 pair only lets the engine reach the store;ARCHIVE_KEYis what reads what is in it. -
Start the stack.
docker compose up -dThe first start pulls the images, which takes a few minutes; later starts take seconds.
A required setting that is missing stops the start and is named. Most are named by
docker compose upitself. The archive settings are checked when the stack starts:upreports thatarchive-storeorarchive-bucketdid not start or complete, the engine does not start, anddocker compose logs archive-store archive-bucketnames the missing key.Another eMemory stack already running on this machine? Give this one its own project name and ports: set
EMEMORY_PORT,CONSOLE_PORTandEMEMORY_NETWORKinlocal.env(see the template) and start it withdocker compose -p <name> up -d. -
Check health.
curl -s http://localhost:8765/healthExpect
"status":"healthy", with"embedding":{"model":"nomic-embed-text","width":768,"state":"ok"}. Until every service is up it can answerdegraded; give it a minute. -
Mint a client key (needed once authentication is on; the template starts with it off, which is safe because the stack answers on this machine only). Put the hash in
API_KEY_HASH_LIST, keep the key for the client. To turn authentication on, also setAUTH_ENABLED=true, then rundocker compose up -dagain so the stack picks up the change; a call without the key then gets401.python3 -c "import hashlib,secrets; k='emem_'+secrets.token_urlsafe(32); print('key: ', k); print('hash:', hashlib.sha256(k.encode()).hexdigest())" -
Connect an MCP client to
http://localhost:8765/mcp(streamable HTTP). With authentication on, add the headerAuthorization: Bearer <key>. In Claude Code, for example (other clients: Claude integration, ChatGPT and OpenAI, OpenClaw, other MCP clients):claude mcp add --transport http everythingmemory http://localhost:8765/mcp -
Store a record. From the agent:
e_ingest {"content": "Acme's renewal is due on 1 March 2027. Sarah owns it.", "properties": ["org:Acme", "topic:renewal"]}Or over REST:
curl -s -X POST http://localhost:8765/api/v2/ingest -H "Content-Type: application/json" \-d '{"content": "Acme'"'"'s renewal is due on 1 March 2027. Sarah owns it.", "properties": ["org:Acme", "topic:renewal"]}' -
Find it.
e_gather {"action": "find", "query": "when is the Acme renewal due"}curl -s -X POST http://localhost:8765/api/v2/gather -H "Content-Type: application/json" \-d '{"action": "find", "query": "when is the Acme renewal due"}'
Next
- What an agent does from here: a walkthrough.
- Running it beyond a first try: single stack.
- Every setting: configuration options.
- Backing up or moving a memory to another machine: bundles.
- The source code is available on request, under the Business Source License 1.1: licence.