First-Run Model Download: On first startup, the embedding service downloads the Jina embeddings model (~500MB). This takes 2-5 minutes depending on your connection. The service will appear unhealthy during this time - this is normal. Wait for it to complete before testing.
| Requirement | Minimum Version | Recommended | Notes |
|---|---|---|---|
| Python | 3.10 | 3.11+ | Required for async + match statements. AsyncSDKWrapper requires 3.11+ |
| Docker | 20.10 | Latest | For Qdrant + embedding service |
| OS | Linux, macOS, WSL2 | Linux | Windows requires WSL2 |
| RAM | 16 GiB | 32 GiB | Core tier minimum; Core+Langfuse needs 32 GiB |
| Disk | 5 GiB | 10 GiB+ | Docker images alone are ~3 GiB; allow extra space for data |
AI Memory runs on 16 GiB RAM (4 cores minimum). Adding the optional Langfuse LLM observability module increases the requirement to 32 GiB RAM (8 cores recommended).
| Tier | Services | Minimum RAM | Recommended CPU |
|---|---|---|---|
| Core (default) | 8 services | 16 GiB | 4 cores |
| Core + Langfuse (opt-in) | 15 services | 32 GiB | 8 cores |
The module requires Python packages for core functionality. These are automatically installed by the Docker services, but if you're developing or debugging locally:
# Install core dependencies
pip install -r requirements.txt
# Install development dependencies (testing, linting)
pip install -r requirements-dev.txtCore Dependencies:
qdrant-client- Vector database clienthttpx- HTTP client for embedding servicepydantic- Data validationanthropic- Anthropic API client (for AsyncSDKWrapper)tenacity- Retry logic with exponential backoff (for AsyncSDKWrapper)prometheus-client- Metrics collection
Note: Docker installation handles all dependencies automatically. The tenacity package provides the exponential backoff retry logic used by AsyncSDKWrapper.
If you encounter errors when using AsyncSDKWrapper:
| Error | Cause | Fix |
|---|---|---|
QueueTimeoutError |
Request queued longer than 60s | Increase queue_timeout parameter or reduce request rate |
QueueDepthExceededError |
More than 100 requests queued | Reduce request rate or increase max_queue_depth parameter |
RateLimitError after retries |
API rate limits exceeded | Wait for rate limit window to reset (1 minute) or upgrade API tier |
Example with custom limits:
async with AsyncSDKWrapper(
cwd="/path/to/project",
queue_timeout=120.0, # 2 minute timeout
max_queue_depth=200 # Allow 200 queued requests
) as wrapper:
result = await wrapper.send_message("Hello")Before running the installer, make sure you have these ready:
- Docker Desktop installed and running
- Python 3.10+ installed
- Claude Code installed
- ~5 GiB free disk space
- (Optional) GitHub Personal Access Token (PAT) for repository sync — see GitHub integration setup
- (Optional) Jira API token for Jira sync
- (Optional) SOPS + age for encrypted secrets
macOS (Homebrew):
brew install python@3.11
python3 --version # Verify: Python 3.11.xUbuntu/Debian:
sudo apt update
sudo apt install python3.11 python3.11-venv python3-pip
python3 --version # Verify: Python 3.11.xWindows (WSL2):
# Inside WSL2 terminal
sudo apt update
sudo apt install python3.11 python3.11-venv python3-pipmacOS:
brew install --cask docker
# Start Docker Desktop from ApplicationsUbuntu/Debian:
# Install Docker Engine
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add user to docker group (avoid sudo)
sudo usermod -aG docker $USER
newgrp docker # Activate group
# Verify
docker ps # Should not errorWindows:
- Install Docker Desktop for Windows
- Enable WSL2 integration in Docker Desktop settings
Follow official Claude Code installation: claude.ai/code
If you want to store API keys and tokens encrypted in Git (recommended for teams and shared machines), install SOPS and age before running the installer:
macOS (Homebrew):
brew install sops ageUbuntu/Debian:
# SOPS
curl -LO https://github.com/getsops/sops/releases/download/v3.9.4/sops-v3.9.4.linux.amd64
sudo mv sops-v3.9.4.linux.amd64 /usr/local/bin/sops
sudo chmod +x /usr/local/bin/sops
# age
sudo apt install ageWindows (WSL2):
# Inside WSL2 terminal — same as Ubuntu/Debian aboveVerify installation:
sops --version # Should print sops x.x.x
age-keygen --version # Should print age x.x.xNote: SOPS+age is optional. The installer will detect whether they're installed and show availability next to the option. Without them, you can use plaintext
.envfiles or system keyring instead.
⚠️ Install ONCE, Add Projects: AI-Memory is installed to a single location. Clone the repository once, then run the installer for each project you want to add. Do NOT clone ai-memory into each project!
The installer handles all setup automatically:
# 1. Clone repository (DO THIS ONCE!)
git clone https://github.com/Hidden-History/ai-memory.git
cd ai-memory
# 2. Run installer for your first project
./scripts/install.sh /path/to/target-project
# Example:
./scripts/install.sh ~/projects/my-appWhat the installer does:
- ✅ Validates prerequisites (Python, Docker, Claude Code project)
- ✅ Copies
.claude/hooks/and.claude/skills/to target project - ✅ Updates
.claude/settings.jsonwith hook configuration - ✅ Creates
~/.ai-memory/installation directory - ✅ Installs Python dependencies (qdrant-client, httpx, pydantic)
- ✅ Starts Docker services (Qdrant, embedding, monitoring)
- ✅ Optionally configures Jira Cloud integration (see below)
- ✅ Runs health check to verify all services
Optional: Jira Cloud Integration
The installer offers optional Jira Cloud integration. When enabled, it prompts for:
- Enable Jira sync?
[y/N] - Jira instance URL (e.g.,
https://company.atlassian.net) - Jira email
- Jira API token (hidden input)
- Project keys (JSON array, e.g.,
["PROJ","DEV"])
The installer validates credentials via the Jira API before proceeding. On success, it offers an initial full sync and configures automated cron-based sync (6am/6pm daily).
See docs/JIRA-INTEGRATION.md for complete Jira setup and usage guide.
Optional: GitHub Repository Integration (v2.0.6+)
The installer offers optional GitHub integration for syncing PRs, issues, commits, and code into memory. When enabled, it prompts for:
- Enable GitHub sync?
[y/N] - GitHub Personal Access Token — see step-by-step walkthrough below
- GitHub repository (e.g.,
owner/repo-name)
The installer validates the token via the GitHub API before proceeding. On success, it configures automated sync.
- Go to github.com/settings/tokens?type=beta (fine-grained tokens page)
- Click Generate new token
- Set a descriptive token name (e.g.,
ai-memory-sync) - Set an expiration (90 days recommended)
- Under Repository access, select Only select repositories → choose your repository
- Under Repository permissions, enable the following (all Read-only):
- Contents — Read-only
- Issues — Read-only
- Pull requests — Read-only
- Actions — Read-only (for CI results)
- Metadata — Read-only (always required; auto-selected)
- Click Generate token and copy the token immediately (it is only shown once)
- Paste the token when the installer prompts for
GITHUB_TOKEN
Required environment variables:
| Variable | Description |
|---|---|
GITHUB_TOKEN |
Fine-grained Personal Access Token with the permissions listed above |
GITHUB_REPO |
Repository in owner/repo format |
GITHUB_SYNC_ENABLED |
Set to true to enable (default: false) |
See docs/GITHUB-INTEGRATION.md for complete setup guide.
Optional: Parzival Session Agent (v2.0.6+)
Parzival provides cross-session memory for project oversight — session handoffs, insights, and project knowledge persist in Qdrant.
- Enable Parzival?
[y/N] - Your name (used in handoff documents)
Required environment variables:
| Variable | Description | Default |
|---|---|---|
PARZIVAL_ENABLED |
Enable Parzival integration | false |
PARZIVAL_USER_NAME |
Your name for handoffs | (required if enabled) |
See docs/PARZIVAL-SESSION-GUIDE.md for usage.
Note: The installer generates
~/.ai-memory/docker/.envwith random secrets for Qdrant, Grafana, and Prometheus automatically. The Grafana admin password is randomly generated (not "admin") and stored asGRAFANA_ADMIN_PASSWORDin that file. To customize values or configure the LLM classifier provider, edit~/.ai-memory/docker/.envafter installation. Seedocker/.env.examplefor all available options.
Installation output:
The installer will validate prerequisites, copy hooks/skills, configure settings, start Docker services, and run health checks. Progress is shown in the terminal. On success, a summary banner displays, including the URLs for the Streamlit and Grafana dashboards and a reminder to find your Grafana password in ~/.ai-memory/docker/.env.
⚠️ Do NOT clone ai-memory again! Navigate to your existing ai-memory directory and run the installer from there.
AI Memory uses a single Docker stack for all projects. Memories are isolated using group_id (project name) in Qdrant.
Adding a second (or third, etc.) project:
# Navigate to your EXISTING ai-memory directory (where you cloned it)
cd /path/to/ai-memory
# Run installer on the new project directory
./scripts/install.sh ~/projects/my-second-app
# The installer auto-detects existing installation and:
# - Skips Docker setup (already running)
# - Skips port checks (services are expected to be running)
# - Prompts for project name
# - Prompts for project-specific GitHub repo (auto-detected from .git/config)
# - Optionally configures Jira project keys
# - Registers project in ~/.ai-memory/config/projects.d/
# - Restarts github-sync to pick up new project
# - Copies hooks to the new projectProject Name Prompt:
┌─────────────────────────────────────────────────────────────┐
│ Project Configuration │
└─────────────────────────────────────────────────────────────┘
📁 Project directory: /home/user/projects/my-second-app
The project name is used to isolate memories in Qdrant.
Each project gets its own memory space (group_id).
Project name [my-second-app]: _
Custom Project Name via CLI:
# Skip interactive prompt by providing project name as argument
./scripts/install.sh ~/projects/my-app my-custom-project-idHow Multi-Project Isolation Works:
- Each project gets unique
AI_MEMORY_PROJECT_IDin.claude/settings.json - Hooks use this ID as
group_idwhen storing memories - SessionStart retrieves only memories matching the current project
- One Qdrant instance, multiple isolated memory spaces
Example Multi-Project Setup:
# Project A - e-commerce app
./scripts/install.sh ~/projects/ecommerce-app
# Project B - API service (add-project mode auto-detected)
./scripts/install.sh ~/projects/api-service
# Project C - with custom ID
./scripts/install.sh ~/projects/frontend frontend-dashboardEach project has completely isolated memories while sharing the same Docker infrastructure.
By default, all projects share the GITHUB_TOKEN configured during initial installation. This works when the token has access to all repositories (e.g., classic PATs with repo scope, or fine-grained PATs scoped to "All repositories").
Per-Project Tokens (Fine-Grained PATs)
If you use fine-grained PATs scoped to specific repositories, each project may need its own token. The installer handles this automatically:
- When adding a project, the installer tests connectivity with the shared token
- If the test fails (non-200 HTTP response, e.g., 401, 403, 404), it detects the token type and explains the issue
- You get four recovery options:
- Enter a per-project token -- stored in
projects.d/*.yaml, used only for this project - Replace the shared token -- updates
docker/.envfor all projects - Skip GitHub sync -- disables sync for this project
- Continue anyway -- register the project and fix the token later
- Enter a per-project token -- stored in
Manual Per-Project Token Configuration
You can also manually add a per-project token by editing the YAML config:
# ~/.ai-memory/config/projects.d/my-project.yaml
project_id: my-project
source_directory: /home/user/projects/my-project
github:
repo: my-org/my-project
branch: main
enabled: true
token: github_pat_XXXXXXXXXXXX # Per-project token override
jira:
enabled: falseAfter editing, restart the github-sync container:
cd ~/.ai-memory/docker
docker compose restart github-syncNon-Interactive Mode (CI/Automation)
For automated setups, use the GITHUB_PROJECT_TOKEN environment variable:
GITHUB_PROJECT_TOKEN=github_pat_XXXX \
GITHUB_REPO=my-org/my-project \
NON_INTERACTIVE=true \
./scripts/install.sh ~/projects/my-projectNote:
GITHUB_PROJECT_TOKENonly applies when adding a project to an existing installation (the installer's 'Add project' option). For initial setup, useGITHUB_TOKENinstead.
Enabling Parzival in non-interactive installs (v2.3.3+, PR #124)
By default, NON_INTERACTIVE=true skips Parzival setup and sets PARZIVAL_ENABLED=false. Set INSTALL_PARZIVAL=true alongside NON_INTERACTIVE=true to opt into the full Parzival V2 setup path:
NON_INTERACTIVE=true INSTALL_PARZIVAL=true \
AI_MEMORY_ADD_PROJECT_MODE=true \
GITHUB_REPO=my-org/my-project \
./scripts/install.sh /path/to/project my-org/my-projectNote:
INSTALL_PARZIVALonly enables Parzival when its value is the literal stringtrue. Any other value (including1,yes, or unset) leaves the default skip behavior in place. In interactive installs, settingINSTALL_PARZIVAL=trueskips the y/N prompt and enables Parzival directly; without it, the installer prompts as usual.
Token Resolution Order
The sync engine resolves tokens in this order:
- Per-project token from
projects.d/*.yaml(github.tokenfield) - Shared
GITHUB_TOKENfromdocker/.env
Startup Validation
On container startup, the github-sync service validates each project's token. Projects with invalid tokens are logged as warnings and skipped during sync (they do not crash the service). Fix the token and restart the container to resume sync.
For advanced users who want full control:
Step 1: Clone repository
git clone https://github.com/Hidden-History/ai-memory.git
cd ai-memoryStep 2: Copy files to target project
TARGET_PROJECT="/path/to/your/project"
# Copy hooks
cp -r .claude/hooks "$TARGET_PROJECT/.claude/"
# Copy skills
cp -r .claude/skills "$TARGET_PROJECT/.claude/"Step 3: Update .claude/settings.json
Add hook configuration to $TARGET_PROJECT/.claude/settings.json:
{
"hooks": {
"SessionStart": [
{
"matcher": "resume|compact",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/session_start.py", "timeout": 30000}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/user_prompt_capture.py"}
]
},
{
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/context_injection_tier2.py", "timeout": 5000}
]
}
],
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/new_file_trigger.py", "timeout": 2000}
]
},
{
"matcher": "Edit",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/first_edit_trigger.py", "timeout": 2000}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/error_detection.py", "timeout": 2000},
{"type": "command", "command": ".claude/hooks/scripts/error_pattern_capture.py"}
]
},
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/post_tool_capture.py"}
]
}
],
"PreCompact": [
{
"matcher": "auto|manual",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/pre_compact_save.py", "timeout": 10000}
]
}
],
"Stop": [
{
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/agent_response_capture.py"}
]
}
]
}
}Step 4: Create installation directory
mkdir -p ~/.ai-memory/{logs,cache,templates/conventions}Step 5: Install Python dependencies
pip install qdrant-client httpx pydantic prometheus-clientStep 6: Configure Docker environment
The Docker services require credentials and configuration. Create a .env file from the example:
cd docker
cp .env.example .envEdit docker/.env and set these required values:
| Variable | How to Generate | Required? |
|---|---|---|
QDRANT_API_KEY |
python3 -c "import secrets; print(secrets.token_urlsafe(32))" |
Yes |
GRAFANA_ADMIN_PASSWORD |
python3 -c "import secrets; print(secrets.token_urlsafe(16))" |
Yes |
GRAFANA_SECRET_KEY |
python3 -c "import secrets; print(secrets.token_urlsafe(32))" |
Yes |
PROMETHEUS_ADMIN_PASSWORD |
python3 -c "import secrets; print(secrets.token_urlsafe(16))" |
Yes (if using monitoring) |
AI_MEMORY_INSTALL_DIR |
Set to your ai-memory clone path (e.g., /home/user/ai-memory) |
Yes |
The Prometheus bcrypt hash is generated automatically at container start from PROMETHEUS_ADMIN_PASSWORD by the prometheus-init container. No manual hash generation is needed. The installer generates PROMETHEUS_BASIC_AUTH_HEADER automatically for the health check.
The classifier configuration (Ollama, OpenRouter, etc.) at the bottom of .env can use defaults for local development. See the comments in .env.example for provider-specific setup.
Step 7: Start Docker services
docker compose -f docker/docker-compose.yml up -dStep 8: Verify health
python scripts/health-check.pyIf you already have v1.x installed, upgrade by re-running the installer:
# 1. Navigate to installation directory
cd /path/to/target-project
# 2. Pull latest changes (if installed from Git)
git pull origin main
# 3. Run installer to update
./scripts/install.sh .What gets upgraded:
- Docker services restart with new configurations
- Hook scripts update to latest versions (including V2.0 automatic triggers)
- Docker volumes persist automatically (your data is safe)
- Collections automatically migrate from v1.x names to v2.0 names
V2.0 Migration Notes:
- Old collection names (
implementations,best_practices,agent-memory) automatically renamed - New collections:
code-patterns,conventions,discussions - Memory types updated to V2.0 schema (17 types (30 types in v2.0.6))
- Automatic triggers enabled (error detection, new file, first edit, decision keywords, best practices)
- No data loss - all existing memories preserved
No manual migration needed - The installer handles all updates automatically.
v2.0.6 adds temporal memory features (decay scoring, GitHub sync, security scanning, Parzival integration).
Automated upgrade:
# 1. Pull latest
cd /path/to/ai-memory
git fetch origin && git checkout v2.0.6
# 2. Run the migration script (backs up data automatically)
python scripts/migrate_v205_to_v206.py
# 3. Re-run installer to update hooks and services
./scripts/install.sh /path/to/your-projectWhat the migration script does:
- Creates automatic backup of all Qdrant collections
- Adds v2.0.6 payload indexes to existing collections
- Re-embeds code-patterns collection with
jina-v2-base-codemodel (improves code retrieval 10-30%) - Preserves all existing data — no memories are lost
Optional: Enable GitHub sync (see below) Optional: Enable Parzival session agent (see below)
V2.0.6 Migration Notes:
- Memory types expanded from 17 to 30 (9 GitHub types + 4 agent types)
- New config variables available — see CONFIGURATION.md for full list
- Existing hooks are updated automatically by the installer
- New skills available immediately after upgrade
To verify your installed version:
# Check Docker Compose version (if using Git)
git describe --tags
# Or check CHANGELOG.md
cat CHANGELOG.md | head -20# Recommended: use the unified stack manager
./scripts/stack.sh status
# Or use docker compose directly
docker compose -f docker/docker-compose.yml psExpected output:
NAME STATUS PORTS
ai-memory-qdrant running 0.0.0.0:26350->6333/tcp
ai-memory-embedding running 0.0.0.0:28080->8080/tcp
ai-memory-monitoring-api running 0.0.0.0:28000->8000/tcp
python scripts/health-check.pyExpected output:
═══════════════════════════════════════════════════════════
AI Memory Module Health Check
═══════════════════════════════════════════════════════════
[1/3] Checking Qdrant (localhost:26350)...
✅ Qdrant is healthy
📊 Collections: code-patterns, conventions, discussions
[2/3] Checking Embedding Service (localhost:28080)...
✅ Embedding service is healthy
📊 Model: jinaai/jina-embeddings-v2-base-en
[3/3] Checking Monitoring API (localhost:28000)...
✅ Monitoring API is healthy
📊 Metrics: 42 registered
═══════════════════════════════════════════════════════════
All Services Healthy ✅
═══════════════════════════════════════════════════════════
In your target project, start Claude Code and run a simple command:
cd /path/to/target/project
# Use Claude Code to write a test file
# Memory should be captured automaticallyVerify memory was stored:
curl -H "api-key: $QDRANT_API_KEY" http://localhost:26350/collections/code-patterns/points/scroll | jqIf you enabled Jira Cloud integration during installation:
# Check Jira sync status
python scripts/jira_sync.py --status
# Run incremental sync
python scripts/jira_sync.py --incremental- Streamlit Dashboard: http://localhost:28501 - Memory browser and statistics
- Grafana: http://localhost:23000 — Login with credentials set during installation (check
~/.ai-memory/docker/.envforGRAFANA_ADMIN_PASSWORD) - Performance dashboards - Prometheus: http://localhost:29090 - Raw metrics explorer
- Pushgateway: http://localhost:29091 - Hook metrics collection (requires
--profile monitoring)
The module includes comprehensive monitoring via the --profile monitoring flag:
docker compose -f docker/docker-compose.yml --profile monitoring up -dMonitoring Stack:
| Service | Port | Purpose |
|---|---|---|
| Prometheus | 29090 | Metrics collection and storage |
| Pushgateway | 29091 | Metrics from short-lived processes (hooks) |
| Grafana | 23000 | Pre-configured dashboards and visualization |
Key Features:
- Pre-built dashboards for memory performance, hook latency, and system health
- Hook execution metrics pushed from session_start, post_tool_capture, and other hooks
- Collection size warnings and threshold alerts
- Embedding service performance tracking
Note: Langfuse is entirely optional. AI Memory works fully without it. Skip this section if you did not enable Langfuse during installation.
When Langfuse is enabled (opt-in), the following additional ports are used:
| Port | Service | Notes |
|---|---|---|
| 23100 | Langfuse Web UI | Optional (Langfuse) |
| 23130 | Langfuse Worker | Optional (Langfuse) |
| 25432 | Langfuse PostgreSQL | Optional (Langfuse) |
| 26379 | Langfuse Redis | Optional (Langfuse) |
| 28123 | Langfuse ClickHouse | Optional (Langfuse) |
| 29000 | Langfuse MinIO | Optional (Langfuse) |
docker compose -f docker/docker-compose.yml --profile monitoring up -dThis starts:
- Prometheus (port 29090): Metrics collection
- Pushgateway (port 29091): Hook metrics ingestion
- Grafana (port 23000): Dashboards and visualization
- Open http://localhost:23000
- Login with username
adminand the password from~/.ai-memory/docker/.env(GRAFANA_ADMIN_PASSWORD) - Navigate to Dashboards → AI Memory
# Check Pushgateway has metrics
curl http://localhost:29091/metrics | grep aimemory_
# Check Prometheus is healthy
curl -s http://localhost:29090/-/healthySeed the conventions collection with common best practices:
# Preview what will be seeded
python3 scripts/memory/seed_best_practices.py --dry-run
# Seed from default templates
python3 scripts/memory/seed_best_practices.py
# Seed from custom directory
python3 scripts/memory/seed_best_practices.py --templates-dir ./my-conventionsOr enable during installation:
SEED_BEST_PRACTICES=true ./scripts/install.sh /path/to/projectUse stack.sh — the unified stack manager — for all day-to-day operations. It handles the correct startup/shutdown order automatically (core first on start; Langfuse first on stop).
# Start all services (reads docker/.env to determine which profiles to activate)
./scripts/stack.sh start
# Check status of all containers
./scripts/stack.sh status
# Stop all services (correct shutdown order: Langfuse first, then core)
./scripts/stack.sh stop
# Full restart
./scripts/stack.sh restart
# Nuclear option — removes all containers, volumes, and network (requires confirmation)
./scripts/stack.sh nuke
# Non-interactive nuke (CI/scripts)
./scripts/stack.sh nuke --yesNote:
stack.shreadsdocker/.envto determine which services to start. SetLANGFUSE_ENABLED=truebefore runningstack.sh startif you want Langfuse started automatically. IfLANGFUSE_ENABLEDisfalse(the default), only core services are started.
# All services
docker compose -f docker/docker-compose.yml logs
# Follow logs in real-time
docker compose -f docker/docker-compose.yml logs -f
# Specific service logs
docker compose -f docker/docker-compose.yml logs ai-memory-qdrant
docker compose -f docker/docker-compose.yml logs ai-memory-embeddingIf your computer restarts, the Docker services need to be started manually:
cd /path/to/ai-memory # or wherever you cloned the repo
./scripts/stack.sh startTo enable auto-start on boot, configure Docker Desktop (macOS/Windows) or systemd (Linux) to start the Docker daemon automatically.
For users who prefer to manage services manually without stack.sh:
# Start core services (Qdrant, Embedding, Monitoring API)
docker compose -f docker/docker-compose.yml up -d
# Start with full monitoring (adds Prometheus, Grafana, Pushgateway)
docker compose -f docker/docker-compose.yml --profile monitoring up -d# Stop core services (preserves data)
docker compose -f docker/docker-compose.yml down
# Stop core + monitoring services (if started with --profile monitoring)
docker compose -f docker/docker-compose.yml --profile monitoring down
# Stop services AND delete data volumes (DESTRUCTIVE)
docker compose -f docker/docker-compose.yml down -v
# Stop ALL including monitoring AND delete volumes (DESTRUCTIVE)
docker compose -f docker/docker-compose.yml --profile monitoring down -vImportant: If you started with
--profile monitoring, you must stop with the same flag to properly shut down Prometheus, Grafana, and Pushgateway.
# Restart core services
docker compose -f docker/docker-compose.yml restart
# Restart core + monitoring services
docker compose -f docker/docker-compose.yml --profile monitoring restart
# Restart a specific service
docker compose -f docker/docker-compose.yml restart ai-memory-qdrant
docker compose -f docker/docker-compose.yml restart ai-memory-embedding
docker compose -f docker/docker-compose.yml restart ai-memory-prometheus # monitoring profile only# View running services
docker compose -f docker/docker-compose.yml ps
# Quick health check
curl -s -H "api-key: $QDRANT_API_KEY" http://localhost:26350/health | head -1 # Qdrant
curl -s http://localhost:28080/health # Embedding
# Full health check
python scripts/health-check.pyCreate ~/.ai-memory/docker/.env to override defaults:
# Service endpoints
QDRANT_HOST=localhost
QDRANT_PORT=26350
EMBEDDING_HOST=127.0.0.1
EMBEDDING_PORT=28080
# Installation directory
AI_MEMORY_INSTALL_DIR=/home/user/.ai-memory
# Logging
AI_MEMORY_LOG_LEVEL=INFO # DEBUG for verbose
# Jira Cloud Integration (Optional)
JIRA_INSTANCE_URL=https://company.atlassian.net
JIRA_EMAIL=user@company.com
JIRA_API_TOKEN=your_api_token_here
JIRA_PROJECTS=["PROJ","DEV","OPS"]
JIRA_SYNC_ENABLED=true
JIRA_SYNC_DELAY_MS=100Note: Jira environment variables are automatically set by the installer when Jira sync is enabled. See docs/JIRA-INTEGRATION.md for details.
JIRA_PROJECTS must be a JSON array:
- Correct:
JIRA_PROJECTS='["PROJ1","PROJ2"]' - Legacy:
JIRA_PROJECTS='PROJ1,PROJ2'(auto-converted to JSON array; prefer JSON format above)
Edit .claude/settings.json in your target project to customize hook behavior:
{
"hooks": {
"SessionStart": [
{
"matcher": "resume|compact",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/session_start.py", "timeout": 30000}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/user_prompt_capture.py"}
]
},
{
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/context_injection_tier2.py", "timeout": 5000}
]
}
],
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/new_file_trigger.py", "timeout": 2000}
]
},
{
"matcher": "Edit",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/first_edit_trigger.py", "timeout": 2000}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/error_detection.py", "timeout": 2000},
{"type": "command", "command": ".claude/hooks/scripts/error_pattern_capture.py"}
]
},
{
"matcher": "Edit|Write|NotebookEdit",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/post_tool_capture.py"}
]
}
],
"PreCompact": [
{
"matcher": "auto|manual",
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/pre_compact_save.py", "timeout": 10000}
]
}
],
"Stop": [
{
"hooks": [
{"type": "command", "command": ".claude/hooks/scripts/agent_response_capture.py"}
]
}
]
}
}Note: The PreCompact hook is critical for session continuity. It saves your session summary before context compaction, enabling the "aha moment" when Claude remembers previous sessions.
See docs/HOOKS.md for comprehensive hook documentation.
# 1. Stop Docker services
docker compose -f docker/docker-compose.yml down -v
# Or use the stack manager to remove everything (recommended):
./scripts/stack.sh nuke --yesNote:
stack.sh nukehandles both core and Langfuse containers and volumes in the correct shutdown order.
# 2. Remove installation directory
rm -rf ~/.ai-memory
# 3. Remove hooks from target project
cd /path/to/target/project
rm -rf .claude/hooks/scripts/{session_start,post_tool_capture,stop_hook}.py
rm -rf .claude/skills/ai-memory-*
# 4. Remove hook configuration from .claude/settings.json
# (Manual edit required - remove hooks section)
# 5. Uninstall Python dependencies (optional)
pip uninstall qdrant-client httpx pydantic prometheus-clientTo remove data but keep services:
docker compose -f docker/docker-compose.yml down -vInstallation fails with "Python not found"
Solution:
# Verify Python 3.10+ is installed
python3 --version
# If not installed, see Prerequisites section aboveDocker services won't start
Solution:
# Check if Docker daemon is running
docker ps
# Check for port conflicts
lsof -i :26350 # Qdrant
lsof -i :28080 # Embedding
# View detailed logs
docker compose -f docker/docker-compose.yml logsHooks not triggering in Claude Code
Solution:
- Verify
.claude/settings.jsonwas updated correctly - Restart Claude Code session
- Check hook scripts are executable:
chmod +x .claude/hooks/scripts/*.py - Check hook logs for errors (if logging enabled)
See TROUBLESHOOTING.md for comprehensive troubleshooting guide.
Sources (2026 Best Practices):