Skip to content

Authentication

AutoMem uses a two-tier token-based authentication system to control access to different classes of operations. All endpoints except /health require a valid API token.

For deployment-specific token generation on Railway, see Railway Deployment. For complete endpoint documentation with authentication requirements, see Memory Operations.


Token TypeEnvironment VariableRequired ForPurpose
API TokenAUTOMEM_API_TOKENAll endpoints except /healthStandard memory operations (store, recall, update, delete)
Admin TokenADMIN_API_TOKENAdmin and enrichment endpointsPrivileged operations (reprocessing, re-embedding, bulk operations)

AutoMem accepts authentication credentials via three methods, checked in the following priority order:

graph TD
    Request["Incoming Request"]

    CheckBearer{"Authorization header<br/>starts with 'Bearer'?"}
    ExtractBearer["Extract token<br/>from Bearer string"]

    CheckCustomHeader{"X-API-Key or<br/>X-API-Token header?"}
    ExtractHeader["Extract token<br/>from header"]

    CheckQuery{"Query param<br/>api_key/apiKey/api_token?"}
    ExtractQuery["Extract token<br/>from query string"]

    NoToken["Return None<br/>→ 401 Unauthorized"]
    ValidateToken["Validate against<br/>AUTOMEM_API_TOKEN or<br/>ADMIN_API_TOKEN"]

    Request --> CheckBearer
    CheckBearer -->|Yes| ExtractBearer
    CheckBearer -->|No| CheckCustomHeader

    CheckCustomHeader -->|Yes| ExtractHeader
    CheckCustomHeader -->|No| CheckQuery

    CheckQuery -->|Yes| ExtractQuery
    CheckQuery -->|No| NoToken

    ExtractBearer --> ValidateToken
    ExtractHeader --> ValidateToken
    ExtractQuery --> ValidateToken

Standard OAuth 2.0-style authentication using the Authorization header:

Terminal window
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
https://your-service.railway.app/recall?q=query

Advantages:

  • Industry standard
  • Automatically handled by most HTTP libraries
  • Cannot be logged in server access logs (more secure than query params)

Alternative header-based authentication using X-API-Key:

Terminal window
curl -H "X-API-Key: YOUR_API_TOKEN" \
https://your-service.railway.app/recall?q=query

Use this when client libraries do not support Bearer tokens easily.

Fallback authentication via URL query string:

Terminal window
curl "https://your-service.railway.app/recall?q=query&api_key=YOUR_API_TOKEN"

This diagram shows how requests flow through both the MCP SSE server and the Flask API:

graph LR
    subgraph "Token Sources"
        BearerHeader["Authorization: Bearer TOKEN"]
        APIKeyHeader["X-API-Key: TOKEN"]
        QueryParam["?api_key=TOKEN"]
    end

    subgraph "mcp-sse-server :8080"
        GetAuthToken["getAuthToken(req)"]
        ValidateToken["Compare vs<br/>AUTOMEM_API_TOKEN"]
        AddAuthHeader["Add Authorization:<br/>Bearer header"]
    end

    subgraph "Flask API :8001"
        RequireAPIToken["@require_api_token"]
        ExtractToken["extract_token(request)<br/>multiple sources"]
        CheckLevel["Check endpoint<br/>requires ADMIN?"]
        ValidateAdmin["Validate<br/>ADMIN_API_TOKEN"]
        ProcessRequest["Route to handler"]
    end

    BearerHeader --> GetAuthToken
    APIKeyHeader --> GetAuthToken
    QueryParam --> GetAuthToken

    GetAuthToken --> ValidateToken
    ValidateToken -->|Valid| AddAuthHeader
    ValidateToken -->|Invalid| Reject401["401 Unauthorized"]

    AddAuthHeader --> RequireAPIToken
    RequireAPIToken --> ExtractToken
    ExtractToken --> CheckLevel

    CheckLevel -->|Standard| ProcessRequest
    CheckLevel -->|Admin endpoint| ValidateAdmin
    ValidateAdmin -->|Valid| ProcessRequest
    ValidateAdmin -->|Invalid| Reject403["403 Forbidden"]

Admin endpoints require both the API token and an additional admin token. The admin token is provided in a separate X-Admin-Token header:

Terminal window
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-H "X-Admin-Token: YOUR_ADMIN_TOKEN" \
-X POST https://your-service.railway.app/enrichment/reprocess
EndpointMethodPurpose
/admin/reembedPOSTRegenerate embeddings in batches
/enrichment/reprocessPOSTRe-queue memories for enrichment
/enrichment/statusGETView enrichment pipeline status

graph TB
    subgraph "Public Endpoints"
        Health["/health<br/>GET"]
    end

    subgraph "API Token Required"
        Memory["/memory<br/>POST, GET, PATCH, DELETE"]
        Recall["/recall<br/>GET"]
        Associate["/associate<br/>POST"]
        ByTag["/memory/by-tag<br/>GET"]
        Consolidate["/consolidate<br/>POST, GET"]
        Analyze["/analyze<br/>GET"]
        StartupRecall["/startup-recall<br/>GET"]
    end

    subgraph "Admin Token Required"
        Reembed["/admin/reembed<br/>POST"]
        Reprocess["/enrichment/reprocess<br/>POST"]
        EnrichStatus["/enrichment/status<br/>GET"]
    end

    style Health fill:#90EE90
    style Memory fill:#FFD700
    style Recall fill:#FFD700
    style Associate fill:#FFD700
    style ByTag fill:#FFD700
    style Consolidate fill:#FFD700
    style Analyze fill:#FFD700
    style StartupRecall fill:#FFD700
    style Reembed fill:#FF6B6B
    style Reprocess fill:#FF6B6B
    style EnrichStatus fill:#FF6B6B
CategoryEndpointsAPI TokenAdmin Token
Public/healthNoNo
Standard/memory, /recall, /associate, /memory/by-tag, /consolidate, /analyze, /startup-recallYesNo
Admin/admin/reembed, /enrichment/reprocess, /enrichment/statusYesYes

Configure authentication tokens via environment variables loaded in this order:

  1. Process environment (e.g., export AUTOMEM_API_TOKEN=...)
  2. .env file in project root
  3. ~/.config/automem/.env (user-specific configuration)

The variables API_TOKEN and ADMIN_TOKEN are accepted as backward-compatible aliases for AUTOMEM_API_TOKEN and ADMIN_API_TOKEN respectively.

Railway (Automatic):

Railway’s template automatically generates secure tokens using the generator: secret directive in railway-template.json. No manual action required.

Manual (Local Development):

Generate secure tokens using OpenSSL:

Terminal window
# Generate API token
openssl rand -hex 32
# Generate Admin token (use a different value)
openssl rand -hex 32

import requests
headers = {
"Authorization": f"Bearer {api_token}",
"Content-Type": "application/json"
}
response = requests.post(
"https://your-service.railway.app/memory",
headers=headers,
json={"content": "Important decision made today", "type": "Decision"}
)
const response = await fetch("https://your-service.railway.app/recall?q=decisions", {
headers: {
"Authorization": `Bearer ${apiToken}`,
}
});
const data = await response.json();
Terminal window
# Store a memory
curl -X POST https://your-service.railway.app/memory \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content": "Prefer PostgreSQL for relational data", "type": "Preference"}'
# Recall memories
curl "https://your-service.railway.app/recall?q=database+preferences" \
-H "Authorization: Bearer YOUR_TOKEN"

NPM Package (@verygoodplugins/mcp-automem)

Section titled “NPM Package (@verygoodplugins/mcp-automem)”

Desktop tools like Claude Desktop and Cursor IDE use the NPM package, which requires API token configuration in the platform’s MCP config file:

{
"mcpServers": {
"automem": {
"command": "npx",
"args": ["-y", "@verygoodplugins/mcp-automem"],
"env": {
"AUTOMEM_ENDPOINT": "https://your-service.railway.app",
"AUTOMEM_API_KEY": "YOUR_API_TOKEN"
}
}
}
}

The client automatically injects the token as Authorization: Bearer header on all requests.

For cloud-based AI platforms (ChatGPT, ElevenLabs), the SSE bridge requires AUTOMEM_API_TOKEN set in the Railway environment. The bridge validates incoming requests against this token and forwards them to the AutoMem API transparently.


PracticeDescriptionPriority
Strong tokensUse cryptographically random tokens (32+ bytes)Critical
Environment variablesNever hardcode tokens in code or commit to GitCritical
Separate admin tokensUse different tokens for API and admin accessCritical
HTTPS onlyAlways use HTTPS in production (Railway provides automatically)Critical
Prefer Bearer authUse Authorization: Bearer over query paramsHigh
Rotate regularlyChange tokens every 90 days or after suspected exposureHigh
Environment separationDifferent tokens for dev/staging/productionHigh
Monitor logsWatch for 401 errors indicating unauthorized attemptsMedium
Audit trailLog who performs admin operations (via admin token)Medium
MistakeRiskSolution
Committing tokens to GitPublic exposure, unauthorized accessUse .gitignore, environment variables
Using same token everywhereSingle point of compromiseSeparate tokens per environment
Query param authentication in productionTokens logged in server logsUse Bearer header
No admin token separationAnyone with API access can perform admin opsConfigure separate ADMIN_API_TOKEN
Weak tokens (e.g., “password123”)Easy to guess/brute forceUse cryptographic generators

When rotating tokens (for example, after suspected exposure or periodic maintenance):

  1. Generate new tokens: openssl rand -hex 32
  2. Update server environment variables (Railway dashboard or CLI)
  3. Update all clients with new tokens before removing old tokens
  4. Test connectivity with new tokens
  5. Remove old tokens from server configuration entirely
  6. Restart the service to ensure old tokens are not cached

Symptom: All requests return 401 Unauthorized

Common causes:

  1. Token not set in environment variable — verify with echo $AUTOMEM_API_TOKEN
  2. Typo in token value — check for trailing spaces or newlines
  3. Using wrong token (API token vs admin token)
  4. Token mismatch between client and server

Diagnosis:

Terminal window
# Test your token directly
curl -v -H "Authorization: Bearer YOUR_TOKEN" \
https://your-service.railway.app/recall?q=test

Symptom: Standard endpoints work, but admin endpoints return 401 Unauthorized

Common causes:

  1. Missing X-Admin-Token header — admin endpoints require both headers
  2. ADMIN_API_TOKEN not configured on server
  3. Admin token mismatch between client and server

If a token is exposed (committed to Git, shared in logs):

  1. Immediate rotation: Generate a new token and update server configuration — deploy immediately
  2. Audit access: Check server logs for unauthorized requests; look for unusual patterns in /health or /analyze endpoints
  3. Revoke old token: Remove from environment variables and restart the service to ensure it is not cached