diff --git a/diagnose_and_fix.py b/diagnose_and_fix.py new file mode 100644 index 0000000..9597015 --- /dev/null +++ b/diagnose_and_fix.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python3 +""" +Comprehensive diagnostic and repair tool for Dolibarr MCP Server. +This script identifies and fixes common installation and configuration issues. +""" + +import sys +import os +import json +import subprocess +from pathlib import Path +import importlib.util + +class DolibarrMCPDiagnostic: + def __init__(self): + self.issues = [] + self.fixes_applied = [] + self.root_dir = Path(__file__).resolve().parent + + def run_diagnostics(self): + """Run all diagnostic checks.""" + print("=" * 60) + print("Dolibarr MCP Server - Diagnostic & Repair Tool") + print("=" * 60) + print() + + # Check Python version + self.check_python_version() + + # Check virtual environment + self.check_virtual_environment() + + # Check package installation + self.check_package_installation() + + # Check module structure + self.check_module_structure() + + # Check environment variables + self.check_environment() + + # Check MCP server files + self.check_server_files() + + # Report results + self.report_results() + + def check_python_version(self): + """Check if Python version is compatible.""" + print("Checking Python version...") + version = sys.version_info + if version.major < 3 or (version.major == 3 and version.minor < 8): + self.issues.append(f"Python {version.major}.{version.minor} detected. Python 3.8+ required.") + else: + print(f"✓ Python {version.major}.{version.minor}.{version.micro} - OK") + + def check_virtual_environment(self): + """Check if running in a virtual environment.""" + print("Checking virtual environment...") + in_venv = hasattr(sys, 'real_prefix') or ( + hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix + ) + + if not in_venv: + print("⚠ Not running in a virtual environment") + venv_path = self.root_dir / 'venv_dolibarr' + if not venv_path.exists(): + print(f" Creating virtual environment at {venv_path}...") + try: + subprocess.run([sys.executable, '-m', 'venv', str(venv_path)], check=True) + self.fixes_applied.append("Created virtual environment") + except subprocess.CalledProcessError as e: + self.issues.append(f"Failed to create virtual environment: {e}") + else: + print(f"✓ Virtual environment active: {sys.prefix}") + + def check_package_installation(self): + """Check if the package is installed correctly.""" + print("Checking package installation...") + + # Try to import the module + try: + import dolibarr_mcp + print("✓ dolibarr_mcp module found") + except ImportError: + print("✗ dolibarr_mcp module not found") + + # Try to fix by adjusting sys.path + src_path = self.root_dir / 'src' + if src_path.exists(): + sys.path.insert(0, str(src_path)) + try: + import dolibarr_mcp + print("✓ Fixed by adding src to path") + self.fixes_applied.append(f"Added {src_path} to Python path") + except ImportError: + self.issues.append("Module cannot be imported even with path adjustment") + self.attempt_install() + + def attempt_install(self): + """Attempt to install the package.""" + print(" Attempting to install package...") + try: + subprocess.run([sys.executable, '-m', 'pip', 'install', '-e', str(self.root_dir)], + check=True, capture_output=True, text=True) + self.fixes_applied.append("Installed package in development mode") + print(" ✓ Package installed successfully") + except subprocess.CalledProcessError as e: + self.issues.append(f"Failed to install package: {e}") + + def check_module_structure(self): + """Check if the module structure is correct.""" + print("Checking module structure...") + + required_files = [ + self.root_dir / 'src' / 'dolibarr_mcp' / '__init__.py', + self.root_dir / 'src' / 'dolibarr_mcp' / 'dolibarr_mcp_server.py', + self.root_dir / 'src' / 'dolibarr_mcp' / 'dolibarr_client.py', + self.root_dir / 'src' / 'dolibarr_mcp' / 'config.py', + ] + + missing_files = [] + for file in required_files: + if not file.exists(): + missing_files.append(str(file.relative_to(self.root_dir))) + + if missing_files: + self.issues.append(f"Missing required files: {', '.join(missing_files)}") + else: + print("✓ All required module files present") + + def check_environment(self): + """Check environment variables.""" + print("Checking environment configuration...") + + env_file = self.root_dir / '.env' + if not env_file.exists(): + print("✗ .env file not found") + env_example = self.root_dir / '.env.example' + if env_example.exists(): + print(" Creating .env from .env.example...") + import shutil + shutil.copy(env_example, env_file) + self.fixes_applied.append("Created .env file from template") + print(" ⚠ Please edit .env with your Dolibarr credentials") + else: + print("✓ .env file exists") + + # Check if it has required variables + try: + from dotenv import load_dotenv + load_dotenv(env_file) + + required_vars = ['DOLIBARR_URL', 'DOLIBARR_API_KEY'] + missing_vars = [] + + for var in required_vars: + if not os.getenv(var): + missing_vars.append(var) + + if missing_vars: + self.issues.append(f"Missing environment variables: {', '.join(missing_vars)}") + else: + print("✓ All required environment variables set") + except ImportError: + print(" Installing python-dotenv...") + subprocess.run([sys.executable, '-m', 'pip', 'install', 'python-dotenv'], + capture_output=True) + self.fixes_applied.append("Installed python-dotenv") + + def check_server_files(self): + """Check if MCP server can be started.""" + print("Checking MCP server readiness...") + + # Try to import and check main function + try: + spec = importlib.util.spec_from_file_location( + "server_test", + self.root_dir / 'src' / 'dolibarr_mcp' / 'dolibarr_mcp_server.py' + ) + if spec and spec.loader: + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + if hasattr(module, 'main'): + print("✓ Server main function found") + else: + self.issues.append("Server main function not found") + except Exception as e: + self.issues.append(f"Cannot load server module: {e}") + + def report_results(self): + """Report diagnostic results and provide recommendations.""" + print() + print("=" * 60) + print("Diagnostic Results") + print("=" * 60) + + if self.fixes_applied: + print("\n✅ Fixes Applied:") + for fix in self.fixes_applied: + print(f" - {fix}") + + if self.issues: + print("\n⚠ Issues Found:") + for issue in self.issues: + print(f" - {issue}") + + print("\n📋 Recommended Actions:") + print("1. Run fix_installation.bat to reinstall") + print("2. Update .env file with your Dolibarr credentials") + print("3. Try running: python mcp_server_launcher.py") + else: + print("\n✅ No issues found! Server should be ready to run.") + print("\nYou can now:") + print("1. Configure Claude Desktop (see CLAUDE_CONFIG.md)") + print("2. Run the server with: python mcp_server_launcher.py") + + # Create a quick launcher if everything is OK + if not self.issues: + self.create_quick_launcher() + + def create_quick_launcher(self): + """Create a quick launcher script.""" + launcher_path = self.root_dir / 'quick_start.bat' + + content = f'''@echo off +echo Starting Dolibarr MCP Server... +cd /d "{self.root_dir}" + +if exist venv_dolibarr ( + call venv_dolibarr\\Scripts\\activate +) + +python mcp_server_launcher.py +pause +''' + + with open(launcher_path, 'w') as f: + f.write(content) + + print(f"\n✨ Created quick_start.bat for easy server launch") + +if __name__ == "__main__": + diagnostic = DolibarrMCPDiagnostic() + diagnostic.run_diagnostics()