Containerized Service
Run MemexAI as a separate service, then connect over TypeScript, Python, or MCP.
The containerized service path is the recommended default. Your application does not need database credentials; it connects to MemexAI over HTTP with the TypeScript SDK, Python SDK, or through MCP over SSE/stdio.
Fastest path
If you want a coding agent to do the integration inside your app, paste this into the agent:
Setup MemexAI by following https://memexai.space/setup.mdThat public setup file tells the agent to inspect your app, choose the right adapter, start the local service, wire memory tools, add the MemexAI prompt block, and run a two-turn memory proof. See Coding Agent Onboarding for the human-readable version.
If you want to wire it manually, follow this page:
- Start the Docker Compose service.
- Connect your app with the TypeScript SDK, Python SDK, or MCP.
- Use one stable
userIdper end user. - Pass both the MemexAI tools and
memory.getSystemPrompt(...)into every model call. - Verify that one turn writes memory and a later turn recalls it.
What you are starting
TLDR: Docker runs Postgres plus a MemexAI HTTP service. Your app calls the service with MEMEX_API_KEY; operators use the admin UI with MEMEX_ADMIN_SECRET.
Under the hood:
- the service creates the
mx_*Postgres tables on startup - agent routes execute memory tools and write revisions/access logs
- admin routes let you inspect and correct memory files
memory.getSystemPrompt(...)fetches the prompt block that makes stored memory affect the next answer- optional model configuration powers
memory_memorize, answer synthesis inmemory_search, hybrid search embeddings, and background dreaming
Compose file
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: memexai
POSTGRES_PASSWORD: memexai
POSTGRES_DB: memexai
volumes:
- memexai_postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U memexai"]
interval: 5s
timeout: 5s
retries: 5
memexai:
image: soorajshankar/memexai:latest
depends_on:
postgres:
condition: service_healthy
environment:
DATABASE_URL: postgresql://memexai:memexai@postgres:5432/memexai
MEMEX_API_KEY: dev-agent-key
MEMEX_ADMIN_SECRET: dev-admin-secret
GEMINI_API_KEY: ...
MEMEX_DREAM_ENABLED: "false"
# MEMEX_SHARED_WRITE_MODE: rw # optional: let agent tools write shared/**
# MEMEX_TELEMETRY_DISABLED: "true" # optional opt-out
ports:
- "8080:8080"
volumes:
memexai_postgres_data:Start it:
docker compose up -dVerify it:
curl -fsS http://localhost:8080/healthThe API and admin UI are available at http://localhost:8080. For local defaults, open:
http://localhost:8080/admin?defaultAdminSecret=1&defaultApiKey=1&onboarding=1If your build does not support the default-login query params, open http://localhost:8080/admin and enter:
Admin secret: dev-admin-secret
Agent API key: dev-agent-keyConnect with the TypeScript SDK
npm install @memexai/sdk ai @ai-sdk/googleimport { MemexAI } from '@memexai/sdk'
import { generateText, stepCountIs } from 'ai'
import { createGoogleGenerativeAI } from '@ai-sdk/google'
const memex = new MemexAI({
url: 'http://localhost:8080',
apiKey: process.env.MEMEX_API_KEY ?? 'dev-agent-key',
})
const memory = memex.forUser({ userId: 'user_123', actor: 'assistant' })
const system = await memory.getSystemPrompt('You are a helpful assistant with durable user memory.')
const result = await generateText({
model: createGoogleGenerativeAI()('gemini-2.5-flash'),
system,
prompt: 'Remember that I prefer quiet neighborhoods near good schools.',
tools: memory.createAgenticToolset(),
stopWhen: stepCountIs(5),
})
console.log(result.text)memory.getSystemPrompt(...) adds the MemexAI prompt block to your base prompt. Without that prompt block or an equivalent system section, the tools can store memory, but the next response may not be conditioned on it.
Verify the memory loop
Run two separate calls for the same userId.
Turn one:
Remember that I prefer quiet neighborhoods near good schools.Turn two:
What kind of neighborhood do I prefer?A successful setup answers from stored memory on turn two. In the admin UI, the Files tab should show the user memory file, Revisions should show the write, and Access Logs should show the later read or search.
If turn one writes memory but turn two stays generic, check that the second model call uses the same userId and includes await memory.getSystemPrompt(...).
Connect with the Python SDK
python3 -m pip install memexaifrom memexai import MemexAI
memex = MemexAI(
url="http://localhost:8080",
api_key="dev-agent-key",
)
memory = memex.for_user("user_123", actor="assistant")
result = await memory.search("What does this user prefer?")
print(result.get("answer") or result["results"])
await memex.close()Connect with MCP
MCP clients can connect to the same service over SSE:
http://localhost:8080/v1/mcp/sse?userId=user_123&actor=claude&apiKey=dev-agent-keyOr through stdio after building the service:
bun run build:service
DATABASE_URL=postgresql://memexai:memexai@localhost:5433/memexai \
MEMEX_API_KEY=dev-agent-key \
node apps/service/dist/index.js --stdio --user-id user_123 --actor claude-desktopSee MCP Clients for details.
Model configuration
LLM-backed memory_memorize and agentic memory_search are configured on the service, not in the SDK.
GEMINI_API_KEY=...
GEMINI_MODEL=gemini-2.5-flash
# or
OPENAI_API_KEY=...
OPENAI_MODEL=gpt-4.1-miniWithout a service model, memory_search still works through Postgres full-text search, or hybrid pgvector search when embeddings are configured. memory_memorize returns MODEL_NOT_CONFIGURED.
For the smoothest first run, set GEMINI_API_KEY on the service so the agentic memory_memorize tool can decide what should become durable memory.
Shared writable mode
By default, agents can read shared/** but can write only user/**. To let agent tools contribute durable global knowledge, project canon, policies, style guides, or learned procedures to shared/**, set:
MEMEX_SHARED_WRITE_MODE=rwKeep this disabled for untrusted public-user agents. When enabled, prefer memory_patch over full rewrites and keep private user facts, secrets, raw transcripts, and untrusted external content out of shared/**.
Search configuration
MemexAI uses BM25 Postgres full-text search by default. With MEMEX_SEARCH_MODE=auto and a Gemini API key, the service also stores pgvector embeddings for memory files and runs hybrid BM25 + vector search with reciprocal rank fusion.
MEMEX_SEARCH_MODE=auto
GEMINI_API_KEY=...Set MEMEX_SEARCH_MODE=bm25 to force full-text search only.
Anonymous telemetry
MemexAI service telemetry is enabled by default for the OSS Docker image and service process. It sends anonymous product usage events to PostHog so the project can understand whether installs reach first memory, use MCP, enable dreaming, and hit service errors.
Telemetry never sends memory content, prompts, file paths, tool arguments, user IDs, API keys, admin secrets, or database URLs.
Disable service telemetry with:
MEMEX_TELEMETRY_DISABLED=trueTo use a different PostHog project or a self-hosted collector, set MEMEX_TELEMETRY_POSTHOG_KEY and MEMEX_TELEMETRY_POSTHOG_HOST.
Background dreaming
Dreaming is optional background memory consolidation for long-horizon agents. Use it when user memory keeps growing across sessions and you want MemexAI to clean the durable record between conversations: merge duplicate facts, compact fragmented notes, resolve direct corrections, refresh stale indexes, and keep files readable for the next agent trajectory.
Turn on the scheduler with:
MEMEX_DREAM_ENABLED=trueThe database dream_enabled config key is the runtime master switch. The admin Dreams panel and endpoints under /v1/admin/dream/* let operators read and update dream config, list user dream status, pause all dreaming, and pause or resume specific users.
Dreaming skips users with no qualifying memory changes, waits for the configured grace period after the latest write, excludes log files from consolidation, and avoids writing user/dream-log.md when there was nothing to update.
See Background Dreaming for the full operating model.