Portrait of Michael Limberger

Michael Limberger

Need me? Email mike@limberger.ca

AI

Automated Setup Script

Let the script do the clicking

This script automates Claude Code plus local Ollama. Save it as setup-claude-local.sh, make it executable, and run it.

Show me.

chmod +x setup-claude-local.sh
./setup-claude-local.sh

It checks prerequisites (Node.js, Ollama 0.14.0+), asks for your Ollama server IP, asks for context size based on RAM, creates the Modelfile and configured model, generates ~/.claude/settings.json, and installs Claude Code if needed. Copy everything in the block below and save it as setup-claude-local.sh.

#!/bin/bash
        
        # Claude Code + Local Ollama Setup Script
        # Example project label (Techalicious Academy · historical)
        # site gone; kept as sample comment only
        
        set -e
        
        echo ""
        echo "========================================"
        echo "  Claude Code + Local Ollama Setup"
        echo "========================================"
        echo ""
        
        # ------------------------------------------------------------------------------
        # Colors for output
        # ------------------------------------------------------------------------------
        RED='\033[0;31m'
        GREEN='\033[0;32m'
        YELLOW='\033[1;33m'
        BLUE='\033[0;34m'
        NC='\033[0m' # No Color
        
        ok()    { echo -e "${GREEN}[OK]${NC} $1"; }
        warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }
        fail()  { echo -e "${RED}[FAIL]${NC} $1"; exit 1; }
        info()  { echo -e "${BLUE}[INFO]${NC} $1"; }
        
        # ------------------------------------------------------------------------------
        # Check Prerequisites
        # ------------------------------------------------------------------------------
        echo "Checking prerequisites..."
        echo ""
        
        # Check Node.js
        if command -v node &> /dev/null; then
            NODE_VERSION=$(node --version)
            ok "Node.js installed: $NODE_VERSION"
        else
            fail "Node.js not found. Install it first: https://nodejs.org"
        fi
        
        # Check npm
        if command -v npm &> /dev/null; then
            NPM_VERSION=$(npm --version)
            ok "npm installed: $NPM_VERSION"
        else
            fail "npm not found. Install Node.js with npm."
        fi
        
        # Check Ollama
        if command -v ollama &> /dev/null; then
            OLLAMA_VERSION=$(ollama --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
            ok "Ollama installed: $OLLAMA_VERSION"
            
            # Check version is 0.14.0+
            MAJOR=$(echo $OLLAMA_VERSION | cut -d. -f1)
            MINOR=$(echo $OLLAMA_VERSION | cut -d. -f2)
            
            if [ "$MAJOR" -eq 0 ] && [ "$MINOR" -lt 14 ]; then
                fail "Ollama version must be 0.14.0 or higher (you have $OLLAMA_VERSION)"
            fi
        else
            fail "Ollama not found. Install it first: https://ollama.com"
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Get Ollama Server Location
        # ------------------------------------------------------------------------------
        echo "Where is your Ollama server running?"
        echo ""
        echo "  1) This machine (localhost)"
        echo "  2) Another machine on my network"
        echo ""
        read -p "Enter choice [1]: " SERVER_CHOICE
        SERVER_CHOICE=${SERVER_CHOICE:-1}
        
        if [ "$SERVER_CHOICE" = "1" ]; then
            OLLAMA_IP="localhost"
            info "Using localhost"
        else
            read -p "Enter Ollama server IP (e.g., 10.0.0.79): " OLLAMA_IP
            if [ -z "$OLLAMA_IP" ]; then
                fail "IP address required for remote server"
            fi
            info "Using remote server: $OLLAMA_IP"
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Test Ollama Connection
        # ------------------------------------------------------------------------------
        info "Testing connection to Ollama at $OLLAMA_IP:11434..."
        
        if curl -s --connect-timeout 5 "http://$OLLAMA_IP:11434/api/version" > /dev/null; then
            ok "Ollama is reachable"
        else
            fail "Cannot connect to Ollama at http://$OLLAMA_IP:11434
            
        If remote: Add 'export OLLAMA_HOST=\"0.0.0.0:11434\"' to ~/.zshrc, then source and restart ollama.
        If local: Is Ollama running? Try: ollama serve"
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Select Base Model
        # ------------------------------------------------------------------------------
        echo "Which base model do you want to use?"
        echo ""
        echo "  1) qwen3-coder-next (recommended, ~18GB)"
        echo "  2) qwen2.5-coder:14b (~9GB)"
        echo "  3) qwen2.5-coder:7b (~4.5GB)"
        echo "  4) Custom (enter your own)"
        echo ""
        read -p "Enter choice [1]: " MODEL_CHOICE
        MODEL_CHOICE=${MODEL_CHOICE:-1}
        
        case $MODEL_CHOICE in
            1) BASE_MODEL="qwen3-coder-next:latest" ;;
            2) BASE_MODEL="qwen2.5-coder:14b" ;;
            3) BASE_MODEL="qwen2.5-coder:7b" ;;
            4)
                read -p "Enter model name (as shown in ollama list): " BASE_MODEL
                if [ -z "$BASE_MODEL" ]; then
                    fail "Model name required"
                fi
                ;;
            *) BASE_MODEL="qwen3-coder-next:latest" ;;
        esac
        
        info "Using base model: $BASE_MODEL"
        echo ""
        
        # ------------------------------------------------------------------------------
        # Check if model exists, offer to pull
        # ------------------------------------------------------------------------------
        if [ "$OLLAMA_IP" = "localhost" ]; then
            if ! ollama list | grep -q "${BASE_MODEL%%:*}"; then
                warn "Model $BASE_MODEL not found locally"
                read -p "Pull it now? [Y/n]: " PULL_MODEL
                PULL_MODEL=${PULL_MODEL:-Y}
                
                if [[ "$PULL_MODEL" =~ ^[Yy] ]]; then
                    info "Pulling $BASE_MODEL (this may take a while)..."
                    ollama pull $BASE_MODEL
                    ok "Model pulled successfully"
                else
                    warn "Skipping pull. Make sure the model exists before continuing."
                fi
            else
                ok "Base model found"
            fi
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Select Context Size
        # ------------------------------------------------------------------------------
        echo "How much unified memory (RAM) does your AI machine have?"
        echo ""
        echo "  1) 16GB  -> 8K context"
        echo "  2) 32GB  -> 32K context (recommended)"
        echo "  3) 64GB+ -> 64K context"
        echo "  4) Custom"
        echo ""
        read -p "Enter choice [2]: " RAM_CHOICE
        RAM_CHOICE=${RAM_CHOICE:-2}
        
        case $RAM_CHOICE in
            1) CONTEXT_SIZE=8192; CTX_LABEL="8k" ;;
            2) CONTEXT_SIZE=32768; CTX_LABEL="32k" ;;
            3) CONTEXT_SIZE=65536; CTX_LABEL="64k" ;;
            4)
                read -p "Enter context size (e.g., 16384): " CONTEXT_SIZE
                CTX_LABEL="${CONTEXT_SIZE}"
                ;;
            *) CONTEXT_SIZE=32768; CTX_LABEL="32k" ;;
        esac
        
        # Generate configured model name
        MODEL_BASE_NAME=$(echo $BASE_MODEL | cut -d: -f1 | sed 's/\./-/g')
        CONFIGURED_MODEL="${MODEL_BASE_NAME}-${CTX_LABEL}"
        
        info "Will create model: $CONFIGURED_MODEL with $CONTEXT_SIZE context"
        echo ""
        
        # ------------------------------------------------------------------------------
        # Create Modelfile
        # ------------------------------------------------------------------------------
        MODELFILE_PATH="$HOME/Modelfile-claude-local"
        
        info "Creating Modelfile at $MODELFILE_PATH..."
        
        cat > "$MODELFILE_PATH" << EOF
        FROM $BASE_MODEL
        PARAMETER num_ctx $CONTEXT_SIZE
        EOF
        
        ok "Modelfile created"
        echo ""
        
        # ------------------------------------------------------------------------------
        # Create Configured Model
        # ------------------------------------------------------------------------------
        if [ "$OLLAMA_IP" = "localhost" ]; then
            info "Creating configured model: $CONFIGURED_MODEL..."
            
            if ollama list | grep -q "$CONFIGURED_MODEL"; then
                warn "Model $CONFIGURED_MODEL already exists"
                read -p "Recreate it? [y/N]: " RECREATE
                RECREATE=${RECREATE:-N}
                
                if [[ "$RECREATE" =~ ^[Yy] ]]; then
                    ollama create "$CONFIGURED_MODEL" -f "$MODELFILE_PATH"
                    ok "Model recreated"
                else
                    info "Keeping existing model"
                fi
            else
                ollama create "$CONFIGURED_MODEL" -f "$MODELFILE_PATH"
                ok "Model created: $CONFIGURED_MODEL"
            fi
        else
            warn "Remote server detected."
            echo ""
            echo "Run these commands on your Ollama server ($OLLAMA_IP):"
            echo ""
            echo "  # Create Modelfile"
            echo "  cat > ~/Modelfile-claude-local << 'EOF'"
            echo "  FROM $BASE_MODEL"
            echo "  PARAMETER num_ctx $CONTEXT_SIZE"
            echo "  EOF"
            echo ""
            echo "  # Create configured model"
            echo "  ollama create $CONFIGURED_MODEL -f ~/Modelfile-claude-local"
            echo ""
            read -p "Press Enter when done..."
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Create settings.json
        # ------------------------------------------------------------------------------
        CLAUDE_DIR="$HOME/.claude"
        SETTINGS_FILE="$CLAUDE_DIR/settings.json"
        
        info "Creating Claude Code settings..."
        
        mkdir -p "$CLAUDE_DIR"
        
        # Check if settings.json exists
        if [ -f "$SETTINGS_FILE" ]; then
            warn "Settings file already exists at $SETTINGS_FILE"
            read -p "Overwrite? [y/N]: " OVERWRITE
            OVERWRITE=${OVERWRITE:-N}
            
            if [[ ! "$OVERWRITE" =~ ^[Yy] ]]; then
                info "Keeping existing settings"
                echo ""
                echo "Your model name is: $CONFIGURED_MODEL"
                echo "Update ANTHROPIC_MODEL in $SETTINGS_FILE manually if needed."
                echo ""
            fi
        fi
        
        if [ ! -f "$SETTINGS_FILE" ] || [[ "$OVERWRITE" =~ ^[Yy] ]]; then
            cat > "$SETTINGS_FILE" << EOF
        {
          "env": {
            "ANTHROPIC_BASE_URL": "http://$OLLAMA_IP:11434",
            "ANTHROPIC_AUTH_TOKEN": "ollama",
            "ANTHROPIC_MODEL": "$CONFIGURED_MODEL",
            "ANTHROPIC_SMALL_FAST_MODEL": "$CONFIGURED_MODEL",
            "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
            "API_TIMEOUT_MS": "600000"
          }
        }
        EOF
            ok "Settings created at $SETTINGS_FILE"
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Add Environment Variables to ~/.zshrc
        # ------------------------------------------------------------------------------
        ZSHRC="$HOME/.zshrc"
        MARKER="# Claude Code + Local Ollama"
        
        info "Adding environment variables to ~/.zshrc..."
        
        if grep -q "$MARKER" "$ZSHRC" 2>/dev/null; then
            warn "Environment variables already in ~/.zshrc"
            read -p "Replace them? [y/N]: " REPLACE_ENV
            REPLACE_ENV=${REPLACE_ENV:-N}
            
            if [[ "$REPLACE_ENV" =~ ^[Yy] ]]; then
                # Remove old block
                sed -i '' "/$MARKER/,/^$/d" "$ZSHRC"
            fi
        fi
        
        if ! grep -q "$MARKER" "$ZSHRC" 2>/dev/null || [[ "$REPLACE_ENV" =~ ^[Yy] ]]; then
            cat >> "$ZSHRC" << EOF
        
        $MARKER
        export ANTHROPIC_BASE_URL="http://$OLLAMA_IP:11434"
        export ANTHROPIC_AUTH_TOKEN="ollama"
        export ANTHROPIC_MODEL="$CONFIGURED_MODEL"
        export ANTHROPIC_SMALL_FAST_MODEL="$CONFIGURED_MODEL"
        export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1"
        export API_TIMEOUT_MS="600000"
        EOF
            ok "Environment variables added to ~/.zshrc"
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Install Claude Code
        # ------------------------------------------------------------------------------
        if command -v claude &> /dev/null; then
            CLAUDE_VERSION=$(claude --version 2>&1 | head -1)
            ok "Claude Code already installed: $CLAUDE_VERSION"
        else
            info "Installing Claude Code..."
            npm install -g @anthropic-ai/claude-code
            
            if command -v claude &> /dev/null; then
                ok "Claude Code installed"
            else
                warn "Claude Code installed but not in PATH"
                echo "You may need to restart your terminal or add npm bin to PATH"
            fi
        fi
        
        echo ""
        
        # ------------------------------------------------------------------------------
        # Summary
        # ------------------------------------------------------------------------------
        echo "========================================"
        echo "  Setup Complete!"
        echo "========================================"
        echo ""
        echo "Configuration:"
        echo "  Ollama Server:    http://$OLLAMA_IP:11434"
        echo "  Model:            $CONFIGURED_MODEL"
        echo "  Context Size:     $CONTEXT_SIZE tokens"
        echo "  Settings File:    $SETTINGS_FILE"
        echo "  Environment:      ~/.zshrc"
        echo ""
        echo "Next steps:"
        echo ""
        echo "  1. source ~/.zshrc"
        echo "  2. cd into a project directory"
        echo "  3. Run: claude"
        echo "  4. Select option 3 (3rd-party platform)"
        echo "  5. Start coding!"
        echo ""
        echo "Verification commands:"
        echo ""
        echo "  # Test Ollama connection"
        echo "  curl http://$OLLAMA_IP:11434/api/version"
        echo ""
        echo "  # Verify model context (run model first)"
        echo "  ollama run $CONFIGURED_MODEL"
        echo "  # In another terminal:"
        echo "  ollama ps"
        echo ""
        echo "  # Should show CONTEXT: $CONTEXT_SIZE"
        echo ""