#!/usr/bin/env python3
"""
NoctisAI Setup Validation Script
Validates complete setup for new users
"""
import sys
import os
import json
import subprocess
import time
from pathlib import Path
class SetupValidator:
def __init__(self):
self.base_dir = Path(__file__).parent.parent
self.validation_results = {
"system_requirements": False,
"python_environment": False,
"dependencies": False,
"file_structure": False,
"permissions": False,
"mcp_configuration": False,
"network_connectivity": False,
"test_execution": False
}
self.errors = []
def log(self, message, level="INFO"):
"""Log messages with timestamps"""
timestamp = time.strftime("%H:%M:%S")
print(f"[{timestamp}] [{level}] {message}")
def validate_system_requirements(self):
"""Validate system requirements"""
self.log("๐ Validating system requirements...")
try:
# Check OS
import platform
system = platform.system().lower()
if system not in ['linux', 'darwin', 'windows']:
self.errors.append(f"Unsupported OS: {system}")
return False
# Check Python version
python_version = sys.version_info
if python_version.major < 3 or (python_version.major == 3 and python_version.minor < 8):
self.errors.append(f"Python 3.8+ required, found {python_version.major}.{python_version.minor}")
return False
# Check available memory (basic check)
try:
import psutil
memory = psutil.virtual_memory()
if memory.total < 1024 * 1024 * 1024: # 1GB
self.errors.append("Insufficient memory (less than 1GB)")
return False
except ImportError:
self.log("โ ๏ธ psutil not available, skipping memory check", "WARN")
self.validation_results["system_requirements"] = True
self.log("โ
System requirements validated", "PASS")
return True
except Exception as e:
self.errors.append(f"System requirements validation failed: {e}")
return False
def validate_python_environment(self):
"""Validate Python environment"""
self.log("๐ Validating Python environment...")
try:
# Check if we're in a virtual environment
if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
self.log("โ
Virtual environment detected", "PASS")
else:
self.log("โ ๏ธ No virtual environment detected", "WARN")
self.log("๐ก Recommendation: Create virtual environment with 'python3 -m venv noctis-env'", "INFO")
# Check Python executable
python_exe = sys.executable
if python_exe:
self.log(f"โ
Python executable: {python_exe}", "PASS")
else:
self.errors.append("Python executable not found")
return False
self.validation_results["python_environment"] = True
return True
except Exception as e:
self.errors.append(f"Python environment validation failed: {e}")
return False
def validate_dependencies(self):
"""Validate all dependencies"""
self.log("๐ฆ Validating dependencies...")
required_packages = [
'fastapi', 'uvicorn', 'mcp', 'requests', 'cryptography',
'hashlib', 'base64', 'json', 'pathlib', 'subprocess'
]
missing_packages = []
for package in required_packages:
try:
__import__(package)
self.log(f"โ
{package} available", "PASS")
except ImportError:
missing_packages.append(package)
self.log(f"โ {package} missing", "FAIL")
if missing_packages:
self.errors.append(f"Missing packages: {', '.join(missing_packages)}")
self.log("๐ก Install with: pip install -r requirements.txt", "INFO")
return False
self.validation_results["dependencies"] = True
self.log("โ
All dependencies validated", "PASS")
return True
def validate_file_structure(self):
"""Validate file structure"""
self.log("๐ Validating file structure...")
required_files = [
"src/noctis_ai/__init__.py",
"src/noctis_ai/mcp/__init__.py",
"src/noctis_ai/mcp/noctis_mcp.py",
"src/noctis_ai/mcp/malware_tools.py",
"src/noctis_ai/mcp/threat_intel_tools.py",
"src/noctis_ai/mcp/osint_tools.py",
"src/noctis_ai/mcp/forensic_tools.py",
"src/noctis_ai/mcp/thesilencer_integration.py",
"run_noctis_mcp.py",
"requirements.txt",
"README.md",
"scripts/test_noctisai.py",
"scripts/health_check.py"
]
missing_files = []
for file_path in required_files:
full_path = self.base_dir / file_path
if full_path.exists():
self.log(f"โ
{file_path}", "PASS")
else:
missing_files.append(file_path)
self.log(f"โ {file_path} missing", "FAIL")
if missing_files:
self.errors.append(f"Missing files: {', '.join(missing_files)}")
return False
self.validation_results["file_structure"] = True
self.log("โ
File structure validated", "PASS")
return True
def validate_permissions(self):
"""Validate permissions"""
self.log("๐ Validating permissions...")
try:
# Check if we can read files
test_file = self.base_dir / "README.md"
if not os.access(test_file, os.R_OK):
self.errors.append("Cannot read files")
return False
# Check if we can write to output directories
output_dirs = ["output", "logs"]
for dir_path in output_dirs:
full_path = self.base_dir / dir_path
if not full_path.exists():
try:
full_path.mkdir(parents=True, exist_ok=True)
except Exception as e:
self.errors.append(f"Cannot create directory {dir_path}: {e}")
return False
if not os.access(full_path, os.W_OK):
self.errors.append(f"Cannot write to directory {dir_path}")
return False
self.validation_results["permissions"] = True
self.log("โ
Permissions validated", "PASS")
return True
except Exception as e:
self.errors.append(f"Permissions validation failed: {e}")
return False
def validate_mcp_configuration(self):
"""Validate MCP configuration"""
self.log("โ๏ธ Validating MCP configuration...")
mcp_config_path = Path.home() / ".cursor" / "mcp.json"
if not mcp_config_path.exists():
self.log("โ ๏ธ MCP configuration not found", "WARN")
self.log("๐ก Create ~/.cursor/mcp.json with NoctisAI configuration", "INFO")
return False
try:
with open(mcp_config_path, 'r') as f:
config = json.load(f)
if "mcpServers" not in config:
self.errors.append("MCP configuration missing 'mcpServers' section")
return False
if "noctis-ai" not in config["mcpServers"]:
self.errors.append("NoctisAI not configured in MCP")
return False
noctis_config = config["mcpServers"]["noctis-ai"]
if "command" not in noctis_config or "args" not in noctis_config:
self.errors.append("NoctisAI MCP configuration incomplete")
return False
self.validation_results["mcp_configuration"] = True
self.log("โ
MCP configuration validated", "PASS")
return True
except Exception as e:
self.errors.append(f"MCP configuration validation failed: {e}")
return False
def validate_network_connectivity(self):
"""Validate network connectivity"""
self.log("๐ Validating network connectivity...")
try:
import requests
test_urls = [
"https://www.google.com",
"https://api.github.com"
]
for url in test_urls:
try:
response = requests.get(url, timeout=5)
if response.status_code == 200:
self.log(f"โ
{url} accessible", "PASS")
else:
self.log(f"โ ๏ธ {url} returned status {response.status_code}", "WARN")
except Exception as e:
self.log(f"โ ๏ธ {url} not accessible: {e}", "WARN")
self.validation_results["network_connectivity"] = True
self.log("โ
Network connectivity validated", "PASS")
return True
except Exception as e:
self.log(f"โ ๏ธ Network connectivity check failed: {e}", "WARN")
return False
def validate_test_execution(self):
"""Validate test execution"""
self.log("๐งช Validating test execution...")
try:
# Run a simple import test
sys.path.insert(0, str(self.base_dir / "src"))
from noctis_ai.mcp import noctis_mcp
self.log("โ
NoctisAI MCP import successful", "PASS")
from noctis_ai.mcp.malware_tools import generate_payload
self.log("โ
Malware tools import successful", "PASS")
from noctis_ai.mcp.thesilencer_integration import TheSilencerIntegration
self.log("โ
TheSilencer integration import successful", "PASS")
# Test basic functionality
server = noctis_mcp.NoctisMCP()
tools = server.list_tools()
if tools and len(tools) > 0:
self.log(f"โ
MCP server initialized with {len(tools)} tools", "PASS")
else:
self.errors.append("MCP server initialization failed")
return False
self.validation_results["test_execution"] = True
self.log("โ
Test execution validated", "PASS")
return True
except Exception as e:
self.errors.append(f"Test execution validation failed: {e}")
return False
def run_validation(self):
"""Run complete validation"""
self.log("๐ Starting NoctisAI setup validation...")
self.log("=" * 60)
validations = [
("System Requirements", self.validate_system_requirements),
("Python Environment", self.validate_python_environment),
("Dependencies", self.validate_dependencies),
("File Structure", self.validate_file_structure),
("Permissions", self.validate_permissions),
("MCP Configuration", self.validate_mcp_configuration),
("Network Connectivity", self.validate_network_connectivity),
("Test Execution", self.validate_test_execution)
]
for validation_name, validation_func in validations:
try:
self.log(f"\n๐ {validation_name}")
validation_func()
except Exception as e:
self.errors.append(f"{validation_name} validation failed: {e}")
self.log(f"โ {validation_name} validation failed: {e}", "FAIL")
self.print_validation_report()
return self.is_setup_valid()
def is_setup_valid(self):
"""Check if setup is valid"""
critical_validations = [
"system_requirements", "python_environment", "dependencies",
"file_structure", "permissions", "test_execution"
]
return all(self.validation_results[validation] for validation in critical_validations)
def print_validation_report(self):
"""Print validation report"""
self.log("\n" + "=" * 60)
self.log("๐ SETUP VALIDATION REPORT")
self.log("=" * 60)
# Overall status
is_valid = self.is_setup_valid()
status_emoji = "โ
" if is_valid else "โ"
self.log(f"{status_emoji} Setup Status: {'VALID' if is_valid else 'INVALID'}")
# Individual validations
self.log("\n๐ Validation Results:")
for validation, status in self.validation_results.items():
status_emoji = "โ
" if status else "โ"
self.log(f" {status_emoji} {validation.replace('_', ' ').title()}")
# Errors
if self.errors:
self.log("\n๐จ Issues Found:")
for error in self.errors:
self.log(f" โข {error}")
# Recommendations
self.log("\n๐ก Next Steps:")
if not self.validation_results["python_environment"]:
self.log(" 1. Create virtual environment: python3 -m venv noctis-env")
self.log(" 2. Activate it: source noctis-env/bin/activate")
if not self.validation_results["dependencies"]:
self.log(" 1. Install dependencies: pip install -r requirements.txt")
if not self.validation_results["mcp_configuration"]:
self.log(" 1. Create MCP configuration: ~/.cursor/mcp.json")
self.log(" 2. Add NoctisAI server configuration")
if is_valid:
self.log(" ๐ Setup is valid! You can now run NoctisAI")
self.log(" ๐ Start server: python run_noctis_mcp.py")
self.log(" ๐งช Run tests: python scripts/test_noctisai.py")
else:
self.log(" ๐ง Fix the issues above before proceeding")
def get_validation_results(self):
"""Get validation results"""
return {
"is_valid": self.is_setup_valid(),
"results": self.validation_results,
"errors": self.errors
}
def main():
"""Main validation runner"""
validator = SetupValidator()
is_valid = validator.run_validation()
sys.exit(0 if is_valid else 1)
if __name__ == "__main__":
main()