DaVinci Resolve MCP

by samuelgursky
Verified
#!/bin/bash # mcp_resolve-claude_start # Script to start DaVinci Resolve MCP server for Claude Desktop integration # This is a convenience wrapper for the Claude Desktop integration # Colors for terminal output GREEN='\033[0;32m' YELLOW='\033[0;33m' BLUE='\033[0;34m' RED='\033[0;31m' NC='\033[0m' # No Color SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" LOG_FILE="$SCRIPT_DIR/claude_resolve_server.log" CONFIG_DIR="$HOME/.config/Claude Desktop" CONFIG_FILE="$CONFIG_DIR/claude_desktop_config.json" TEMPLATE_FILE="$SCRIPT_DIR/config-templates/claude-desktop.template.json" # Display banner echo -e "${BLUE}=============================================${NC}" echo -e "${BLUE} DaVinci Resolve - Claude Desktop Integration ${NC}" echo -e "${BLUE}=============================================${NC}" # Check if DaVinci Resolve is running check_resolve_running() { # Try to detect with pgrep if pgrep -q "Resolve"; then echo -e "${GREEN}✓ DaVinci Resolve is running${NC}" return 0 fi # Fallback: use ps to check for Resolve process if ps -ef | grep -q "[R]esolve" || ps -ef | grep -q "[D]aVinci Resolve"; then echo -e "${GREEN}✓ DaVinci Resolve is running${NC}" return 0 fi echo -e "${RED}✗ DaVinci Resolve is not running${NC}" echo -e "${YELLOW}Please start DaVinci Resolve before continuing${NC}" return 1 } # Initialize log file echo "Starting Claude-Resolve MCP Server at $(date)" > "$LOG_FILE" # Check environment variables check_environment() { echo -e "${YELLOW}Checking environment variables...${NC}" # Set default paths if not already set export RESOLVE_SCRIPT_API="${RESOLVE_SCRIPT_API:-/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting}" export RESOLVE_SCRIPT_LIB="${RESOLVE_SCRIPT_LIB:-/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so}" export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/" export PYTHONUNBUFFERED=1 # Log environment echo "Environment variables:" >> "$LOG_FILE" echo "RESOLVE_SCRIPT_API=$RESOLVE_SCRIPT_API" >> "$LOG_FILE" echo "RESOLVE_SCRIPT_LIB=$RESOLVE_SCRIPT_LIB" >> "$LOG_FILE" echo "PYTHONPATH=$PYTHONPATH" >> "$LOG_FILE" # Check if files exist if [ ! -d "$RESOLVE_SCRIPT_API" ]; then echo -e "${RED}✗ DaVinci Resolve API path not found: $RESOLVE_SCRIPT_API${NC}" return 1 fi if [ ! -f "$RESOLVE_SCRIPT_LIB" ]; then echo -e "${RED}✗ DaVinci Resolve library not found: $RESOLVE_SCRIPT_LIB${NC}" return 1 fi echo -e "${GREEN}✓ Environment variables set correctly${NC}" return 0 } # Make script executable make_executable() { chmod +x "$SCRIPT_DIR/resolve_mcp_server.py" echo -e "${GREEN}✓ Made server script executable${NC}" } # Check and create Claude Desktop config setup_claude_config() { # Check if Claude Desktop config directory exists if [ ! -d "$CONFIG_DIR" ]; then echo -e "${YELLOW}Creating Claude Desktop config directory...${NC}" mkdir -p "$CONFIG_DIR" fi # Check if Claude Desktop config file exists if [ ! -f "$CONFIG_FILE" ]; then echo -e "${YELLOW}Creating Claude Desktop configuration file...${NC}" # Check if template exists if [ ! -f "$TEMPLATE_FILE" ]; then echo -e "${RED}✗ Template file not found: $TEMPLATE_FILE${NC}" return 1 fi # Copy and modify template cp "$TEMPLATE_FILE" "$CONFIG_FILE" # Replace PROJECT_ROOT placeholder with actual path sed -i '' "s|\${PROJECT_ROOT}|$SCRIPT_DIR|g" "$CONFIG_FILE" echo -e "${GREEN}✓ Created Claude Desktop configuration file at $CONFIG_FILE${NC}" else echo -e "${GREEN}✓ Claude Desktop configuration file exists${NC}" fi return 0 } # Display usage information show_usage() { echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " -p, --project NAME Attempt to open a specific DaVinci Resolve project" echo " -f, --force Skip the DaVinci Resolve running check" echo " -h, --help Display this help message" echo "" exit 0 } # Handle signals (Ctrl+C) cleanup() { echo -e "\n${YELLOW}Received termination signal. Cleaning up...${NC}" # Kill server process if it's running if [ -n "$SERVER_PID" ] && ps -p $SERVER_PID > /dev/null; then echo -e "${YELLOW}Stopping MCP server (PID: $SERVER_PID)...${NC}" kill $SERVER_PID 2>/dev/null echo "Server stopped by user at $(date)" >> "$LOG_FILE" fi echo -e "${GREEN}Cleanup complete. Goodbye!${NC}" exit 0 } # Parse arguments PROJECT_NAME="" FORCE_MODE=false parse_arguments() { while [[ $# -gt 0 ]]; do case $1 in --project|-p) PROJECT_NAME="$2" echo -e "${YELLOW}Will attempt to open project: $2${NC}" shift 2 ;; --force|-f) FORCE_MODE=true echo -e "${YELLOW}Force mode enabled: Will skip Resolve running check${NC}" shift ;; --help|-h) show_usage ;; *) echo -e "${YELLOW}Unknown argument: $1${NC}" shift ;; esac done } # Main function main() { # Set up signal handler for clean shutdown trap cleanup SIGINT SIGTERM echo -e "${YELLOW}Starting DaVinci Resolve MCP Server for Claude Desktop...${NC}" # Check if Resolve is running, unless force mode is on if [ "$FORCE_MODE" = false ]; then if ! check_resolve_running; then echo -e "${YELLOW}Waiting for DaVinci Resolve to start...${NC}" sleep 5 if ! check_resolve_running; then echo -e "${RED}DaVinci Resolve must be running. Please start it and try again.${NC}" echo -e "${YELLOW}Or use --force flag to bypass this check.${NC}" exit 1 fi fi else echo -e "${YELLOW}Skipping DaVinci Resolve check due to force mode${NC}" fi # Check environment if ! check_environment; then echo -e "${RED}Environment setup failed. Please check paths.${NC}" exit 1 fi # Make scripts executable make_executable # Setup Claude Desktop configuration if ! setup_claude_config; then echo -e "${RED}Failed to setup Claude Desktop configuration.${NC}" exit 1 fi # Start the server echo -e "${GREEN}Starting MCP server for Claude Desktop...${NC}" echo -e "${BLUE}Connecting to DaVinci Resolve...${NC}" # Check if venv exists VENV_DIR="$SCRIPT_DIR/venv" if [ ! -d "$VENV_DIR" ]; then echo -e "${RED}Virtual environment not found. Please run setup.sh first.${NC}" exit 1 fi # Start the server using MCP CLI from venv if [ -n "$PROJECT_NAME" ]; then echo -e "${YELLOW}Starting server with project: $PROJECT_NAME${NC}" # Run the server with project option "$VENV_DIR/bin/mcp" dev "$SCRIPT_DIR/resolve_mcp_server.py" --project "$PROJECT_NAME" > "$LOG_FILE" 2>&1 & SERVER_PID=$! else # Run the server "$VENV_DIR/bin/mcp" dev "$SCRIPT_DIR/resolve_mcp_server.py" > "$LOG_FILE" 2>&1 & SERVER_PID=$! fi # Wait a bit to make sure the server starts sleep 2 # Check if the server is still running if ps -p $SERVER_PID > /dev/null; then echo -e "${GREEN}MCP server is running with PID: $SERVER_PID${NC}" echo -e "${BLUE}You can now use Claude Desktop to connect to DaVinci Resolve.${NC}" echo -e "${GREEN}Configuration complete! Please start Claude Desktop to use with DaVinci Resolve.${NC}" echo -e "${YELLOW}Note: Keep this terminal window open while using Claude Desktop with DaVinci Resolve.${NC}" echo "Server started with PID: $SERVER_PID at $(date)" >> "$LOG_FILE" # Keep terminal open so user can see messages echo -e "${YELLOW}Press Ctrl+C to exit when done${NC}" # Wait for the server process wait $SERVER_PID # If we get here, the server has exited echo -e "${RED}Server exited unexpectedly.${NC}" echo "Server exited at $(date)" >> "$LOG_FILE" else echo -e "${RED}Server failed to start or exited immediately.${NC}" echo "Server failed to start at $(date)" >> "$LOG_FILE" echo -e "${YELLOW}Check the log file for details: $LOG_FILE${NC}" cat "$LOG_FILE" fi exit 1 } # Parse any command line arguments parse_arguments "$@" # Run main function main exit 0