AutoMem
Memory framework
First committed by jack-arturo
Published in verygoodplugins/automem. Publisher page
827 GitHub stars
What it is
Long-term memory for AI assistants. Graph + vector store that recalls decisions, relationships, and context across sessions.
AutoGineer overview, from the brain’s own files
AutoMem is a memory service designed to provide AI assistants with persistent, long-term recall. By combining a graph database (FalkorDB) for structured relationships and a vector database (Qdrant) for semantic search, it enables agents to retrieve not just similar snippets, but the context and reasoning behind past decisions. It supports a wide range of AI tools via the Model Context Protocol (MCP) and a REST API, allowing a single memory store to be shared across multiple platforms like Claude, Cursor, and GitHub Copilot. The system includes automated consolidation cycles to manage memory relevance and importance over time, ensuring that the agent's knowledge base remains efficient as history grows.
How it works
Memory model: Hybrid
AutoGineer overview, from the brain’s own files
AutoMem operates as a service with two primary storage layers: FalkorDB for storing memories as nodes with typed relationships, and Qdrant for storing vector embeddings. When an AI client requests a recall, the system performs a hybrid query that combines semantic similarity, graph traversal, and temporal alignment to rank results. A background enrichment pipeline and consolidation engine process memories to maintain relevance, while the MCP bridge allows various AI agents to interact with the memory service locally or remotely.
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 9 |
| docs | docs | 18 |
| scripts | scripts | 39 |
| tests | tests | 78 |
| .railway | folder | 2 |
| automem | folder | 70 |
| benchmarks | folder | 9 |
| mcp-sse-server | folder | 14 |
The agent reads
- docs/COMPARISON.md evidence: README.md
The agent writes
- benchmarks/EXPERIMENT_LOG.md evidence: AGENTS.md
- docs/ evidence: AGENTS.md
Requirements
Runtimes: Python
Databases: FalkorDB, MongoDB, PostgreSQL, Qdrant, Redis, SQLite
API keys (by name): ADMIN_API_TOKEN, AUTOMEM_API_TOKEN, AUTOMEM_TEST_ADMIN_TOKEN, AUTOMEM_TEST_API_TOKEN, CLASSIFICATION_API_KEY, OPENAI_API_KEY, OPENROUTER_API_KEY, QDRANT_API_KEY, VOYAGE_API_KEY
Works with: Claude Code, OpenAI Codex, GitHub Copilot, Cursor, Kiro, OpenCode, Amp, Cline, JetBrains Junie, Devin (ex-Windsurf)
Set it up
This brain runs code automatically: 1 script. Review Makefile before opening the folder in Claude Code. No step below turns a hook on for you.
Makefile:echo "🔧 Setting up development environment..."; bash scripts/bootstrap_dev.sh; echo "✅ Virtual environment ready!"; echo "💡 Run 'source .venv/bin/activate' to activate"
- Not scanned by AutoGineerThe author’s README also describes installing it from a clone of its repository. Read its install section: AutoGineer did not scan that path. https://github.com/verygoodplugins/automem/blob/1a7ba1a6afe69835f62ad7f6013e33301d1ab83e/README.md#run-it
First committed by jack-arturo. Published in verygoodplugins/automem. Licence: MIT License.
Usage
AutoGineer overview, from the brain’s own files
- Connect local AI tools like Claude Desktop or Cursor to the AutoMem service via the MCP bridge.
- Use the REST API to programmatically store decisions, preferences, and project context.
- Query the memory service to retrieve the reasoning behind past technical choices or project milestones.
- Deploy the memory service on local infrastructure or cloud platforms like Railway for persistent agent access.
- “Why did we choose PostgreSQL?”
- The agent retrieves the decision node, the rationale, and the considered alternatives, providing the context behind the architectural choice.
- “What are our current preferences for message queues?”
- The agent traverses the graph to identify the relationship between Kafka and RabbitMQ, surfacing the team's preference for 'boring technology'.
Documentation by jack-arturo
<p align="center"> <img src="https://automem.ai/img/G_Vd7EYWYAM_3SF.jpeg" alt="AutoMem" width="600" /> </p>
<p align="center"> <a href="https://www.npmjs.com/package/@verygoodplugins/mcp-automem"><img src="https://img.shields.io/npm/v/@verygoodplugins/mcp-automem?label=mcp-automem" alt="npm version" /></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/verygoodplugins/automem" alt="License" /></a> <a href="https://automem.ai/discord"><img src="https://img.shields.io/badge/Discord-Join-5865F2?logo=discord&logoColor=white" alt="Discord" /></a> <a href="https://x.com/automem_ai"><img src="https://img.shields.io/badge/X-@automem__ai-000000?logo=x&logoColor=white" alt="X" /></a> <a href="https://automem.ai/benchmarks"><img src="https://img.shields.io/badge/LoCoMo%20(AMB)-85.1%25-success" alt="LoCoMo on the neutral Agent Memory Benchmark" /></a> <a href="benchmarks/EXPERIMENT_LOG.md#results"><img src="https://img.shields.io/badge/LongMemEval%20full-87.0%25-blueviolet" alt="LongMemEval full on AutoMem's internal harness: 87.0%" /></a> <a href="https://automem.ai/benchmarks"><img src="https://img.shields.io/badge/BEAM%2010M%20(AMB)-57.4%25-success" alt="BEAM 10M on the neutral Agent Memory Benchmark" /></a> <a href="https://railway.com/deploy/automem-ai-memory-service?referralCode=VuFE6g&utm_medium=integration&utm_source=github&utm_campaign=generic"><img src="https://img.shields.io/badge/Deploy%20on-Railway-0B0D0E?logo=railway&logoColor=white" alt="Deploy on Railway" /></a> </p>
<p align="center"> <strong>Long-term memory for AI assistants — fast, private, and yours.</strong> </p>
AutoMem
AutoMem gives your AI a memory that survives the chat.
Save the decisions, preferences, notes, and context that matter. The next time you open Claude, Cursor, Codex, ChatGPT, or another connected assistant, it can bring back the right details instead of making you repeat yourself.
Ask, “Why did we choose PostgreSQL?” and AutoMem can return the decision, the alternatives you considered, the principle behind it, and the work that followed — not just a pile of similarly worded snippets.
Why AutoMem feels different
No LLM call in the middle of recall. AutoMem looks up memories directly through its graph and vector index. That keeps normal retrieval fast and avoids an extra generative-LLM charge every time your assistant needs context. It still uses embeddings — from Voyage, OpenAI, or a local provider — and optional enrichment can add more structure over time.
More than vector search. A vector match finds something similar; AutoMem also records typed relationships between memories. It can follow the connections between a decision, its rationale, and its consequences, so your assistant has a better chance of returning the why, not only the words it recognizes.
One memory across your tools. Use the local MCP bridge with Claude Desktop, Cursor, Claude Code, Codex, Copilot, and more. For cloud agents, Remote MCP connects the same service to ChatGPT Developer Mode, Claude.ai, and ElevenLabs over HTTPS. Your memory is not locked to one chat app.
Own the data and the setup. Run AutoMem locally with Docker, on your own infrastructure, or as a small Railway service group. It exposes both MCP and a REST API, so it fits into the tools and workflows you already use.
Proven where long context gets hard
On the independent Agent Memory Benchmark's BEAM long-context tests, AutoMem scored 57.4% at 10 million source tokens while giving the answerer an average of only ~2.6–4.8k retrieved tokens. That is the kind of efficiency that lets memory stay useful as an agent's history grows.
The full picture — test setup, raw outputs, methodology, historical runs, and reproduction commands — is in automem.ai/benchmarks and benchmarks/EXPERIMENT_LOG.md.
How it works
AutoMem combines two storage layers behind a single API:
FalkorDB stores memories as nodes with 11 typed relationships between them. The graph is the canonical record.
Qdrant stores an embedding for every memory. Recall is a hybrid query — semantic similarity, graph traversal, temporal alignment, tag overlap, and importance — ranked by a 9-component score.
flowchart TB
subgraph service [AutoMem Service Flask]
API[REST API<br/>Memory Lifecycle]
Enrichment[Background Enrichment<br/>Pipeline]
Consolidation[Consolidation<br/>Engine]
Backups[Automated Backups<br/>Optional]
end
subgraph storage [Dual Storage Layer]
FalkorDB[(FalkorDB<br/>Graph Database)]
Qdrant[(Qdrant<br/>Vector Database)]
end
Client[AI Client] -->|Store/Recall/Associate| API
API --> FalkorDB
API --> Qdrant
Enrichment -->|11 edge types<br/>Pattern nodes| FalkorDB
Enrichment -->|Semantic search<br/>1024-d vectors| Qdrant
Consolidation --> FalkorDB
Consolidation --> Qdrant
Backups -.->|Optional| FalkorDB
Backups -.->|Optional| QdrantIf Qdrant is unavailable, the graph still serves recall in a degraded mode. If FalkorDB is down, the API returns 503 — the graph is the source of truth.
Multi-hop bridge discovery
Ask "why boring tech for Kafka?" and AutoMem doesn't just match the word "Kafka". It traverses the graph from the seed memories to find the bridge that connects them:
Seed 1: "Migrated to PostgreSQL for operational simplicity"
Seed 2: "Evaluating Kafka vs RabbitMQ for message queue"
Bridge: "Team prefers boring technology — proven, debuggable systems"
Both seeds carry an EXEMPLIFIES edge to the bridge memory. AutoMem ranks the bridge above the seeds and surfaces it in the recall response, so the assistant answers with your reasoning, not isolated facts. Tune via expand_relations, relation_limit, and expansion_limit on GET /recall.
11 authorable relationship types
| Type | Use case | Example |
|---|---|---|
RELATES_TO | General connection | Bug report → Related issue |
LEADS_TO | Causal relationship | Problem → Solution |
OCCURRED_BEFORE | Temporal sequence | Planning → Execution |
PREFERS_OVER | User preferences | PostgreSQL → MongoDB |
EXEMPLIFIES | Pattern examples | Code review → Best practice |
CONTRADICTS | Conflicting info | Old approach → New approach |
REINFORCES | Supporting evidence | Decision → Validation |
INVALIDATED_BY | Outdated info | Legacy docs → Current docs |
EVOLVED_INTO | Knowledge evolution | Initial design → Final design |
DERIVED_FROM | Source tracking | Implementation → Spec |
PART_OF | Hierarchical structure | Feature → Epic |
Three more edge types are added automatically by the enrichment pipeline and consolidation engine: SIMILAR_TO, PRECEDED_BY, and DISCOVERED.
Memory consolidation, neuroscience-inspired
AutoMem implements biological memory consolidation cycles. Wrong rabbit holes fade naturally. Important memories with strong connections strengthen over time.
| Cycle | Frequency | Purpose |
|---|---|---|
| Decay | Daily | Exponential relevance scoring (age, access, connections, importance) |
| Creative | Weekly | REM-like processing that discovers non-obvious connections |
| Cluster | Monthly | Groups similar memories, generates meta-patterns |
| Forget | Off by default | Archives low-relevance memories (<0.2), deletes very old (<0.05) |
Tune intervals via CONSOLIDATION_*_INTERVAL_SECONDS. See docs/ENVIRONMENT_VARIABLES.md.
For more on the recall scoring formula, enrichment internals, and how AutoMem differs from RAG and pure vector databases, see docs/COMPARISON.md.
Research foundation
AutoMem implements techniques from peer-reviewed memory research:
HippoRAG 2 (Ohio State, 2025) — graph + vector hybrid for associative memory
A-MEM (2025) — Zettelkasten-inspired dynamic memory organization
MELODI (DeepMind, 2024) — gist-based memory compression
ReadAgent (DeepMind, 2024) — episodic memory for context extension
Full writeups, findings, and how AutoMem implements each → docs/RESEARCH.md.
Run it
Railway (60 seconds)
Recommended Railway projects run AutoMem as a small service group: automem (the API), automem-graph-viewer (the standalone UI), falkordb (graph), qdrant (vectors), and mcp-automem (the MCP bridge for ChatGPT, Claude.ai, and ElevenLabs). Services use pre-built Docker images and auto-redeploy on :stable, so Railway does not spend compute rebuilding source.
→ Full setup: INSTALLATION.md
Docker Compose (local)
git clone https://github.com/verygoodplugins/automem.git
cd automem
make dev| Service | URL | Purpose |
|---|---|---|
| AutoMem API | http://localhost:8001 | Memory REST API |
| FalkorDB | localhost:6379 | Graph database |
| Qdrant | localhost:6333 | Vector database |
| FalkorDB Browser | http://localhost:3000 | Local graph inspection UI |
Database and browser ports bind to localhost by default; the API binding is unchanged.
→ Full setup: INSTALLATION.md
Python (development)
make install
source .venv/bin/activate
PORT=8001 python app.pyRequires Python 3.10+ (3.12 recommended). → INSTALLATION.md
Contributing: feature PRs target the develop branch. main only moves via validated release merges, so users deploying from main (e.g. Railway auto-deploys) see one deploy per release instead of one per PR.
Connect your AI
| Client | Mode | Setup |
|---|---|---|
| Claude Desktop, Cursor, Claude Code, Codex, Copilot, Antigravity | Local MCP bridge | npx @verygoodplugins/mcp-automem setup |
| ChatGPT (developer mode), Claude.ai web/mobile, ElevenLabs Agents | Remote MCP (HTTPS) | docs/MCP_SSE.md |
| Anything else | Direct REST API | docs/API.md |
The MCP bridge is published as @verygoodplugins/mcp-automem. It handles client-specific config (rules files, hooks, templates) and proxies to your AutoMem service — local or Railway.
Direct API call:
import requests
token = "your-automem-api-token"
requests.post(
"https://your-automem.railway.app/memory",
headers={"Authorization": f"Bearer {token}"},
json={
"content": "Chose PostgreSQL over MongoDB for ACID compliance",
"type": "Decision",
"tags": ["database", "architecture"],
"importance": 0.9,
},
)Screenshots
<!-- CAPTURE CHECKLIST — replace each placeholder image once captured: 1. docs/img/graph-recall.png — FalkorDB browser at http://localhost:3000 showing a memory node with multiple typed edges visible (PREFERS_OVER, EXEMPLIFIES, RELATES_TO). Proves the graph is real. 2. docs/img/claude-recall.png — Claude Desktop conversation where the assistant cites a recalled memory inline, with the AutoMem MCP tool call visible in the trace. 3. docs/img/railway-services.png — Railway dashboard showing the production service group (automem, automem-graph-viewer, mcp-automem, qdrant, falkordb). A version exists as a GitHub user-attachment in INSTALLATION.md; capture a clean version and host it in-repo. Until each PNG exists, the table cells will render as broken-image icons on GitHub. -->
Screenshots will be added once the referenced in-repo image assets are available.
Known limitations
AutoMem is pre-1.0 and honest about its rough edges. The active ones for recall quality:
Tags are a hard gate, not a soft boost. Tags filter before scoring, so a memory missing the queried tag won't surface even on a perfect semantic match. Within a tag scope, high-importance off-topic memories can still over-rank — mitigated by the opt-in
RECALL_RELEVANCE_GATE, not yet on by default (#130).Temporal and preference updates. Recall doesn't yet reliably prefer the newest version of a conflicting fact, or fully resolve multi-session preference updates. The
RECALL_RECENCY_BIAS=autore-rank helps temporal-intent queries but stays opt-in pending broader validation (#158, #159).The MCP SSE bridge doesn't forward
state_mode. The HTTP recall API supports it; the SSE proxy doesn't pass it through yet (#172).Entity-node synthesis is experimental and off by default. First-class
Entitynodes (IDENTITY_SYNTHESIS_ENABLED) are gated off while people-entity word-pair noise is addressed (#181).
Docs, community, and license
Setup
Installation guide — Railway, Docker, development
Qdrant setup — vector database configuration
Environment variables — full reference
API and integration
API reference — endpoints, scoring, enrichment
Remote MCP — ChatGPT, Claude.ai, ElevenLabs
Migrations — embedding dimensions, 0.16.0 data migrations, MCP SQLite import
Research and comparison
Research foundation — papers and how AutoMem implements them
Comparison — vs. RAG, vector DBs, building your own
Benchmark history — internal LoCoMo / LongMemEval harness runs + the neutral AMB (BEAM + Core-3) summary
AMB head-to-head + reproducibility — neutral Agent Memory Benchmark results and the
AUTOMEM_REPRODUCE.md"run it yourself" recipe
Operations
Scripts — maintenance, migration, recovery, and eval tooling, by lifecycle
Testing guide — unit, integration, benchmarks
Community
automem.ai — official site
Discord — community chat
X / @automem_ai — updates
YouTube / @AutoJackBot — tutorials
GitHub issues — bugs and feature requests
Sibling repos
mcp-automem— universal MCP bridge / install funnelautomem-evals— exploratory recall-quality labautomem-graph-viewer— standalone graph visualization
MIT licensed. Deploy anywhere. No vendor lock-in.
INSTALLATION.md
Installation & Deployment Guide
Complete setup instructions for AutoMem across all environments.
Table of Contents
Prerequisites
Quick Start
Deployment
Railway (Recommended)
Docker Compose (Local)
Bare API (Development)
Configuration
API Reference
Migration
Testing
Troubleshooting
Prerequisites
Python 3.10+ (the codebase supports 3.10 and newer; local bootstrap is standardized on 3.12)
Docker & Docker Compose (for bundled stack)
Railway CLI (optional, only needed if you prefer the terminal over the dashboard):
npm i -g @railway/cli
Quick Start
Local Development (Recommended)
# Clone repository
git clone https://github.com/verygoodplugins/automem.git
cd automem
# Create virtual environment (standardized on Python 3.12 for local dev)
make install
source .venv/bin/activate # On Windows (WSL or Git Bash): same command; native cmd: .venv\Scripts\activate.bat; PowerShell: .venv\Scripts\Activate.ps1
# Start all services (FalkorDB + Qdrant + API)
make devmake install looks for python3.12 first (and a few common install locations), then falls back to python3 if it is already 3.12. It exits with an error only when no Python 3.12 interpreter can be found. Override the interpreter with the AUTOMEM_PYTHON environment variable (accepts a bare command name or an absolute path).
Services:
API:
http://localhost:8001FalkorDB:
localhost:6379Qdrant:
localhost:6333FalkorDB Browser (official local graph UI):
http://localhost:3000
/viewer is not the local FalkorDB browser. It redirects/bootstraps to a standalone graph viewer only when GRAPH_VIEWER_URL is configured.
Optional Enhancement:
Install spaCy for richer entity extraction:
pip install spacy
python -m spacy download en_core_web_smDeployment
Railway (Recommended)
What is Railway? Cloud hosting platform (like Heroku, but modern) where your AutoMem service runs 24/7 in containers.
Cost breakdown:
✅ $5 free credits for 30-day trial (no credit card required)
✅ ~$0.50/month typical AutoMem usage after trial
✅ $1/month minimum if you use less than that
✅ No image-build cost — services pull pre-built Docker images from GitHub Container Registry, so you only pay Railway compute
Should You Deploy to Railway?
✅ Deploy to Railway if you:
Use multiple devices - Access same memories from laptop, desktop, mobile
Collaborate with a team - Share memories across team members
Want always-on availability - Don't want to start Docker containers daily
Need remote access - Use AI tools on tablet/phone without local services
Value simplicity - Set it once, forget about it
🏠 Stick with local if you:
Work on one machine - Don't need cross-device sync
Privacy first - Keep all memories on your hardware
Have Docker skills - Comfortable managing local services
Prefer zero cost - No cloud bills, just local compute
Developing/testing - Local is faster for iteration
<!-- Screenshot placeholder: docs/img/railway-services.png — Railway dashboard showing the production service group (automem, automem-graph-viewer, mcp-automem, qdrant, falkordb). Capture once and host in-repo so this stops depending on a fragile GitHub user-attachment URL. -->
Screenshot pending: Railway services dashboard image will be added at docs/img/railway-services.png once captured.
Option A: One-Click Deploy ⭐ (Fastest)
What this does:
Creates the core Railway services from pre-built Docker images:
automem←ghcr.io/verygoodplugins/automem:stablemcp-automem←ghcr.io/verygoodplugins/mcp-automem:stableqdrant←qdrant/qdrant:latestfalkordb←falkordb/falkordb:latest
The standalone graph viewer is a companion service to add after the core deploy:
automem-graph-viewer←ghcr.io/verygoodplugins/automem-graph-viewer:stable
Sets up persistent storage and volumes
Generates secure API tokens (
AUTOMEM_API_TOKEN,ADMIN_API_TOKEN)Configures internal networking (
FALKORDB_HOST,FALKORDB_PORT)Generates public domain automatically
After clicking:
Sign in with GitHub (if not logged in)
Review environment variables
Add
VOYAGE_API_KEYfor the recommendedvoyage-4embeddings (OpenAI is supported as the API fallback)Click "Deploy"
Wait ~60 seconds for deployment to complete ✅
Next: Skip to Get Your AutoMem URL below to get your endpoint.
How Updates Work
Once deployed, your Railway services pull updates automatically — no git push, no rebuild on every commit:
| Service | Image | Update cadence |
|---|---|---|
automem | ghcr.io/verygoodplugins/automem:stable | Auto-redeploy nightly |
automem-graph-viewer | ghcr.io/verygoodplugins/automem-graph-viewer:stable | Auto-redeploy nightly |
mcp-automem | ghcr.io/verygoodplugins/mcp-automem:stable | Auto-redeploy nightly |
qdrant | qdrant/qdrant:latest | Auto-redeploy nightly |
falkordb | falkordb/falkordb:latest | Auto-redeploy nightly |
The :stable tag always points at the most recent vX.Y.Z release tag. New releases ship through release-please — when a release PR is merged to main, GitHub Actions builds the image, publishes the new version (v0.16.0, v0.16, v0), and re-points :stable. See CHANGELOG.md for the release history.
Want to ship faster than nightly? In Railway, click the service → Deployments → Deploy latest to pull :stable immediately.
Want to pin a specific version? Edit the service's image (Settings → Source → Image) from :stable to :v0.16.0 (or any published vX.Y.Z). Roll back the same way.
Using the legacy MCP image path? ghcr.io/verygoodplugins/automem/mcp-sse-server:stable is dual-published from the same workflow and tracks the same release tags — existing deployments keep working without changes.
Option B: Manual Setup (Advanced)
<details> <summary><b>Need more control? Click to expand manual deployment steps</b></summary>
Step 1: Prerequisites
# Install Railway CLI
npm i -g @railway/cli
# Log in
railway login
# (Optional) Initialize project
railway initStep 2: Provision FalkorDB
Create new Railway service:
Image:
falkordb/falkordb:latestAdd persistent volume (critical for data persistence)
Note the internal connection details (shown in service settings)
Optional: Set
REDIS_PASSWORDfor authentication
Railway automatically exposes:
REDIS_HOSTREDIS_PORTREDIS_PASSWORD
Reference these in AutoMem config via ${{service.<name>.internalHost}}
Step 3: Deploy AutoMem from the published Docker image
Create a new Railway service from the AutoMem image:
In Railway → + New → Deploy from Docker image
Image:
ghcr.io/verygoodplugins/automem:stable(Optional) pin a specific version with
:v0.16.0instead of:stableAdd a public domain: Settings → Networking → Generate Domain
Configure environment variables:
Variable Description Required AUTOMEM_API_TOKENAuth token for all client calls ✅ Yes ADMIN_API_TOKENToken for admin/enrichment endpoints ✅ Yes FALKORDB_HOSTInternal hostname of FalkorDB service ✅ Yes FALKORDB_PORTFalkorDB port (usually 6379)✅ Yes VOYAGE_API_KEYRecommended API key for voyage-4embeddingsRecommended OPENAI_API_KEYOpenAI-compatible embedding fallback Optional EMBEDDING_PROVIDERProvider selection ( autoprefers Voyage)autoFALKORDB_PASSWORDPassword if set on FalkorDB If enabled QDRANT_URLQdrant Cloud endpoint Optional QDRANT_API_KEYQdrant API key If using Qdrant Verify deployment:
curl https://your-automem.up.railway.app/healthExpected:
{"status": "healthy"}503= FalkorDB connection issue (check host/port/password)(Optional) Add the MCP bridge service the same way:
Image:
ghcr.io/verygoodplugins/mcp-automem:stableSet
AUTOMEM_API_URLto the internal URL ofautomem(e.g.http://automem.railway.internal:8001)Set
AUTOMEM_API_TOKENto the same token as the API serviceGenerate a public domain so cloud AI clients (ChatGPT, Claude.ai, ElevenLabs) can reach it
Step 4: Add the Graph Viewer companion service
Create a new Railway service from the Graph Viewer image:
In Railway → + New → Deploy from Docker image
Image:
ghcr.io/verygoodplugins/automem-graph-viewer:stableAdd a public domain: Settings → Networking → Generate Domain
Wire the API service to the viewer domain:
Set these on the
automemAPI service, then redeploy/restart the API:GRAPH_VIEWER_URL=https://your-viewer.up.railway.app VIEWER_ALLOWED_ORIGINS=https://your-viewer.up.railway.appLeave database and private-network credentials off the viewer service.
The viewer is browser-side UI. It calls the public AutoMem API URL supplied by
/viewerbootstrap (?server=<automem-origin>) or by the token prompt. Railway private domains such as*.railway.internalonly work for service-to-service traffic and cannot be reached by a user's browser.The standalone viewer service normally needs no Railway variables. Do not set
VITE_API_TARGET,VITE_BASE, orVITE_ENABLE_HAND_CONTROLSin production.VITE_API_TARGETis only for the local Vite dev proxy,VITE_BASEis not a supported variable, and hand controls are controlled by the UI at runtime.
Get Your AutoMem URL
Click on your automem service (the API, not FalkorDB)
Go to "Settings" tab
Scroll to "Networking" → "Public Networking"
Click "Generate Domain" (if not already generated)
Copy the URL - looks like:
automem-production-abc123.up.railway.app
✅ Save this URL! You'll need it for connecting your AI tools.
</details>
What You Just Built
flowchart TB
subgraph devices [Your AI Tools]
Laptop[💻 Laptop]
Desktop[🖥️ Desktop]
Mobile[📱 Mobile]
Tablet[📱 Tablet]
end
subgraph railway [Railway Cloud - Your Free Tier]
direction TB
Domain[Public Domain<br/>your-url.up.railway.app<br/>HTTPS Port 443]
ViewerDomain[Viewer Public Domain<br/>viewer-url.up.railway.app<br/>HTTPS Port 443]
subgraph services [Services]
API[AutoMem API<br/>Flask Service<br/>Internal Port 8001]
Viewer[Graph Viewer<br/>React/Three.js<br/>Static Service]
MCP[MCP Bridge<br/>Remote Clients]
FalkorDB[(FalkorDB<br/>Graph Database<br/>Port 6379)]
Qdrant[(Qdrant<br/>Vector Store<br/>Port 6333)]
Volume[Persistent Volume<br/>Data Storage]
end
Domain -->|Routes to| API
ViewerDomain -->|Routes to| Viewer
API -->|/viewer bootstrap| ViewerDomain
Viewer -->|Browser API calls public domain| Domain
MCP -->|Internal API calls| API
API -->|Internal networking| FalkorDB
API -->|Internal networking| Qdrant
FalkorDB -->|Mounts| Volume
end
Laptop -->|HTTPS| Domain
Desktop -->|HTTPS| Domain
Mobile -->|HTTPS| Domain
Tablet -->|HTTPS| Domain
Cloud[☁️ Access from anywhere<br/>Any device, anytime]
devices -.->|Always available| Cloud
railway -.->|24/7 uptime| CloudVerify Deployment
Test that everything works:
# Replace with YOUR Railway URL
curl https://automem-production-abc123.up.railway.app/healthExpected response:
{ "status": "healthy", "falkordb": "connected" }Got an error?
503 Service Unavailable= FalkorDB can't connect. Check:FALKORDB_HOSTis set tofalkordb.railway.internalor${{FalkorDB.RAILWAY_PRIVATE_DOMAIN}}FalkorDB service is running (green dot in Railway dashboard)
Persistent volume is mounted at
/data
401 Unauthorized= You're trying a protected endpoint./healthshould work without auth.
Next Steps
Store first memory:
curl -X POST https://your-automem.railway.app/memory \
-H "Authorization: Bearer $AUTOMEM_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"First memory from Railway","importance":0.7}'Connect your AI tools - Use your Railway URL in:
Remote MCP for ChatGPT/Claude.ai/ElevenLabs: see docs/MCP_SSE.md
Claude Desktop, Cursor, Claude Code, etc.
Set up monitoring (optional): See Health Monitoring Guide
👉 Full Railway Guide - Advanced configuration, monitoring, troubleshooting 👉 Post-Deploy Checklist - Step-by-step verification
Docker Compose (Local)
Run complete stack locally:
# Start all services
make dev
# Or manually with docker compose
docker compose up -ddocker-compose.yml includes:
AutoMem Flask API (port 8001)
FalkorDB (port 6379)
Qdrant HTTP and gRPC (ports 6333 and 6334)
FalkorDB Browser via FalkorDB built-in UI (port 3000)
FalkorDB, its browser, and both Qdrant ports bind to 127.0.0.1 by default.
AutoMem reaches the databases over the Docker network, so this does not change
connections between containers. The AutoMem API port keeps its existing binding.
To make the database ports available on a different host address, explicitly set
AUTOMEM_DB_BIND_ADDRESS when starting Compose. For IPv6, use brackets (for
example, [::1]). Binding to 0.0.0.0 exposes the database ports on every IPv4
interface; secure them with authentication and network controls before doing so.
Localhost binding limits network exposure but does not authenticate local users.
Use Docker Engine 28 or newer: older Docker releases have a localhost-publishing
limitation.
Existing local installs: Updating the checkout alone does not change running
containers. After updating docker-compose.yml, recreate the two database services
to apply the new bindings. This briefly interrupts database connections but keeps
the named data volumes:
docker compose up -d --no-deps falkordb qdrantCheck docker compose ps and the AutoMem /health endpoint afterward. The guided
installer's existing-server update rebuilds the API only, so it does not apply
these database bindings by itself.
Stop services:
make stop
# Or: docker compose downBare API (Development)
Run API without Docker (requires external FalkorDB):
# Activate virtual environment
source .venv/bin/activate
# Set connection details
export FALKORDB_HOST=localhost
export FALKORDB_PORT=6379
export PORT=8001
# Optional: Qdrant configuration (pick one)
export QDRANT_URL=http://localhost:6333 # Full URL (Qdrant Cloud or explicit)
# export QDRANT_HOST=localhost # OR just hostname (auto-constructs URL)
# export QDRANT_API_KEY=your_key # Only needed for Qdrant Cloud
# Run API
python app.pyWithout Qdrant, semantic vector storage is unavailable. With Qdrant and EMBEDDING_PROVIDER=auto, AutoMem tries configured Voyage, OpenAI, explicitly configured Ollama, and then local FastEmbed. For Railway, configure Voyage rather than depending on the FastEmbed fallback.
Configuration
Environment Variables
AutoMem loads configuration from:
Process environment
.envin project root~/.config/automem/.env
Core Settings
| Variable | Description | Default |
|---|---|---|
PORT | API server port | 8001 |
FALKORDB_HOST | FalkorDB hostname | localhost |
FALKORDB_PORT | FalkorDB port | 6379 |
FALKORDB_PASSWORD | FalkorDB password (if auth enabled) | unset |
FALKORDB_GRAPH | Graph database name | memories |
Authentication
| Variable | Description | Default |
|---|---|---|
AUTOMEM_API_TOKEN | Required for all endpoints except /health | unset (required) |
ADMIN_API_TOKEN | Required for /admin/* and enrichment controls | unset (required) |
Client authentication methods (in order of preference):
Authorization: Bearer <token>headerX-API-Key: <token>header?api_key=<token>query parameter
Admin operations additionally require X-Admin-Token: <admin_token> header.
Vector Search (Optional)
| Variable | Description | Default |
|---|---|---|
QDRANT_URL | Qdrant Cloud endpoint (takes precedence over QDRANT_HOST) | unset |
QDRANT_HOST | Qdrant hostname for self-hosted (auto-constructs http://host:port) | unset |
QDRANT_PORT | Qdrant port (used with QDRANT_HOST) | 6333 |
QDRANT_API_KEY | Qdrant authentication (if API-key auth is enabled) | optional |
QDRANT_COLLECTION | Qdrant collection name | memories |
VECTOR_SIZE | Embedding dimension | 1024 |
EMBEDDING_PROVIDER | Embedding provider selection | auto |
EMBEDDING_MODEL | OpenAI embedding model | text-embedding-3-small |
VOYAGE_API_KEY | Voyage API key (Voyage provider) | unset |
VOYAGE_MODEL | Voyage model (Voyage provider) | voyage-4 |
OPENAI_API_KEY | API key (OpenAI or compatible provider) | unset |
OPENAI_BASE_URL | Custom endpoint for OpenAI-compatible providers | unset |
OLLAMA_BASE_URL | Ollama endpoint for intentional local/self-hosted use | http://localhost:11434 |
OLLAMA_MODEL | Pulled Ollama embedding model | nomic-embed-text |
👉 New to Qdrant? See the Qdrant Setup Guide for setup options (self-hosted on Railway or Qdrant Cloud).
Upgrade safety:
VECTOR_SIZE_AUTODETECT=true(default) adopts an existing collection dimension to avoid a startup mismatch. It does not migrate vectors: changing embedding provider or model requires recreating the collection and re-embedding, even when both models are 1024d.The recommended setup is Voyage (
voyage-4) at 1024d. If Voyage is unavailable, an OpenAI-compatible provider is the API fallback. Use FastEmbed only for intentional local/self-hosted deployments; its 1024d cloud fallback can add roughly 4 GB RSS and materially increase hosting cost.
Enrichment Pipeline
| Variable | Description | Default |
|---|---|---|
ENRICHMENT_MAX_ATTEMPTS | Retry limit for failed enrichments | 3 |
ENRICHMENT_SIMILARITY_LIMIT | Number of semantic neighbors | 5 |
ENRICHMENT_SIMILARITY_THRESHOLD | Min cosine score for SIMILAR_TO | 0.8 |
ENRICHMENT_IDLE_SLEEP_SECONDS | Sleep when queue empty | 2 |
ENRICHMENT_FAILURE_BACKOFF_SECONDS | Backoff between retries | 5 |
ENRICHMENT_ENABLE_SUMMARIES | Auto-generate summaries | true |
ENRICHMENT_SPACY_MODEL | spaCy model for entities | en_core_web_sm |
Consolidation Engine
| Variable | Description | Default |
|---|---|---|
CONSOLIDATION_DECAY_INTERVAL_SECONDS | Decay cycle frequency | 3600 (1 hour) |
CONSOLIDATION_DECAY_IMPORTANCE_THRESHOLD | Min importance to process (empty = all) | 0.3 |
CONSOLIDATION_CREATIVE_INTERVAL_SECONDS | Creative association cycle | 3600 (1 hour) |
CONSOLIDATION_CLUSTER_INTERVAL_SECONDS | Clustering cycle | 21600 (6 hours) |
CONSOLIDATION_FORGET_INTERVAL_SECONDS | Forgetting cycle | 86400 (1 day) |
Search Scoring (Advanced)
| Variable | Description | Default |
|---|---|---|
RECALL_RELATION_LIMIT | Max related memories per result | 5 |
SEARCH_WEIGHT_* | Custom scoring weights | See app.py defaults |
API Reference
Authentication
All endpoints except /health require authentication via:
Authorization: Bearer <AUTOMEM_API_TOKEN>(recommended)X-API-Key: <AUTOMEM_API_TOKEN>?api_key=<AUTOMEM_API_TOKEN>
Admin endpoints additionally require:
X-Admin-Token: <ADMIN_API_TOKEN>
Endpoints
GET /health
Check service health.
Response:
{
"status": "healthy",
"falkordb": "connected",
"qdrant": "connected"
}POST /memory
Store a new memory.
Request Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
content | string | ✅ Yes | Memory content (min 1 char) |
tags | array | No | Tags for categorization (e.g., ["decision", "database"]) |
importance | float | No | Importance score 0.0-1.0 (default: 0.5) |
type | string | No | Memory classification (default: auto-classified) |
confidence | float | No | Confidence in type 0.0-1.0 (default: 0.9 if type provided, auto-computed otherwise) |
metadata | object | No | Custom metadata (any JSON object) |
timestamp | string | No | ISO 8601 timestamp (default: current time) |
embedding | array | No | Vector embedding (auto-generated if omitted; default 1024d with voyage-4) |
t_valid | string | No | ISO timestamp when memory becomes valid |
t_invalid | string | No | ISO timestamp when memory expires |
updated_at | string | No | ISO timestamp of last update (default: timestamp) |
last_accessed | string | No | ISO timestamp of last access (default: updated_at) |
Valid Memory Types:
Decision- Strategic or technical decisionsPattern- Recurring approaches or best practicesPreference- User/team preferencesStyle- Code style or formatting preferencesHabit- Regular behaviors or workflowsInsight- Key learnings or realizationsContext- General contextual information (default)
Request Example:
{
"content": "Chose PostgreSQL over MongoDB for ACID compliance",
"type": "Decision",
"confidence": 0.95,
"tags": ["database", "architecture"],
"importance": 0.9,
"metadata": {
"source": "architecture-meeting",
"alternatives": ["MongoDB", "MySQL"],
"deciding_factors": ["ACID", "team_expertise"]
},
"timestamp": "2025-09-16T12:37:21Z"
}Response: 201 Created
{
"status": "success",
"memory_id": "uuid-generated-id",
"stored_at": "2025-09-16T12:37:21Z",
"type": "Decision",
"confidence": 0.95,
"qdrant": "stored",
"embedding_status": "generated",
"enrichment": "queued",
"metadata": {...},
"timestamp": "2025-09-16T12:37:21Z",
"updated_at": "2025-09-16T12:37:21Z",
"last_accessed": "2025-09-16T12:37:21Z"
}Notes:
Explicit
typepreferred: Sendtypewhen you know the classification for immediate, accurate categorizationAuto-classification fallback: Omit
typeto let enrichment pipeline classify based on contentEmbedding auto-generation: Service generates vectors through the configured provider;
autoprefers Voyage, then OpenAI, configured Ollama, FastEmbed, and finally placeholdersTimestamp defaults: All time fields default to current UTC time if not provided
Background enrichment: Entity extraction and relationship building queued automatically
Type validation: Invalid types return
400 Bad Requestwith list of valid optionsIDs are server-generated: Clients cannot set
id; AutoMem always assigns a UUID to prevent collisions/overwrites.
GET /recall
Retrieve memories using hybrid search.
Query Parameters:
| Parameter | Description | Example |
|---|---|---|
query | Full-text search string | database migration |
embedding | Vector (comma-separated, dimension matches VECTOR_SIZE) | 0.12,0.56,... |
limit | Max results (1-50) | 10 |
time_query | Natural time phrases | today, last week, last 7 days |
start | ISO timestamp (lower bound) | 2025-09-01T00:00:00Z |
end | ISO timestamp (upper bound) | 2025-09-30T23:59:59Z |
tags | Tag filters (multiple allowed) | slack, decision |
tag_mode | any or all | any (default) |
tag_match | prefix or exact | prefix (default) |
context | High-level context label | coding-style, preference |
language | Explicit language hint | python, typescript |
active_path | Active file path (used to infer language/context) | /Users/jack/project/app.py |
context_tags | Comma or list of tags to prioritize | coding-style,python |
context_types | Memory types to prioritize | Style,Preference |
priority_ids | Specific memory IDs to treat as anchors | uuid-1,uuid-2 |
Examples:
# Hybrid query with tags
GET /recall?query=handoff&tags=slack&tag_mode=any
# Semantic search only
GET /recall?embedding=0.12,0.56,...&limit=10
# Time-based recall
GET /recall?query=database&time_query=last%20month
# Tag prefix matching (matches slack:*, slack:U123:*, etc.)
GET /recall?tags=slack&tag_match=prefix
# Require all tags
GET /recall?tags=deployment&tags=success&tag_mode=allResponse:
{
"status": "success",
"results": [
{
"id": "memory-uuid",
"match_type": "vector",
"final_score": 0.82,
"score_components": {
"vector": 0.64,
"tag": 0.5,
"recency": 0.9,
"exact": 1.0
},
"memory": {
"content": "...",
"tags": ["deployment"],
"importance": 0.9,
"timestamp": "2025-09-16T12:37:21Z"
}
}
],
"time_window": {
"start": "2025-09-01T00:00:00+00:00",
"end": "2025-09-30T23:59:59+00:00"
},
"tags": ["slack"],
"count": 5,
"context_priority": {
"language": "python",
"context": "coding-style",
"priority_tags": ["coding-style","python"],
"priority_types": ["Style","Preference"],
"injected": false
}
}When no context hints are provided, recall behaves exactly as before (hybrid vector/keyword/tags/time). Context hints simply boost and, if needed, inject style/preference memories relevant to the active file; see docs/API.md for full details.
PATCH /memory/<id>
Update an existing memory.
Request: (all fields optional)
{
"content": "Updated content",
"tags": ["new-tag"],
"importance": 0.95,
"metadata": { "updated": true }
}Notes:
Changing content triggers automatic re-embedding
Partial updates supported (only send fields to change)
DELETE /memory/<id>
Delete a memory from both FalkorDB and Qdrant.
Response:
{
"status": "success",
"message": "Memory deleted successfully"
}GET /memory/by-tag
Filter memories by tags.
Query Parameters:
tags- One or more tags (multipletagsparams or comma-separated)limit- Max results per page (default 20, max 200)offset- Zero-based page offset (default 0)
Example:
GET /memory/by-tag?tags=deployment&tags=success&limit=20&offset=0Returns the current page of most important/recent memories matching any requested tag, plus
pagination metadata (limit, offset, has_more).
DELETE /memory/by-tag
Delete all memories matching any requested tag.
Query Parameters:
tags- One or more tags (multipletagsparams or comma-separated)
Example:
DELETE /memory/by-tag?tags=deployment&tags=successReturns a success payload with deleted_count.
POST /associate
Create a relationship between two memories.
Request:
{
"memory1_id": "uuid-source",
"memory2_id": "uuid-target",
"type": "RELATES_TO",
"strength": 0.8
}Authorable Relationship Types:
RELATES_TO- General connectionLEADS_TO- Causal (bug→solution)OCCURRED_BEFORE- Temporal sequencePREFERS_OVER- User/team preferencesEXEMPLIFIES- Pattern examplesCONTRADICTS- Conflicting approachesREINFORCES- Supporting evidenceINVALIDATED_BY- Outdated informationEVOLVED_INTO- Knowledge evolutionDERIVED_FROM- Source relationshipsPART_OF- Hierarchical structure
System-generated / internal relationship types:
SIMILAR_TO- Semantic neighbors created automaticallyPRECEDED_BY- Temporal links created automaticallyDISCOVERED- Internal consolidation edge withkind=explains|shares_theme|parallel_context
Response:
{
"status": "success",
"message": "Association created successfully"
}GET /enrichment/status
Check enrichment pipeline health.
Response:
{
"status": "healthy",
"pending": 5,
"in_flight": 2,
"last_success": "2025-10-01T12:34:56Z",
"last_error": null,
"workers": 1
}POST /enrichment/reprocess
Re-queue memories for enrichment (requires admin token).
Request:
{
"ids": ["memory-id-1", "memory-id-2"],
"force": true
}Headers Required:
Authorization: Bearer <AUTOMEM_API_TOKEN>X-Admin-Token: <ADMIN_API_TOKEN>
POST /admin/reembed
Regenerate embeddings in batches (requires admin token).
Request:
{
"batch_size": 32,
"limit": 100
}Example:
curl -X POST https://your-automem.railway.app/admin/reembed \
-H "Authorization: Bearer $AUTOMEM_API_TOKEN" \
-H "X-Admin-Token: $ADMIN_API_TOKEN" \
-d '{"batch_size": 32, "limit": 100}'Perfect for migrations or after updating embedding model.
Migration
For the current migration-script catalog, safety classification, and CLI flags, see scripts/README.md. Follow the migration runbook below for the required backup and validation sequence.
From MCP SQLite Memory Service
Use the migration helper to transfer memories from legacy MCP SQLite:
# Preview migration (dry-run)
python scripts/migrate_mcp_sqlite.py --dry-run
# Run migration with custom settings
python scripts/migrate_mcp_sqlite.py \
--db /path/to/sqlite_vec.db \
--automem-url https://your-automem.railway.app \
--api-token "$AUTOMEM_API_TOKEN" \
--limit 1000 \
--sleep 0.1Options:
--db- SQLite database path (auto-detected on macOS/Linux/Windows if omitted)--automem-url- AutoMem endpoint (default:http://localhost:8001)--api-token- API token (usesAUTOMEM_API_TOKENenv var if not specified)--limit- Max memories to migrate--offset- Skip first N memories--sleep- Delay between batches (seconds)--dry-run- Preview payloads without sending
What Gets Migrated:
✅ Content, tags, importance, metadata
✅ Timestamps preserved
✅ Legacy metadata stored under
metadata.legacy✅ Batch processing with progress tracking
Start with --dry-run to inspect, then rerun without it to execute.
Testing
AutoMem includes comprehensive test coverage across three modes:
Unit Tests (Default)
make testNo external services required
Uses in-memory stubs
Fast execution
Filtered warnings (see
pytest.ini)
Integration Tests (Local Docker)
make test-integrationAutomatically starts Docker services
Runs full integration suite
Creates/updates/deletes with unique UUIDs
Cleans up after itself
Requires Docker and Railway CLI
Live Server Tests (Railway)
make test-liveTests against live Railway deployment
Requires Railway CLI and project linkage
Interactive confirmation before running
Use
./test-live-server-auto.shfor CI
Manual Integration Testing:
# Custom endpoint
AUTOMEM_RUN_INTEGRATION_TESTS=1 \
AUTOMEM_TEST_BASE_URL=https://your-automem.railway.app \
AUTOMEM_ALLOW_LIVE=1 \
AUTOMEM_TEST_API_TOKEN=$AUTOMEM_API_TOKEN \
AUTOMEM_TEST_ADMIN_TOKEN=$ADMIN_API_TOKEN \
make test
# Local with auto Docker management
AUTOMEM_RUN_INTEGRATION_TESTS=1 \
AUTOMEM_START_DOCKER=1 \
AUTOMEM_STOP_DOCKER=1 \
make testEnvironment Variables:
AUTOMEM_TEST_BASE_URL- Override defaulthttp://localhost:8001AUTOMEM_ALLOW_LIVE=1- Required for non-localhost endpointsAUTOMEM_TEST_API_TOKEN/AUTOMEM_TEST_ADMIN_TOKEN- Auth tokens
See TESTING.md for complete testing documentation.
Troubleshooting
Common Issues
401 Unauthorized
Cause: Missing or incorrect API token
Fix: Ensure
AUTOMEM_API_TOKENmatches client's header/query paramCheck: Look for
Authorization: Bearer <token>in request
503 Service Unavailable / FalkorDB is unavailable
Cause: Cannot connect to FalkorDB
Fix: Verify
FALKORDB_HOSTandFALKORDB_PORTare correctCheck: Test connection:
redis-cli -h $FALKORDB_HOST -p $FALKORDB_PORT pingRailway: Ensure FalkorDB service is running and internal hostname is correct
Embedding dimension mismatch
Cause: Incorrect embedding dimension
Fix: Supply a vector matching
VECTOR_SIZEor omit field entirelyNote: Service generates placeholder if embedding omitted
Qdrant Errors (Logged but Non-Blocking)
Behavior: API continues working; vector search disabled
Fix: Check
QDRANT_URLandQDRANT_API_KEYconfigurationLogs: Inspect application logs for specific Qdrant error messages
Fallback: FalkorDB operations continue normally
Enrichment Not Processing
Check:
GET /enrichment/statusfor queue healthCauses:
Worker thread crashed (check logs)
spaCy model not installed (
pip install spacy)Memory already enriched (check
metadata.enriched_at)
Fix: Force reprocess:
POST /enrichment/reprocesswith memory IDs
Consolidation Not Running
Check: Application logs for scheduler errors
Verify: Interval environment variables are valid integers
Test: Manually trigger (requires code modification for testing)
Debug Mode
Enable detailed logging:
# Development
export FLASK_ENV=development
export LOG_LEVEL=DEBUG
python app.py
# Production (Railway)
# Set LOG_LEVEL=DEBUG in environment variablesHealth Checks
# Basic health
curl https://your-automem.railway.app/health
# Enrichment status
curl https://your-automem.railway.app/enrichment/status \
-H "Authorization: Bearer $AUTOMEM_API_TOKEN"
# Test memory storage
curl -X POST https://your-automem.railway.app/memory \
-H "Authorization: Bearer $AUTOMEM_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"Test memory","importance":0.5}'Support
Documentation: automem.ai
Issues: GitHub Issues
MCP Integration: @verygoodplugins/mcp-automem
License
MIT License - See LICENSE file for details.
273 files · 249 not served here
- .cursorignore (not served here)
- .dockerignore (not served here)
- .env.example (not served here)
- .flake8 (not served here)
- .gitattributes (not served here)
- .github/workflows/backup.yml (not served here)
- .github/workflows/benchmarks-dispatch.yml (not served here)
- .github/workflows/ci.yml (not served here)
- .github/workflows/docker-build-mcp-automem.yml (not served here)
- .github/workflows/docker-build.yml (not served here)
- .github/workflows/docs-dispatch.yml (not served here)
- .github/workflows/mcp-parity.yml (not served here)
- .github/workflows/release-please.yml (not served here)
- .github/workflows/semantic-pr-title.yml (not served here)
- .gitignore (not served here)
- .nixpacksignore (not served here)
- .pre-commit-config.yaml (not served here)
- .python-version (not served here)
- .railway/backup-falkordb.sh (not served here)
- .railway/falkordb.Dockerfile (not served here)
- .secrets.baseline (not served here)
- AGENTS.md
- ATTRIBUTION.md
- AUTOGINEER-RUNS.md
- CHANGELOG.md
- CLAUDE.md
- Dockerfile (not served here)
- INSTALLATION.md
- LICENSE
- Makefile (not served here)
- README.md
- app.py (not served here)
- automem/__init__.py (not served here)
- automem/analytics/__init__.py (not served here)
- automem/analytics/runtime_helpers.py (not served here)
- automem/api/admin.py (not served here)
- automem/api/auth_helpers.py (not served here)
- automem/api/backup.py (not served here)
- automem/api/consolidation.py (not served here)
- automem/api/enrichment.py (not served here)
- automem/api/entity.py (not served here)
- automem/api/graph.py (not served here)
- automem/api/health.py (not served here)
- automem/api/memory.py (not served here)
- automem/api/recall.py (not served here)
- automem/api/runtime_bootstrap.py (not served here)
- automem/api/runtime_memory_routes.py (not served here)
- automem/api/runtime_recall_routes.py (not served here)
- automem/api/stream.py (not served here)
- automem/api/viewer.py (not served here)
- automem/app_helper_bindings.py (not served here)
- automem/backup.py (not served here)
- automem/classification/__init__.py (not served here)
- automem/classification/memory_classifier.py (not served here)
- automem/config.py (not served here)
- automem/consolidation/entity_dedup.py (not served here)
- automem/consolidation/identity_synthesis.py (not served here)
- automem/consolidation/runtime_bindings.py (not served here)
- automem/consolidation/runtime_helpers.py (not served here)
- automem/consolidation/runtime_routes.py (not served here)
- automem/consolidation/runtime_scheduler.py (not served here)
- automem/embedding/__init__.py (not served here)
- automem/embedding/fastembed.py (not served here)
- automem/embedding/ollama.py (not served here)
- automem/embedding/openai.py (not served here)
- automem/embedding/placeholder.py (not served here)
- automem/embedding/provider.py (not served here)
- automem/embedding/provider_init.py (not served here)
- automem/embedding/runtime_bindings.py (not served here)
- automem/embedding/runtime_helpers.py (not served here)
- automem/embedding/runtime_pipeline.py (not served here)
- automem/embedding/voyage.py (not served here)
- automem/enrichment/__init__.py (not served here)
- automem/enrichment/runtime_bindings.py (not served here)
- automem/enrichment/runtime_helpers.py (not served here)
- automem/enrichment/runtime_orchestration.py (not served here)
- automem/enrichment/runtime_queue_bindings.py (not served here)
- automem/enrichment/runtime_worker.py (not served here)
- automem/runtime_environment.py (not served here)
- automem/runtime_wiring.py (not served here)
- automem/search/runtime_keywords.py (not served here)
- automem/search/runtime_recall_helpers.py (not served here)
- automem/search/runtime_relations.py (not served here)
- automem/service_runtime.py (not served here)
- automem/service_runtime_bindings.py (not served here)
- automem/service_state.py (not served here)
- automem/stores/graph_store.py (not served here)
- automem/stores/runtime_clients.py (not served here)
- automem/stores/vector_payload.py (not served here)
- automem/stores/vector_store.py (not served here)
- automem/sync/accounting.py (not served here)
- automem/sync/runtime_bindings.py (not served here)
- automem/sync/runtime_worker.py (not served here)
- automem/utils/__init__.py (not served here)
- automem/utils/entity_extraction.py (not served here)
- automem/utils/entity_quality.py (not served here)
- automem/utils/graph.py (not served here)
- automem/utils/scoring.py (not served here)
- automem/utils/tags.py (not served here)
- automem/utils/text.py (not served here)
- automem/utils/time.py (not served here)
- automem/utils/validation.py (not served here)
- benchmarks/EXPERIMENT_LOG.md (not served here)
- benchmarks/baselines/health_baseline.json (not served here)
- benchmarks/baselines/locomo-mini_baseline.json (not served here)
- benchmarks/baselines/postmerge-20261022.json (not served here)
- benchmarks/baselines/pr266-tag-prefix-20261021.json (not served here)
- benchmarks/postmortems/.gitkeep (not served here)
- benchmarks/postmortems/2026-03-11_issue74_entity_expansion_precision.md (not served here)
- benchmarks/postmortems/2026-03-11_pr80_enhanced_recall.md (not served here)
- benchmarks/postmortems/2026-03-12_issue79_priority_ids_fetch.md (not served here)
- consolidation.py (not served here)
- docker-compose.yml (not served here)
- docs/AGENT_TEMPLATE.md
- docs/API.md
- docs/BENCHMARK_JUDGE_POLICY.md
- docs/COMPARISON.md
- docs/ENVIRONMENT_VARIABLES.md (not served here)
- docs/EVALS_CONTRACT.md
- docs/HEALTH_MONITORING.md
- docs/MCP_SSE.md
- docs/MCP_TRANSPORT_PARITY.md
- docs/METADATA_BEHAVIOR.md
- docs/MIGRATIONS.md
- docs/MONITORING_AND_BACKUPS.md
- docs/QDRANT_SETUP.md
- docs/RAILWAY_DEPLOYMENT.md
- docs/RECALL_QUALITY_LAB.md
- docs/RESEARCH.md
- docs/TESTING.md
- docs/img/qdrant-configuration.jpg (not served here)
- mcp-sse-server/Dockerfile (not served here)
- mcp-sse-server/README.md (not served here)
- mcp-sse-server/package-lock.json (not served here)
- mcp-sse-server/package.json (not served here)
- mcp-sse-server/parity/clients.js (not served here)
- mcp-sse-server/parity/fake-automem.js (not served here)
- mcp-sse-server/parity/normalize.js (not served here)
- mcp-sse-server/parity/scenarios.js (not served here)
- mcp-sse-server/railway.json (not served here)
- mcp-sse-server/server.js (not served here)
- mcp-sse-server/test/parity.test.js (not served here)
- mcp-sse-server/test/recall-parity.test.js (not served here)
- mcp-sse-server/test/server.test.js (not served here)
- mcp-sse-server/test/sse-sessions.test.js (not served here)
- pyproject.toml (not served here)
- pytest.ini (not served here)
- railway.json (not served here)
- railway.toml (not served here)
- requirements-dev.txt (not served here)
- requirements.txt (not served here)
- run-integration-tests.sh (not served here)
- scripts/Dockerfile.health-monitor (not served here)
- scripts/README.md (not served here)
- scripts/audit_relevance.py (not served here)
- scripts/automem_watch.py (not served here)
- scripts/backfill_tag_prefixes.py (not served here)
- scripts/backup_automem.py (not served here)
- scripts/bench/analyze_locomo_results.py (not served here)
- scripts/bench/compare_branch.sh (not served here)
- scripts/bench/compare_configs.sh (not served here)
- scripts/bench/compare_results.py (not served here)
- scripts/bench/health_check.py (not served here)
- scripts/bench/ingest_and_snapshot.sh (not served here)
- scripts/bench/restore_and_eval.sh (not served here)
- scripts/bootstrap_dev.sh (not served here)
- scripts/browse_memories.py (not served here)
- scripts/cleanup_memory_types.py (not served here)
- scripts/deduplicate_qdrant.py (not served here)
- scripts/deploy_check.sh (not served here)
- scripts/health_monitor.py (not served here)
- scripts/lab/clone_production.sh (not served here)
- scripts/lab/configs/baseline.json (not served here)
- scripts/lab/configs/issue78_archive_filter.json (not served here)
- scripts/lab/configs/issue78_combined.json (not served here)
- scripts/lab/configs/issue78_relevance_weight.json (not served here)
- scripts/lab/create_test_queries.py (not served here)
- scripts/lab/lab_corpus.py (not served here)
- scripts/lab/lab_metrics.py (not served here)
- scripts/lab/repair_entity_tags.py (not served here)
- scripts/lab/run_recall_test.py (not served here)
- scripts/lib/common.sh (not served here)
- scripts/migrate_entity_nodes.py (not served here)
- scripts/migrate_mcp_sqlite.py (not served here)
- scripts/reclassify_with_llm.py (not served here)
- scripts/recover_from_qdrant.py (not served here)
- scripts/reembed_embeddings.py (not served here)
- scripts/reenrich_batch.py (not served here)
- scripts/rescore_relevance.py (not served here)
- scripts/restore_from_backup.py (not served here)
- scripts/run_longmemeval_watch.sh (not served here)
- test-live-server-auto.sh (not served here)
- test-live-server.sh (not served here)
- test-locomo-benchmark.sh (not served here)
- test-longmemeval-benchmark.sh (not served here)
- tests/benchmarks/backends.py (not served here)
- tests/benchmarks/core_adapter/evaluate.js (not served here)
- tests/benchmarks/judge_policy.py (not served here)
- tests/benchmarks/judge_preflight.py (not served here)
- tests/benchmarks/longmemeval/__init__.py (not served here)
- tests/benchmarks/longmemeval/analyze_results.py (not served here)
- tests/benchmarks/longmemeval/configs.py (not served here)
- tests/benchmarks/longmemeval/diagnose_failures.py (not served here)
- tests/benchmarks/longmemeval/evaluator.py (not served here)
- tests/benchmarks/longmemeval/test_analysis.py (not served here)
- tests/benchmarks/longmemeval/test_answer_prompt.py (not served here)
- tests/benchmarks/longmemeval/test_diagnose_failures.py (not served here)
- tests/benchmarks/longmemeval/test_evaluator.py (not served here)
- tests/benchmarks/longmemeval/test_longmemeval.py (not served here)
- tests/benchmarks/results/compare_issue74_entity_precision_20260311.json (not served here)
- tests/benchmarks/results/compare_issue79_priority_ids_20260311.json (not served here)
- tests/benchmarks/results/compare_pr80_bm25_only_f10_judge_off.json (not served here)
- tests/benchmarks/results/compare_pr80_judge_off_20260311.json (not served here)
- tests/benchmarks/results/compare_pr80_judge_on_20260311.json (not served here)
- tests/benchmarks/results/longmemeval_baseline_5_4mini_20260425_223943.json (not served here)
- tests/benchmarks/results/longmemeval_baseline_5_4mini_20260425_223943.jsonl (not served here)
- tests/benchmarks/test_locomo.py (not served here)
- tests/benchmarks/test_multihop_quick.py (not served here)
- tests/conftest.py (not served here)
- tests/contracts/test_error_contract.py (not served here)
- tests/contracts/test_routes_contract.py (not served here)
- tests/lab/conftest.py (not served here)
- tests/lab/test_lab_corpus.py (not served here)
- tests/lab/test_lab_metrics.py (not served here)
- tests/lab/test_run_recall_test.py (not served here)
- tests/support/__init__.py (not served here)
- tests/support/fake_graph.py (not served here)
- tests/test_admin_http_regressions.py (not served here)
- tests/test_api_endpoints.py (not served here)
- tests/test_app.py (not served here)
- tests/test_backup_endpoint.py (not served here)
- tests/test_benchmark_backends.py (not served here)
- tests/test_benchmark_env_loading.py (not served here)
- tests/test_benchmark_result_analyzer.py (not served here)
- tests/test_classification_stats.py (not served here)
- tests/test_consolidation_collection.py (not served here)
- tests/test_consolidation_engine.py (not served here)
- tests/test_content_size.py (not served here)
- tests/test_context_tag_separator.py (not served here)
- tests/test_docker_compose_port_security.py (not served here)
- tests/test_embedding_integrity.py (not served here)
- tests/test_embedding_providers.py (not served here)
- tests/test_embedding_runtime_helpers.py (not served here)
- tests/test_enrichment.py (not served here)
- tests/test_enrichment_circuit.py (not served here)
- tests/test_enrichment_concurrent_updates.py (not served here)
- tests/test_enrichment_worker.py (not served here)
- tests/test_entity_identities.py (not served here)
- tests/test_entity_quality.py (not served here)
- tests/test_falkordb_backup_export.py (not served here)
- tests/test_health_monitor.py (not served here)
- tests/test_identity_config.py (not served here)
- tests/test_integration.py (not served here)
- tests/test_keyword_score_normalization.py (not served here)
- tests/test_locomo_benchmark_script.py (not served here)
- tests/test_locomo_cat5_judge.py (not served here)
- tests/test_locomo_speaker_extraction.py (not served here)
- tests/test_longmemeval_benchmark_script.py (not served here)
- tests/test_makefile_targets.py (not served here)
- tests/test_memory_type_validation.py (not served here)
- tests/test_memory_vector_payloads.py (not served here)
- tests/test_metadata_recall_search.py (not served here)
- tests/test_prefix_tag_filters.py (not served here)
- tests/test_recall_artifact_exclusion.py (not served here)
- tests/test_recall_entity_extraction.py (not served here)
- tests/test_recall_overfetch.py (not served here)
- tests/test_recover_from_qdrant.py (not served here)
- tests/test_repair_entity_tags.py (not served here)
- tests/test_runtime_qdrant_init.py (not served here)
- tests/test_service_runtime.py (not served here)
- tests/test_stream_events.py (not served here)
- tests/test_structured_logging.py (not served here)
- tests/test_vector_size_safety.py (not served here)
Advantages
- Avoids redundant LLM calls during recall by using direct graph and vector index lookups. evidence: README.md
- Records typed relationships between memories to surface the 'why' behind decisions rather than just isolated facts. evidence: README.md
- Provides a unified memory store accessible across multiple different AI tools and chat applications. evidence: README.md
Limitations
- Tags act as a hard filter, meaning memories without the queried tag are excluded even if they are semantically relevant. evidence: README.md
- The system does not yet reliably resolve conflicting facts or prioritize the newest version of information automatically. evidence: README.md
- The MCP SSE bridge currently lacks support for passing through state_mode configurations. evidence: README.md
Security
Risk level: Medium risk
This brain runs
Git hooks (8)
.pre-commit-config.yaml:pre-commit hooks from https://github.com/psf/black at 24.4.2 (contributor tooling: runs only after pre-commit install)· uses the network.pre-commit-config.yaml:pre-commit hooks from https://github.com/pycqa/isort at 5.13.2 (contributor tooling: runs only after pre-commit install)· uses the network.pre-commit-config.yaml:pre-commit hooks from https://github.com/pycqa/flake8 at 7.1.1 (contributor tooling: runs only after pre-commit install)· uses the network.pre-commit-config.yaml:pre-commit hooks from https://github.com/compilerla/conventional-pre-commit at v3.2.0 (contributor tooling: runs only after pre-commit install)· uses the network.pre-commit-config.yaml:pre-commit hooks from https://github.com/pre-commit/pre-commit-hooks at v4.6.0 (contributor tooling: runs only after pre-commit install)· uses the network.pre-commit-config.yaml:pre-commit hooks from https://github.com/Yelp/detect-secrets at v1.5.0 (contributor tooling: runs only after pre-commit install)· uses the network.pre-commit-config.yaml:bash -c 'PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 ./venv/bin/pytest tests/ --ignore=tests/benchmarks --ignore=tests/test_integration.py -x -q'.pre-commit-config.yaml:bash -c 'command -v coderabbit >/dev/null 2>&1 || { echo "coderabbit CLI not installed, skipping"; exit 0; }; coderabbit review --type committed --plain'
Agent instructions that run or fetch something (39)
AGENTS.md:`make install`: Create `.venv` (and symlink `venv -> .venv`) and install dev deps.AGENTS.md:`make dev`: Start local stack via Docker (FalkorDB, Qdrant, API).AGENTS.md:`make test`: Run unit tests (fast, no services).AGENTS.md:`make test-integration`: Start Docker and run full integration tests.AGENTS.md:`make fmt` / `make lint`: Format with Black/Isort and lint with Flake8.AGENTS.md:`make bench-eval BENCH=locomo-mini`: Run snapshot-based benchmark (~2 min).AGENTS.md:`make deploy` / `make status`: Deploy/check Railway.AGENTS.md:Quick health: `curl :8001/health`.· uses the networkAGENTS.md:Run `pre-commit install` and `make fmt && make lint` before committing.AGENTS.md:Unit tests: `make test`.AGENTS.md:Integration: `make test-integration` (requires Docker).AGENTS.md:| Tier | Benchmark | Command | Runtime | Cost | When to use | |------|-----------|---------|---------|------|-------------| | 0 | Unit tests | `make test` | 30s | free | Every change | | 1 | LoCoMo-mini (2 convos, 304 Qs) | `make bench-eval BENCH=locomo-mini` | 2-3 min | free / ~$0.20 …[+355 chars]AGENTS.md:`make bench-eval BENCH=locomo-mini CONFIG=baseline` — eval from snapshot (~2 min).AGENTS.md:`make bench-compare BENCH=locomo CONFIG=<name> BASELINE=baseline` — A/B compare two configs.AGENTS.md:`make bench-compare-branch BRANCH=<branch>` — compare a branch against baseline.AGENTS.md:`make bench-ingest BENCH=locomo` — ingest + snapshot (run once per embedding change).AGENTS.md:`make bench-health` — recall health check (score distribution, entity quality, latency).AGENTS.md:Run `make bench-eval BENCH=locomo-mini` on `main` to confirm the current baseline.AGENTS.md:Run the same eval on the branch.AGENTS.md:Promote to `make bench-eval BENCH=locomo` (full) before merge.AGENTS.md:`benchmarks/snapshots/` — Qdrant/FalkorDB snapshot data (gitignored, regenerate with `make bench-ingest`).AGENTS.md:`benchmarks/results/` — per-run result JSONs (gitignored).AGENTS.md:release-please and GHCR `:stable` then run on `main`.CLAUDE.md:`GET /consolidate/status` - Check consolidation scheduler status and last run timesCLAUDE.md:Adds short summaries, timestamps (`enriched_at`), and per-run metrics under `metadata.enrichment`.CLAUDE.md:# Run testsCLAUDE.md:make test-integration # Starts services and runs integration testsCLAUDE.md:make test-live # Same as above via MakefileCLAUDE.md:JIT_ENRICHMENT_ENABLED=true # Run entity/summary extraction inline on recall for unenriched memoriesCLAUDE.md:Install spaCy locally to improve entity extraction:CLAUDE.md:pip install spacyCLAUDE.md:python -m spacy download en_core_web_smCLAUDE.md:**Local Development** - Make changes and test with `make dev`CLAUDE.md:**Unit Tests** - Verify with `make test`CLAUDE.md:**Integration Tests** - Validate with `make test-integration`CLAUDE.md:**Deploy to Railway** - Push changes with `make deploy`CLAUDE.md:**Live Validation** - Test deployed instance with `make test-live`CLAUDE.md:**Benchmarking** - Validate performance with `make test-locomo-live`CLAUDE.md:# Run integration tests against Railway
Install scripts (1)
Makefile(make install):echo "🔧 Setting up development environment..."; bash scripts/bootstrap_dev.sh; echo "✅ Virtual environment ready!"; echo "💡 Run 'source .venv/bin/activate' to activate"
- Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:9)
- Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:16)
- Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:23)
- Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:30)
- Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:38)
- Medium risk: runs-git-hook-remote-exec (.pre-commit-config.yaml:50)
- Medium risk: runs-instruction-instruction-network (AGENTS.md:23)
- Low risk: network-instructions (.pre-commit-config.yaml:2)
- Low risk: network-instructions (CLAUDE.md:299)
- Low risk: network-instructions (Makefile:91)
- Low risk: scripts-present (scripts/bootstrap_dev.sh)
Attribution and licence
- First committed by
jack-arturo
- Publisher
- Very Good Plugins (Community)
- Source
- verygoodplugins/automem · commit 1a7ba1a
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- jack-arturo, mikemikimike, zackkatz, dexhunter
AutoGineer is not affiliated with or endorsed by jack-arturo or Very Good Plugins.
Install from source
249 of its files are not served here, so there is no ZIP. verygoodplugins/automem at 1a7ba1a