# 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):** ```bash 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** ```bash 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** ```bash 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** ```bash 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** ```bash # 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** ```bash # 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) ```bash # 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** ```bash 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** ```bash # 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** ```bash sudo nano /etc/systemd/system/claudetools-api.service ``` ```ini [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** ```bash # 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** ```bash sudo nano /etc/nginx/sites-available/claudetools-api ``` ```nginx 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"; } } ``` ```bash # 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)** ```bash # 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** ```bash # 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** ```bash # 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** ```bash # 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: ```bash # 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:** ```bash # 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:** ```bash ssh guru@172.16.3.30 cd /opt/claudetools git pull origin main sudo systemctl restart claudetools-api ``` **Viewing logs:** ```bash # 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:** ```bash # 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)