Generated banner for AutoMem
Generated logo for AutoMem

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.
— the description by jack-arturo

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.

Folders
FolderRoleFiles
.githubagent-config9
docsdocs18
scriptsscripts39
teststests78
.railwayfolder2
automemfolder70
benchmarksfolder9
mcp-sse-serverfolder14

The agent reads

The agent writes

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

  1. 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"
  2. 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
  3. 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| Qdrant

If 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
TypeUse caseExample
RELATES_TOGeneral connectionBug report → Related issue
LEADS_TOCausal relationshipProblem → Solution
OCCURRED_BEFORETemporal sequencePlanning → Execution
PREFERS_OVERUser preferencesPostgreSQL → MongoDB
EXEMPLIFIESPattern examplesCode review → Best practice
CONTRADICTSConflicting infoOld approach → New approach
REINFORCESSupporting evidenceDecision → Validation
INVALIDATED_BYOutdated infoLegacy docs → Current docs
EVOLVED_INTOKnowledge evolutionInitial design → Final design
DERIVED_FROMSource trackingImplementation → Spec
PART_OFHierarchical structureFeature → 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.

CycleFrequencyPurpose
DecayDailyExponential relevance scoring (age, access, connections, importance)
CreativeWeeklyREM-like processing that discovers non-obvious connections
ClusterMonthlyGroups similar memories, generates meta-patterns
ForgetOff by defaultArchives 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)

Image: Deploy on Railway

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
ServiceURLPurpose
AutoMem APIhttp://localhost:8001Memory REST API
FalkorDBlocalhost:6379Graph database
Qdrantlocalhost:6333Vector database
FalkorDB Browserhttp://localhost:3000Local 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.py

Requires 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

ClientModeSetup
Claude Desktop, Cursor, Claude Code, Codex, Copilot, AntigravityLocal MCP bridgenpx @verygoodplugins/mcp-automem setup
ChatGPT (developer mode), Claude.ai web/mobile, ElevenLabs AgentsRemote MCP (HTTPS)docs/MCP_SSE.md
Anything elseDirect REST APIdocs/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=auto re-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 Entity nodes (IDENTITY_SYNTHESIS_ENABLED) are gated off while people-entity word-pair noise is addressed (#181).

Docs, community, and license

Setup

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

Operations

Community

Sibling repos

MIT licensed. Deploy anywhere. No vendor lock-in.

docs/RAILWAY_DEPLOYMENT.md

Railway Deployment Guide

For operational scripts used after deployment (health checks, backups, recovery, and migrations), see the scripts catalog.

Complete guide to deploying AutoMem on Railway with persistent storage, backups, and zero data loss.

Quick Start (One-Click Deploy)

Image: Deploy on Railway

This template automatically sets up:

  • ✅ automem — AutoMem Flask API with health checks

  • ✅ mcp-automem — MCP bridge for cloud AI platforms (ChatGPT, Claude.ai, ElevenLabs)

  • ✅ qdrant — Vector database for semantic search (with persistent volume)

  • ✅ falkordb — Graph database with persistent volumes and password protection

  • ✅ Automatic secret generation and service networking

flowchart TB
    subgraph internet [Public Internet]
        Users[AI Clients<br/>Direct API]
        CloudAI[Cloud AI Platforms<br/>ChatGPT, Claude.ai, ElevenLabs]
        Local[Local Tools<br/>Cursor, Claude Desktop, Claude Code]
    end

    subgraph railway [Railway Project]
        subgraph mcpbridge [MCP Bridge Service]
            MCPServer[MCP Bridge<br/>Streamable HTTP<br/>Port 8080]
            MCPDomain[Public Domain<br/>mcp.up.railway.app]
        end

        subgraph api [automem Service]
            FlaskAPI[Flask API<br/>Port 8001]
            APIDomain[Public Domain<br/>automem.up.railway.app]

            Enrichment[Enrichment Pipeline]
            Consolidation[Consolidation Engine]
        end

        subgraph db [falkordb Service]
            FalkorDB[(FalkorDB<br/>Port 6379)]
            Volume[Persistent Volume<br/>/var/lib/falkordb/data]
            TCPProxy[TCP Proxy<br/>Optional admin access]
        end

        subgraph qdrantsvc [qdrant Service]
            Qdrant[(Qdrant<br/>Port 6333)]
            QdrantVolume[Persistent Volume<br/>/qdrant/storage]
        end

        subgraph external [External Services]
            QdrantCloud[(Qdrant Cloud<br/>Optional managed alternative)]
            Voyage[Voyage API<br/>Recommended embeddings]
            OpenAI[OpenAI API<br/>Fallback embeddings]
        end
    end

    Users -->|HTTPS| APIDomain
    CloudAI -->|Streamable HTTP| MCPDomain
    Local -->|HTTPS| APIDomain

    MCPDomain --> MCPServer
    APIDomain --> FlaskAPI

    MCPServer -->|Internal<br/>automem.railway.internal:8001| FlaskAPI

    FlaskAPI -->|Internal<br/>falkordb.railway.internal:6379| FalkorDB
    FlaskAPI -->|Internal<br/>qdrant.railway.internal:6333| Qdrant
    FlaskAPI -.->|Optional alternative| QdrantCloud
    FlaskAPI --> Voyage
    FlaskAPI -.-> OpenAI

    Enrichment --> FalkorDB
    Enrichment -.-> QdrantCloud
    Enrichment -.-> Qdrant
    Consolidation --> FalkorDB

    FalkorDB --> Volume
    Qdrant --> QdrantVolume

    TCPProxy -.->|Optional<br/>Admin-only TCP access| FalkorDB

How Updates Work

Once your services are running, Railway pulls new images automatically — no git push, no source rebuild on every commit:

ServiceImageUpdate cadence
automemghcr.io/verygoodplugins/automem:stableAuto-redeploy nightly
mcp-automemghcr.io/verygoodplugins/mcp-automem:stableAuto-redeploy nightly
qdrantqdrant/qdrant:v1.11.3Pinned; upgrade deliberately
falkordbfalkordb/falkordb:latestTemplate default; pin in production

Production recommendation: For stateful services such as Qdrant and FalkorDB, prefer pinned image versions over mutable tags like :latest so Railway redeploys do not unexpectedly roll your database to a new release.

How :stable is built

Two GitHub Actions workflows publish to GHCR:

Both workflows publish on every v* tag push (cut by release-please when a release PR merges to main). On every release the workflows publish:

  • :vX.Y.Z, :vX.Y, :vX — semver pointers

  • :sha-abcdef0 — short commit SHA

  • :latest — every released main commit (don't use this in production; it tracks every release)

  • :stable — same as the latest vX.Y.Z, the conservative pointer Railway tracks

Tag strategy
TagWhat it points atWhen to use
:stableLatest released vX.Y.ZRecommended for production — what the Railway template uses
:vX.Y.ZA specific releasePin a known-good version after a regression
:vX.YLatest patch in a minor lineStay on a minor version, accept patches
:latestLatest released main commitSame as :stable today, but no contractual guarantee — avoid in prod
:sha-xxxxxxxA specific commitReproduce a single CI run for debugging
Operating the deploy

Deploy a new release immediately (don't wait for nightly): Railway → service → Deployments → Deploy latest.

Pin to a specific version: Service → Settings → Source → Image → change :stable to :v0.16.0. Railway will pull and redeploy.

Roll back: Same flow — change the image tag to the prior vX.Y.Z, redeploy. Persistent volumes (FalkorDB data) are unaffected.

Use 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 services that use the old path keep working without changes.


Post-Deploy Checklist

After deploying, complete these steps to fully configure AutoMem:

Required: Add Your API Keys
  1. Go to automem → Variables

  2. Set these variables:

VariableRequiredHow to Get
VOYAGE_API_KEYRecommendedVoyage API key for voyage-4
OPENAI_API_KEYOptional fallbackplatform.openai.com/api-keys
QDRANT_URLOption AQdrant Cloud URL — see Qdrant Setup Guide
QDRANT_API_KEYOption AQdrant Cloud API key
QDRANT_HOSTOption Bqdrant (self-hosted on Railway — see Step 1b)

Set EMBEDDING_PROVIDER=auto, VOYAGE_MODEL=voyage-4, and VECTOR_SIZE=1024 with the Voyage key. In auto mode, OpenAI is the API fallback. Do not rely on FastEmbed for Railway: its 1024d fallback can add roughly 4 GB RSS and materially increase the service cost. See Voyage pricing for the current free-tier limits and rates.

👉 Qdrant Cloud? Follow the Qdrant Setup Guide for step-by-step collection setup. 👉 Self-hosted Qdrant? See Step 1b — remember to set QDRANT__SERVICE__HOST=:: on the Qdrant service.

  1. Redeploy the automem after adding variables.

Verify Deployment
# Check health (should show falkordb: connected)
curl https://your-automem.up.railway.app/health

# Store a test memory
curl -X POST "https://your-automem.up.railway.app/memory" \
  -H "Authorization: Bearer YOUR_AUTOMEM_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "Test memory from Railway", "tags": ["test"]}'
MCP Bridge (Included)

The template includes mcp-automem, which exposes AutoMem as an MCP server over HTTPS. This enables cloud AI platforms to access your memories:

PlatformHow to Connect
ChatGPTSettings → Connectors → Add Server → https://your-sse.up.railway.app/mcp?api_token=TOKEN
Claude.aiSettings → MCP → https://your-sse.up.railway.app/mcp?api_token=TOKEN
Claude MobileSettings → MCP Servers → same URL as above
Claude DesktopPrefer the same remote MCP URL if you want connector state shared with Claude.ai/iOS
ElevenLabsAgent config → MCP → same URL (or use Authorization header)

👉 See MCP_SSE.md for detailed setup per platform.

Don't need the MCP bridge? If you only use Cursor, Claude Code, or direct API access:

  1. Go to Railway Dashboard → mcp-automem service

  2. Click the three dots menu → Delete Service

  3. This saves ~$2-3/month and has no impact on the core memory API

Claude Desktop can still use the local MCP package, but Anthropic now syncs connector state across Desktop, Claude.ai, and iOS. If you want one shared Claude connector, keep the Railway MCP bridge enabled and use the remote URL everywhere.

Optional: Standalone Graph Viewer Service

Deploy automem-graph-viewer as a separate Railway service, then configure these on automem:

VariableValue
ENABLE_GRAPH_VIEWERtrue
GRAPH_VIEWER_URLhttps://<your-viewer-domain>
VIEWER_ALLOWED_ORIGINShttps://<your-viewer-domain>

AutoMem keeps /viewer for compatibility and redirects/bootstraps users to the standalone viewer. Use /viewer on automem as the public entrypoint; the standalone viewer is the backing service behind that route. Keep FalkorDB internal and avoid using direct public DB access as a viewer transport.

Get Your API Tokens

Your tokens were auto-generated during deployment. Find them in:

  • Railway Dashboard → automem → Variables

  • Look for AUTOMEM_API_TOKEN and ADMIN_API_TOKEN


Step 1: Create FalkorDB Service with Persistence
  1. Create new service in Railway

    • Click "+ New Service"

    • Select "Docker Image"

    • Image: falkordb/falkordb:latest

  2. Add persistent volume (CRITICAL!)

    • Go to service → Settings → Volumes

    • Click "Add Volume"

    • Mount path: /var/lib/falkordb/data

    • This ensures data survives restarts

  3. Configure environment variables:

    PORT=6379
    FALKOR_PASSWORD=${{shared.FALKOR_PASSWORD}}  # Auto-generated secret
    FALKOR_USERNAME=default
    FALKOR_HOST=${{RAILWAY_PRIVATE_DOMAIN}}
    FALKOR_PORT=${{PORT}}
    FALKOR_PUBLIC_HOST=${{RAILWAY_TCP_PROXY_DOMAIN}}
    FALKOR_PUBLIC_PORT=${{RAILWAY_TCP_PROXY_PORT}}
    REDIS_ARGS=--save 60 1 --appendonly yes --appendfsync everysec

    Note: FalkorDB handles authentication via FALKOR_PASSWORD - don't add --requirepass to REDIS_ARGS.

  4. Health check: Leave blank/disabled (FalkorDB doesn't have HTTP endpoints). Railway monitors container status automatically.

  5. Note the internal URL: ${{FalkorDB.RAILWAY_PRIVATE_DOMAIN}}

Step 1b: Qdrant Vector Database

Choose one of these options:

Option A: Qdrant Cloud (Managed)

Use Qdrant Cloud for a fully managed vector database. See the Qdrant Setup Guide for step-by-step instructions. Set QDRANT_URL and QDRANT_API_KEY on automem.

Option B: Self-Hosted Qdrant on Railway

Run Qdrant inside your Railway project for lower latency (internal networking, no HTTPS overhead) and simpler architecture.

  1. Create new service in Railway

    • Click "+ New Service"

    • Select "Docker Image"

    • Image: qdrant/qdrant:v1.11.3

  2. Add persistent volume (CRITICAL!)

    • Go to service → Settings → Volumes

    • Click "Add Volume"

    • Mount path: /qdrant/storage

    • This ensures vectors survive restarts

  3. Configure environment variables:

    PORT=6333
    QDRANT__SERVICE__HOST=::

    ⚠️ QDRANT__SERVICE__HOST=:: is required. Railway's internal networking uses IPv6. Qdrant defaults to binding 0.0.0.0 (IPv4 only), which silently refuses all internal connections. Setting :: enables dual-stack (IPv6 + IPv4) binding. Without this, you'll get "Connection refused" errors that are extremely difficult to diagnose — DNS resolves fine, Qdrant logs show it's running, but no connections arrive.

  4. No health check needed: Qdrant doesn't expose an HTTP health path that Railway can use. Container monitoring handles restarts.

  5. On automem, set:

    QDRANT_HOST=qdrant   # Must match your Qdrant service name in Railway

    AutoMem constructs http://qdrant:6333 automatically. No QDRANT_URL or QDRANT_API_KEY needed for internal networking.

    Note: The hostname must match your Railway service name. If you named the service something other than "qdrant", use that name instead (e.g. QDRANT_HOST=my-vector-db). You can also use Railway's reference variable: QDRANT_HOST=${{Qdrant.RAILWAY_PRIVATE_DOMAIN}}.

Step 2: Deploy AutoMem API
  1. Connect GitHub repo or Deploy from Docker

    • If using GitHub: Connect repository and set root directory

    • If using Docker: Use existing Dockerfile

  2. Configure environment variables:

    Option A: Variable References (template style)

    # Database connections
    FALKORDB_HOST=${{FalkorDB.RAILWAY_PRIVATE_DOMAIN}}
    FALKORDB_PORT=6379
    FALKORDB_PASSWORD=${{FalkorDB.FALKOR_PASSWORD}}
    FALKORDB_GRAPH=memories
    
    # API authentication (Railway auto-generates secrets)
    AUTOMEM_API_TOKEN=${{shared.AUTOMEM_API_TOKEN}}
    ADMIN_API_TOKEN=${{shared.ADMIN_API_TOKEN}}
    
    # Recommended cloud embeddings: Voyage first, OpenAI fallback
    EMBEDDING_PROVIDER=auto
    VOYAGE_API_KEY=<your-voyage-key>
    VOYAGE_MODEL=voyage-4
    VECTOR_SIZE=1024
    # Optional: OpenAI-compatible API fallback when Voyage is unavailable
    # OPENAI_API_KEY=<your-openai-key>
    
    # Vector search — pick ONE:
    # Option A: Qdrant Cloud
    QDRANT_URL=<your-qdrant-cloud-url>
    QDRANT_API_KEY=<your-qdrant-api-key>
    # Option B: Self-hosted Qdrant on Railway (see Step 1b)
    # QDRANT_HOST=qdrant
    QDRANT_COLLECTION=memories
    
    # Port (REQUIRED - Flask needs explicit port)
    PORT=8001

    Option B: Hardcoded Values (recommended for stability)

    # Database connections - use actual values from FalkorDB service
    FALKORDB_HOST=falkordb.railway.internal
    FALKORDB_PORT=6379
    FALKORDB_PASSWORD=<copy-from-falkordb-service>
    FALKORDB_GRAPH=memories
    
    # API authentication - generate or copy from shared variables
    AUTOMEM_API_TOKEN=<your-generated-token>
    ADMIN_API_TOKEN=<your-generated-token>
    
    # Recommended cloud embeddings: Voyage first, OpenAI fallback
    EMBEDDING_PROVIDER=auto
    VOYAGE_API_KEY=<your-voyage-key>
    VOYAGE_MODEL=voyage-4
    VECTOR_SIZE=1024
    # Optional: OpenAI-compatible API fallback when Voyage is unavailable
    # OPENAI_API_KEY=<your-openai-key>
    
    # Vector search — pick ONE:
    # Option A: Qdrant Cloud
    QDRANT_URL=<your-qdrant-cloud-url>
    QDRANT_API_KEY=<your-qdrant-api-key>
    # Option B: Self-hosted Qdrant on Railway (see Step 1b)
    # QDRANT_HOST=qdrant
    QDRANT_COLLECTION=memories
    
    # Port (REQUIRED - Flask needs explicit port)
    PORT=8001

    Note: Hardcoded values (Option B) are more stable and easier to debug, while variable references (Option A) update automatically but can be harder to troubleshoot.

    ⚠️ Important: PORT=8001 is required for the automem. Without it, Flask defaults to port 5000, causing connection failures from other services.

  3. Set health check:

    • Path: /health

    • Timeout: 100s

  4. Generate public domain:

    • Settings → Networking → Generate Domain

    • Save your URL: https://your-automem.up.railway.app

Step 3: Verify Deployment
# Check health
curl https://your-automem.up.railway.app/health

# Expected response:
{
  "status": "healthy",
  "falkordb": "connected",
  "qdrant": "connected",
  "memory_count": 1234,  # Added in recent versions
  "enrichment": {
    "status": "running",
    "queue_depth": 0,
    "pending": 0,
    "inflight": 0,
    "processed": 0,
    "failed": 0
  },
  "graph": "memories",
  "timestamp": "2025-10-20T03:47:39+00:00"
}

Note: memory_count field requires AutoMem commit from Oct 20, 2025 or later. For detailed analytics, use /analyze endpoint.

# Check detailed memory analytics
curl "https://your-automem.up.railway.app/analyze?api_key=YOUR_API_TOKEN"

# Shows:
# - Total memories by type (Context, Decision, Insight, etc.)
# - Entity frequency (projects, tools)
# - Confidence distribution
# - Temporal insights (activity by hour)

If you get 503:

  • Check FalkorDB is running and healthy

  • Verify FALKORDB_HOST is set to private domain (use falkordb.railway.internal, not ${{...}} syntax)

  • Confirm FALKORDB_PASSWORD matches between services

  • Test connection: railway logs --service automem | grep -i falkordb

Step 4: Store First Memory
export AUTOMEM_URL="https://your-automem.up.railway.app"
export AUTOMEM_TOKEN="your-api-token"

curl -X POST "$AUTOMEM_URL/memory" \
  -H "Authorization: Bearer $AUTOMEM_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "First memory from Railway!",
    "tags": ["test", "deployment"],
    "importance": 0.8
  }'

Data Persistence & Backups

Persistent Volumes (Required)

Railway volumes ensure data survives:

  • Service restarts

  • Deployments

  • Platform maintenance

Volume Configuration:

  • Mount path: /var/lib/falkordb/data

  • Minimum size: 1GB (adjust based on needs)

  • Backed up automatically by Railway

Automated Backups

Railway provides built-in volume backups for FalkorDB (automatic, one-click restore).

For comprehensive backups covering both FalkorDB and Qdrant with S3 upload:

👉 See MONITORING_AND_BACKUPS.md for complete backup setup including:

  • Railway volume backups (built-in)

  • GitHub Actions automated backups (recommended, free)

  • Manual backup scripts

Disaster Recovery

If FalkorDB data is lost but Qdrant is intact:

# SSH into AutoMem service
railway run

# Run recovery script
python scripts/recover_from_qdrant.py

# This will:
# - Read all 636+ memories from Qdrant
# - Rebuild FalkorDB graph structure
# - Restore all relationships

Standalone Graph Viewer (Public UI)

The production graph UI should be a separate Railway service in the same project, not bundled into the AutoMem API container. AutoMem core owns API/auth/data and keeps /viewer/* as the canonical entrypoint; that route bootstraps users into the standalone viewer, preserves hash tokens, and passes server=<automem-origin>.

  1. Create the viewer service:

    • Image: ghcr.io/verygoodplugins/automem-graph-viewer:stable

    • Public domain: enabled

    • No database credentials, no RAILWAY_PRIVATE_DOMAIN, no FalkorDB/Qdrant variables

    • No VITE_API_TARGET, VITE_BASE, or VITE_ENABLE_HAND_CONTROLS in production

  2. Configure the AutoMem API service:

    GRAPH_VIEWER_URL=https://your-viewer.up.railway.app
    VIEWER_ALLOWED_ORIGINS=https://your-viewer.up.railway.app
  3. Use /viewer on the API domain as the user-facing link:

    https://your-automem.up.railway.app/viewer/#token=<AUTOMEM_API_TOKEN>

Browser traffic must use public domains. Railway private networking is only for service-to-service traffic, so the viewer cannot call automem.railway.internal from the user's browser.

The standalone viewer should be served at /. Only use VITE_BASE_PATH=/viewer/ for a different deployment model where the built viewer assets are actually hosted under /viewer/ on the API origin.


Optional: FalkorDB Browser (Admin / Debug)

For low-level graph debugging by operators (separate from the public standalone graph-viewer):

  1. Create new service:

    • Image: falkordb/falkordb-browser:latest

    • Port: 3000

  2. Configure connection:

    FALKORDB_URL=redis://default:${{FalkorDB.FALKOR_PASSWORD}}@${{FalkorDB.RAILWAY_PRIVATE_DOMAIN}}:6379
  3. Access:

    • Prefer private networking / access-controlled exposure (for example Cloudflare Access)

    • Avoid treating this as the public product viewer path

    • Visual query builder included


Monitoring & Health Checks

Built-in Health Endpoint
# Check system health
curl https://your-automem.up.railway.app/health

# Response includes:
# - FalkorDB connection status
# - Qdrant connection status
# - Memory count
# - Timestamp
Automated Health Monitoring

Deploy health monitor as separate service:

# In new Railway service
docker run automem/health-monitor \
  -e AUTOMEM_API_URL=${{AutoMemAPI.RAILWAY_PUBLIC_DOMAIN}} \
  -e CHECK_INTERVAL=300

This will:

  • Monitor FalkorDB/Qdrant health every 5min

  • Check memory count consistency

  • Auto-trigger recovery if >5% drift detected

  • Send alerts via webhook (configure ALERT_WEBHOOK_URL)


Cost Optimization

Recommended Railway Plan: Pro ($20/mo)

Service Sizing:

  • automem: 512MB RAM, 0.5 vCPU (~$5/mo)

  • FalkorDB: 1GB RAM, 1 vCPU + 2GB volume (~$10/mo)

  • mcp-automem: 256MB RAM, 0.25 vCPU (~$2-3/mo)

  • Qdrant (choose one):

    • Cloud: Free tier (1GB) or $25/mo (10GB)

    • Self-hosted on Railway: ~$3-5/mo (256MB RAM + 1GB volume)

Total: ~$17-40/month depending on usage

Cost Saving Tips:

  • Self-host Qdrant on Railway to avoid Qdrant Cloud costs and reduce latency

  • Or use Qdrant Cloud free tier initially

  • Start with smaller FalkorDB volume (1GB)

  • Use Railway's usage-based pricing (scales down when idle)

  • Remove mcp-automem if you only use Cursor/Claude Desktop (saves ~$2-3/mo)


Troubleshooting

Connection Issues

Problem: API can't connect to FalkorDB

Solution:

# Check internal networking
railway logs --service automem | grep FalkorDB

# Verify private domain
echo $FALKORDB_HOST  # Should be: falkordb.railway.internal

# Test connection
railway run --service automem
> redis-cli -h $FALKORDB_HOST -p 6379 -a $FALKORDB_PASSWORD ping
Service Connection Refused (ECONNREFUSED)

Problem: SSE or other services get "fetch failed" or "ECONNREFUSED" when connecting to automem

Symptoms:

Error: connect ECONNREFUSED fd12:ca03:42be:0:1000:50:1079:5b6c:8001

Causes & Solutions:

  1. Missing PORT variable (most common):

    • Check automem variables: PORT must be set to 8001

    • Without it, Flask defaults to port 5000

    • Fix: Add PORT=8001 to automem environment variables and redeploy

  2. IPv6 binding issue (fixed in latest code):

    • Railway internal networking uses IPv6

    • Older AutoMem versions bound to IPv4 only (0.0.0.0)

    • Fix: Update to latest code (Flask now binds to :: for IPv6 dual-stack)

    • Check startup logs should show: * Running on http://[::1]:8001

  3. Wrong internal hostname:

    • Verify AUTOMEM_API_URL in SSE service matches automem's RAILWAY_PRIVATE_DOMAIN

    • Should be: http://automem.railway.internal:8001

Qdrant "Connection Refused" on Internal Networking

Problem: automem can't connect to self-hosted Qdrant via internal networking. Health endpoint shows qdrant: "disconnected", logs show Connection refused (errno 111).

Root cause: Railway's internal networking uses IPv6, but Qdrant's Docker image binds to 0.0.0.0 (IPv4 only) by default. The internal hostname resolves to an IPv6 address, but Qdrant isn't listening on IPv6 — the kernel refuses the connection before it ever reaches the Qdrant process. This is why Qdrant logs show zero incoming connection attempts even though DNS resolves correctly.

Fix: Set this environment variable on the Qdrant service (not automem):

QDRANT__SERVICE__HOST=::

:: is the IPv6 equivalent of 0.0.0.0 — it enables dual-stack binding (IPv6 + IPv4). Redeploy Qdrant after setting this.

Also verify on automem:

  • QDRANT_HOST=qdrant (Railway resolves short service names internally)

  • Or QDRANT_URL=http://qdrant:6333 (explicit URL form)

  • Do NOT use https:// for internal connections

Variable Reference Issues

Problem: Variables using ${{...}} syntax not resolving (showing literal ${{...}} in logs)

Cause: Railway variable references only work in templates, not manual service configuration

Solution: Use hardcoded values instead

# ❌ Don't use in manual setup:
FALKORDB_HOST=${{FalkorDB.RAILWAY_PRIVATE_DOMAIN}}

# ✅ Do use in manual setup:
FALKORDB_HOST=falkordb.railway.internal
FALKORDB_PASSWORD=<copy-exact-value-from-falkordb-service>

Benefit: Hardcoded values are more stable, easier to debug, and work consistently across redeployments.

Data Loss

Problem: FalkorDB restarted and lost data

Cause: No persistent volume configured

Solution:

  1. Add volume to FalkorDB service (Settings → Volumes)

  2. Run recovery: python scripts/recover_from_qdrant.py

  3. Redeploy FalkorDB service

High Memory Usage

Problem: FalkorDB using too much RAM

Solution:

# Optimize Redis memory
REDIS_ARGS=--maxmemory 512mb --maxmemory-policy allkeys-lru

Security Best Practices

  1. Always set FALKOR_PASSWORD (Railway auto-generates)

  2. Use Railway's private networking for service-to-service

  3. Don't expose FalkorDB publicly (use private domain only)

  4. Rotate API tokens periodically via Railway dashboard

  5. Enable Railway's Audit Logs (Enterprise plan)

Note on Service Naming: Railway's internal DNS is based on the service name (e.g., automem.railway.internal). If you rename a service, its RAILWAY_PRIVATE_DOMAIN updates automatically, but you'll need to update any hardcoded hostnames in other services' environment variables.


Next Steps

  • [ ] Set up monitoring alerts (see MONITORING_AND_BACKUPS.md)

  • [ ] Configure automated backups (see MONITORING_AND_BACKUPS.md)

  • [x] Add Remote MCP server integration — see docs/MCP_SSE.md

  • [x] Add standalone graph-viewer companion-service setup

  • [ ] Deploy FalkorDB Browser only for admin/debug workflows

  • [ ] Set up staging environment

Questions? Open an issue: https://github.com/verygoodplugins/automem/issues

273 files · 249 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 network
  • AGENTS.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 times
  • CLAUDE.md: Adds short summaries, timestamps (`enriched_at`), and per-run metrics under `metadata.enrichment`.
  • CLAUDE.md: # Run tests
  • CLAUDE.md: make test-integration # Starts services and runs integration tests
  • CLAUDE.md: make test-live # Same as above via Makefile
  • CLAUDE.md: JIT_ENRICHMENT_ENABLED=true # Run entity/summary extraction inline on recall for unenriched memories
  • CLAUDE.md: Install spaCy locally to improve entity extraction:
  • CLAUDE.md: pip install spacy
  • CLAUDE.md: python -m spacy download en_core_web_sm
  • CLAUDE.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
GitHub avatar of jack-arturojack-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