Back to skills
SKILL.md
474 Installation 658ef4bb
CSecurityComplete setup instructions for AutoMem across all environments.
- 9 stars
- 0 votes
- 0 copies
- 2 views
- Added June 1, 2026
Works with
Security analysis
72/100- Uses curl or wget to download content
- Exfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study
- Installs packages at runtime which could introduce malicious dependencies
- Installs packages at runtime which could introduce malicious dependencies
Pro scans all 2 files and shows the line behind each finding
npx -y skills add tools-only/X-Skills --skill 474-installation_658ef4bb --agent claude-codeAre you the author of 474 Installation 658ef4bb?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-474-installation-658ef4bb)# Installation & Deployment Guide
Complete setup instructions for AutoMem across all environments.
## Table of Contents
- [Prerequisites](#prerequisites)
- [Quick Start](#quick-start)
- [Deployment](#deployment)
- [Railway (Recommended)](#railway-recommended)
- [Docker Compose (Local)](#docker-compose-local)
- [Bare API (Development)](#bare-api-development)
- [Configuration](#configuration)
- [API Reference](#api-reference)
- [Migration](#migration)
- [Testing](#testing)
- [Troubleshooting](#troubleshooting)
---
## Prerequisites
- **Python 3.10+**
- **Docker & Docker Compose** (for bundled stack)
- **Railway CLI** (for Railway deployment): `npm i -g @railway/cli`
---
## Quick Start
### Local Development (Recommended)
```bash
# Clone repository
git clone https://github.com/verygoodplugins/automem.git
cd automem
# Create virtual environment
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements-dev.txt
# Start all services (FalkorDB + Qdrant + API)
make dev
```
**Services:**
- API: `http://localhost:8001`
- FalkorDB: `localhost:6379`
- Qdrant: `localhost:6333`
**Optional Enhancement:**
Install spaCy for richer entity extraction:
```bash
pip install spacy
python -m spacy download en_core_web_sm
```
---
## Deployment
### 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
---
#### 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
- 
---
#### Option A: One-Click Deploy ⭐ (Fastest)
[](https://railway.com/deploy/automem-ai-memory-service?referralCode=VuFE6g&utm_medium=integration&utm_source=template&utm_campaign=generic)
**What this does:**
- Creates AutoMem API + Remote MCP server + FalkorDB services automatically
- 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](#get-your-automem-url) below to get your endpoint.
---
#### Option B: Manual Setup (Advanced)
<details>
<summary><b>Need more control? Click to expand manual deployment steps</b></summary>
#### Step 1: Prerequisites
```bash
# 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
1. Deploy from repo:
```bash
railway up
```
Or connect repo in Railway UI for auto-deploys.
2. Configure environment variables:
| Variable | Description | Required |
| ------------------- | ------------------------------------- | --------------- |
| `AUTOMEM_API_TOKEN` | Auth token for all client calls | ✅ Yes |
| `ADMIN_API_TOKEN` | Token for admin/enrichment endpoints | ✅ Yes |
| `FALKORDB_HOST` | Internal hostname of FalkorDB service | ✅ Yes |
| `FALKORDB_PORT` | FalkorDB port (usually `6379`) | ✅ Yes |
| `OPENAI_API_KEY` | Enables real embeddings | Recommended |
| `FALKORDB_PASSWORD` | Password if set on FalkorDB | If enabled |
| `QDRANT_URL` | Qdrant Cloud endpoint | Optional |
| `QDRANT_API_KEY` | Qdrant API key | If using Qdrant |
3. Verify deployment:
```bash
curl https://your-automem.up.railway.app/health
```
Expected: `{"status": "healthy"}`
`503` = FalkorDB connection issue (check host/port/password)
#### Get Your AutoMem URL
1. Click on your **automem-api** 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.
</details>
---
#### What You Just Built
```mermaid
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]
subgraph services [Services]
API[AutoMem API<br/>Flask Service<br/>Internal Port 8001]
FalkorDB[(FalkorDB<br/>Graph Database<br/>Port 6379)]
Volume[Persistent Volume<br/>Data Storage]
end
Domain -->|Routes to| API
API -->|Internal networking| FalkorDB
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:
```bash
# Replace with YOUR Railway URL
curl https://automem-production-abc123.up.railway.app/health
```
**Expected response:**
```json
{ "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**:
```bash
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}'
```
2. **Connect your AI tools** - Use your Railway URL in:
- [AutoMem MCP Client](https://github.com/verygoodplugins/mcp-automem)
- Remote MCP for ChatGPT/Claude.ai/ElevenLabs: see docs/MCP_SSE.md
- Claude Desktop, Cursor, Claude Code, etc.
3. **Set up monitoring** (optional): See [Health Monitoring Guide](docs/HEALTH_MONITORING.md)
👉 **[Full Railway Guide](docs/RAILWAY_DEPLOYMENT.md)** - Advanced configuration, monitoring, troubleshooting
👉 **[Deployment Checklist](docs/DEPLOYMENT_CHECKLIST.md)** - Step-by-step verification
---
### Docker Compose (Local)
Run complete stack locally:
```bash
# 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)
Stop services:
```bash
make stop
# Or: docker-compose down
```
---
### Bare API (Development)
Run API without Docker (requires external FalkorDB):
```bash
# Activate virtual environment
source venv/bin/activate
# Set connection details
export FALKORDB_HOST=localhost
export FALKORDB_PORT=6379
export PORT=8001
# Optional: Qdrant configuration
export QDRANT_URL=http://localhost:6333
# export QDRANT_API_KEY=your_key
# 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
| 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):
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)
| Variable | Description | Default |
| ------------------- | ------------------------------------- | ---------- |
| `QDRANT_URL` | Qdrant API endpoint | _unset_ |
| `QDRANT_API_KEY` | Qdrant authentication | _optional_ |
| `QDRANT_COLLECTION` | Qdrant collection name | `memories` |
| `VECTOR_SIZE` | Embedding dimension | `3072` |
| `EMBEDDING_PROVIDER`| Embedding provider selection | `auto` |
| `EMBEDDING_MODEL` | OpenAI embedding model | `text-embedding-3-large` |
| `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_ |
👉 **New to Qdrant?** See the [Qdrant Setup Guide](docs/QDRANT_SETUP.md) for step-by-step instructions on creating a collection with the right settings.
> Existing deployments on 768d should set `VECTOR_SIZE=768` (and keep `EMBEDDING_MODEL=text-embedding-3-small`) until after running `scripts/reembed_embeddings.py`. The server now fails fast if your configured dimension does not match the Qdrant collection.
>
> Voyage models support specific dimensions (256, 512, 1024, 2048). If you use `EMBEDDING_PROVIDER=voyage`, set `VECTOR_SIZE` to one of those values and keep it consistent with your Qdrant collection.
#### 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:**
```json
{
"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 3072d or 768d with small model) |
| `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 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:**
```json
{
"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`
```json
{
"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:**
| Parameter | Description | Example |
| -------------- | ------------------------------------------------- | ----------------------------------- |
| `query` | Full-text search string | `database migration` |
| `embedding` | 768-d vector (comma-separated) | `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:**
```bash
# 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:**
```json
{
"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)
```json
{
"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:**
```json
{
"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 (default 50)
**Example:**
```bash
GET /memory/by-tag?tags=deployment&tags=success&limit=20
```
Returns most recent/important memories matching any requested tag.
---
#### `POST /associate`
Create a relationship between two memories.
**Request:**
```json
{
"memory1_id": "uuid-source",
"memory2_id": "uuid-target",
"type": "RELATES_TO",
"strength": 0.8
}
```
**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
**Response:**
```json
{
"status": "success",
"message": "Association created successfully"
}
```
---
#### `GET /enrichment/status`
Check enrichment pipeline health.
**Response:**
```json
{
"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:**
```json
{
"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:**
```json
{
"batch_size": 32,
"limit": 100
}
```
**Example:**
```bash
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:
```bash
# 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)
```bash
make test
```
- No external services required
- Uses in-memory stubs
- Fast execution
- Filtered warnings (see `pytest.ini`)
### Integration Tests (Local Docker)
```bash
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)
```bash
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:**
```bash
# 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](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 must contain exactly 768 values`
- **Cause:** Incorrect embedding dimension
- **Fix:** Supply full 768-d vector 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:
```bash
# Development
export FLASK_ENV=development
export LOG_LEVEL=DEBUG
python app.py
# Production (Railway)
# Set LOG_LEVEL=DEBUG in environment variables
```
### Health Checks
```bash
# 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](https://automem.ai)
- **Issues:** [GitHub Issues](https://github.com/verygoodplugins/automem/issues)
- **MCP Integration:** [@verygoodplugins/mcp-automem](https://www.npmjs.com/package/@verygoodplugins/mcp-automem)
---
## License
MIT License - See [LICENSE](LICENSE) file for details.
Files in this skill
- README.md
- skill.md
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.