Files
claudetools/MIGRATION_TO_RMM_PLAN.md
Mike Swanson 25f3759ecc [Config] Add coding guidelines and code-fixer agent
Major additions:
- Add CODING_GUIDELINES.md with "NO EMOJIS" rule
- Create code-fixer agent for automated violation fixes
- Add offline mode v2 hooks with local caching/queue
- Add periodic context save with invisible Task Scheduler setup
- Add agent coordination rules and database connection docs

Infrastructure:
- Update hooks: task-complete-v2, user-prompt-submit-v2
- Add periodic_save_check.py for auto-save every 5min
- Add PowerShell scripts: setup_periodic_save.ps1, update_to_invisible.ps1
- Add sync-contexts script for queue synchronization

Documentation:
- OFFLINE_MODE.md, PERIODIC_SAVE_INVISIBLE_SETUP.md
- Migration procedures and verification docs
- Fix flashing window guide

Updates:
- Update agent configs (backup, code-review, coding, database, gitea, testing)
- Update claude.md with coding guidelines reference
- Update .gitignore for new cache/queue directories

Status: Pre-automated-fixer baseline commit

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-17 12:51:43 -07:00

15 KiB

ClaudeTools Migration to RMM Server

Date: 2026-01-17 Objective: Centralize ClaudeTools database and API on RMM server (172.16.3.30) Estimated Time: 30-45 minutes


Current State

Database (Jupiter - 172.16.3.20:3306):

  • MariaDB in Docker container
  • Database: claudetools
  • User: claudetools
  • Password: CT_e8fcd5a3952030a79ed6debae6c954ed
  • 43 tables, ~0 rows (newly created)

API:

  • Running locally on each machine (localhost:8000)
  • Requires Python, venv, dependencies on each machine
  • Inconsistent versions across machines

Configuration:

  • Encryption Key: C:\Users\MikeSwanson\claude-projects\shared-data\.encryption-key
  • JWT Secret: NdwgH6jsGR1WfPdUwR3u9i1NwNx3QthhLHBsRCfFxcg=

Target State

Database (RMM Server - 172.16.3.30:3306):

  • MariaDB installed natively on Ubuntu 22.04
  • Database: claudetools
  • User: claudetools
  • Same password (for simplicity)
  • Accessible from local network (172.16.3.0/24)

API (RMM Server - 172.16.3.30:8001):

  • Running as systemd service
  • URL: http://172.16.3.30:8001
  • External URL (via nginx): https://claudetools-api.azcomputerguru.com
  • Auto-starts on boot
  • Single deployment point

Client Configuration (.claude/context-recall-config.env):

CLAUDE_API_URL=http://172.16.3.30:8001
CLAUDE_PROJECT_ID=auto-detected
JWT_TOKEN=obtained-from-central-api
CONTEXT_RECALL_ENABLED=true

Migration Steps

Phase 1: Database Setup on RMM Server (10 min)

1.1 Install MariaDB on RMM Server

ssh guru@172.16.3.30

# Install MariaDB
sudo apt update
sudo apt install -y mariadb-server mariadb-client

# Start and enable service
sudo systemctl start mariadb
sudo systemctl enable mariadb

# Secure installation
sudo mysql_secure_installation
# - Set root password: CT_rmm_root_2026
# - Remove anonymous users: Yes
# - Disallow root login remotely: Yes
# - Remove test database: Yes
# - Reload privilege tables: Yes

1.2 Create ClaudeTools Database and User

sudo mysql -u root -p

CREATE DATABASE claudetools CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

CREATE USER 'claudetools'@'172.16.3.%' IDENTIFIED BY 'CT_e8fcd5a3952030a79ed6debae6c954ed';
GRANT ALL PRIVILEGES ON claudetools.* TO 'claudetools'@'172.16.3.%';

CREATE USER 'claudetools'@'localhost' IDENTIFIED BY 'CT_e8fcd5a3952030a79ed6debae6c954ed';
GRANT ALL PRIVILEGES ON claudetools.* TO 'claudetools'@'localhost';

FLUSH PRIVILEGES;
EXIT;

1.3 Configure MariaDB for Network Access

sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf

# Change bind-address to allow network connections
# FROM: bind-address = 127.0.0.1
# TO:   bind-address = 0.0.0.0

sudo systemctl restart mariadb

# Test connection from Windows
# From D:\ClaudeTools:
mysql -h 172.16.3.30 -u claudetools -p claudetools
# Password: CT_e8fcd5a3952030a79ed6debae6c954ed

Phase 2: Export Data from Jupiter (5 min)

2.1 Export Current Database

# On Jupiter (172.16.3.20)
ssh root@172.16.3.20

# Export database
docker exec -it mariadb mysqldump \
  -u claudetools \
  -pCT_e8fcd5a3952030a79ed6debae6c954ed \
  claudetools > /tmp/claudetools_export.sql

# Check export size
ls -lh /tmp/claudetools_export.sql

# Copy to RMM server
scp /tmp/claudetools_export.sql guru@172.16.3.30:/tmp/

2.2 Import to RMM Server

# On RMM server
ssh guru@172.16.3.30

# Import database
mysql -u claudetools -pCT_e8fcd5a3952030a79ed6debae6c954ed claudetools < /tmp/claudetools_export.sql

# Verify tables
mysql -u claudetools -pCT_e8fcd5a3952030a79ed6debae6c954ed claudetools -e "SHOW TABLES;"

# Should show 43 tables

Alternative: Fresh Migration with Alembic (if export is empty/small)

# On Windows (D:\ClaudeTools)
# Update .env to point to RMM server
DATABASE_URL=mysql+pymysql://claudetools:CT_e8fcd5a3952030a79ed6debae6c954ed@172.16.3.30:3306/claudetools?charset=utf8mb4

# Run migrations
alembic upgrade head

# This creates all 43 tables fresh

Phase 3: Deploy API on RMM Server (15 min)

3.1 Create API Directory and Virtual Environment

ssh guru@172.16.3.30

# Create directory
sudo mkdir -p /opt/claudetools
sudo chown guru:guru /opt/claudetools
cd /opt/claudetools

# Clone or copy API code
# Option A: Via git (recommended)
git clone https://git.azcomputerguru.com/mike/ClaudeTools.git .

# Option B: Copy from Windows
# From Windows: scp -r D:\ClaudeTools\api guru@172.16.3.30:/opt/claudetools/
# From Windows: scp D:\ClaudeTools\requirements.txt guru@172.16.3.30:/opt/claudetools/
# From Windows: scp D:\ClaudeTools\alembic.ini guru@172.16.3.30:/opt/claudetools/
# From Windows: scp -r D:\ClaudeTools\migrations guru@172.16.3.30:/opt/claudetools/

# Create Python virtual environment
python3 -m venv venv
source venv/bin/activate

# Install dependencies
pip install --upgrade pip
pip install -r requirements.txt

3.2 Configure Environment

# Create .env file
cat > /opt/claudetools/.env <<'EOF'
# Database Configuration
DATABASE_URL=mysql+pymysql://claudetools:CT_e8fcd5a3952030a79ed6debae6c954ed@localhost:3306/claudetools?charset=utf8mb4
DATABASE_POOL_SIZE=20
DATABASE_MAX_OVERFLOW=10

# Security Configuration
JWT_SECRET_KEY=NdwgH6jsGR1WfPdUwR3u9i1NwNx3QthhLHBsRCfFxcg=
ENCRYPTION_KEY=your-encryption-key-from-shared-data
JWT_ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=1440

# API Configuration
ALLOWED_ORIGINS=*
DATABASE_NAME=claudetools
EOF

# Copy encryption key from shared data
# From Windows: scp C:\Users\MikeSwanson\claude-projects\shared-data\.encryption-key guru@172.16.3.30:/opt/claudetools/.encryption-key

# Update .env with actual encryption key
ENCRYPTION_KEY=$(cat /opt/claudetools/.encryption-key)
sed -i "s|ENCRYPTION_KEY=.*|ENCRYPTION_KEY=$ENCRYPTION_KEY|" /opt/claudetools/.env

3.3 Create Systemd Service

sudo nano /etc/systemd/system/claudetools-api.service
[Unit]
Description=ClaudeTools Context Recall API
After=network.target mariadb.service
Wants=mariadb.service

[Service]
Type=simple
User=guru
Group=guru
WorkingDirectory=/opt/claudetools
Environment="PATH=/opt/claudetools/venv/bin"
EnvironmentFile=/opt/claudetools/.env
ExecStart=/opt/claudetools/venv/bin/uvicorn api.main:app --host 0.0.0.0 --port 8001 --workers 2
Restart=always
RestartSec=10

# Logging
StandardOutput=append:/var/log/claudetools-api.log
StandardError=append:/var/log/claudetools-api-error.log

[Install]
WantedBy=multi-user.target

3.4 Start Service

# Create log files
sudo touch /var/log/claudetools-api.log /var/log/claudetools-api-error.log
sudo chown guru:guru /var/log/claudetools-api*.log

# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable claudetools-api
sudo systemctl start claudetools-api

# Check status
sudo systemctl status claudetools-api

# Test API
curl http://localhost:8001/health
curl http://172.16.3.30:8001/health

# View logs
sudo journalctl -u claudetools-api -f

Phase 4: Configure Nginx Reverse Proxy (5 min)

4.1 Create Nginx Config

sudo nano /etc/nginx/sites-available/claudetools-api
server {
    listen 80;
    server_name claudetools-api.azcomputerguru.com;

    location / {
        proxy_pass http://localhost:8001;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # WebSocket support (if needed)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
# Enable site
sudo ln -s /etc/nginx/sites-available/claudetools-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

# Test
curl http://172.16.3.30/health

4.2 Setup SSL (Optional - via NPM or Certbot)

# Option A: Use NPM on Jupiter (easier)
# Add proxy host in NPM: claudetools-api.azcomputerguru.com → http://172.16.3.30:8001

# Option B: Use Certbot directly
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d claudetools-api.azcomputerguru.com

Phase 5: Update Client Configurations (5 min)

5.1 Update Shared Config Template

# On Windows
# Edit C:\Users\MikeSwanson\claude-projects\shared-data\context-recall-config.env.template

cat > "C:\Users\MikeSwanson\claude-projects\shared-data\context-recall-config.env.template" <<'EOF'
# Claude Code Context Recall Configuration Template
# Copy this to your project's .claude/context-recall-config.env

# API Configuration
CLAUDE_API_URL=http://172.16.3.30:8001

# Project Identification (auto-detected from git)
CLAUDE_PROJECT_ID=

# Authentication (get from API)
JWT_TOKEN=

# Context Recall Settings
CONTEXT_RECALL_ENABLED=true
MIN_RELEVANCE_SCORE=5.0
MAX_CONTEXTS=10
AUTO_SAVE_CONTEXT=true
DEFAULT_RELEVANCE_SCORE=7.0
DEBUG_CONTEXT_RECALL=false
EOF

5.2 Update Current Machine

# In D:\ClaudeTools
# Update .claude/context-recall-config.env
sed -i 's|CLAUDE_API_URL=.*|CLAUDE_API_URL=http://172.16.3.30:8001|' .claude/context-recall-config.env

# Get new JWT token from central API
curl -X POST http://172.16.3.30:8001/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your-password"}' | jq -r '.access_token'

# Update JWT_TOKEN in config file

Phase 6: Create New-Machine Setup Script (5 min)

6.1 Create Simple Setup Script

# Save as: scripts/setup-new-machine.sh
cat > scripts/setup-new-machine.sh <<'EOF'
#!/bin/bash
#
# ClaudeTools New Machine Setup
# Quick setup for new machines (30 seconds)
#

set -e

echo "=========================================="
echo "ClaudeTools New Machine Setup"
echo "=========================================="
echo ""

# Detect project root
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
CONFIG_FILE="$PROJECT_ROOT/.claude/context-recall-config.env"

echo "Project root: $PROJECT_ROOT"
echo ""

# Check if template exists in shared data
SHARED_TEMPLATE="C:/Users/MikeSwanson/claude-projects/shared-data/context-recall-config.env"

if [ ! -f "$SHARED_TEMPLATE" ]; then
    echo "❌ ERROR: Template not found at $SHARED_TEMPLATE"
    exit 1
fi

# Copy template
echo "[1/3] Copying configuration template..."
cp "$SHARED_TEMPLATE" "$CONFIG_FILE"
echo "✓ Configuration file created"
echo ""

# Get project ID from git
echo "[2/3] Detecting project ID..."
PROJECT_ID=$(git config --local claude.projectid 2>/dev/null || echo "")

if [ -z "$PROJECT_ID" ]; then
    # Generate from git remote
    GIT_REMOTE=$(git config --get remote.origin.url 2>/dev/null || echo "")
    if [ -n "$GIT_REMOTE" ]; then
        PROJECT_ID=$(echo -n "$GIT_REMOTE" | md5sum | cut -d' ' -f1)
        git config --local claude.projectid "$PROJECT_ID"
        echo "✓ Generated project ID: $PROJECT_ID"
    else
        echo "⚠ Warning: Could not detect project ID"
    fi
else
    echo "✓ Project ID: $PROJECT_ID"
fi

# Update config with project ID
if [ -n "$PROJECT_ID" ]; then
    sed -i "s|CLAUDE_PROJECT_ID=.*|CLAUDE_PROJECT_ID=$PROJECT_ID|" "$CONFIG_FILE"
fi

echo ""

# Get JWT token
echo "[3/3] Obtaining JWT token..."
echo "Enter API credentials:"
read -p "Username [admin]: " API_USERNAME
API_USERNAME="${API_USERNAME:-admin}"
read -sp "Password: " API_PASSWORD
echo ""

if [ -z "$API_PASSWORD" ]; then
    echo "❌ ERROR: Password required"
    exit 1
fi

JWT_TOKEN=$(curl -s -X POST http://172.16.3.30:8001/api/auth/login \
    -H "Content-Type: application/json" \
    -d "{\"username\": \"$API_USERNAME\", \"password\": \"$API_PASSWORD\"}" | \
    grep -o '"access_token":"[^"]*' | sed 's/"access_token":"//')

if [ -z "$JWT_TOKEN" ]; then
    echo "❌ ERROR: Failed to get JWT token"
    exit 1
fi

# Update config with token
sed -i "s|JWT_TOKEN=.*|JWT_TOKEN=$JWT_TOKEN|" "$CONFIG_FILE"

echo "✓ JWT token obtained and saved"
echo ""

echo "=========================================="
echo "Setup Complete!"
echo "=========================================="
echo ""
echo "Configuration file: $CONFIG_FILE"
echo "API URL: http://172.16.3.30:8001"
echo "Project ID: $PROJECT_ID"
echo ""
echo "You can now use Claude Code normally."
echo "Context will be automatically recalled from the central server."
echo ""
EOF

chmod +x scripts/setup-new-machine.sh

Rollback Plan

If migration fails, revert to Jupiter database:

# Update .claude/context-recall-config.env
CLAUDE_API_URL=http://172.16.3.20:8000

# Restart local API
cd D:\ClaudeTools
api\venv\Scripts\activate
python -m api.main

Testing Checklist

After migration, verify:

  • Database accessible from RMM server: mysql -h localhost -u claudetools -p
  • Database accessible from Windows: mysql -h 172.16.3.30 -u claudetools -p
  • API health endpoint: curl http://172.16.3.30:8001/health
  • API docs accessible: http://172.16.3.30:8001/api/docs
  • JWT authentication works: curl -X POST http://172.16.3.30:8001/api/auth/login ...
  • Context recall works: bash .claude/hooks/user-prompt-submit
  • Context saving works: bash .claude/hooks/task-complete
  • Service auto-starts: sudo systemctl restart claudetools-api && systemctl status claudetools-api
  • Logs are clean: sudo journalctl -u claudetools-api -n 50

New Machine Setup (Post-Migration)

Simple 3-step process:

# 1. Clone repo
git clone https://git.azcomputerguru.com/mike/ClaudeTools.git
cd ClaudeTools

# 2. Run setup script
bash scripts/setup-new-machine.sh

# 3. Done! (30 seconds total)

No need for:

  • Python installation
  • Virtual environment
  • Dependencies installation
  • API server management
  • Database configuration

Maintenance

Updating API code:

ssh guru@172.16.3.30
cd /opt/claudetools
git pull origin main
sudo systemctl restart claudetools-api

Viewing logs:

# Live tail
sudo journalctl -u claudetools-api -f

# Last 100 lines
sudo journalctl -u claudetools-api -n 100

# Log files
tail -f /var/log/claudetools-api.log
tail -f /var/log/claudetools-api-error.log

Database backup:

# Daily backup cron
crontab -e

# Add:
0 2 * * * mysqldump -u claudetools -pCT_e8fcd5a3952030a79ed6debae6c954ed claudetools | gzip > /home/guru/backups/claudetools_$(date +\%Y\%m\%d).sql.gz

Benefits of Central Architecture

Before (Local API on each machine):

  • Setup time: 15 minutes per machine
  • Dependencies: Python, venv, 20+ packages per machine
  • Maintenance: Update N machines separately
  • Version drift: Different API versions across machines
  • Troubleshooting: Complex, machine-specific issues

After (Central API on RMM server):

  • Setup time: 30 seconds per machine
  • Dependencies: None (just git clone + config file)
  • Maintenance: Update once, affects all machines
  • Version consistency: Single API version everywhere
  • Troubleshooting: Check one service, one log

Resource usage:

  • Before: 3-5 Python processes (one per machine)
  • After: 1 systemd service with 2 workers

Next Steps

  1. Execute migration (Phases 1-5)
  2. Test thoroughly (Testing Checklist)
  3. Update shared template in credentials.md
  4. Document in SESSION_STATE.md
  5. Commit migration scripts to git
  6. Setup monitoring/alerting for API service (optional)
  7. Configure SSL certificate (optional, via NPM)

Estimated Total Time: 30-45 minutes Risk Level: Low (database is new, easy rollback) Downtime: 5 minutes (during API switchover)