Installation & Deployment Guide

June 22, 2026 · View on GitHub

Complete setup instructions for AutoMem across all environments.

Table of Contents


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

# 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 dev

make 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:8001
  • FalkorDB: localhost:6379
  • Qdrant: localhost:6333
  • FalkorDB 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_sm

Deployment

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 pending: Railway services dashboard image will be added at docs/img/railway-services.png once captured.


Option A: One-Click Deploy ⭐ (Fastest)

Deploy on Railway

What this does:

  • Creates the core Railway services from pre-built Docker images:
    • automemghcr.io/verygoodplugins/automem:stable
    • mcp-automemghcr.io/verygoodplugins/mcp-automem:stable
    • qdrantqdrant/qdrant:latest
    • falkordbfalkordb/falkordb:latest
  • The standalone graph viewer is a companion service to add after the core deploy:
    • automem-graph-viewerghcr.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:

  1. Sign in with GitHub (if not logged in)
  2. Review environment variables
  3. (Optional) Add OPENAI_API_KEY for real embeddings instead of mock embeddings
  4. Click "Deploy"
  5. 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:

ServiceImageUpdate cadence
automemghcr.io/verygoodplugins/automem:stableAuto-redeploy nightly
automem-graph-viewerghcr.io/verygoodplugins/automem-graph-viewer:stableAuto-redeploy nightly
mcp-automemghcr.io/verygoodplugins/mcp-automem:stableAuto-redeploy nightly
qdrantqdrant/qdrant:latestAuto-redeploy nightly
falkordbfalkordb/falkordb:latestAuto-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 → DeploymentsDeploy 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)

Need more control? Click to expand manual deployment steps

Step 1: Prerequisites

# Install Railway CLI
npm i -g @railway/cli

# Log in
railway login

# (Optional) Initialize project
railway init

Step 2: Provision FalkorDB

  1. Create new Railway service:

    • Image: falkordb/falkordb:latest
    • Add persistent volume (critical for data persistence)
  2. Note the internal connection details (shown in service settings)

  3. Optional: Set REDIS_PASSWORD for authentication

Railway automatically exposes:

  • REDIS_HOST
  • REDIS_PORT
  • REDIS_PASSWORD

Reference these in AutoMem config via ${{service.<name>.internalHost}}

Step 3: Deploy AutoMem from the published Docker image

  1. Create a new Railway service from the AutoMem image:

    • In Railway → + NewDeploy from Docker image
    • Image: ghcr.io/verygoodplugins/automem:stable
    • (Optional) pin a specific version with :v0.16.0 instead of :stable
    • Add a public domain: Settings → Networking → Generate Domain
  2. Configure environment variables:

    VariableDescriptionRequired
    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
    OPENAI_API_KEYEnables real embeddingsRecommended
    FALKORDB_PASSWORDPassword if set on FalkorDBIf enabled
    QDRANT_URLQdrant Cloud endpointOptional
    QDRANT_API_KEYQdrant API keyIf using Qdrant
  3. Verify deployment:

    curl https://your-automem.up.railway.app/health
    

    Expected: {"status": "healthy"} 503 = FalkorDB connection issue (check host/port/password)

  4. (Optional) Add the MCP bridge service the same way:

    • Image: ghcr.io/verygoodplugins/mcp-automem:stable
    • Set AUTOMEM_API_URL to the internal URL of automem (e.g. http://automem.railway.internal:8001)
    • Set AUTOMEM_API_TOKEN to the same token as the API service
    • Generate a public domain so cloud AI clients (ChatGPT, Claude.ai, ElevenLabs) can reach it

Step 4: Add the Graph Viewer companion service

  1. Create a new Railway service from the Graph Viewer image:

    • In Railway → + NewDeploy from Docker image
    • Image: ghcr.io/verygoodplugins/automem-graph-viewer:stable
    • Add a public domain: Settings → Networking → Generate Domain
  2. Wire the API service to the viewer domain:

    Set these on the automem API service, then redeploy/restart the API:

    GRAPH_VIEWER_URL=https://your-viewer.up.railway.app
    VIEWER_ALLOWED_ORIGINS=https://your-viewer.up.railway.app
    
  3. Leave database and private-network credentials off the viewer service.

    The viewer is browser-side UI. It calls the public AutoMem API URL supplied by /viewer bootstrap (?server=<automem-origin>) or by the token prompt. Railway private domains such as *.railway.internal only 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, or VITE_ENABLE_HAND_CONTROLS in production. VITE_API_TARGET is only for the local Vite dev proxy, VITE_BASE is not a supported variable, and hand controls are controlled by the UI at runtime.

Get Your AutoMem URL

  1. Click on your automem service (the API, not FalkorDB)
  2. Go to "Settings" tab
  3. Scroll to "Networking""Public Networking"
  4. Click "Generate Domain" (if not already generated)
  5. Copy the URL - looks like: automem-production-abc123.up.railway.app

✅ Save this URL! You'll need it for connecting your AI tools.


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| Cloud

Verify Deployment

Test that everything works:

# Replace with YOUR Railway URL
curl https://automem-production-abc123.up.railway.app/health

Expected response:

{ "status": "healthy", "falkordb": "connected" }

Got an error?

  • 503 Service Unavailable = FalkorDB can't connect. Check:
    • FALKORDB_HOST is set to falkordb.railway.internal or ${{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. /health should work without auth.

Next Steps

  1. 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}'
  1. Connect your AI tools - Use your Railway URL in:

    • AutoMem MCP Client
    • Remote MCP for ChatGPT/Claude.ai/ElevenLabs: see docs/MCP_SSE.md
    • Claude Desktop, Cursor, Claude Code, etc.
  2. Set up monitoring (optional): See Health Monitoring Guide

👉 Full Railway Guide - Advanced configuration, monitoring, troubleshooting 👉 Deployment 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 -d

docker-compose.yml includes:

  • AutoMem Flask API (port 8001)
  • FalkorDB (port 6379)
  • Qdrant (port 6333)
  • FalkorDB Browser via FalkorDB built-in UI (port 3000)

Stop services:

make stop
# Or: docker compose down

Bare 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.py

The API will use deterministic placeholder embeddings if no OPENAI_API_KEY or Qdrant is configured.


Configuration

Environment Variables

AutoMem loads configuration from:

  1. Process environment
  2. .env in project root
  3. ~/.config/automem/.env

Core Settings

VariableDescriptionDefault
PORTAPI server port8001
FALKORDB_HOSTFalkorDB hostnamelocalhost
FALKORDB_PORTFalkorDB port6379
FALKORDB_PASSWORDFalkorDB password (if auth enabled)unset
FALKORDB_GRAPHGraph database namememories

Authentication

VariableDescriptionDefault
AUTOMEM_API_TOKENRequired for all endpoints except /healthunset (required)
ADMIN_API_TOKENRequired for /admin/* and enrichment controlsunset (required)

Client authentication methods (in order of preference):

  1. Authorization: Bearer <token> header
  2. X-API-Key: <token> header
  3. ?api_key=<token> query parameter

Admin operations additionally require X-Admin-Token: <admin_token> header.

Vector Search (Optional)

VariableDescriptionDefault
QDRANT_URLQdrant Cloud endpoint (takes precedence over QDRANT_HOST)unset
QDRANT_HOSTQdrant hostname for self-hosted (auto-constructs http://host:port)unset
QDRANT_PORTQdrant port (used with QDRANT_HOST)6333
QDRANT_API_KEYQdrant authentication (if API-key auth is enabled)optional
QDRANT_COLLECTIONQdrant collection namememories
VECTOR_SIZEEmbedding dimension1024
EMBEDDING_PROVIDEREmbedding provider selectionauto
EMBEDDING_MODELOpenAI embedding modeltext-embedding-3-small
VOYAGE_API_KEYVoyage API key (Voyage provider)unset
VOYAGE_MODELVoyage model (Voyage provider)voyage-4
OPENAI_API_KEYAPI key (OpenAI or compatible provider)unset
OPENAI_BASE_URLCustom endpoint for OpenAI-compatible providersunset

👉 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) automatically adopts your existing collection dimension on startup. No manual action needed when updating — existing 3072d or 768d collections continue to work.

The recommended setup is Voyage (voyage-4) at 1024d. If you only have an OpenAI key, text-embedding-3-small is used as fallback and truncated to VECTOR_SIZE via Matryoshka.

Enrichment Pipeline

VariableDescriptionDefault
ENRICHMENT_MAX_ATTEMPTSRetry limit for failed enrichments3
ENRICHMENT_SIMILARITY_LIMITNumber of semantic neighbors5
ENRICHMENT_SIMILARITY_THRESHOLDMin cosine score for SIMILAR_TO0.8
ENRICHMENT_IDLE_SLEEP_SECONDSSleep when queue empty2
ENRICHMENT_FAILURE_BACKOFF_SECONDSBackoff between retries5
ENRICHMENT_ENABLE_SUMMARIESAuto-generate summariestrue
ENRICHMENT_SPACY_MODELspaCy model for entitiesen_core_web_sm

Consolidation Engine

VariableDescriptionDefault
CONSOLIDATION_DECAY_INTERVAL_SECONDSDecay cycle frequency3600 (1 hour)
CONSOLIDATION_DECAY_IMPORTANCE_THRESHOLDMin importance to process (empty = all)0.3
CONSOLIDATION_CREATIVE_INTERVAL_SECONDSCreative association cycle3600 (1 hour)
CONSOLIDATION_CLUSTER_INTERVAL_SECONDSClustering cycle21600 (6 hours)
CONSOLIDATION_FORGET_INTERVAL_SECONDSForgetting cycle86400 (1 day)

Search Scoring (Advanced)

VariableDescriptionDefault
RECALL_RELATION_LIMITMax related memories per result5
SEARCH_WEIGHT_*Custom scoring weightsSee 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:

FieldTypeRequiredDescription
contentstring✅ YesMemory content (min 1 char)
tagsarrayNoTags for categorization (e.g., ["decision", "database"])
importancefloatNoImportance score 0.0-1.0 (default: 0.5)
typestringNoMemory classification (default: auto-classified)
confidencefloatNoConfidence in type 0.0-1.0 (default: 0.9 if type provided, auto-computed otherwise)
metadataobjectNoCustom metadata (any JSON object)
timestampstringNoISO 8601 timestamp (default: current time)
embeddingarrayNoVector embedding (auto-generated if omitted; default 1024d with voyage-4)
t_validstringNoISO timestamp when memory becomes valid
t_invalidstringNoISO timestamp when memory expires
updated_atstringNoISO timestamp of last update (default: timestamp)
last_accessedstringNoISO timestamp of last access (default: updated_at)

Valid Memory Types:

  • Decision - Strategic or technical decisions
  • Pattern - Recurring approaches or best practices
  • Preference - User/team preferences
  • Style - Code style or formatting preferences
  • Habit - Regular behaviors or workflows
  • Insight - Key learnings or realizations
  • Context - 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 type preferred: Send type when you know the classification for immediate, accurate categorization
  • Auto-classification fallback: Omit type to let enrichment pipeline classify based on content
  • Embedding auto-generation: Service generates real embeddings (OpenAI) or placeholder vectors if omitted
  • Timestamp 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 Request with list of valid options
  • IDs 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:

ParameterDescriptionExample
queryFull-text search stringdatabase migration
embeddingVector (comma-separated, dimension matches VECTOR_SIZE)0.12,0.56,...
limitMax results (1-50)10
time_queryNatural time phrasestoday, last week, last 7 days
startISO timestamp (lower bound)2025-09-01T00:00:00Z
endISO timestamp (upper bound)2025-09-30T23:59:59Z
tagsTag filters (multiple allowed)slack, decision
tag_modeany or allany (default)
tag_matchprefix or exactprefix (default)
contextHigh-level context labelcoding-style, preference
languageExplicit language hintpython, typescript
active_pathActive file path (used to infer language/context)/Users/jack/project/app.py
context_tagsComma or list of tags to prioritizecoding-style,python
context_typesMemory types to prioritizeStyle,Preference
priority_idsSpecific memory IDs to treat as anchorsuuid-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=all

Response:

{
  "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 (multiple tags params 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=0

Returns 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 (multiple tags params or comma-separated)

Example:

DELETE /memory/by-tag?tags=deployment&tags=success

Returns 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 connection
  • LEADS_TO - Causal (bug→solution)
  • OCCURRED_BEFORE - Temporal sequence
  • PREFERS_OVER - User/team preferences
  • EXEMPLIFIES - Pattern examples
  • CONTRADICTS - Conflicting approaches
  • REINFORCES - Supporting evidence
  • INVALIDATED_BY - Outdated information
  • EVOLVED_INTO - Knowledge evolution
  • DERIVED_FROM - Source relationships
  • PART_OF - Hierarchical structure

System-generated / internal relationship types:

  • SIMILAR_TO - Semantic neighbors created automatically
  • PRECEDED_BY - Temporal links created automatically
  • DISCOVERED - Internal consolidation edge with kind=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

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.1

Options:

  • --db - SQLite database path (auto-detected on macOS/Linux/Windows if omitted)
  • --automem-url - AutoMem endpoint (default: http://localhost:8001)
  • --api-token - API token (uses AUTOMEM_API_TOKEN env 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 test
  • No external services required
  • Uses in-memory stubs
  • Fast execution
  • Filtered warnings (see pytest.ini)

Integration Tests (Local Docker)

make test-integration
  • Automatically 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-live
  • Tests against live Railway deployment
  • Requires Railway CLI and project linkage
  • Interactive confirmation before running
  • Use ./test-live-server-auto.sh for 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 test

Environment Variables:

  • AUTOMEM_TEST_BASE_URL - Override default http://localhost:8001
  • AUTOMEM_ALLOW_LIVE=1 - Required for non-localhost endpoints
  • AUTOMEM_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_TOKEN matches client's header/query param
  • Check: Look for Authorization: Bearer <token> in request

503 Service Unavailable / FalkorDB is unavailable

  • Cause: Cannot connect to FalkorDB
  • Fix: Verify FALKORDB_HOST and FALKORDB_PORT are correct
  • Check: Test connection: redis-cli -h $FALKORDB_HOST -p $FALKORDB_PORT ping
  • Railway: Ensure FalkorDB service is running and internal hostname is correct

Embedding dimension mismatch

  • Cause: Incorrect embedding dimension
  • Fix: Supply a vector matching VECTOR_SIZE or omit field entirely
  • Note: Service generates placeholder if embedding omitted

Qdrant Errors (Logged but Non-Blocking)

  • Behavior: API continues working; vector search disabled
  • Fix: Check QDRANT_URL and QDRANT_API_KEY configuration
  • Logs: Inspect application logs for specific Qdrant error messages
  • Fallback: FalkorDB operations continue normally

Enrichment Not Processing

  • Check: GET /enrichment/status for queue health
  • Causes:
    • Worker thread crashed (check logs)
    • spaCy model not installed (pip install spacy)
    • Memory already enriched (check metadata.enriched_at)
  • Fix: Force reprocess: POST /enrichment/reprocess with 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 variables

Health 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


License

MIT License - See LICENSE file for details.