bulletproof-deploy.shโข10.1 kB
#!/bin/bash
#
# Bulletproof Deployment Script for SkyeNet-MCP-ACE
# Handles all edge cases and ensures repeatable deployments
#
set -e
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}๐ Bulletproof Deploy for SkyeNet-MCP-ACE${NC}"
echo "=============================================="
# Step 1: System Requirements Check
echo -e "${YELLOW}๐ Checking system requirements...${NC}"
# Check if we're running as root or have sudo access
if [ "$EUID" -eq 0 ]; then
    echo -e "${GREEN}โ
 Running as root${NC}"
elif sudo -n true 2>/dev/null; then
    echo -e "${GREEN}โ
 Sudo access available${NC}"
else
    echo -e "${RED}โ This script requires root access or sudo privileges${NC}"
    exit 1
fi
# Step 2: Node.js 20+ Requirement
echo -e "${YELLOW}๐ Ensuring Node.js 20+ is available...${NC}"
# Check if Node.js 20+ is available system-wide
if command -v node >/dev/null 2>&1; then
    NODE_VERSION=$(node --version | cut -d'v' -f2 | cut -d'.' -f1)
    if [ "$NODE_VERSION" -ge 20 ]; then
        echo -e "${GREEN}โ
 Node.js 20+ is available system-wide${NC}"
        SYSTEM_NODE_AVAILABLE=true
    else
        echo -e "${YELLOW}โ ๏ธ  System Node.js is version $NODE_VERSION, need 20+${NC}"
        SYSTEM_NODE_AVAILABLE=false
    fi
else
    echo -e "${YELLOW}โ ๏ธ  No system Node.js found${NC}"
    SYSTEM_NODE_AVAILABLE=false
fi
# Install Node.js 20+ if not available
if [ "$SYSTEM_NODE_AVAILABLE" = false ]; then
    echo -e "${YELLOW}๐ฆ Installing Node.js 20+ system-wide...${NC}"
    
    # Add NodeSource repository
    curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
    
    # Install Node.js 20
    sudo apt-get install -y nodejs
    
    # Verify installation
    if command -v node >/dev/null 2>&1; then
        NODE_VERSION=$(node --version)
        echo -e "${GREEN}โ
 Node.js $NODE_VERSION installed successfully${NC}"
    else
        echo -e "${RED}โ Failed to install Node.js 20+${NC}"
        exit 1
    fi
fi
# Step 3: Clean Previous Installations
echo -e "${YELLOW}๐งน Cleaning previous installations...${NC}"
# Kill any running MCP servers
pkill -f "skyenet-mcp" 2>/dev/null || true
pkill -f "mcp" 2>/dev/null || true
sleep 2
# Remove old server binary
sudo rm -f /usr/local/sbin/skyenet-mcp-ace-server 2>/dev/null || true
# Remove old global installations
sudo rm -rf /usr/local/lib/node_modules/skyenet-mcp-ace 2>/dev/null || true
# Step 4: Build from Source
echo -e "${YELLOW}๐จ Building from source...${NC}"
npm run clean
npm run build
# Step 5: Install Dependencies System-Wide
echo -e "${YELLOW}๐ฆ Installing dependencies system-wide...${NC}"
# Install MCP SDK system-wide
sudo npm install -g @modelcontextprotocol/sdk
# Install other required dependencies
sudo npm install -g node-fetch@2.6.7
sudo npm install -g tough-cookie
# Step 6: Install Package System-Wide
echo -e "${YELLOW}๐ฆ Installing package system-wide...${NC}"
# Remove any existing installation to prevent symlink issues
sudo rm -rf /usr/local/lib/node_modules/skyenet-mcp-ace
# Install the package system-wide by copying files directly (not symlinking)
sudo cp -r . /usr/local/lib/node_modules/skyenet-mcp-ace
# Ensure proper ownership and permissions for system-wide access
sudo chown -R root:root /usr/local/lib/node_modules/skyenet-mcp-ace
sudo chmod -R 755 /usr/local/lib/node_modules/skyenet-mcp-ace
# Verify installation is not a symlink and has required files
if [ -L "/usr/local/lib/node_modules/skyenet-mcp-ace" ]; then
    echo -e "${RED}โ Installation created symlink instead of copying files${NC}"
    echo -e "${RED}โ This will cause multi-user access issues${NC}"
    exit 1
fi
if [ ! -f "/usr/local/lib/node_modules/skyenet-mcp-ace/build/index.js" ]; then
    echo -e "${RED}โ Required build files not found in system installation${NC}"
    exit 1
fi
echo -e "${GREEN}โ
 Package installed system-wide with proper permissions${NC}"
# Step 7: Create Bulletproof Server Wrapper
echo -e "${YELLOW}๐ง Creating bulletproof server wrapper...${NC}"
cat > /tmp/skyenet-mcp-ace-server << 'EOF'
#!/bin/bash
# Bulletproof server wrapper for SkyeNet-MCP-ACE
# Handles all edge cases and user scenarios
# Use system Node.js (guaranteed to be Node.js 20+)
NODE_PATH="/usr/bin/node"
# Verify Node.js is available and correct version
if [ ! -f "$NODE_PATH" ]; then
    echo "Error: Node.js not found at $NODE_PATH" >&2
    exit 1
fi
# Check Node.js version
NODE_VERSION=$("$NODE_PATH" --version | cut -d'v' -f2 | cut -d'.' -f1)
if [ "$NODE_VERSION" -lt 20 ]; then
    echo "Error: Node.js version $NODE_VERSION is too old. Required: 20+" >&2
    exit 1
fi
# Find the installation directory with multiple fallbacks
GLOBAL_DIR=""
# Method 1: Try system directory first (preferred for multi-user access)
if [ -d "/usr/local/lib/node_modules/skyenet-mcp-ace" ] && [ ! -L "/usr/local/lib/node_modules/skyenet-mcp-ace" ]; then
    GLOBAL_DIR="/usr/local/lib/node_modules/skyenet-mcp-ace"
fi
# Method 2: Try npm list (works for most installations)
if [ -z "$GLOBAL_DIR" ] && command -v npm >/dev/null 2>&1; then
    GLOBAL_DIR=$(npm list -g skyenet-mcp-ace --depth=0 2>/dev/null | grep skyenet-mcp-ace | awk '{print $NF}' | sed 's/.*-> //')
    
    # If it's a relative path (symlink), resolve it
    if [[ "$GLOBAL_DIR" == ./* ]]; then
        NPM_PREFIX=$(npm config get prefix 2>/dev/null || echo "/usr/local")
        GLOBAL_DIR="$NPM_PREFIX/lib/node_modules/skyenet-mcp-ace"
    fi
    
    # If it's still a symlink, resolve it to the actual path
    if [ -L "$GLOBAL_DIR" ]; then
        GLOBAL_DIR=$(readlink -f "$GLOBAL_DIR")
    fi
fi
# Method 3: Try alternative system directory
if [ ! -d "$GLOBAL_DIR" ]; then
    GLOBAL_DIR="/usr/lib/node_modules/skyenet-mcp-ace"
fi
# Method 4: Try to find it anywhere
if [ ! -d "$GLOBAL_DIR" ]; then
    GLOBAL_DIR=$(find /usr -name "skyenet-mcp-ace" -type d 2>/dev/null | head -1)
fi
# Final fallback to current project directory (development mode)
if [ ! -d "$GLOBAL_DIR" ]; then
    GLOBAL_DIR="/home/tyler852923/SkyeNet-MCP-ACE"
fi
# Verify the installation directory exists and has the required files
if [ ! -d "$GLOBAL_DIR" ]; then
    echo "Error: Could not find skyenet-mcp-ace installation directory" >&2
    echo "Searched locations:" >&2
    echo "  - /usr/local/lib/node_modules/skyenet-mcp-ace" >&2
    echo "  - /usr/lib/node_modules/skyenet-mcp-ace" >&2
    echo "  - npm global installation" >&2
    echo "Run 'sudo ./bulletproof-deploy.sh' to install properly" >&2
    exit 1
fi
if [ ! -f "$GLOBAL_DIR/build/index.js" ]; then
    echo "Error: Could not find build/index.js in $GLOBAL_DIR" >&2
    echo "Installation appears incomplete. Run 'sudo ./bulletproof-deploy.sh' to reinstall" >&2
    exit 1
fi
# Check if installation is a symlink (which can cause multi-user access issues)
if [ -L "$GLOBAL_DIR" ]; then
    echo "Warning: Installation is a symlink, which may cause multi-user access issues" >&2
    echo "Consider running 'sudo ./bulletproof-deploy.sh' to fix this" >&2
fi
# Change to the installation directory and run the server
cd "$GLOBAL_DIR"
exec "$NODE_PATH" build/index.js "$@"
EOF
# Install the server wrapper
sudo cp /tmp/skyenet-mcp-ace-server /usr/local/sbin/skyenet-mcp-ace-server
sudo chmod +x /usr/local/sbin/skyenet-mcp-ace-server
rm -f /tmp/skyenet-mcp-ace-server
# Step 8: Verify Installation
echo -e "${YELLOW}โ
 Verifying installation...${NC}"
# Test 1: Server starts without errors
if echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' | timeout 10s /usr/local/sbin/skyenet-mcp-ace-server 2>/dev/null | grep -q "execute_background_script"; then
    echo -e "${GREEN}โ
 Server starts correctly${NC}"
else
    echo -e "${RED}โ Server failed to start${NC}"
    exit 1
fi
# Test 2: All tools are available
TOOL_COUNT=$(echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}' | timeout 10s /usr/local/sbin/skyenet-mcp-ace-server 2>/dev/null | grep -o '"name":"[^"]*"' | wc -l)
if [ "$TOOL_COUNT" -eq 3 ]; then
    echo -e "${GREEN}โ
 All 3 tools available${NC}"
else
    echo -e "${RED}โ Expected 3 tools, found $TOOL_COUNT${NC}"
    exit 1
fi
# Test 3: Context bloat reduction features work
echo -e "${YELLOW}๐งช Testing context bloat reduction features...${NC}"
# Test Update Set Recent (Minimal Mode)
RECENT_SIZE=$(echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "execute_updateset_operation", "arguments": {"operation": "recent", "response_mode": "minimal"}}}' | timeout 15s /usr/local/sbin/skyenet-mcp-ace-server 2>&1 | wc -c)
if [ "$RECENT_SIZE" -lt 5000 ]; then
    echo -e "${GREEN}โ
 Update Set Recent minimal mode: ${RECENT_SIZE} bytes${NC}"
else
    echo -e "${RED}โ Update Set Recent too large: ${RECENT_SIZE} bytes${NC}"
    exit 1
fi
# Test Quiet Mode
QUIET_SIZE=$(echo '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "execute_updateset_operation", "arguments": {"operation": "set_working", "update_set_sys_id": "test", "quiet": true}}}' | timeout 10s /usr/local/sbin/skyenet-mcp-ace-server 2>&1 | wc -c)
if [ "$QUIET_SIZE" -lt 1000 ]; then
    echo -e "${GREEN}โ
 Quiet mode: ${QUIET_SIZE} bytes${NC}"
else
    echo -e "${RED}โ Quiet mode too large: ${QUIET_SIZE} bytes${NC}"
    exit 1
fi
# Test 4: Multi-user compatibility
echo -e "${YELLOW}๐ฅ Testing multi-user compatibility...${NC}"
# Test with different user (if possible)
if id "tyler" >/dev/null 2>&1; then
    if sudo -u tyler /usr/local/sbin/skyenet-mcp-ace-server 2>&1 | head -1 | grep -q "SkyeNet MCP ACE Server"; then
        echo -e "${GREEN}โ
 Multi-user compatibility verified${NC}"
    else
        echo -e "${RED}โ Multi-user compatibility failed${NC}"
        exit 1
    fi
else
    echo -e "${YELLOW}โ ๏ธ  Skipping multi-user test (tyler user not found)${NC}"
fi
echo -e "${GREEN}๐ Bulletproof deployment completed successfully!${NC}"
echo -e "${BLUE}๐ Server is ready for production use${NC}"
echo -e "${BLUE}๐ All edge cases handled and locked in${NC}"