DaVinci MCP Professional v3.0.0
A modern, professional Model Context Protocol server for DaVinci Resolve integration
Loading...
Searching...
No Matches
cli.py
Go to the documentation of this file.
1"""
2Command line interface for DaVinci Resolve MCP Server.
3"""
4
5import asyncio
6import logging
7import sys
8import os
9
10import click
11from colorama import init as init_colorama, Fore, Style
12
13# Set UTF-8 encoding for Windows console only for direct output, not for stdio
14if os.name == "nt": # Windows
15 os.environ["PYTHONIOENCODING"] = "utf-8"
16 # Only set console encoding if we're running in interactive mode
17 # Don't modify stdout/stderr if they might be used by MCP stdio
18 if hasattr(sys.stdout, "isatty") and sys.stdout.isatty():
19 try:
20 # Store original stdout/stderr in case we need them
21 _original_stdout = sys.stdout
22 _original_stderr = sys.stderr
23 except (AttributeError, OSError):
24 pass # Fallback to default behavior
25
26from . import __version__
27from .server import DaVinciMCPServer
28from .utils import check_resolve_running, check_resolve_installation
29
30
31# Initialize colorama for cross-platform colored output
32init_colorama()
33
34# Set up logging
35logging.basicConfig(
36 level=logging.INFO,
37 format=f"{Fore.CYAN}%(asctime)s{Style.RESET_ALL} - "
38 f"{Fore.YELLOW}%(name)s{Style.RESET_ALL} - "
39 f"%(levelname)s - %(message)s",
40)
41
42logger = logging.getLogger(__name__)
43
44
45def print_status(message: str, status: str = "INFO") -> None:
46 """Print a colored status message."""
47 if status == "OK":
48 click.echo(f"{Fore.GREEN}[OK]{Style.RESET_ALL} {message}")
49 elif status == "ERROR":
50 click.echo(f"{Fore.RED}[ERROR]{Style.RESET_ALL} {message}")
51 elif status == "WARNING":
52 click.echo(f"{Fore.YELLOW}[WARNING]{Style.RESET_ALL} {message}")
53 else:
54 click.echo(f"{Fore.CYAN}[INFO]{Style.RESET_ALL} {message}")
55
56
57def check_prerequisites() -> bool:
58 """Check if prerequisites are met."""
59 print_status("Checking DaVinci Resolve installation...")
60
61 installation = check_resolve_installation()
62
63 if not installation["api_path_exists"]:
64 print_status("DaVinci Resolve API path not found", "ERROR")
65 return False
66
67 if not installation["lib_path_exists"]:
68 print_status("DaVinci Resolve library not found", "ERROR")
69 return False
70
71 if not installation["modules_path_exists"]:
72 print_status("DaVinci Resolve modules path not found", "ERROR")
73 return False
74
75 print_status("DaVinci Resolve installation verified", "OK")
76
77 print_status("Checking if DaVinci Resolve is running...")
78 if not check_resolve_running():
79 print_status("DaVinci Resolve is not running", "ERROR")
81 "Please start DaVinci Resolve before running the MCP server", "WARNING"
82 )
83 return False
84
85 print_status("DaVinci Resolve is running", "OK")
86 return True
87
88
89@click.command()
90@click.option("--debug", is_flag=True, help="Enable debug logging")
91@click.option("--skip-checks", is_flag=True, help="Skip prerequisite checks")
92def main(debug: bool = False, skip_checks: bool = False) -> None:
93 """Start the DaVinci Resolve MCP Server."""
94
95 if debug:
96 logging.getLogger().setLevel(logging.DEBUG)
97 logging.getLogger("davinci_mcp").setLevel(logging.DEBUG)
98 print_status("Debug logging enabled")
99
100 # Print banner
101 click.echo(f"\n{Fore.MAGENTA}{'=' * 60}{Style.RESET_ALL}")
102 click.echo(f"{Fore.MAGENTA} DaVinci MCP Professional v{__version__}{Style.RESET_ALL}")
103 click.echo(f"{Fore.MAGENTA}{'=' * 60}{Style.RESET_ALL}\n")
104
105 # Check prerequisites unless skipped
106 if not skip_checks:
107 if not check_prerequisites():
108 print_status("Prerequisites not met. Exiting.", "ERROR")
109 sys.exit(1)
110
111 click.echo() # Empty line for spacing
112
113 # Start the server
114 try:
115 print_status("Starting MCP server...")
116 server = DaVinciMCPServer()
117
118 asyncio.run(server.run())
119
120 except KeyboardInterrupt:
121 print_status("\nShutting down server...", "WARNING")
122 sys.exit(0)
123 except Exception as e:
124 print_status(f"Server error: {e}", "ERROR")
125 if debug:
126 import traceback
127
128 traceback.print_exc()
129 sys.exit(1)
130
131
132if __name__ == "__main__":
133 main()
bool check_prerequisites()
Definition cli.py:57
None print_status(str message, str status="INFO")
Definition cli.py:45
None main(bool debug=False, bool skip_checks=False)
Definition cli.py:92