#
tokens: 48684/50000 58/85 files (page 1/5)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 1 of 5. Use http://codebase.md/samuelgursky/davinci-resolve-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .cursorrules
├── .gitignore
├── CHANGELOG.md
├── CHANGES.md
├── config
│   ├── cursor-mcp-example.json
│   ├── macos
│   │   ├── claude-desktop-config.template.json
│   │   └── cursor-mcp-config.template.json
│   ├── mcp-project-template.json
│   ├── README.md
│   ├── sample_config.json
│   └── windows
│       ├── claude-desktop-config.template.json
│       └── cursor-mcp-config.template.json
├── docs
│   ├── CHANGELOG.md
│   ├── COMMIT_MESSAGE.txt
│   ├── FEATURES.md
│   ├── PROJECT_MCP_SETUP.md
│   ├── TOOLS_README.md
│   └── VERSION.md
├── examples
│   ├── getting_started.py
│   ├── markers
│   │   ├── add_spaced_markers.py
│   │   ├── add_timecode_marker.py
│   │   ├── alternating_markers.py
│   │   ├── clear_add_markers.py
│   │   ├── README.md
│   │   └── test_marker_frames.py
│   ├── media
│   │   ├── import_folder.py
│   │   └── README.md
│   ├── README.md
│   └── timeline
│       ├── README.md
│       ├── timeline_check.py
│       └── timeline_info.py
├── INSTALL.md
├── LICENSE
├── logs
│   └── .gitkeep
├── README.md
├── requirements.txt
├── resolve_mcp_server.py
├── run-now.bat
├── run-now.sh
├── scripts
│   ├── batch_automation.py
│   ├── check-resolve-ready.bat
│   ├── check-resolve-ready.ps1
│   ├── check-resolve-ready.sh
│   ├── create_app_shortcut.sh
│   ├── create-release-zip.bat
│   ├── create-release-zip.sh
│   ├── launch.sh
│   ├── mcp_resolve_launcher.sh
│   ├── mcp_resolve-claude_start
│   ├── mcp_resolve-cursor_start
│   ├── README.md
│   ├── resolve_mcp_server.py
│   ├── restart-server.bat
│   ├── restart-server.sh
│   ├── run-now.bat
│   ├── run-now.sh
│   ├── run-server.sh
│   ├── server.sh
│   ├── setup
│   │   ├── install.bat
│   │   └── install.sh
│   ├── setup.sh
│   ├── utils.sh
│   ├── verify-installation.bat
│   └── verify-installation.sh
├── src
│   ├── __init__.py
│   ├── api
│   │   ├── __init__.py
│   │   ├── color_operations.py
│   │   ├── delivery_operations.py
│   │   ├── media_operations.py
│   │   ├── project_operations.py
│   │   └── timeline_operations.py
│   ├── bin
│   │   └── __init__.py
│   ├── main.py
│   ├── resolve_mcp_server.py
│   └── utils
│       ├── __init__.py
│       ├── app_control.py
│       ├── cloud_operations.py
│       ├── layout_presets.py
│       ├── object_inspection.py
│       ├── platform.py
│       ├── project_properties.py
│       └── resolve_connection.py
└── tests
    ├── benchmark_server.py
    ├── create_test_timeline.py
    ├── test_custom_timeline.py
    ├── test_improvements.py
    ├── test-after-restart.bat
    └── test-after-restart.sh
```

# Files

--------------------------------------------------------------------------------
/logs/.gitkeep:
--------------------------------------------------------------------------------

```
1 | 
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
 1 | # Python
 2 | __pycache__/
 3 | *.py[cod]
 4 | *$py.class
 5 | *.so
 6 | .Python
 7 | venv/
 8 | env/
 9 | build/
10 | develop-eggs/
11 | dist/
12 | downloads/
13 | eggs/
14 | .eggs/
15 | lib/
16 | lib64/
17 | parts/
18 | sdist/
19 | var/
20 | *.egg-info/
21 | .installed.cfg
22 | *.egg
23 | 
24 | # Logs and temporary files
25 | logs/*.log
26 | *.log
27 | *.swp
28 | .DS_Store
29 | to_clean/
30 | logs_backup/
31 | cleanup_backup/
32 | 
33 | # Configuration files with sensitive info
34 | # Don't ignore templates
35 | .cursor/mcp.json
36 | claude_desktop_config.json
37 | !config-templates/*.template.json
38 | 
39 | # IDE specific files
40 | .idea/
41 | .vscode/
42 | *.sublime-project
43 | *.sublime-workspace
44 | 
45 | # Session-specific files
46 | *.session
47 | *.pid
48 | 
49 | # PyInstaller
50 | #  Usually these files are written by a python script from a template
51 | #  before PyInstaller builds the exe, so as to inject date/other infos into it.
52 | *.manifest
53 | *.spec
54 | 
55 | # Installer logs
56 | pip-log.txt
57 | pip-delete-this-directory.txt
58 | 
59 | # Unit test / coverage reports
60 | htmlcov/
61 | .tox/
62 | .coverage
63 | .coverage.*
64 | .cache
65 | nosetests.xml
66 | coverage.xml
67 | *.cover
68 | .hypothesis/
69 | .pytest_cache/
70 | 
71 | # VS Code
72 | .vscode/
73 | 
74 | # Cursor
75 | .cursor/
76 | 
77 | # macOS specific files
78 | .AppleDouble
79 | .LSOverride
80 | 
81 | # Environments
82 | .env
83 | .venv
84 | env/
85 | venv/
86 | ENV/
87 | env.bak/
88 | venv.bak/
89 | 
90 | # Keep the logs directory but not its contents
91 | logs/*
92 | !logs/.gitkeep
93 | 
94 | # Any backup directories
95 | *_backup/
96 | 
97 | # Cursor
98 | .cursor/ 
```

--------------------------------------------------------------------------------
/.cursorrules:
--------------------------------------------------------------------------------

```
 1 | # DaVinci Resolve MCP Server development rules for Cursor
 2 | 
 3 | # Rules for the project
 4 | rules:
 5 |   # Quick navigation commands
 6 |   - name: View project structure
 7 |     match: /(project|structure|files)/i
 8 |     actions: ls -la
 9 |     
10 |   - name: Show main server file
11 |     match: /show (server|main|resolve_mcp_server)( file)?/i
12 |     actions: cat resolve_mcp_server.py
13 |     
14 |   - name: Edit main server file
15 |     match: /edit (server|main|resolve_mcp_server)( file)?/i
16 |     actions: open resolve_mcp_server.py
17 | 
18 |   # Run commands
19 |   - name: Run server in dev mode
20 |     match: /run( server)?( in dev)?/i
21 |     actions: ./run-now.sh
22 |     
23 |   - name: Setup server
24 |     match: /setup( server)?/i
25 |     actions: ./setup.sh
26 |     
27 |   # View logs and instructions
28 |   - name: Show README
29 |     match: /show readme/i
30 |     actions: cat README.md
31 |     
32 |   - name: View changelog
33 |     match: /show changelog/i
34 |     actions: cat CHANGELOG.md
35 | 
36 |   # DaVinci Resolve specific
37 |   - name: Check Resolve environment
38 |     match: /check (resolve|environment|env|paths)/i
39 |     actions: |
40 |       echo "RESOLVE_SCRIPT_API = $RESOLVE_SCRIPT_API"
41 |       echo "RESOLVE_SCRIPT_LIB = $RESOLVE_SCRIPT_LIB"
42 |       echo "PYTHONPATH = $PYTHONPATH"
43 |       
44 |   - name: Check if Resolve is running
45 |     match: /is resolve running/i
46 |     actions: ps -ef | grep -i "[D]aVinci Resolve"
47 | 
48 | # Directory settings
49 | directories:
50 |   # Ignore virtual environment folder in searches
51 |   - path: venv
52 |     excludeFromSearch: true 
```

--------------------------------------------------------------------------------
/examples/media/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Media Examples
 2 | 
 3 | This directory contains examples demonstrating how to work with media files and the Media Pool in DaVinci Resolve using the MCP server.
 4 | 
 5 | ## Available Examples
 6 | 
 7 | ### import_folder.py
 8 | Shows how to import a folder of media files into the Media Pool.
 9 | 
10 | ## Running the Examples
11 | 
12 | Ensure DaVinci Resolve is running and that you have a project open.
13 | 
14 | ```bash
15 | # From the root directory of the repository
16 | python examples/media/import_folder.py
17 | ```
18 | 
19 | ## Media Operations
20 | 
21 | Common media operations demonstrated in these examples:
22 | - Importing media files into the Media Pool
23 | - Creating and organizing bins (folders)
24 | - Working with clips in the Media Pool
25 | - Adding clips to timelines
26 | 
27 | ## Common Issues
28 | 
29 | - File paths must be valid and accessible to DaVinci Resolve
30 | - Some media formats may not be supported for import
31 | - Large media files may take time to import and process
32 | - DaVinci Resolve may have limitations on certain media operations depending on the version 
```

--------------------------------------------------------------------------------
/examples/timeline/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Timeline Examples
 2 | 
 3 | This directory contains examples demonstrating how to work with timelines in DaVinci Resolve using the MCP server.
 4 | 
 5 | ## Available Examples
 6 | 
 7 | ### timeline_info.py
 8 | Shows how to retrieve various information about timelines in a project.
 9 | 
10 | ### timeline_check.py
11 | Demonstrates how to validate timeline properties and settings.
12 | 
13 | ## Running the Examples
14 | 
15 | Ensure DaVinci Resolve is running and that you have a project open, preferably with multiple timelines.
16 | 
17 | ```bash
18 | # From the root directory of the repository
19 | python examples/timeline/timeline_info.py
20 | ```
21 | 
22 | ## Timeline Operations
23 | 
24 | Common operations demonstrated in these examples:
25 | - Listing all timelines in a project
26 | - Getting information about the current timeline
27 | - Switching between timelines
28 | - Creating new timelines
29 | - Working with timeline settings
30 | 
31 | ## Common Issues
32 | 
33 | - Some timeline operations require administrative access to the project
34 | - Timeline operations may fail if the project is in read-only mode
35 | - Creating timelines may be affected by project settings 
```

--------------------------------------------------------------------------------
/examples/markers/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Marker Examples
 2 | 
 3 | This directory contains examples demonstrating how to work with markers in DaVinci Resolve timelines using the MCP server.
 4 | 
 5 | ## Available Examples
 6 | 
 7 | ### add_timecode_marker.py
 8 | Shows how to add markers with timecode values at specified positions.
 9 | 
10 | ### add_spaced_markers.py
11 | Demonstrates adding markers at regular intervals throughout a timeline.
12 | 
13 | ### alternating_markers.py
14 | Shows how to add markers with alternating colors and notes.
15 | 
16 | ### clear_add_markers.py
17 | Demonstrates how to clear all markers and then add new ones.
18 | 
19 | ### test_marker_frames.py
20 | A test script to verify marker placement at specific frames.
21 | 
22 | ## Running the Examples
23 | 
24 | Ensure DaVinci Resolve is running and that you have a project open with at least one timeline.
25 | 
26 | ```bash
27 | # From the root directory of the repository
28 | python examples/markers/add_timecode_marker.py
29 | ```
30 | 
31 | ## Marker Colors
32 | 
33 | DaVinci Resolve supports the following marker colors that can be used in scripts:
34 | - Blue
35 | - Cyan 
36 | - Green
37 | - Yellow
38 | - Red
39 | - Pink
40 | - Purple
41 | - Fuchsia
42 | - Rose
43 | - Lavender
44 | - Sky
45 | - Mint
46 | - Lemon
47 | - Sand
48 | - Cocoa
49 | - Cream
50 | 
51 | ## Common Issues
52 | 
53 | - Make sure a timeline is open before trying to add markers
54 | - Markers can only be placed on valid frames that contain media
55 | - Some marker operations require specific permissions or project settings 
```

--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # DaVinci Resolve MCP Examples
 2 | 
 3 | This directory contains example scripts demonstrating how to use the DaVinci Resolve MCP server with different features of DaVinci Resolve.
 4 | 
 5 | ## Directory Structure
 6 | 
 7 | - **markers/** - Examples related to timeline markers and marker operations
 8 | - **timeline/** - Examples for timeline management and operations
 9 | - **media/** - Examples for media pool operations and media management
10 | 
11 | ## How to Run Examples
12 | 
13 | 1. Make sure DaVinci Resolve is running
14 | 2. Ensure the MCP server is set up (run `./scripts/check-resolve-ready.sh` first)
15 | 3. Use a Python environment with the MCP SDK installed
16 | 4. Run an example script with:
17 | 
18 | ```bash
19 | # Activate the virtual environment
20 | source venv/bin/activate  # macOS/Linux
21 | # or
22 | venv\Scripts\activate  # Windows
23 | 
24 | # Run an example
25 | python examples/markers/add_timecode_marker.py
26 | ```
27 | 
28 | ## Example Categories
29 | 
30 | ### Markers Examples
31 | 
32 | Examples in `markers/` demonstrate how to:
33 | - Add markers at specific frames
34 | - Add markers with timecode values
35 | - Add markers at regular intervals
36 | - Test marker frame placement
37 | - Clear and replace markers
38 | 
39 | ### Timeline Examples
40 | 
41 | Examples in `timeline/` demonstrate how to:
42 | - Get information about timelines
43 | - Check timeline properties
44 | - Perform operations on timelines
45 | 
46 | ### Media Examples
47 | 
48 | Examples in `media/` demonstrate how to:
49 | - Import media into the media pool
50 | - Organize media in bins
51 | - Add media to timelines
52 | 
53 | ## Creating Your Own Examples
54 | 
55 | When creating new examples, please follow these guidelines:
56 | 
57 | 1. Place them in the appropriate category folder
58 | 2. Include clear comments explaining what the example does
59 | 3. Handle errors gracefully
60 | 4. Follow the code style of existing examples
61 | 
62 | If you create an example that doesn't fit in an existing category, feel free to create a new directory. 
```

--------------------------------------------------------------------------------
/config/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # DaVinci Resolve MCP Configuration Templates
 2 | 
 3 | This directory contains configuration templates for integrating DaVinci Resolve MCP with different AI assistant clients.
 4 | 
 5 | ## ⚠️ IMPORTANT: Path Configuration Required
 6 | 
 7 | **All template files require you to replace the placeholder paths with your actual paths to the repository.**
 8 | 
 9 | The templates contain placeholders like `${PROJECT_ROOT}` that **MUST** be replaced with your actual filesystem paths. Cursor and other tools **do not** automatically resolve these variables.
10 | 
11 | For example:
12 | - Replace `${PROJECT_ROOT}` with `/Users/username/davinci-resolve-mcp` on macOS
13 | - Replace `${PROJECT_ROOT}` with `C:\Users\username\davinci-resolve-mcp` on Windows
14 | 
15 | **Failure to replace these placeholders is the most common cause of connection problems.**
16 | 
17 | ## Available Templates
18 | 
19 | ### Cursor Integration
20 | 
21 | `cursor-mcp-config.template.json` - Template for configuring Cursor AI to use the DaVinci Resolve MCP server.
22 | 
23 | To use this template:
24 | 
25 | 1. Copy the contents to your Cursor MCP configuration file:
26 |    - macOS: `~/.cursor/mcp.json`
27 |    - Windows: `%APPDATA%\Cursor\mcp.json`
28 | 
29 | 2. Replace the placeholders with your actual paths:
30 |    - `${PROJECT_ROOT}` - Path to the DaVinci Resolve MCP repository
31 | 
32 | Example (macOS):
33 | ```json
34 | {
35 |   "mcpServers": {
36 |     "davinci-resolve": {
37 |       "name": "DaVinci Resolve MCP",
38 |       "command": "/Users/username/davinci-resolve-mcp/venv/bin/python",
39 |       "args": ["/Users/username/davinci-resolve-mcp/resolve_mcp_server.py"]
40 |     }
41 |   }
42 | }
43 | ```
44 | 
45 | ### Claude Desktop Integration
46 | 
47 | `claude-desktop-config.template.json` - Template for configuring Claude Desktop to use the DaVinci Resolve MCP server.
48 | 
49 | To use this template:
50 | 
51 | - Copy the template to your Claude Desktop configuration directory (location varies by installation)
52 |   - Windows - %appdata%\Claude\claude_desktop_config.json
53 | - Rename it to `claude_desktop_config.json`
54 | - Replace the placeholders with your actual paths:
55 |    - `${PROJECT_ROOT}` - Path to the DaVinci Resolve MCP repository
56 | 
57 | ## Automatic Setup
58 | 
59 | For automatic configuration, use the appropriate launch script which will set up the configuration for you:
60 | 
61 | ```bash
62 | # For Cursor
63 | ./scripts/mcp_resolve-cursor_start
64 | 
65 | # For Claude Desktop
66 | ./scripts/mcp_resolve-claude_start
67 | ```
68 | 
69 | Or use the universal launcher:
70 | 
71 | ```bash
72 | ./scripts/mcp_resolve_launcher.sh 
```

--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # DaVinci Resolve MCP Scripts
  2 | 
  3 | This directory contains all the utility and launcher scripts for the DaVinci Resolve MCP server.
  4 | 
  5 | ## Quick Start Scripts
  6 | 
  7 | ### run-now.sh / run-now.bat
  8 | Quick start scripts for macOS/Linux and Windows that set up the environment and start the server in one step.
  9 | 
 10 | ```bash
 11 | # macOS/Linux
 12 | ./scripts/run-now.sh
 13 | 
 14 | # Windows
 15 | scripts\run-now.bat
 16 | ```
 17 | 
 18 | ## Pre-Launch Check Scripts
 19 | 
 20 | ### check-resolve-ready.sh / check-resolve-ready.bat
 21 | Scripts that verify your environment is properly configured before launching the server.
 22 | 
 23 | ```bash
 24 | # macOS/Linux
 25 | ./scripts/check-resolve-ready.sh
 26 | 
 27 | # Windows
 28 | scripts\check-resolve-ready.bat
 29 | ```
 30 | 
 31 | ## Client-Specific Launch Scripts
 32 | 
 33 | ### mcp_resolve-cursor_start
 34 | Dedicated script for launching the server configured for Cursor AI integration.
 35 | 
 36 | ```bash
 37 | ./scripts/mcp_resolve-cursor_start
 38 | ```
 39 | 
 40 | ### mcp_resolve-claude_start
 41 | Dedicated script for launching the server configured for Claude Desktop integration.
 42 | 
 43 | ```bash
 44 | ./scripts/mcp_resolve-claude_start
 45 | ```
 46 | 
 47 | ## Universal Launcher
 48 | 
 49 | ### mcp_resolve_launcher.sh
 50 | Interactive launcher script that provides a menu for managing different server instances.
 51 | 
 52 | ```bash
 53 | ./scripts/mcp_resolve_launcher.sh
 54 | ```
 55 | 
 56 | Command-line options:
 57 | - `--start-cursor` - Start the Cursor MCP server
 58 | - `--start-claude` - Start the Claude Desktop MCP server
 59 | - `--start-both` - Start both servers
 60 | - `--stop-all` - Stop all running servers
 61 | - `--status` - Show server status
 62 | - `--force` - Skip DaVinci Resolve running check
 63 | - `--project "Project Name"` - Open a specific project on startup
 64 | 
 65 | ## Setup and Server Management
 66 | 
 67 | ### setup.sh
 68 | Complete installation script that sets up the environment, virtual environment, and dependencies.
 69 | 
 70 | ```bash
 71 | ./scripts/setup.sh
 72 | ```
 73 | 
 74 | ### server.sh
 75 | Consolidated server management script with commands for starting, stopping, and checking server status.
 76 | 
 77 | ```bash
 78 | ./scripts/server.sh start
 79 | ./scripts/server.sh stop
 80 | ./scripts/server.sh status
 81 | ```
 82 | 
 83 | ## Utility Scripts
 84 | 
 85 | ### utils.sh
 86 | Common utility functions used by other scripts.
 87 | 
 88 | ## Script Organization
 89 | 
 90 | The scripts are organized by function:
 91 | - **Quick start scripts** - For getting up and running quickly
 92 | - **Environment check scripts** - For verifying proper configuration
 93 | - **Client-specific scripts** - For launching with specific AI assistants
 94 | - **Management scripts** - For controlling server operation
 95 | 
 96 | ## Notes for Developers
 97 | 
 98 | - Most scripts include environment setup to ensure DaVinci Resolve can be accessed
 99 | - The launcher scripts have symbolic links in the root directory for easier access
100 | - Scripts check for DaVinci Resolve before starting to avoid connection issues 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # DaVinci Resolve MCP Server
  2 | 
  3 | [![Version](https://img.shields.io/badge/version-1.3.8-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
  4 | [![DaVinci Resolve](https://img.shields.io/badge/DaVinci%20Resolve-18.5+-darkred.svg)](https://www.blackmagicdesign.com/products/davinciresolve)
  5 | [![Python](https://img.shields.io/badge/python-3.6+-green.svg)](https://www.python.org/downloads/)
  6 | [![macOS](https://img.shields.io/badge/macOS-stable-brightgreen.svg)](https://www.apple.com/macos/)
  7 | [![Windows](https://img.shields.io/badge/Windows-stable-brightgreen.svg)](https://www.microsoft.com/windows)
  8 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
  9 | 
 10 | A Model Context Protocol (MCP) server that connects AI coding assistants (Cursor, Claude Desktop) to DaVinci Resolve, enabling them to query and control DaVinci Resolve through natural language.
 11 | 
 12 | ## Features
 13 | 
 14 | For a comprehensive list of implemented and planned features, see [docs/FEATURES.md](docs/FEATURES.md).
 15 | 
 16 | ## Requirements
 17 | 
 18 | - **macOS** or **Windows** with DaVinci Resolve installed
 19 | - **Python 3.6+**
 20 | - DaVinci Resolve running in the background
 21 | - (Optional) Node.js/npm for some features
 22 | 
 23 | ## Installation Guide
 24 | 
 25 | For detailed installation instructions, please see [INSTALL.md](INSTALL.md). This guide covers:
 26 | - Prerequisites and system requirements
 27 | - Step-by-step installation process
 28 | - Configuration details
 29 | - Common troubleshooting steps
 30 | 
 31 | ## Platform Support
 32 | 
 33 | | Platform | Status | One-Step Install | Quick Start |
 34 | |----------|--------|------------------|-------------|
 35 | | macOS | ✅ Stable | `./install.sh` | `./run-now.sh` |
 36 | | Windows | ✅ Stable | `install.bat` | `run-now.bat` |
 37 | | Linux | ❌ Not supported | N/A | N/A |
 38 | 
 39 | ## Quick Start Guide
 40 | 
 41 | ### New One-Step Installation (Recommended)
 42 | 
 43 | The easiest way to get started is with our new unified installation script. This script does everything automatically:
 44 | 
 45 | - Clone the repository:
 46 |    ```bash
 47 |    git clone https://github.com/samuelgursky/davinci-resolve-mcp.git
 48 |    cd davinci-resolve-mcp
 49 |    ```
 50 | 
 51 | - Make sure DaVinci Resolve Studio is installed and running
 52 | 
 53 | - Run the installation script:
 54 |    **macOS/Linux:**
 55 |    ```bash
 56 |    ./install.sh
 57 |    ```
 58 |    
 59 |    **Windows:**
 60 |    ```batch
 61 |    install.bat
 62 |    ```
 63 | 
 64 | This will:
 65 | 1. Automatically detect the correct paths on your system
 66 | 2. Create a Python virtual environment
 67 | 3. Install the MCP SDK from the official repository
 68 | 4. Set up environment variables
 69 | 5. Configure Cursor/Claude integration 
 70 | 6. Verify the installation is correct
 71 | 7. Optionally start the MCP server
 72 | 
 73 | ### Alternative Quick Start
 74 | 
 75 | You can also use the original quick start scripts:
 76 | 
 77 | **Windows Users:**
 78 | ```bash
 79 | run-now.bat
 80 | ``` 
 81 | 
 82 | **macOS Users:**
 83 | ```bash
 84 | chmod +x run-now.sh
 85 | ./run-now.sh
 86 | ```
 87 | 
 88 | ## Configuration
 89 | 
 90 | For configuration of DaVinci Resolve MCP with different AI assistant clients like Cursor or Claude, see the [config-templates](config-templates) directory.
 91 | 
 92 | ## Troubleshooting
 93 | 
 94 | For detailed troubleshooting guidance, refer to the [INSTALL.md](INSTALL.md#troubleshooting) file which contains solutions to common issues.
 95 | 
 96 | ### Common Issues
 97 | 
 98 | #### Path Resolution
 99 | - The installation scripts now use more robust path resolution, fixing issues with `run-now.sh` looking for files in the wrong locations
100 | - Always let the scripts determine the correct paths based on their location
101 | 
102 | #### DaVinci Resolve Detection
103 | - We've improved the process detection to reliably find DaVinci Resolve regardless of how it appears in the process list
104 | - Make sure DaVinci Resolve is running before starting the MCP server
105 | 
106 | #### Environment Variables
107 | - Make sure all required environment variables are set correctly
108 | - Review the log file at `scripts/cursor_resolve_server.log` for troubleshooting
109 | 
110 | ### Windows
111 | - Make sure to use forward slashes (/) in configuration files
112 | - Python must be installed and paths configured in configs
113 | - DaVinci Resolve must be running before starting the server
114 | 
115 | ### macOS
116 | - Make sure scripts have execute permissions
117 | - Check Console.app for any Python-related errors
118 | - Verify environment variables are set correctly
119 | - DaVinci Resolve must be running before starting the server
120 | 
121 | ## Support
122 | 
123 | For issues and feature requests, please use the GitHub issue tracker.
124 | 
125 | ## Launch Options
126 | 
127 | After installation, you have several ways to start the server:
128 | 
129 | ### Client-Specific Launch Scripts
130 | 
131 | The repository includes dedicated scripts for launching with specific clients:
132 | 
133 | ```bash
134 | # For Cursor integration (macOS)
135 | chmod +x scripts/mcp_resolve-cursor_start
136 | ./scripts/mcp_resolve-cursor_start
137 | 
138 | # For Claude Desktop integration (macOS)
139 | chmod +x scripts/mcp_resolve-claude_start
140 | ./scripts/mcp_resolve-claude_start
141 | ```
142 | 
143 | These specialized scripts:
144 | - Set up the proper environment for each client
145 | - Verify DaVinci Resolve is running
146 | - Configure client-specific settings
147 | - Start the MCP server with appropriate parameters
148 | 
149 | ### Pre-Launch Check
150 | 
151 | Before connecting AI assistants, verify your environment is properly configured:
152 | 
153 | ```bash
154 | # On macOS
155 | ./scripts/check-resolve-ready.sh
156 | 
157 | # On Windows
158 | ./scripts/check-resolve-ready.bat
159 | ```
160 | 
161 | These scripts will:
162 | - Verify DaVinci Resolve is running (and offer to start it)
163 | - Check environment variables are properly set
164 | - Ensure the Python environment is configured correctly
165 | - Validate Cursor/Claude configuration
166 | - Optionally launch Cursor
167 | 
168 | ### Universal Launcher
169 | 
170 | For advanced users, our unified launcher provides full control over both Cursor and Claude Desktop servers:
171 | 
172 | ```bash
173 | # Make the script executable (macOS only)
174 | chmod +x scripts/mcp_resolve_launcher.sh
175 | 
176 | # Run in interactive mode
177 | ./scripts/mcp_resolve_launcher.sh
178 | 
179 | # Or use command line options
180 | ./scripts/mcp_resolve_launcher.sh --start-cursor    # Start Cursor server (uses mcp_resolve-cursor_start)
181 | ./scripts/mcp_resolve_launcher.sh --start-claude    # Start Claude Desktop server (uses mcp_resolve-claude_start)
182 | ./scripts/mcp_resolve_launcher.sh --start-both      # Start both servers
183 | ./scripts/mcp_resolve_launcher.sh --stop-all        # Stop all running servers
184 | ./scripts/mcp_resolve_launcher.sh --status          # Show server status
185 | ```
186 | 
187 | Additional options:
188 | - Force mode (skip Resolve running check): `--force`
189 | - Project selection: `--project "Project Name"`
190 | 
191 | ## Full Installation
192 | 
193 | For a complete manual installation:
194 | 
195 | 1. Clone this repository:
196 |    ```bash
197 |    git clone https://github.com/samuelgursky/davinci-resolve-mcp.git
198 |    cd davinci-resolve-mcp
199 |    ```
200 | 
201 | 2. Create a Python virtual environment:
202 |    ```bash
203 |    # Create virtual environment
204 |    python -m venv venv
205 |    
206 |    # Activate it
207 |    # On macOS/Linux:
208 |    source venv/bin/activate
209 |    # On Windows:
210 |    venv\Scripts\activate
211 |    
212 |    # Install dependencies from requirements.txt
213 |    pip install -r requirements.txt
214 |    
215 |    # Alternatively, install MCP SDK directly
216 |    pip install git+https://github.com/modelcontextprotocol/python-sdk.git
217 |    ```
218 | 
219 | 3. Set up DaVinci Resolve scripting environment variables:
220 | 
221 |    **For macOS**:
222 |    ```bash
223 |    export RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
224 |    export RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
225 |    export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"
226 |    ```
227 | 
228 |    **For Windows**:
229 |    ```cmd
230 |    set RESOLVE_SCRIPT_API=C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting
231 |    set RESOLVE_SCRIPT_LIB=C:\Program Files\Blackmagic Design\DaVinci Resolve\fusionscript.dll
232 |    set PYTHONPATH=%PYTHONPATH%;%RESOLVE_SCRIPT_API%\Modules
233 |    ```
234 |    
235 |    Alternatively, run the pre-launch check script which will set these for you:
236 |    ```
237 |    # On macOS
238 |    ./scripts/check-resolve-ready.sh
239 |    
240 |    # On Windows
241 |    ./scripts/check-resolve-ready.bat
242 |    ```
243 | 
244 | 4. Configure Cursor to use the server by creating a configuration file:
245 | 
246 |    **For macOS** (`~/.cursor/mcp.json`):
247 |    ```json
248 |    {
249 |      "mcpServers": {
250 |        "davinci-resolve": {
251 |          "name": "DaVinci Resolve MCP",
252 |          "command": "/path/to/your/venv/bin/python",
253 |          "args": [
254 |            "/path/to/your/davinci-resolve-mcp/src/main.py"
255 |          ]
256 |        }
257 |      }
258 |    }
259 |    ```
260 | 
261 |    **For Windows** (`%APPDATA%\Cursor\mcp.json`):
262 |    ```json
263 |    {
264 |      "mcpServers": {
265 |        "davinci-resolve": {
266 |          "name": "DaVinci Resolve MCP",
267 |          "command": "C:\\path\\to\\venv\\Scripts\\python.exe",
268 |          "args": ["C:\\path\\to\\davinci-resolve-mcp\\src\\main.py"]
269 |        }
270 |      }
271 |    }
272 |    ```
273 | 
274 | 5. Start the server using one of the client-specific scripts:
275 |    ```bash
276 |    # For Cursor
277 |    ./scripts/mcp_resolve-cursor_start
278 |    
279 |    # For Claude Desktop
280 |    ./scripts/mcp_resolve-claude_start
281 |    ```
282 | 
283 | ## Usage with AI Assistants
284 | 
285 | ### Using with Cursor
286 | 
287 | 1. Start the Cursor server using the dedicated script:
288 |    ```bash
289 |    ./scripts/mcp_resolve-cursor_start
290 |    ```
291 |    Or use the universal launcher:
292 |    ```bash
293 |    ./scripts/mcp_resolve_launcher.sh --start-cursor
294 |    ```
295 | 
296 | 2. Start Cursor and open a project.
297 | 
298 | 3. In Cursor's AI chat, you can now interact with DaVinci Resolve. Try commands like:
299 |    - "What version of DaVinci Resolve is running?"
300 |    - "List all projects in DaVinci Resolve"
301 |    - "Create a new timeline called 'My Sequence'"
302 |    - "Add a marker at the current position"
303 | 
304 | ### Using with Claude Desktop
305 | 
306 | 1. Create a `claude_desktop_config.json` file in your Claude Desktop configuration directory using the template in the `config-templates` directory.
307 | 
308 | 2. Run the Claude Desktop server using the dedicated script:
309 |    ```bash
310 |    ./scripts/mcp_resolve-claude_start
311 |    ```
312 |    Or use the universal launcher:
313 |    ```bash
314 |    ./scripts/mcp_resolve_launcher.sh --start-claude
315 |    ```
316 | 
317 | 3. In Claude Desktop, you can now interact with DaVinci Resolve using the same commands as with Cursor.
318 | 
319 | ## Available Features
320 | 
321 | ### General
322 | - Get DaVinci Resolve version
323 | - Get/switch current page (Edit, Color, Fusion, etc.)
324 | 
325 | ### Project Management
326 | - List available projects
327 | - Get current project name
328 | - Open project by name
329 | - Create new project
330 | - Save current project
331 | 
332 | ### Timeline Operations
333 | - List all timelines
334 | - Get current timeline info
335 | - Create new timeline
336 | - Switch to timeline by name
337 | - Add marker to timeline
338 | 
339 | ### Media Pool Operations
340 | - List media pool clips
341 | - Import media file
342 | - Create media bin
343 | - Add clip to timeline
344 | 
345 | ## Windows Support Notes
346 | 
347 | Windows support is stable in v1.3.3 and should not require additional troubleshooting:
348 | - Ensure DaVinci Resolve is installed in the default location
349 | - Environment variables are properly set as described above
350 | - Windows paths may require adjustment based on your installation
351 | - For issues, please check the logs in the `logs/` directory
352 | 
353 | ## Troubleshooting
354 | 
355 | ### DaVinci Resolve Connection
356 | Make sure DaVinci Resolve is running before starting the server. If the server can't connect to Resolve, check that:
357 | 
358 | 1. Your environment variables are set correctly
359 | 2. You have the correct paths for your DaVinci Resolve installation
360 | 3. You have restarted your terminal after setting environment variables
361 | 
362 | ## Project Structure
363 | 
364 | ```
365 | davinci-resolve-mcp/
366 | ├── README.md               # This file
367 | ├── docs/                   # Documentation
368 | │   ├── FEATURES.md         # Feature list and status
369 | │   ├── CHANGELOG.md        # Version history
370 | │   ├── VERSION.md          # Version information
371 | │   ├── TOOLS_README.md     # Tools documentation
372 | │   ├── PROJECT_MCP_SETUP.md # Project setup guide
373 | │   └── COMMIT_MESSAGE.txt  # Latest commit information
374 | ├── config-templates/       # Configuration templates
375 | │   ├── sample_config.json  # Example configuration
376 | │   ├── cursor-mcp-example.json # Cursor config example
377 | │   └── mcp-project-template.json # MCP project template
378 | ├── scripts/                # Utility scripts
379 | │   ├── tests/              # Test scripts
380 | │   │   ├── benchmark_server.py # Performance tests
381 | │   │   ├── test_improvements.py # Test scripts
382 | │   │   ├── test_custom_timeline.py # Timeline tests
383 | │   │   ├── create_test_timeline.py # Create test timeline
384 | │   │   ├── test-after-restart.sh # Test after restart (Unix)
385 | │   │   └── test-after-restart.bat # Test after restart (Windows)
386 | │   ├── batch_automation.py # Batch automation script
387 | │   ├── restart-server.sh   # Server restart script (Unix)
388 | │   ├── restart-server.bat  # Server restart script (Windows)
389 | │   ├── run-now.sh          # Quick start script (Unix)
390 | │   └── run-now.bat         # Quick start script (Windows)
391 | ├── resolve_mcp_server.py   # Main server implementation
392 | ├── src/                    # Source code
393 | │   ├── api/                # API implementation
394 | │   ├── features/           # Feature modules
395 | │   └── utils/              # Utility functions
396 | ├── logs/                   # Log files
397 | ├── tools/                  # Development tools
398 | ├── assets/                 # Project assets
399 | └── examples/               # Example code
400 | ```
401 | 
402 | ## License
403 | 
404 | MIT
405 | 
406 | ## Acknowledgments
407 | 
408 | - Blackmagic Design for DaVinci Resolve and its API
409 | - The MCP protocol team for enabling AI assistant integration
410 | 
411 | ## Author
412 | 
413 | Samuel Gursky ([email protected])
414 | - GitHub: [github.com/samuelgursky](https://github.com/samuelgursky)
415 | 
416 | ## Future Plans
417 | 
418 | - Windows and Linux support
419 | - Additional DaVinci Resolve features
420 | - Support for Claude Desktop
421 | 
422 | ## Development
423 | 
424 | If you'd like to contribute, please check the feature checklist in the repo and pick an unimplemented feature to work on. The code is structured with clear sections for different areas of functionality.
425 | 
426 | ## License
427 | 
428 | MIT
429 | 
430 | ## Acknowledgments
431 | 
432 | - Blackmagic Design for DaVinci Resolve and its API
433 | - The MCP protocol team for enabling AI assistant integration
434 | 
435 | ## Project Structure
436 | 
437 | After cleanup, the project has the following structure:
438 | 
439 | - `resolve_mcp_server.py` - The main MCP server implementation
440 | - `run-now.sh` - Quick start script that handles setup and runs the server
441 | - `setup.sh` - Complete setup script for installation
442 | - `check-resolve-ready.sh` - Pre-launch check to verify DaVinci Resolve is ready
443 | - `start-server.sh` - Script to start the server
444 | - `run-server.sh` - Simplified script to run the server directly
445 | 
446 | **Key Directories:**
447 | - `src/` - Source code and modules
448 | - `assets/` - Project assets and resources
449 | - `logs/` - Log files directory
450 | - `scripts/` - Helper scripts
451 | 
452 | When developing, it's recommended to use `./run-now.sh` which sets up the environment and launches the server in one step. 
453 | 
454 | ## Changelog
455 | 
456 | See [docs/CHANGELOG.md](docs/CHANGELOG.md) for a detailed history of changes. 
457 | 
458 | ### Cursor-Specific Setup
459 | 
460 | When integrating with Cursor, follow these specific steps:
461 | 
462 | 1. Make sure DaVinci Resolve is running before starting Cursor
463 | 
464 | 2. Install required dependencies:
465 |    ```bash
466 |    # From the davinci-resolve-mcp directory:
467 |    pip install -r requirements.txt
468 |    ```
469 |    Note: This will install the MCP package and other dependencies automatically.
470 | 
471 | 3. Set up the MCP server configuration in Cursor:
472 |    
473 |    Create or edit `~/.cursor/mcp.json` on macOS (or `%USERPROFILE%\.cursor\mcp.json` on Windows):
474 |    
475 |    ```json
476 |    {
477 |      "mcpServers": {
478 |        "davinci-resolve": {
479 |          "name": "DaVinci Resolve MCP",
480 |          "command": "/path/to/your/venv/bin/python",
481 |          "args": [
482 |            "/path/to/your/davinci-resolve-mcp/src/main.py"
483 |          ]
484 |        }
485 |      }
486 |    }
487 |    ```
488 |    
489 |    **Important Notes:**
490 |    - Use `main.py` as the entry point (not `resolve_mcp_server.py`)
491 |    - Use absolute paths in the configuration
492 | 
493 | 4. Common issues:
494 |    - "Client closed" error: Check that paths are correct in mcp.json and dependencies are installed
495 |    - Connection problems: Make sure DaVinci Resolve is running before starting Cursor
496 |    - Environment variables: The main.py script will handle setting environment variables
```

--------------------------------------------------------------------------------
/resolve_mcp_server.py:
--------------------------------------------------------------------------------

```python
1 | src/resolve_mcp_server.py
```

--------------------------------------------------------------------------------
/src/api/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | DaVinci Resolve MCP API Package
3 | """ 
```

--------------------------------------------------------------------------------
/src/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | DaVinci Resolve MCP Server Package
3 | """ 
```

--------------------------------------------------------------------------------
/src/utils/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | DaVinci Resolve MCP Utilities Package
3 | """ 
```

--------------------------------------------------------------------------------
/src/bin/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | DaVinci Resolve MCP Binary/Scripts Package
3 | """ 
```

--------------------------------------------------------------------------------
/run-now.sh:
--------------------------------------------------------------------------------

```bash
1 | /Users/samuelgursky/davinci-resolve-mcp-20250401-02/davinci-resolve-mcp/scripts/run-now.sh
```

--------------------------------------------------------------------------------
/run-now.bat:
--------------------------------------------------------------------------------

```
1 | /Users/samuelgursky/davinci-resolve-mcp-20250401-02/davinci-resolve-mcp/scripts/run-now.bat
```

--------------------------------------------------------------------------------
/config/mcp-project-template.json:
--------------------------------------------------------------------------------

```json
1 | {
2 |   "mcpServers": {
3 |     "davinci-resolve": {
4 |       "name": "DaVinci Resolve Project-Specific",
5 |       "command": "${PROJECT_ROOT}/mcp_resolve-cursor_start",
6 |       "args": ["--project", "${PROJECT_NAME}"]
7 |     }
8 |   }
9 | } 
```

--------------------------------------------------------------------------------
/config/cursor-mcp-example.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "mcpServers": {
 3 |     "davinci-resolve": {
 4 |       "name": "DaVinci Resolve MCP",
 5 |       "command": "/path/to/your/venv/bin/python",
 6 |       "args": [
 7 |         "/path/to/your/davinci-resolve-mcp/src/main.py"
 8 |       ]
 9 |     }
10 |   }
11 | } 
```

--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------

```
 1 | # DaVinci Resolve MCP Server Dependencies
 2 | 
 3 | # MCP Protocol SDK with CLI support
 4 | mcp[cli]
 5 | 
 6 | # Dependencies for testing and automation scripts
 7 | requests>=2.28.0
 8 | psutil>=5.9.0
 9 | 
10 | # JSON-RPC Server for API
11 | jsonrpcserver>=5.0.0
12 | 
13 | # Git repository dependencies
14 | git+https://github.com/modelcontextprotocol/python-sdk.git 
```

--------------------------------------------------------------------------------
/config/macos/cursor-mcp-config.template.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "__IMPORTANT_NOTE__": "This is a template! You MUST replace ${PROJECT_ROOT} with your actual path to the project directory (e.g., /Users/username/davinci-resolve-mcp)",
 3 |   "mcpServers": {
 4 |     "davinci-resolve": {
 5 |       "name": "DaVinci Resolve MCP",
 6 |       "command": "${PROJECT_ROOT}/venv/bin/python",
 7 |       "args": ["${PROJECT_ROOT}/resolve_mcp_server.py"]
 8 |     }
 9 |   }
10 | } 
```

--------------------------------------------------------------------------------
/config/windows/cursor-mcp-config.template.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "__IMPORTANT_NOTE__": "This is a template! You MUST replace ${PROJECT_ROOT} with your actual path to the project directory (e.g., C:\\Users\\username\\davinci-resolve-mcp)",
 3 |   "mcpServers": {
 4 |     "davinci-resolve": {
 5 |       "name": "DaVinci Resolve MCP",
 6 |       "command": "${PROJECT_ROOT}/venv/Scripts/python.exe",
 7 |       "args": ["${PROJECT_ROOT}/resolve_mcp_server.py"]
 8 |     }
 9 |   }
10 | } 
```

--------------------------------------------------------------------------------
/scripts/run-server.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | # Wrapper script to run the DaVinci Resolve MCP Server with the virtual environment
 3 | 
 4 | # Source environment variables if not already set
 5 | if [ -z "$RESOLVE_SCRIPT_API" ]; then
 6 |   source "/Users/samuelgursky/.zshrc"
 7 | fi
 8 | 
 9 | # Activate virtual environment and run server
10 | "/Users/samuelgursky/davinci-resolve-mcp-20250326/scripts/venv/bin/python" "/Users/samuelgursky/davinci-resolve-mcp-20250326/scripts/resolve_mcp_server.py" "$@"
11 | 
```

--------------------------------------------------------------------------------
/scripts/check-resolve-ready.bat:
--------------------------------------------------------------------------------

```
 1 | @echo off
 2 | REM DaVinci Resolve MCP Server - Pre-Launch Check for Windows
 3 | REM This batch file launches the PowerShell pre-launch check script
 4 | 
 5 | echo Starting DaVinci Resolve MCP Pre-Launch Check...
 6 | echo.
 7 | 
 8 | REM Run the PowerShell script with bypass execution policy for this session only
 9 | powershell -ExecutionPolicy Bypass -File "%~dp0scripts\check-resolve-ready.ps1"
10 | 
11 | echo.
12 | if %ERRORLEVEL% EQU 0 (
13 |     echo Pre-launch check completed successfully.
14 | ) else (
15 |     echo Pre-launch check encountered issues. Please review any error messages above.
16 |     pause
17 | ) 
```

--------------------------------------------------------------------------------
/config/windows/claude-desktop-config.template.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "mcpServers": {
 3 |     "davinci-resolve": {
 4 |       "name": "DaVinci Resolve MCP",
 5 |       "command": "${PROJECT_ROOT}/venv/Scripts/python.exe",
 6 |       "args": ["${PROJECT_ROOT}/resolve_mcp_server.py"],
 7 |       "env": {
 8 |         "RESOLVE_SCRIPT_API": "C:/ProgramData/Blackmagic Design/DaVinci Resolve/Support/Developer/Scripting",
 9 |         "RESOLVE_SCRIPT_LIB": "C:/Program Files/Blackmagic Design/DaVinci Resolve/fusionscript.dll",
10 |         "PYTHONPATH": "C:/ProgramData/Blackmagic Design/DaVinci Resolve/Support/Developer/Scripting/Modules"
11 |       }
12 |     }
13 |   }
14 | } 
```

--------------------------------------------------------------------------------
/config/macos/claude-desktop-config.template.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "mcpServers": {
 3 |     "davinci-resolve": {
 4 |       "name": "DaVinci Resolve MCP",
 5 |       "command": "${PROJECT_ROOT}/venv/bin/python",
 6 |       "args": ["${PROJECT_ROOT}/resolve_mcp_server.py"],
 7 |       "env": {
 8 |         "RESOLVE_SCRIPT_API": "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting",
 9 |         "RESOLVE_SCRIPT_LIB": "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so",
10 |         "PYTHONPATH": "$PYTHONPATH:/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules/"
11 |       }
12 |     }
13 |   }
14 | } 
```

--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Changelog
 2 | 
 3 | ## v1.3.8 - April 2025
 4 | 
 5 | ### Improvements
 6 | - **Cursor Integration**: Added comprehensive documentation for Cursor setup process
 7 | - **Entry Point**: Standardized on `main.py` as the proper entry point (replaces direct use of `resolve_mcp_server.py`)
 8 | - **Configuration Templates**: Updated example configuration files to use correct paths
 9 | - **Documentation**: Added detailed troubleshooting for "client closed" errors in Cursor
10 | 
11 | ### Fixed
12 | - Ensured consistent documentation for environment setup
13 | 
14 | ## v1.3.7 - Installation Improvements, Path Resolution Fixes, Enhanced Configuration
15 | 
16 | ### Improvements
17 | // ... existing content ... 
```

--------------------------------------------------------------------------------
/config/sample_config.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "project_name": "MCP Automation Demo",
 3 |   "timeline_name": "Demo Timeline",
 4 |   "render_preset": "YouTube 1080p",
 5 |   "media_files": [
 6 |     "/Users/Media/sample_video.mp4",
 7 |     "/Users/Media/interview.mov",
 8 |     "/Users/Media/background.png",
 9 |     "/Users/Media/music.wav"
10 |   ],
11 |   "color_settings": {
12 |     "primary_correction": {
13 |       "gamma_red": 0.05,
14 |       "gamma_green": 0.02,
15 |       "gamma_blue": -0.03
16 |     },
17 |     "secondary_correction": {
18 |       "lift_master": -0.05,
19 |       "gamma_master": 0.02,
20 |       "gain_master": 0.1
21 |     }
22 |   },
23 |   "project_settings": {
24 |     "timelineFrameRate": "24",
25 |     "timelineResolutionWidth": 1920,
26 |     "timelineResolutionHeight": 1080
27 |   },
28 |   "render_settings": {
29 |     "destination": "/Users/Media/Output",
30 |     "format": "mp4",
31 |     "preset": "YouTube 1080p",
32 |     "use_in_out_range": false
33 |   },
34 |   "organize_bins": {
35 |     "Video": [".mp4", ".mov", ".mxf", ".avi"],
36 |     "Audio": [".wav", ".mp3", ".aac", ".m4a"],
37 |     "Images": [".png", ".jpg", ".jpeg", ".tiff", ".tif", ".exr"],
38 |     "Graphics": [".psd", ".ai", ".eps"]
39 |   }
40 | } 
```

--------------------------------------------------------------------------------
/src/main.py:
--------------------------------------------------------------------------------

```python
 1 | #!/usr/bin/env python3
 2 | """
 3 | DaVinci Resolve MCP Server - Main Entry Point
 4 | This file serves as the main entry point for running the DaVinci Resolve MCP server
 5 | """
 6 | 
 7 | import os
 8 | import sys
 9 | import argparse
10 | import logging
11 | from pathlib import Path
12 | 
13 | # Add the parent directory to sys.path to ensure imports work
14 | project_dir = Path(__file__).parent.parent
15 | sys.path.insert(0, str(project_dir))
16 | 
17 | # Import the connection utils first to set environment variables
18 | from src.utils.resolve_connection import check_environment_variables, set_default_environment_variables
19 | 
20 | # Set up logging
21 | logging.basicConfig(
22 |     level=logging.INFO,
23 |     format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
24 |     handlers=[logging.StreamHandler()]
25 | )
26 | logger = logging.getLogger("davinci-resolve-mcp.main")
27 | 
28 | def check_setup():
29 |     """Check if the environment is properly set up."""
30 |     env_status = check_environment_variables()
31 |     if not env_status["all_set"]:
32 |         logger.warning(f"Setting default environment variables. Missing: {env_status['missing']}")
33 |         set_default_environment_variables()
34 |         
35 |     return True
36 | 
37 | def run_server(debug=False):
38 |     """Run the MCP server."""
39 |     from src.resolve_mcp_server import mcp
40 |     
41 |     # Set logging level based on debug flag
42 |     if debug:
43 |         logging.getLogger("davinci-resolve-mcp").setLevel(logging.DEBUG)
44 |         logger.info("Debug mode enabled")
45 |     
46 |     # Run the server
47 |     logger.info("Starting DaVinci Resolve MCP Server...")
48 |     mcp.run()
49 | 
50 | def main():
51 |     """Main entry point for the application."""
52 |     parser = argparse.ArgumentParser(description="DaVinci Resolve MCP Server")
53 |     parser.add_argument("--debug", action="store_true", help="Enable debug logging")
54 |     args = parser.parse_args()
55 |     
56 |     if check_setup():
57 |         run_server(debug=args.debug)
58 |     else:
59 |         logger.error("Failed to set up the environment. Please check the configuration.")
60 |         return 1
61 |     
62 |     return 0
63 | 
64 | if __name__ == "__main__":
65 |     sys.exit(main()) 
```

--------------------------------------------------------------------------------
/scripts/restart-server.bat:
--------------------------------------------------------------------------------

```
 1 | @echo off
 2 | :: Restart script for DaVinci Resolve MCP Server
 3 | :: Created as part of feature updates on March 29, 2024
 4 | 
 5 | echo ========================================================
 6 | echo DaVinci Resolve MCP Server - Restart Script
 7 | echo ========================================================
 8 | 
 9 | :: Change to the directory where the script is located
10 | cd /d "%~dp0"
11 | 
12 | :: Check if the server is running
13 | echo Checking for running server...
14 | wmic process where "commandline like '%%python%%resolve_mcp_server.py%%'" get processid 2>nul | findstr /r "[0-9]" > temp_pid.txt
15 | 
16 | :: Check if any PID was found
17 | set /p SERVER_PID=<temp_pid.txt
18 | del temp_pid.txt
19 | 
20 | if not defined SERVER_PID (
21 |     echo No running DaVinci Resolve MCP Server detected.
22 | ) else (
23 |     echo Stopping existing DaVinci Resolve MCP Server with PID: %SERVER_PID%
24 |     
25 |     :: Stop the process
26 |     taskkill /PID %SERVER_PID% /F
27 |     
28 |     :: Wait a moment to ensure it's stopped
29 |     timeout /t 2 /nobreak > nul
30 |     
31 |     echo Server process stopped.
32 | )
33 | 
34 | :: Make sure we have the right environment
35 | if exist setup.bat (
36 |     echo Setting up environment...
37 |     call setup.bat
38 | ) else (
39 |     echo Warning: setup.bat not found. Environment may not be properly configured.
40 | )
41 | 
42 | :: Start the server again
43 | echo Starting DaVinci Resolve MCP Server...
44 | if exist "%SCRIPT_DIR%\..\run-now.bat" (
45 |     echo Starting server with run-now.bat...
46 |     start "" cmd /c "%SCRIPT_DIR%\..\run-now.bat"
47 |     
48 |     :: Wait a moment
49 |     timeout /t 3 /nobreak > nul
50 |     
51 |     :: Check if it started
52 |     wmic process where "commandline like '%%python%%resolve_mcp_server.py%%'" get processid 2>nul | findstr /r "[0-9]" > nul
53 |     if %ERRORLEVEL% EQU 0 (
54 |         echo DaVinci Resolve MCP Server started successfully!
55 |     ) else (
56 |         echo Failed to start DaVinci Resolve MCP Server. Check logs for errors.
57 |     )
58 | ) else (
59 |     echo Error: run-now.bat not found. Cannot start the server.
60 |     exit /b 1
61 | )
62 | 
63 | echo ========================================================
64 | echo Restart operation completed.
65 | echo ======================================================== 
```

--------------------------------------------------------------------------------
/scripts/create-release-zip.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | # create-release-zip.sh
 3 | # Script to create a versioned zip file for distribution
 4 | 
 5 | # Colors for terminal output
 6 | GREEN='\033[0;32m'
 7 | YELLOW='\033[0;33m'
 8 | BLUE='\033[0;34m'
 9 | RED='\033[0;31m'
10 | NC='\033[0m' # No Color
11 | 
12 | # Get the directory where this script is located
13 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
14 | PROJECT_ROOT="$( cd "$SCRIPT_DIR/.." &> /dev/null && pwd )"
15 | 
16 | # Get version from VERSION.md
17 | VERSION=$(grep -m 1 "Current Version:" "$PROJECT_ROOT/docs/VERSION.md" | sed 's/Current Version: //')
18 | 
19 | if [ -z "$VERSION" ]; then
20 |     echo -e "${RED}Error: Could not determine version from VERSION.md${NC}"
21 |     exit 1
22 | fi
23 | 
24 | # Create filename with version
25 | ZIP_FILE="davinci-resolve-mcp-v$VERSION.zip"
26 | DIST_DIR="$PROJECT_ROOT/dist"
27 | ZIP_PATH="$DIST_DIR/$ZIP_FILE"
28 | 
29 | # Ensure dist directory exists
30 | mkdir -p "$DIST_DIR"
31 | 
32 | echo -e "${BLUE}=================================================${NC}"
33 | echo -e "${BLUE}  Creating Release Zip for DaVinci Resolve MCP   ${NC}"
34 | echo -e "${BLUE}=================================================${NC}"
35 | echo -e "${YELLOW}Version: $VERSION${NC}"
36 | echo -e "${YELLOW}Output file: $ZIP_FILE${NC}"
37 | echo -e "${YELLOW}Output directory: $DIST_DIR${NC}"
38 | echo ""
39 | 
40 | # Change to project root directory
41 | cd "$PROJECT_ROOT" || exit 1
42 | 
43 | # Create zip file with tracked files
44 | echo -e "${YELLOW}Adding tracked files to zip...${NC}"
45 | git ls-files | zip -@ "$ZIP_PATH"
46 | 
47 | # Add untracked files (but exclude ignored files and the .git directory)
48 | echo -e "${YELLOW}Adding untracked files to zip...${NC}"
49 | git ls-files --others --exclude-standard | zip -@ "$ZIP_PATH"
50 | 
51 | # Check if the zip file was created successfully
52 | if [ -f "$ZIP_PATH" ]; then
53 |     ZIP_SIZE=$(du -h "$ZIP_PATH" | cut -f1)
54 |     echo -e "${GREEN}Successfully created release zip: $ZIP_PATH (Size: $ZIP_SIZE)${NC}"
55 | else
56 |     echo -e "${RED}Failed to create release zip${NC}"
57 |     exit 1
58 | fi
59 | 
60 | echo -e "${YELLOW}Archive contents:${NC}"
61 | unzip -l "$ZIP_PATH" | head -n 10
62 | echo -e "${YELLOW}... (additional files)${NC}"
63 | echo ""
64 | echo -e "${GREEN}Release zip created successfully!${NC}"
65 | 
66 | exit 0 
```

--------------------------------------------------------------------------------
/scripts/create_app_shortcut.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | # Script to create a macOS desktop app shortcut for the DaVinci Resolve MCP Server Launcher
 3 | 
 4 | # Get the absolute path to the project directory
 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
 6 | PROJECT_DIR="$( cd "$SCRIPT_DIR/.." &> /dev/null && pwd )"
 7 | LAUNCHER_SCRIPT="$SCRIPT_DIR/launch.sh"
 8 | APP_NAME="DaVinci Resolve MCP Server.app"
 9 | APP_DIR="$HOME/Desktop/$APP_NAME"
10 | 
11 | # Make sure the launcher script is executable
12 | chmod +x "$LAUNCHER_SCRIPT"
13 | 
14 | # Create the app structure
15 | echo "Creating app structure at $APP_DIR..."
16 | mkdir -p "$APP_DIR/Contents/MacOS"
17 | mkdir -p "$APP_DIR/Contents/Resources"
18 | 
19 | # Create the Info.plist
20 | cat > "$APP_DIR/Contents/Info.plist" << EOL
21 | <?xml version="1.0" encoding="UTF-8"?>
22 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
23 | <plist version="1.0">
24 | <dict>
25 |     <key>CFBundleExecutable</key>
26 |     <string>app</string>
27 |     <key>CFBundleIconFile</key>
28 |     <string>AppIcon</string>
29 |     <key>CFBundleIdentifier</key>
30 |     <string>com.davinciresolve.mcpserver</string>
31 |     <key>CFBundleInfoDictionaryVersion</key>
32 |     <string>6.0</string>
33 |     <key>CFBundleName</key>
34 |     <string>DaVinci Resolve MCP Server</string>
35 |     <key>CFBundlePackageType</key>
36 |     <string>APPL</string>
37 |     <key>CFBundleShortVersionString</key>
38 |     <string>1.0</string>
39 |     <key>CFBundleVersion</key>
40 |     <string>1</string>
41 |     <key>LSMinimumSystemVersion</key>
42 |     <string>10.13</string>
43 |     <key>NSHumanReadableCopyright</key>
44 |     <string>Copyright © 2023. All rights reserved.</string>
45 | </dict>
46 | </plist>
47 | EOL
48 | 
49 | # Create the wrapper script
50 | cat > "$APP_DIR/Contents/MacOS/app" << EOL
51 | #!/bin/bash
52 | cd "$PROJECT_DIR"
53 | osascript -e 'tell application "Terminal" to do script "\"$LAUNCHER_SCRIPT\""'
54 | EOL
55 | 
56 | # Make the wrapper script executable
57 | chmod +x "$APP_DIR/Contents/MacOS/app"
58 | 
59 | # Copy a default icon if available, or create a placeholder
60 | if [ -f "$PROJECT_DIR/assets/icon.icns" ]; then
61 |     cp "$PROJECT_DIR/assets/icon.icns" "$APP_DIR/Contents/Resources/AppIcon.icns"
62 | fi
63 | 
64 | echo "App shortcut created at $APP_DIR"
65 | echo "Double-click to launch the DaVinci Resolve MCP Server" 
```

--------------------------------------------------------------------------------
/docs/VERSION.md:
--------------------------------------------------------------------------------

```markdown
 1 | # DaVinci Resolve MCP Server
 2 | 
 3 | Current Version: 1.3.8
 4 | 
 5 | ## Release Information
 6 | 
 7 | ### 1.3.8 Changes
 8 | - **Cursor Integration**: Added comprehensive documentation for Cursor setup process
 9 | - **Entry Point**: Standardized on `main.py` as the proper entry point (replaces direct use of `resolve_mcp_server.py`)
10 | - **Configuration Templates**: Updated example configuration files to use correct paths
11 | - **Fixed**: Ensured consistent documentation for environment setup
12 | 
13 | ### 1.3.7 Changes
14 | - Improved installation experience:
15 |   - New one-step installation script for macOS/Linux and Windows
16 |   - Enhanced path resolution in scripts
17 |   - More reliable DaVinci Resolve detection
18 |   - Support for absolute paths in project and global configurations
19 |   - Added comprehensive verification tools for troubleshooting
20 |   - Improved error handling and feedback
21 |   - Enhanced documentation with detailed installation guide
22 | - Fixed configuration issues with project-level MCP configuration
23 | - Updated documentation with detailed installation and troubleshooting steps
24 | 
25 | ### 1.3.6 Changes
26 | - Comprehensive Feature Additions:
27 |   - Complete MediaPoolItem and Folder object functionality
28 |   - Cache Management implementation
29 |   - Timeline Item Properties implementation
30 |   - Keyframe Control implementation
31 |   - Color Preset Management implementation
32 |   - LUT Export functionality
33 | - Project directory restructuring
34 | - Updated Implementation Progress Summary to reflect 100% completion of multiple feature sets
35 | - Enhanced documentation and examples
36 | 
37 | ### 1.3.5 Changes
38 | - Updated Cursor integration with new templating system
39 | - Added automatic Cursor MCP configuration generation
40 | - Improved client-specific launcher scripts
41 | - Fixed path handling in Cursor configuration
42 | - Enhanced cross-platform compatibility
43 | - Improved virtual environment detection and validation
44 | 
45 | ### 1.3.4 Changes
46 | - Improved template configuration for MCP clients
47 | - Added clearer documentation for path configuration
48 | - Fixed Cursor integration templates with correct Python path
49 | - Simplified configuration process with better examples
50 | - Enhanced README with prominent warnings about path replacement
51 | - Removed environment variable requirements from configuration files
52 | 
53 | ## About
54 | DaVinci Resolve MCP Server connects DaVinci Resolve to AI assistants through the Model Context Protocol, allowing AI agents to control DaVinci Resolve directly through natural language.
55 | 
56 | For full changelog, see CHANGELOG.md 
```

--------------------------------------------------------------------------------
/scripts/restart-server.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | # Restart script for DaVinci Resolve MCP Server
 3 | # Created as part of feature updates on March 29, 2024
 4 | 
 5 | echo "========================================================"
 6 | echo "DaVinci Resolve MCP Server - Restart Script"
 7 | echo "========================================================"
 8 | 
 9 | # Get the directory where the script is located
10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
11 | cd "$SCRIPT_DIR"
12 | 
13 | # Function to check if the server is running
14 | check_server_running() {
15 |     # Look for Python processes running the server
16 |     pgrep -f "python.*resolve_mcp_server.py" > /dev/null
17 |     return $?
18 | }
19 | 
20 | # Stop the server if it's running
21 | if check_server_running; then
22 |     echo "Stopping existing DaVinci Resolve MCP Server..."
23 |     
24 |     # Find the PID of the server process
25 |     SERVER_PID=$(pgrep -f "python.*resolve_mcp_server.py")
26 |     
27 |     if [ -n "$SERVER_PID" ]; then
28 |         echo "Server process found with PID: $SERVER_PID"
29 |         kill $SERVER_PID
30 |         
31 |         # Wait for the process to stop
32 |         for i in {1..5}; do
33 |             if ! ps -p $SERVER_PID > /dev/null; then
34 |                 echo "Server process stopped successfully."
35 |                 break
36 |             fi
37 |             echo "Waiting for server to stop... ($i/5)"
38 |             sleep 1
39 |         done
40 |         
41 |         # Force kill if still running
42 |         if ps -p $SERVER_PID > /dev/null; then
43 |             echo "Server did not stop gracefully. Forcing termination..."
44 |             kill -9 $SERVER_PID
45 |             sleep 1
46 |         fi
47 |     else
48 |         echo "Could not determine server PID. Server might be running in an unexpected way."
49 |     fi
50 | else
51 |     echo "No running DaVinci Resolve MCP Server detected."
52 | fi
53 | 
54 | # Make sure we have the right environment
55 | if [ -f "./setup.sh" ]; then
56 |     echo "Setting up environment..."
57 |     source ./setup.sh
58 | else
59 |     echo "Warning: setup.sh not found. Environment may not be properly configured."
60 | fi
61 | 
62 | # Start the server again
63 | echo "Starting DaVinci Resolve MCP Server..."
64 | if [ -f "$SCRIPT_DIR/../run-now.sh" ]; then
65 |     echo "Starting server with run-now.sh..."
66 |     "$SCRIPT_DIR/../run-now.sh" &
67 |     
68 |     # Wait a moment and check if it started
69 |     sleep 2
70 |     if check_server_running; then
71 |         echo "DaVinci Resolve MCP Server started successfully!"
72 |     else
73 |         echo "Failed to start DaVinci Resolve MCP Server. Check logs for errors."
74 |     fi
75 | else
76 |     echo "Error: run-now.sh not found. Cannot start the server."
77 |     exit 1
78 | fi
79 | 
80 | echo "========================================================"
81 | echo "Restart operation completed."
82 | echo "========================================================" 
```

--------------------------------------------------------------------------------
/tests/test-after-restart.bat:
--------------------------------------------------------------------------------

```
 1 | @echo off
 2 | :: Restart DaVinci Resolve MCP Server and run tests
 3 | :: This script combines server restart with automated testing
 4 | 
 5 | echo ========================================================
 6 | echo DaVinci Resolve MCP Server - Test After Restart
 7 | echo ========================================================
 8 | 
 9 | :: Change to the directory where the script is located
10 | cd /d "%~dp0"
11 | 
12 | :: Check if DaVinci Resolve is running
13 | tasklist | findstr "Resolve" > nul
14 | if %ERRORLEVEL% NEQ 0 (
15 |     echo [33m⚠️ DaVinci Resolve is not running. Please start it before continuing.[0m
16 |     set /p continue_anyway=Start testing anyway? (y/n): 
17 |     if /i not "%continue_anyway%"=="y" (
18 |         echo Aborting test.
19 |         exit /b 1
20 |     )
21 |     echo Continuing with testing despite DaVinci Resolve not running...
22 | )
23 | 
24 | :: Step 1: Restart the server using the restart script
25 | echo.
26 | echo Step 1: Restarting DaVinci Resolve MCP Server...
27 | if exist restart-server.bat (
28 |     call restart-server.bat
29 |     
30 |     :: Check if restart was successful
31 |     timeout /t 3 /nobreak > nul
32 |     wmic process where "commandline like '%%python%%resolve_mcp_server.py%%'" get processid 2>nul | findstr /r "[0-9]" > nul
33 |     if %ERRORLEVEL% EQU 0 (
34 |         echo [32m✅ Server restart successful[0m
35 |     ) else (
36 |         echo [31m❌ Server restart failed. Please check server logs for errors.[0m
37 |         exit /b 1
38 |     )
39 | ) else (
40 |     echo [31m❌ restart-server.bat not found. Cannot restart server.[0m
41 |     exit /b 1
42 | )
43 | 
44 | :: Step 2: Create test timeline (optional)
45 | echo.
46 | echo Step 2: Create test timeline with media?
47 | set /p create_timeline=Create test timeline? (y/n): 
48 | if /i "%create_timeline%"=="y" (
49 |     echo Creating test timeline...
50 |     if exist create_test_timeline.py (
51 |         python create_test_timeline.py
52 |         if %ERRORLEVEL% NEQ 0 (
53 |             echo [33m⚠️ Test timeline creation had issues, but we'll continue with testing.[0m
54 |         )
55 |     ) else (
56 |         echo [31m❌ create_test_timeline.py not found. Skipping test timeline creation.[0m
57 |     )
58 | ) else (
59 |     echo Skipping test timeline creation.
60 | )
61 | 
62 | :: Step 3: Run automated tests
63 | echo.
64 | echo Step 3: Running automated tests...
65 | if exist test_improvements.py (
66 |     python test_improvements.py
67 |     set TEST_RESULT=%ERRORLEVEL%
68 |     if %TEST_RESULT% EQU 0 (
69 |         echo [32m✅ All tests passed![0m
70 |     ) else (
71 |         echo [33m⚠️ Some tests failed. Check the logs for details.[0m
72 |     )
73 | ) else (
74 |     echo [31m❌ test_improvements.py not found. Cannot run tests.[0m
75 |     exit /b 1
76 | )
77 | 
78 | echo.
79 | echo ========================================================
80 | echo Testing complete. Results logged to mcp_test_results.log
81 | echo ========================================================
82 | 
83 | exit /b %TEST_RESULT% 
```

--------------------------------------------------------------------------------
/tests/test-after-restart.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | # Restart DaVinci Resolve MCP Server and run tests
 3 | # This script combines server restart with automated testing
 4 | 
 5 | echo "========================================================"
 6 | echo "DaVinci Resolve MCP Server - Test After Restart"
 7 | echo "========================================================"
 8 | 
 9 | # Get the directory where the script is located
10 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
11 | cd "$SCRIPT_DIR"
12 | 
13 | # Check if DaVinci Resolve is running
14 | check_resolve_running() {
15 |     ps -ef | grep -i "[D]aVinci Resolve" > /dev/null
16 |     return $?
17 | }
18 | 
19 | if ! check_resolve_running; then
20 |     echo "⚠️ DaVinci Resolve is not running. Please start it before continuing."
21 |     read -p "Start testing anyway? (y/n): " continue_anyway
22 |     if [[ "$continue_anyway" != "y" ]]; then
23 |         echo "Aborting test."
24 |         exit 1
25 |     fi
26 |     echo "Continuing with testing despite DaVinci Resolve not running..."
27 | fi
28 | 
29 | # Step 1: Restart the server using the restart script
30 | echo "Step 1: Restarting DaVinci Resolve MCP Server..."
31 | if [ -f "./restart-server.sh" ]; then
32 |     ./restart-server.sh
33 |     
34 |     # Check if restart was successful
35 |     sleep 3
36 |     pgrep -f "python.*resolve_mcp_server.py" > /dev/null
37 |     if [ $? -eq 0 ]; then
38 |         echo "✅ Server restart successful"
39 |     else
40 |         echo "❌ Server restart failed. Please check server logs for errors."
41 |         exit 1
42 |     fi
43 | else
44 |     echo "❌ restart-server.sh not found. Cannot restart server."
45 |     exit 1
46 | fi
47 | 
48 | # Step 2: Create test timeline (optional)
49 | echo
50 | echo "Step 2: Create test timeline with media?"
51 | read -p "Create test timeline? (y/n): " create_timeline
52 | if [[ "$create_timeline" == "y" ]]; then
53 |     echo "Creating test timeline..."
54 |     if [ -f "./create_test_timeline.py" ]; then
55 |         python3 ./create_test_timeline.py
56 |         if [ $? -ne 0 ]; then
57 |             echo "⚠️ Test timeline creation had issues, but we'll continue with testing."
58 |         fi
59 |     else
60 |         echo "❌ create_test_timeline.py not found. Skipping test timeline creation."
61 |     fi
62 | else
63 |     echo "Skipping test timeline creation."
64 | fi
65 | 
66 | # Step 3: Run automated tests
67 | echo
68 | echo "Step 3: Running automated tests..."
69 | if [ -f "./test_improvements.py" ]; then
70 |     python3 ./test_improvements.py
71 |     TEST_RESULT=$?
72 |     if [ $TEST_RESULT -eq 0 ]; then
73 |         echo "✅ All tests passed!"
74 |     else
75 |         echo "⚠️ Some tests failed. Check the logs for details."
76 |     fi
77 | else
78 |     echo "❌ test_improvements.py not found. Cannot run tests."
79 |     exit 1
80 | fi
81 | 
82 | echo
83 | echo "========================================================"
84 | echo "Testing complete. Results logged to mcp_test_results.log"
85 | echo "========================================================"
86 | 
87 | exit $TEST_RESULT 
```

--------------------------------------------------------------------------------
/scripts/create-release-zip.bat:
--------------------------------------------------------------------------------

```
 1 | @echo off
 2 | REM create-release-zip.bat
 3 | REM Script to create a versioned zip file for distribution on Windows
 4 | 
 5 | setlocal EnableDelayedExpansion
 6 | 
 7 | REM Colors for terminal output
 8 | set GREEN=[92m
 9 | set YELLOW=[93m
10 | set BLUE=[94m
11 | set RED=[91m
12 | set NC=[0m
13 | 
14 | REM Get the directory where this script is located
15 | set "SCRIPT_DIR=%~dp0"
16 | set "PROJECT_ROOT=%SCRIPT_DIR%.."
17 | 
18 | REM Get version from VERSION.md
19 | for /f "tokens=3" %%i in ('findstr /B /C:"Current Version:" "%PROJECT_ROOT%\docs\VERSION.md"') do (
20 |     set "VERSION=%%i"
21 |     goto :version_found
22 | )
23 | :version_found
24 | 
25 | if "%VERSION%"=="" (
26 |     echo %RED%Error: Could not determine version from VERSION.md%NC%
27 |     exit /b 1
28 | )
29 | 
30 | REM Create filename with version
31 | set "ZIP_FILE=davinci-resolve-mcp-v%VERSION%.zip"
32 | set "DIST_DIR=%PROJECT_ROOT%\dist"
33 | set "ZIP_PATH=%DIST_DIR%\%ZIP_FILE%"
34 | 
35 | REM Ensure dist directory exists
36 | if not exist "%DIST_DIR%" mkdir "%DIST_DIR%"
37 | 
38 | echo %BLUE%=================================================%NC%
39 | echo %BLUE%  Creating Release Zip for DaVinci Resolve MCP   %NC%
40 | echo %BLUE%=================================================%NC%
41 | echo %YELLOW%Version: %VERSION%%NC%
42 | echo %YELLOW%Output file: %ZIP_FILE%%NC%
43 | echo %YELLOW%Output directory: %DIST_DIR%%NC%
44 | echo.
45 | 
46 | REM Change to project root directory
47 | cd /d "%PROJECT_ROOT%" || exit /b 1
48 | 
49 | REM Check if 7-Zip is installed
50 | where 7z >nul 2>&1
51 | if %ERRORLEVEL% neq 0 (
52 |     echo %YELLOW%7-Zip not found, using PowerShell to create zip file%NC%
53 |     
54 |     REM Create temporary file list
55 |     git ls-files > filelist.txt
56 |     git ls-files --others --exclude-standard >> filelist.txt
57 |     
58 |     REM Use PowerShell to create the zip file
59 |     powershell -Command "Add-Type -Assembly System.IO.Compression.FileSystem; $zipFile = [System.IO.Compression.ZipFile]::Open('%ZIP_PATH%', [System.IO.Compression.ZipArchiveMode]::Create); Get-Content filelist.txt | ForEach-Object { if (Test-Path -Path $_ -PathType Leaf) { $file = $_; $entry = $zipFile.CreateEntry($file); $stream = $entry.Open(); $bytes = [System.IO.File]::ReadAllBytes($file); $stream.Write($bytes, 0, $bytes.Length); $stream.Close() } }; $zipFile.Dispose()"
60 |     
61 |     REM Remove temporary file list
62 |     del filelist.txt
63 | ) else (
64 |     echo %YELLOW%Using 7-Zip to create zip file...%NC%
65 |     
66 |     REM Create temporary file list
67 |     git ls-files > filelist.txt
68 |     git ls-files --others --exclude-standard >> filelist.txt
69 |     
70 |     REM Use 7-Zip to create the zip file
71 |     7z a -tzip "%ZIP_PATH%" @filelist.txt
72 |     
73 |     REM Remove temporary file list
74 |     del filelist.txt
75 | )
76 | 
77 | REM Check if the zip file was created successfully
78 | if exist "%ZIP_PATH%" (
79 |     echo %GREEN%Successfully created release zip: %ZIP_PATH%%NC%
80 | ) else (
81 |     echo %RED%Failed to create release zip%NC%
82 |     exit /b 1
83 | )
84 | 
85 | echo %GREEN%Release zip created successfully!%NC%
86 | 
87 | exit /b 0 
```

--------------------------------------------------------------------------------
/src/utils/platform.py:
--------------------------------------------------------------------------------

```python
 1 | #!/usr/bin/env python3
 2 | """
 3 | Platform-specific functionality for DaVinci Resolve MCP Server
 4 | """
 5 | 
 6 | import os
 7 | import sys
 8 | import platform
 9 | 
10 | def get_platform():
11 |     """Identify the current operating system platform.
12 |     
13 |     Returns:
14 |         str: 'windows', 'darwin' (macOS), or 'linux'
15 |     """
16 |     system = platform.system().lower()
17 |     if system == 'darwin':
18 |         return 'darwin'
19 |     elif system == 'windows':
20 |         return 'windows'
21 |     elif system == 'linux':
22 |         return 'linux'
23 |     return system
24 | 
25 | def get_resolve_paths():
26 |     """Get platform-specific paths for DaVinci Resolve scripting API.
27 |     
28 |     Returns:
29 |         dict: Dictionary containing api_path, lib_path, and modules_path
30 |     """
31 |     platform_name = get_platform()
32 |     
33 |     if platform_name == 'darwin':  # macOS
34 |         api_path = "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
35 |         lib_path = "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
36 |         modules_path = os.path.join(api_path, "Modules")
37 |     
38 |     elif platform_name == 'windows':  # Windows
39 |         program_files = os.environ.get('PROGRAMDATA', 'C:\\ProgramData')
40 |         program_files_64 = os.environ.get('PROGRAMFILES', 'C:\\Program Files')
41 |         
42 |         api_path = os.path.join(program_files, 'Blackmagic Design', 'DaVinci Resolve', 'Support', 'Developer', 'Scripting')
43 |         lib_path = os.path.join(program_files_64, 'Blackmagic Design', 'DaVinci Resolve', 'fusionscript.dll')
44 |         modules_path = os.path.join(api_path, "Modules")
45 |     
46 |     elif platform_name == 'linux':  # Linux (not fully implemented)
47 |         # Default locations for Linux - these may need to be adjusted
48 |         api_path = "/opt/resolve/Developer/Scripting"
49 |         lib_path = "/opt/resolve/libs/fusionscript.so"
50 |         modules_path = os.path.join(api_path, "Modules")
51 |     
52 |     else:
53 |         # Fallback to macOS paths if unknown platform
54 |         api_path = "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
55 |         lib_path = "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
56 |         modules_path = os.path.join(api_path, "Modules")
57 |     
58 |     return {
59 |         "api_path": api_path,
60 |         "lib_path": lib_path,
61 |         "modules_path": modules_path
62 |     }
63 | 
64 | def setup_environment():
65 |     """Set up environment variables for DaVinci Resolve scripting.
66 |     
67 |     Returns:
68 |         bool: True if setup was successful, False otherwise
69 |     """
70 |     try:
71 |         paths = get_resolve_paths()
72 |         
73 |         os.environ["RESOLVE_SCRIPT_API"] = paths["api_path"]
74 |         os.environ["RESOLVE_SCRIPT_LIB"] = paths["lib_path"]
75 |         
76 |         # Add modules path to Python's path if it's not already there
77 |         if paths["modules_path"] not in sys.path:
78 |             sys.path.append(paths["modules_path"])
79 |         
80 |         return True
81 |     
82 |     except Exception as e:
83 |         print(f"Error setting up environment: {str(e)}")
84 |         return False 
```

--------------------------------------------------------------------------------
/src/utils/resolve_connection.py:
--------------------------------------------------------------------------------

```python
 1 | #!/usr/bin/env python3
 2 | """
 3 | DaVinci Resolve Connection Utilities
 4 | """
 5 | 
 6 | import os
 7 | import logging
 8 | from .platform import get_platform, get_resolve_paths, setup_environment
 9 | 
10 | logger = logging.getLogger("davinci-resolve-mcp.connection")
11 | 
12 | def initialize_resolve():
13 |     """Initialize connection to DaVinci Resolve application."""
14 |     try:
15 |         # Import the DaVinci Resolve scripting module
16 |         import DaVinciResolveScript as dvr_script
17 |         
18 |         # Get the resolve object
19 |         resolve = dvr_script.scriptapp("Resolve")
20 |         
21 |         if resolve is None:
22 |             logger.error("Failed to get Resolve object. Is DaVinci Resolve running?")
23 |             return None
24 |         
25 |         logger.info(f"Connected to DaVinci Resolve: {resolve.GetProductName()} {resolve.GetVersionString()}")
26 |         return resolve
27 |     
28 |     except ImportError:
29 |         platform_name = get_platform()
30 |         paths = get_resolve_paths()
31 |         
32 |         logger.error("Failed to import DaVinciResolveScript. Check environment variables.")
33 |         logger.error("RESOLVE_SCRIPT_API, RESOLVE_SCRIPT_LIB, and PYTHONPATH must be set correctly.")
34 |         
35 |         if platform_name == 'darwin':
36 |             logger.error("On macOS, typically:")
37 |             logger.error(f'export RESOLVE_SCRIPT_API="{paths["api_path"]}"')
38 |             logger.error(f'export RESOLVE_SCRIPT_LIB="{paths["lib_path"]}"')
39 |             logger.error(f'export PYTHONPATH="$PYTHONPATH:{paths["modules_path"]}"')
40 |         elif platform_name == 'windows':
41 |             logger.error("On Windows, typically:")
42 |             logger.error(f'set RESOLVE_SCRIPT_API={paths["api_path"]}')
43 |             logger.error(f'set RESOLVE_SCRIPT_LIB={paths["lib_path"]}')
44 |             logger.error(f'set PYTHONPATH=%PYTHONPATH%;{paths["modules_path"]}')
45 |         elif platform_name == 'linux':
46 |             logger.error("On Linux, typically:")
47 |             logger.error(f'export RESOLVE_SCRIPT_API="{paths["api_path"]}"')
48 |             logger.error(f'export RESOLVE_SCRIPT_LIB="{paths["lib_path"]}"')
49 |             logger.error(f'export PYTHONPATH="$PYTHONPATH:{paths["modules_path"]}"')
50 |         
51 |         return None
52 |     
53 |     except Exception as e:
54 |         logger.error(f"Unexpected error initializing Resolve: {str(e)}")
55 |         return None
56 | 
57 | def check_environment_variables():
58 |     """Check if the required environment variables are set."""
59 |     resolve_script_api = os.environ.get("RESOLVE_SCRIPT_API")
60 |     resolve_script_lib = os.environ.get("RESOLVE_SCRIPT_LIB")
61 |     
62 |     missing_vars = []
63 |     if not resolve_script_api:
64 |         missing_vars.append("RESOLVE_SCRIPT_API")
65 |     if not resolve_script_lib:
66 |         missing_vars.append("RESOLVE_SCRIPT_LIB")
67 |     
68 |     return {
69 |         "all_set": len(missing_vars) == 0,
70 |         "missing": missing_vars,
71 |         "resolve_script_api": resolve_script_api,
72 |         "resolve_script_lib": resolve_script_lib
73 |     }
74 | 
75 | def set_default_environment_variables():
76 |     """Set the default environment variables based on platform."""
77 |     return setup_environment() 
```

--------------------------------------------------------------------------------
/docs/COMMIT_MESSAGE.txt:
--------------------------------------------------------------------------------

```
 1 | Version 1.3.6 - Feature Consolidation and Project Restructuring
 2 | 
 3 | ADDED:
 4 | - Consolidated extensive feature additions into version 1.3.6:
 5 |   - Complete MediaPoolItem and Folder object functionality
 6 |   - Cache Management implementation
 7 |   - Timeline Item Properties implementation 
 8 |   - Keyframe Control implementation
 9 |   - Color Preset Management implementation
10 |   - LUT Export functionality
11 | 
12 | CHANGED:
13 | - Major project directory restructuring:
14 |   - Moved documentation files to docs/ directory
15 |   - Moved test scripts to scripts/tests/ directory
16 |   - Moved configuration templates to config-templates/ directory 
17 |   - Moved utility scripts to scripts/ directory
18 |   - Updated all scripts to work with the new directory structure
19 |   - Created simpler launcher scripts in the root directory
20 | - Updated version number to 1.3.6 across all relevant files
21 | - Reorganized changelog to consolidate planned features
22 | - Enhanced documentation for better readability
23 | 
24 | FIXED:
25 | - Path references in scripts to ensure cross-platform compatibility
26 | - Launcher scripts to use the correct paths after restructuring
27 | 
28 | feat: Comprehensive reliability enhancements, testing tools, and documentation
29 | 
30 | This commit introduces several key improvements to the DaVinci Resolve MCP Server:
31 | 
32 | 1. Color Page Operations:
33 |    - Added automatic clip selection with ensure_clip_selected helper function
34 |    - Improved error handling for color operations
35 |    - Enhanced error messages with actionable guidance
36 |    - Added fallback mechanisms for clip selection
37 | 
38 | 2. Render Queue Operations:
39 |    - Added ensure_render_settings helper function
40 |    - Created validate_render_preset for better preset validation
41 |    - Implemented retry logic with progressive approaches
42 |    - Enhanced error reporting throughout render operations
43 | 
44 | 3. Parameter Validation:
45 |    - Modified set_project_setting to accept Any type
46 |    - Added type conversion between strings and numbers
47 |    - Improved type validation with better error messages
48 |    - Updated imports for modern type handling
49 | 
50 | 4. Testing Tools:
51 |    - Created test_improvements.py automated test script
52 |    - Added create_test_timeline.py environment generator
53 |    - Developed test-after-restart.sh/.bat combined testing scripts
54 |    - Implemented cross-platform testing frameworks
55 | 
56 | 5. Documentation:
57 |    - Updated FEATURES.md with implementation status
58 |    - Added detailed testing results and next steps
59 |    - Created restart scripts for macOS/Linux and Windows
60 |    - Added comprehensive troubleshooting guide
61 |    - Created development best practices guide for future contributors
62 | 
63 | 6. Server Management:
64 |    - Created restart-server.sh and restart-server.bat for easier server management
65 |    - Added automatic server detection and process management
66 |    - Improved environment validation during server startup
67 | 
68 | These improvements significantly enhance the reliability and maintainability of the MCP server, with particular focus on automatic recovery from common error states, providing clear, actionable error messages to users, and ensuring proper testing methodology.
69 | 
70 | NOTE: The server must be restarted to apply these changes. 
```

--------------------------------------------------------------------------------
/scripts/run-now.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | # Quick setup script to get DaVinci Resolve MCP Server running
 3 | 
 4 | # Colors for terminal output
 5 | RED='\033[0;31m'
 6 | GREEN='\033[0;32m'
 7 | YELLOW='\033[0;33m'
 8 | NC='\033[0m' # No Color
 9 | 
10 | # Get the directory where this script is located
11 | SCRIPT_PATH="$(readlink -f "$0")"
12 | SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
13 | ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
14 | VENV_DIR="$ROOT_DIR/venv"
15 | SERVER_PATH="$ROOT_DIR/src/resolve_mcp_server.py"
16 | 
17 | echo -e "${GREEN}Setting up DaVinci Resolve MCP Server with virtual environment...${NC}"
18 | echo -e "${YELLOW}Project root: $ROOT_DIR${NC}"
19 | 
20 | # Create and activate virtual environment
21 | if [ ! -d "$VENV_DIR" ]; then
22 |     echo -e "${YELLOW}Creating Python virtual environment...${NC}"
23 |     python3 -m venv "$VENV_DIR"
24 | fi
25 | 
26 | # Install dependencies from requirements.txt
27 | echo -e "${YELLOW}Installing dependencies from requirements.txt...${NC}"
28 | "$VENV_DIR/bin/pip" install -r "$ROOT_DIR/requirements.txt"
29 | 
30 | # Source environment variables from .zshrc if they exist
31 | if grep -q "RESOLVE_SCRIPT_API" "$HOME/.zshrc"; then
32 |     echo -e "${YELLOW}Sourcing environment variables from .zshrc...${NC}"
33 |     source "$HOME/.zshrc"
34 | else
35 |     echo -e "${YELLOW}Setting environment variables...${NC}"
36 |     export RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
37 |     export RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
38 |     export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"
39 | fi
40 | 
41 | # Make the server script executable
42 | if [ -f "$SERVER_PATH" ]; then
43 |     echo -e "${YELLOW}Making server script executable...${NC}"
44 |     chmod +x "$SERVER_PATH"
45 | else
46 |     echo -e "${RED}Error: Server script not found at $SERVER_PATH${NC}"
47 |     exit 1
48 | fi
49 | 
50 | # Check if DaVinci Resolve is running
51 | if ps -ef | grep -i "[D]aVinci Resolve" > /dev/null; then
52 |     echo -e "${GREEN}✓ DaVinci Resolve is running${NC}"
53 | else
54 |     echo -e "${RED}✗ DaVinci Resolve is not running${NC}"
55 |     echo -e "${YELLOW}Please start DaVinci Resolve before continuing${NC}"
56 |     echo -e "${YELLOW}Waiting 10 seconds for you to start DaVinci Resolve...${NC}"
57 |     sleep 10
58 |     if ! ps -ef | grep -i "[D]aVinci Resolve" > /dev/null; then
59 |         echo -e "${RED}DaVinci Resolve still not running. Please start it manually.${NC}"
60 |         echo -e "${YELLOW}You can run this script again after starting DaVinci Resolve.${NC}"
61 |         exit 1
62 |     fi
63 |     echo -e "${GREEN}✓ DaVinci Resolve is now running${NC}"
64 | fi
65 | 
66 | # Check if MCP command exists in the virtual environment
67 | if [ ! -f "$VENV_DIR/bin/mcp" ]; then
68 |     echo -e "${RED}MCP command not found. Installing MCP[cli]...${NC}"
69 |     "$VENV_DIR/bin/pip" install "mcp[cli]"
70 |     
71 |     if [ ! -f "$VENV_DIR/bin/mcp" ]; then
72 |         echo -e "${RED}Failed to install MCP. Please check your internet connection and try again.${NC}"
73 |         exit 1
74 |     fi
75 | fi
76 | 
77 | # Run the server with the virtual environment's Python
78 | echo -e "${GREEN}Starting DaVinci Resolve MCP Server...${NC}"
79 | echo -e "${YELLOW}Using server script: $SERVER_PATH${NC}"
80 | echo ""
81 | 
82 | cd "$ROOT_DIR"
83 | "$VENV_DIR/bin/mcp" dev "$SERVER_PATH" 
```

--------------------------------------------------------------------------------
/examples/markers/test_marker_frames.py:
--------------------------------------------------------------------------------

```python
 1 | #!/usr/bin/env python3
 2 | """
 3 | Test Marker Frame Placement Script
 4 | 
 5 | This script demonstrates and tests the enhanced marker functionality in DaVinci Resolve.
 6 | It adds markers at different frame positions, including automatic frame selection,
 7 | to validate the marker functionality works correctly with various inputs.
 8 | 
 9 | Example Usage:
10 |     python test_marker_frames.py
11 | 
12 | The script will:
13 | 1. Connect to DaVinci Resolve
14 | 2. Test adding markers at different frame positions 
15 | 3. Include automatic frame selection when no frame is specified
16 | 4. Output the results of each marker operation
17 | """
18 | 
19 | import os
20 | import sys
21 | import time
22 | 
23 | # Add the project root to the Python path
24 | script_dir = os.path.dirname(os.path.abspath(__file__))
25 | project_root = os.path.abspath(os.path.join(script_dir, '../..'))
26 | sys.path.append(project_root)
27 | 
28 | # Set environment variables for DaVinci Resolve scripting
29 | RESOLVE_API_PATH = "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
30 | RESOLVE_LIB_PATH = "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
31 | RESOLVE_MODULES_PATH = os.path.join(RESOLVE_API_PATH, "Modules")
32 | 
33 | os.environ["RESOLVE_SCRIPT_API"] = RESOLVE_API_PATH
34 | os.environ["RESOLVE_SCRIPT_LIB"] = RESOLVE_LIB_PATH
35 | sys.path.append(RESOLVE_MODULES_PATH)
36 | 
37 | # Import the timeline_operations module from the project
38 | from src.api.timeline_operations import add_marker
39 | 
40 | # Import DaVinci Resolve scripting
41 | import DaVinciResolveScript as dvr_script
42 | 
43 | def main():
44 |     """Main function to test marker placement at different frames."""
45 |     # Connect to Resolve
46 |     resolve = dvr_script.scriptapp("Resolve")
47 |     if not resolve:
48 |         print("Error: Could not connect to DaVinci Resolve")
49 |         sys.exit(1)
50 | 
51 |     print(f"Connected to {resolve.GetProductName()} {resolve.GetVersionString()}")
52 |     print("Testing marker placement at different frames...")
53 | 
54 |     # Display current timeline information
55 |     project_manager = resolve.GetProjectManager()
56 |     current_project = project_manager.GetCurrentProject()
57 |     if not current_project:
58 |         print("Error: No project is currently open")
59 |         sys.exit(1)
60 |         
61 |     current_timeline = current_project.GetCurrentTimeline()
62 |     if not current_timeline:
63 |         print("Error: No timeline is currently open")
64 |         sys.exit(1)
65 |         
66 |     print(f"Current timeline: {current_timeline.GetName()}")
67 |     print(f"Timeline duration: {current_timeline.GetEndFrame()} frames")
68 | 
69 |     # Test with different frames
70 |     # None = auto-selected frame, others are specific frame positions
71 |     test_frames = [None, 86450, 87000, 88000, 89000, 90000]
72 |     
73 |     for frame in test_frames:
74 |         note = f"Test marker at {'auto-selected' if frame is None else frame}"
75 |         color = "Green" if frame is None else "Blue"
76 |         
77 |         print(f"\nAttempting to add {color} marker at frame={frame or 'auto'} with note: '{note}'")
78 |         result = add_marker(resolve, frame, color, note)
79 |         print(f"Result: {result}")
80 |         
81 |         # Small delay between operations
82 |         time.sleep(0.5)
83 | 
84 |     print("\nMarker testing completed successfully!")
85 | 
86 | if __name__ == "__main__":
87 |     main() 
```

--------------------------------------------------------------------------------
/docs/PROJECT_MCP_SETUP.md:
--------------------------------------------------------------------------------

```markdown
  1 | # Project-Specific DaVinci Resolve Integration with Cursor
  2 | 
  3 | This guide explains how to set up project-specific DaVinci Resolve integration with Cursor using MCP.
  4 | 
  5 | ## Overview
  6 | 
  7 | Project-specific integration allows Cursor to interact with a specific DaVinci Resolve project automatically. When you open a Cursor project, it can automatically connect to a matching DaVinci Resolve project.
  8 | 
  9 | ## Setup Steps
 10 | 
 11 | ### 1. Copy the Template
 12 | 
 13 | Create a new file called `mcp.json` in your Cursor project's root directory (not in the `.cursor` folder). Copy the contents from `mcp-project-template.json`:
 14 | 
 15 | ```json
 16 | {
 17 |   "mcpServers": {
 18 |     "davinci-resolve": {
 19 |       "name": "DaVinci Resolve Project-Specific",
 20 |       "command": "${PROJECT_ROOT}/mcp_resolve-cursor_start",
 21 |       "args": ["--project", "${PROJECT_NAME}"]
 22 |     }
 23 |   }
 24 | }
 25 | ```
 26 | 
 27 | ### 2. Copy the Script
 28 | 
 29 | Copy the `mcp_resolve-cursor_start` script to your project root:
 30 | 
 31 | ```bash
 32 | cp /path/to/davinci-resolve-mcp-20250326/mcp_resolve-cursor_start /path/to/your/project/
 33 | ```
 34 | 
 35 | Also copy the `run-direct-server.sh` and `direct_resolve_server.py` files:
 36 | 
 37 | ```bash
 38 | cp /path/to/davinci-resolve-mcp-20250326/run-direct-server.sh /path/to/your/project/
 39 | cp /path/to/davinci-resolve-mcp-20250326/direct_resolve_server.py /path/to/your/project/
 40 | ```
 41 | 
 42 | Make them executable:
 43 | 
 44 | ```bash
 45 | chmod +x /path/to/your/project/mcp_resolve-cursor_start
 46 | chmod +x /path/to/your/project/run-direct-server.sh
 47 | chmod +x /path/to/your/project/direct_resolve_server.py
 48 | ```
 49 | 
 50 | ### 3. Create a Python Virtual Environment
 51 | 
 52 | ```bash
 53 | cd /path/to/your/project/
 54 | python -m venv venv
 55 | source venv/bin/activate
 56 | pip install jsonrpcserver
 57 | ```
 58 | 
 59 | ### 4. Modify Variable Replacement
 60 | 
 61 | By default, Cursor will replace:
 62 | - `${PROJECT_ROOT}` with the absolute path to your project
 63 | - `${PROJECT_NAME}` with the name of your project folder
 64 | 
 65 | If your DaVinci Resolve project has a different name than your Cursor project folder, you'll need to manually edit the `mcp.json` file in your project to specify the correct project name:
 66 | 
 67 | ```json
 68 | {
 69 |   "mcpServers": {
 70 |     "davinci-resolve": {
 71 |       "name": "DaVinci Resolve Project-Specific",
 72 |       "command": "${PROJECT_ROOT}/mcp_resolve-cursor_start",
 73 |       "args": ["--project", "Your DaVinci Resolve Project Name"]
 74 |     }
 75 |   }
 76 | }
 77 | ```
 78 | 
 79 | ## Troubleshooting
 80 | 
 81 | 1. **Make sure DaVinci Resolve is running** before you start Cursor or open your project.
 82 | 
 83 | 2. **Check the log files** for errors:
 84 |    - `cursor_resolve_server.log` - Created by the startup script
 85 |    - `resolve_direct_server.log` - Created by the direct server
 86 | 
 87 | 3. **Verify project exists** - Make sure the project name specified in your `mcp.json` exists in DaVinci Resolve.
 88 | 
 89 | 4. **Permission issues** - Ensure all scripts are executable and have the right permissions.
 90 | 
 91 | 5. **Test manually** by running:
 92 |    ```bash
 93 |    cd /path/to/your/project/
 94 |    ./mcp_resolve-cursor_start --project "Your Project Name"
 95 |    ```
 96 | 
 97 | ## Advanced Configuration
 98 | 
 99 | If you need additional arguments or setup for your project integration, you can modify:
100 | 
101 | 1. The `mcp.json` file in your project to add more arguments
102 | 2. The `mcp_resolve-cursor_start` script to include custom setup steps
103 | 
104 | ## Support
105 | 
106 | For further assistance, please refer to the main documentation or reach out to the development team. 
```

--------------------------------------------------------------------------------
/examples/getting_started.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | Getting Started Example for DaVinci Resolve MCP
  4 | 
  5 | This example demonstrates the basics of connecting to DaVinci Resolve via MCP.
  6 | It shows how to:
  7 | 1. Check if DaVinci Resolve is running
  8 | 2. Get the current project information
  9 | 3. List available timelines
 10 | 4. Get the current page
 11 | 
 12 | Prerequisites:
 13 | - DaVinci Resolve must be running
 14 | - The MCP server must be properly set up
 15 | - A project should be open in DaVinci Resolve
 16 | """
 17 | 
 18 | import os
 19 | import sys
 20 | import json
 21 | import time
 22 | from mcp.client import Client
 23 | 
 24 | # Connect to the MCP server
 25 | def connect_to_mcp_server():
 26 |     """Connect to the MCP server and return the client."""
 27 |     print("Connecting to DaVinci Resolve MCP server...")
 28 |     client = Client()
 29 |     client.connect_to_local_server("DaVinciResolveMCP")
 30 |     return client
 31 | 
 32 | # Get DaVinci Resolve version
 33 | def get_resolve_version(client):
 34 |     """Get the version of DaVinci Resolve."""
 35 |     print("\n--- DaVinci Resolve Version ---")
 36 |     response = client.resource("resolve://version")
 37 |     print(f"DaVinci Resolve Version: {response}")
 38 |     return response
 39 | 
 40 | # Get current page
 41 | def get_current_page(client):
 42 |     """Get the current page in DaVinci Resolve (Edit, Color, etc.)."""
 43 |     print("\n--- Current Page ---")
 44 |     response = client.resource("resolve://current-page")
 45 |     print(f"Current Page: {response}")
 46 |     return response
 47 | 
 48 | # List projects
 49 | def list_projects(client):
 50 |     """List all available projects in DaVinci Resolve."""
 51 |     print("\n--- Available Projects ---")
 52 |     response = client.resource("resolve://projects")
 53 |     
 54 |     if isinstance(response, list):
 55 |         if len(response) > 0:
 56 |             for i, project in enumerate(response, 1):
 57 |                 print(f"{i}. {project}")
 58 |         else:
 59 |             print("No projects found.")
 60 |     else:
 61 |         print(f"Error: {response}")
 62 |     
 63 |     return response
 64 | 
 65 | # Get current project
 66 | def get_current_project(client):
 67 |     """Get the name of the currently open project."""
 68 |     print("\n--- Current Project ---")
 69 |     response = client.resource("resolve://current-project")
 70 |     print(f"Current Project: {response}")
 71 |     return response
 72 | 
 73 | # List timelines
 74 | def list_timelines(client):
 75 |     """List all timelines in the current project."""
 76 |     print("\n--- Available Timelines ---")
 77 |     response = client.resource("resolve://timelines")
 78 |     
 79 |     if isinstance(response, list):
 80 |         if len(response) > 0:
 81 |             for i, timeline in enumerate(response, 1):
 82 |                 print(f"{i}. {timeline}")
 83 |         else:
 84 |             print("No timelines found.")
 85 |     else:
 86 |         print(f"Error: {response}")
 87 |     
 88 |     return response
 89 | 
 90 | # Main function
 91 | def main():
 92 |     """Main function to demonstrate basic DaVinci Resolve MCP functionality."""
 93 |     try:
 94 |         # Connect to the MCP server
 95 |         client = connect_to_mcp_server()
 96 |         print("Connected to MCP server!")
 97 |         
 98 |         # Get DaVinci Resolve version
 99 |         get_resolve_version(client)
100 |         
101 |         # Get current page
102 |         get_current_page(client)
103 |         
104 |         # List projects
105 |         list_projects(client)
106 |         
107 |         # Get current project
108 |         get_current_project(client)
109 |         
110 |         # List timelines
111 |         list_timelines(client)
112 |         
113 |         print("\nGetting Started Example completed successfully!")
114 |         
115 |     except Exception as e:
116 |         print(f"Error: {str(e)}")
117 |         print("\nTroubleshooting tips:")
118 |         print("1. Make sure DaVinci Resolve is running")
119 |         print("2. Check that the MCP server is running (`./run-now.sh`)")
120 |         print("3. Ensure a project is open in DaVinci Resolve")
121 |         print("4. Check environment variables are set correctly")
122 |         return 1
123 |     
124 |     return 0
125 | 
126 | if __name__ == "__main__":
127 |     sys.exit(main()) 
```

--------------------------------------------------------------------------------
/src/api/project_operations.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | DaVinci Resolve Project Operations
  4 | """
  5 | 
  6 | import logging
  7 | from typing import List, Dict, Any
  8 | 
  9 | logger = logging.getLogger("davinci-resolve-mcp.project")
 10 | 
 11 | def list_projects(resolve) -> List[str]:
 12 |     """List all available projects in the current database."""
 13 |     if resolve is None:
 14 |         return ["Error: Not connected to DaVinci Resolve"]
 15 |     
 16 |     project_manager = resolve.GetProjectManager()
 17 |     if not project_manager:
 18 |         return ["Error: Failed to get Project Manager"]
 19 |     
 20 |     projects = project_manager.GetProjectListInCurrentFolder()
 21 |     
 22 |     # Filter out any empty strings that might be in the list
 23 |     return [p for p in projects if p]
 24 | 
 25 | def get_current_project_name(resolve) -> str:
 26 |     """Get the name of the currently open project."""
 27 |     if resolve is None:
 28 |         return "Error: Not connected to DaVinci Resolve"
 29 |     
 30 |     project_manager = resolve.GetProjectManager()
 31 |     if not project_manager:
 32 |         return "Error: Failed to get Project Manager"
 33 |     
 34 |     current_project = project_manager.GetCurrentProject()
 35 |     if not current_project:
 36 |         return "No project currently open"
 37 |     
 38 |     return current_project.GetName()
 39 | 
 40 | def open_project(resolve, name: str) -> str:
 41 |     """Open a project by name."""
 42 |     if resolve is None:
 43 |         return "Error: Not connected to DaVinci Resolve"
 44 |     
 45 |     if not name:
 46 |         return "Error: Project name cannot be empty"
 47 |     
 48 |     project_manager = resolve.GetProjectManager()
 49 |     if not project_manager:
 50 |         return "Error: Failed to get Project Manager"
 51 |     
 52 |     # Check if project exists
 53 |     projects = project_manager.GetProjectListInCurrentFolder()
 54 |     if name not in projects:
 55 |         return f"Error: Project '{name}' not found. Available projects: {', '.join(projects)}"
 56 |     
 57 |     result = project_manager.LoadProject(name)
 58 |     if result:
 59 |         return f"Successfully opened project '{name}'"
 60 |     else:
 61 |         return f"Failed to open project '{name}'"
 62 | 
 63 | def create_project(resolve, name: str) -> str:
 64 |     """Create a new project with the given name."""
 65 |     if resolve is None:
 66 |         return "Error: Not connected to DaVinci Resolve"
 67 |     
 68 |     if not name:
 69 |         return "Error: Project name cannot be empty"
 70 |     
 71 |     project_manager = resolve.GetProjectManager()
 72 |     if not project_manager:
 73 |         return "Error: Failed to get Project Manager"
 74 |     
 75 |     # Check if project already exists
 76 |     projects = project_manager.GetProjectListInCurrentFolder()
 77 |     if name in projects:
 78 |         return f"Error: Project '{name}' already exists"
 79 |     
 80 |     result = project_manager.CreateProject(name)
 81 |     if result:
 82 |         return f"Successfully created project '{name}'"
 83 |     else:
 84 |         return f"Failed to create project '{name}'"
 85 | 
 86 | def save_project(resolve) -> str:
 87 |     """Save the current project."""
 88 |     if resolve is None:
 89 |         return "Error: Not connected to DaVinci Resolve"
 90 |     
 91 |     project_manager = resolve.GetProjectManager()
 92 |     if not project_manager:
 93 |         return "Error: Failed to get Project Manager"
 94 |     
 95 |     current_project = project_manager.GetCurrentProject()
 96 |     if not current_project:
 97 |         return "Error: No project currently open"
 98 |     
 99 |     # DaVinci Resolve auto-saves projects, but we can perform an operation
100 |     # that forces a save, like creating a temp timeline and then removing it
101 |     project_name = current_project.GetName()
102 |     try:
103 |         # Get media pool to trigger a save indirectly
104 |         media_pool = current_project.GetMediaPool()
105 |         if not media_pool:
106 |             return "Project is likely already saved (auto-save enabled)"
107 |             
108 |         # Another approach: DaVinci Resolve auto-saves, so we can just confirm the project exists
109 |         return f"Project '{project_name}' is saved (auto-save enabled in DaVinci Resolve)"
110 |     except Exception as e:
111 |         return f"Error checking project: {str(e)}" 
```

--------------------------------------------------------------------------------
/scripts/resolve_mcp_server.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | DaVinci Resolve MCP Server
  4 | A server that connects to DaVinci Resolve via the Model Context Protocol (MCP)
  5 | """
  6 | 
  7 | import os
  8 | import sys
  9 | import logging
 10 | from typing import List, Dict, Any, Optional
 11 | from mcp.server.fastmcp import FastMCP
 12 | 
 13 | # Configure logging
 14 | logging.basicConfig(
 15 |     level=logging.INFO,
 16 |     format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
 17 |     handlers=[logging.StreamHandler()]
 18 | )
 19 | logger = logging.getLogger("davinci-resolve-mcp")
 20 | 
 21 | # Create MCP server instance
 22 | mcp = FastMCP("DaVinciResolveMCP")
 23 | 
 24 | # Initialize connection to DaVinci Resolve
 25 | def initialize_resolve():
 26 |     """Initialize connection to DaVinci Resolve application."""
 27 |     try:
 28 |         # Import the DaVinci Resolve scripting module
 29 |         import DaVinciResolveScript as dvr_script
 30 |         
 31 |         # Get the resolve object
 32 |         resolve = dvr_script.scriptapp("Resolve")
 33 |         
 34 |         if resolve is None:
 35 |             logger.error("Failed to get Resolve object. Is DaVinci Resolve running?")
 36 |             return None
 37 |         
 38 |         logger.info(f"Connected to DaVinci Resolve: {resolve.GetProductName()} {resolve.GetVersionString()}")
 39 |         return resolve
 40 |     
 41 |     except ImportError:
 42 |         logger.error("Failed to import DaVinciResolveScript. Check environment variables.")
 43 |         logger.error("RESOLVE_SCRIPT_API, RESOLVE_SCRIPT_LIB, and PYTHONPATH must be set correctly.")
 44 |         logger.error("On macOS, typically:")
 45 |         logger.error('export RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"')
 46 |         logger.error('export RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"')
 47 |         logger.error('export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"')
 48 |         return None
 49 |     
 50 |     except Exception as e:
 51 |         logger.error(f"Unexpected error initializing Resolve: {str(e)}")
 52 |         return None
 53 | 
 54 | # Initialize Resolve once at startup
 55 | resolve = initialize_resolve()
 56 | 
 57 | # ------------------
 58 | # MCP Tools/Resources
 59 | # ------------------
 60 | 
 61 | @mcp.resource("resolve://version")
 62 | def get_resolve_version() -> str:
 63 |     """Get DaVinci Resolve version information."""
 64 |     if resolve is None:
 65 |         return "Error: Not connected to DaVinci Resolve"
 66 |     return f"{resolve.GetProductName()} {resolve.GetVersionString()}"
 67 | 
 68 | @mcp.resource("resolve://current-page")
 69 | def get_current_page() -> str:
 70 |     """Get the current page open in DaVinci Resolve (Edit, Color, Fusion, etc.)."""
 71 |     if resolve is None:
 72 |         return "Error: Not connected to DaVinci Resolve"
 73 |     return resolve.GetCurrentPage()
 74 | 
 75 | @mcp.tool()
 76 | def switch_page(page: str) -> str:
 77 |     """Switch to a specific page in DaVinci Resolve.
 78 |     
 79 |     Args:
 80 |         page: The page to switch to. Options: 'media', 'cut', 'edit', 'fusion', 'color', 'fairlight', 'deliver'
 81 |     """
 82 |     if resolve is None:
 83 |         return "Error: Not connected to DaVinci Resolve"
 84 |     
 85 |     valid_pages = ['media', 'cut', 'edit', 'fusion', 'color', 'fairlight', 'deliver']
 86 |     page = page.lower()
 87 |     
 88 |     if page not in valid_pages:
 89 |         return f"Error: Invalid page. Choose from {', '.join(valid_pages)}"
 90 |     
 91 |     resolve.OpenPage(page.capitalize())
 92 |     return f"Successfully switched to {page} page"
 93 | 
 94 | # Start the server
 95 | if __name__ == "__main__":
 96 |     try:
 97 |         if resolve is None:
 98 |             logger.error("Server started but not connected to DaVinci Resolve.")
 99 |             logger.error("Make sure DaVinci Resolve is running and environment variables are correctly set.")
100 |         else:
101 |             logger.info("Successfully connected to DaVinci Resolve.")
102 |         
103 |         logger.info("Starting DaVinci Resolve MCP Server")
104 |         mcp.run()
105 |     except KeyboardInterrupt:
106 |         logger.info("Server shutdown requested")
107 |     except Exception as e:
108 |         logger.error(f"Server error: {str(e)}")
109 |         sys.exit(1)
110 | 
```

--------------------------------------------------------------------------------
/docs/TOOLS_README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # DaVinci Resolve MCP Server Tools
  2 | 
  3 | This directory contains utilities for working with the DaVinci Resolve MCP Server:
  4 | 
  5 | - **benchmark_server.py**: Performance testing tool
  6 | - **batch_automation.py**: Workflow automation script
  7 | - **sample_config.json**: Example configuration file
  8 | 
  9 | ## Benchmark Server
 10 | 
 11 | The benchmarking tool measures MCP server performance and reliability, helping identify bottlenecks and verify improvements.
 12 | 
 13 | ### Features
 14 | 
 15 | - Measures response time for various operations
 16 | - Tracks success rates across multiple iterations
 17 | - Provides statistical analysis (min/max/avg/median/std dev)
 18 | - Monitors resource usage (memory, CPU, threads)
 19 | - Generates detailed logs and JSON reports
 20 | 
 21 | ### Usage
 22 | 
 23 | ```bash
 24 | python benchmark_server.py [--iterations=N] [--delay=SECONDS]
 25 | ```
 26 | 
 27 | ### Requirements
 28 | 
 29 | - DaVinci Resolve must be running with a project open
 30 | - DaVinci Resolve MCP Server must be running
 31 | - Python packages: `requests`, `psutil` (install with `pip install requests psutil`)
 32 | 
 33 | ### Output
 34 | 
 35 | The tool generates:
 36 | 1. A timestamped log file (`mcp_benchmark_*.log`)
 37 | 2. A JSON results file (`benchmark_results_*.json`)
 38 | 3. Console output with summary statistics
 39 | 
 40 | ### Example Output
 41 | 
 42 | ```
 43 | BENCHMARK SUMMARY
 44 | ==================================================
 45 | Overall average response time: 154.32ms
 46 | Overall success rate: 97.5%
 47 | 
 48 | Operations ranked by speed (fastest first):
 49 |   Switch to Edit Page: 98.45ms
 50 |   Get Current Page: 102.78ms
 51 |   List Timelines: 142.33ms
 52 |   Project Settings - String: 188.92ms
 53 |   Project Settings - Integer: 192.56ms
 54 |   Clear Render Queue: 200.91ms
 55 | 
 56 | Resource usage change during benchmark:
 57 |   Memory: 5.24MB
 58 |   CPU: 2.3%
 59 |   threads: 0
 60 |   connections: 1
 61 | ==================================================
 62 | ```
 63 | 
 64 | ## Batch Automation
 65 | 
 66 | The batch automation script demonstrates how to automate common DaVinci Resolve workflows using the MCP server.
 67 | 
 68 | ### Available Workflows
 69 | 
 70 | - **color_grade**: Apply basic color grading to all clips
 71 | - **render_timeline**: Render a timeline with specific settings
 72 | - **organize_media**: Organize media into bins by type
 73 | 
 74 | ### Usage
 75 | 
 76 | ```bash
 77 | python batch_automation.py [--workflow=NAME] [--config=FILE]
 78 | ```
 79 | 
 80 | Where:
 81 | - `--workflow` is one of: `color_grade`, `render_timeline`, `organize_media`
 82 | - `--config` is an optional path to a JSON configuration file
 83 | 
 84 | ### Configuration
 85 | 
 86 | You can customize workflows by providing a JSON configuration file. See `sample_config.json` for an example.
 87 | 
 88 | Key configuration options:
 89 | - `project_name`: Name of the project to create or open
 90 | - `timeline_name`: Name of the timeline to use
 91 | - `media_files`: Array of file paths to import
 92 | - `render_preset`: Render preset to use
 93 | - Various settings for color correction, project settings, etc.
 94 | 
 95 | ### Example Workflow: Color Grade
 96 | 
 97 | This workflow:
 98 | 1. Creates or opens a project
 99 | 2. Creates a timeline
100 | 3. Imports media files (if specified)
101 | 4. Switches to the color page
102 | 5. Adds a primary correction node with warm midtones
103 | 6. Adds a contrast node
104 | 7. Saves the project
105 | 
106 | ### Example Workflow: Render Timeline
107 | 
108 | This workflow:
109 | 1. Creates or opens a project
110 | 2. Creates or selects a timeline
111 | 3. Imports media (for new timelines only)
112 | 4. Sets project settings
113 | 5. Switches to the deliver page
114 | 6. Clears the render queue
115 | 7. Adds the timeline to the render queue
116 | 8. Starts rendering
117 | 
118 | ### Extending
119 | 
120 | You can create new workflows by adding methods to the `WorkflowManager` class:
121 | 
122 | ```python
123 | def run_workflow_custom(self) -> None:
124 |     """My custom workflow."""
125 |     # Implement workflow steps here
126 |     # ...
127 |     
128 | # Then add it to the workflows dictionary:
129 | workflows = {
130 |     "color_grade": self.run_workflow_color_grade,
131 |     "render_timeline": self.run_workflow_render_timeline,
132 |     "organize_media": self.run_workflow_organize_media,
133 |     "custom": self.run_workflow_custom
134 | }
135 | ```
136 | 
137 | ## Best Practices
138 | 
139 | - Always test workflows with sample data before using with production content
140 | - Keep DaVinci Resolve open and with a project loaded before running tools
141 | - Check the MCP server logs if operations fail
142 | - Use the benchmark tool to identify slow operations
143 | - Consider adding delays between operations if reliability issues occur
144 | - Review logs after automation runs to identify any issues 
```

--------------------------------------------------------------------------------
/scripts/verify-installation.bat:
--------------------------------------------------------------------------------

```
  1 | @echo off
  2 | REM verify-installation.bat
  3 | REM Script to verify that the DaVinci Resolve MCP installation has been properly set up
  4 | 
  5 | title DaVinci Resolve MCP Installation Verification
  6 | 
  7 | REM Colors for terminal output
  8 | set GREEN=[92m
  9 | set YELLOW=[93m
 10 | set BLUE=[94m
 11 | set RED=[91m
 12 | set NC=[0m
 13 | 
 14 | REM Get the script directory and project root
 15 | set "SCRIPT_DIR=%~dp0"
 16 | set "PROJECT_ROOT=%SCRIPT_DIR%.."
 17 | set "VENV_DIR=%PROJECT_ROOT%\venv"
 18 | 
 19 | echo %BLUE%===============================================%NC%
 20 | echo %BLUE%  DaVinci Resolve MCP Installation Verification  %NC%
 21 | echo %BLUE%===============================================%NC%
 22 | 
 23 | REM Check if virtual environment exists
 24 | echo %YELLOW%Checking Python virtual environment... %NC%
 25 | if exist "%VENV_DIR%\Scripts\python.exe" (
 26 |     echo %GREEN%OK%NC%
 27 |     set /a "venv_check=1"
 28 | ) else (
 29 |     echo %RED%MISSING%NC%
 30 |     echo %RED%Virtual environment not found at: %VENV_DIR%%NC%
 31 |     set /a "venv_check=0"
 32 | )
 33 | 
 34 | REM Check if MCP SDK is installed
 35 | echo %YELLOW%Checking MCP SDK installation... %NC%
 36 | "%VENV_DIR%\Scripts\pip" list | findstr "mcp" > nul
 37 | if %ERRORLEVEL% == 0 (
 38 |     echo %GREEN%OK%NC%
 39 |     set /a "mcp_check=1"
 40 | ) else (
 41 |     echo %RED%MISSING%NC%
 42 |     echo %RED%MCP SDK not installed in the virtual environment%NC%
 43 |     set /a "mcp_check=0"
 44 | )
 45 | 
 46 | REM Check if Resolve MCP server script exists
 47 | echo %YELLOW%Checking server script... %NC%
 48 | if exist "%PROJECT_ROOT%\src\resolve_mcp_server.py" (
 49 |     echo %GREEN%OK%NC%
 50 |     set /a "script_check=1"
 51 | ) else (
 52 |     echo %RED%MISSING%NC%
 53 |     echo %RED%Server script not found at: %PROJECT_ROOT%\src\resolve_mcp_server.py%NC%
 54 |     set /a "script_check=0"
 55 | )
 56 | 
 57 | REM Check if DaVinci Resolve is running
 58 | echo %YELLOW%Checking if DaVinci Resolve is running... %NC%
 59 | tasklist /FI "IMAGENAME eq Resolve.exe" 2>NUL | find /I /N "Resolve.exe">NUL
 60 | if %ERRORLEVEL% == 0 (
 61 |     echo %GREEN%OK%NC%
 62 |     set /a "resolve_check=1"
 63 | ) else (
 64 |     echo %RED%NOT RUNNING%NC%
 65 |     echo %RED%DaVinci Resolve is not running - please start it%NC%
 66 |     set /a "resolve_check=0"
 67 | )
 68 | 
 69 | REM Check Cursor MCP configuration
 70 | echo %YELLOW%Checking Cursor MCP configuration... %NC%
 71 | set "CURSOR_CONFIG_FILE=%APPDATA%\Cursor\mcp\config.json"
 72 | if exist "%CURSOR_CONFIG_FILE%" (
 73 |     findstr "davinci-resolve" "%CURSOR_CONFIG_FILE%" > nul
 74 |     if %ERRORLEVEL% == 0 (
 75 |         echo %GREEN%OK%NC%
 76 |         echo %GREEN%Cursor MCP config found at: %CURSOR_CONFIG_FILE%%NC%
 77 |         set /a "cursor_check=1"
 78 |     ) else (
 79 |         echo %RED%INVALID%NC%
 80 |         echo %RED%Cursor MCP config does not contain 'davinci-resolve' entry%NC%
 81 |         set /a "cursor_check=0"
 82 |     )
 83 | ) else (
 84 |     echo %RED%MISSING%NC%
 85 |     echo %RED%Cursor MCP config not found at: %CURSOR_CONFIG_FILE%%NC%
 86 |     set /a "cursor_check=0"
 87 | )
 88 | 
 89 | REM Check if all environment variables are set
 90 | echo %YELLOW%Checking environment variables... %NC%
 91 | set /a "env_vars_missing=0"
 92 | 
 93 | if "%RESOLVE_SCRIPT_API%"=="" (
 94 |     set /a "env_vars_missing=1"
 95 | )
 96 | 
 97 | if "%RESOLVE_SCRIPT_LIB%"=="" (
 98 |     set /a "env_vars_missing=1"
 99 | )
100 | 
101 | if "%PYTHONPATH%"=="" (
102 |     set /a "env_vars_missing=1"
103 | ) else (
104 |     echo %PYTHONPATH% | findstr "Modules" > nul
105 |     if %ERRORLEVEL% NEQ 0 (
106 |         set /a "env_vars_missing=1"
107 |     )
108 | )
109 | 
110 | if %env_vars_missing% == 0 (
111 |     echo %GREEN%OK%NC%
112 |     set /a "env_check=1"
113 | ) else (
114 |     echo %RED%MISSING%NC%
115 |     echo %RED%One or more required environment variables are not set%NC%
116 |     set /a "env_check=0"
117 | )
118 | 
119 | REM Calculate total checks passed
120 | set /a "total_checks=6"
121 | set /a "passed_checks=venv_check+mcp_check+script_check+resolve_check+cursor_check+env_check"
122 | 
123 | echo %BLUE%=============================================%NC%
124 | echo %YELLOW%Results: %passed_checks%/%total_checks% checks passed%NC%
125 | 
126 | if %passed_checks% == %total_checks% (
127 |     echo %GREEN%[✓] Installation verification completed successfully!%NC%
128 |     echo %GREEN%[✓] You can now use the MCP server with DaVinci Resolve%NC%
129 |     echo %YELLOW%To start the server, run:%NC%
130 |     echo %BLUE%  run-now.bat%NC%
131 |     echo %YELLOW%Or for more options:%NC%
132 |     echo %BLUE%  scripts\mcp_resolve-cursor_start%NC%
133 |     exit /b 0
134 | ) else (
135 |     echo %RED%[✗] Installation verification failed!%NC%
136 |     echo %YELLOW%Please fix the issues above and run this script again%NC%
137 |     exit /b 1
138 | ) 
```

--------------------------------------------------------------------------------
/scripts/run-now.bat:
--------------------------------------------------------------------------------

```
  1 | @echo off
  2 | REM Quick Start Script for DaVinci Resolve MCP Server (Windows Version)
  3 | REM This script sets up the environment and starts the MCP server
  4 | 
  5 | echo ==============================================
  6 | echo   DaVinci Resolve MCP Server - Quick Start   
  7 | echo ==============================================
  8 | echo.
  9 | 
 10 | REM Get the script directory and root directory (using absolute paths)
 11 | set SCRIPT_DIR=%~dp0
 12 | set ROOT_DIR=%SCRIPT_DIR%..
 13 | echo Project root: %ROOT_DIR%
 14 | 
 15 | set VENV_DIR=%ROOT_DIR%venv
 16 | set RESOLVE_MCP_SERVER=%ROOT_DIR%src\resolve_mcp_server.py
 17 | 
 18 | REM Check if Python is installed
 19 | where python >nul 2>nul
 20 | if %ERRORLEVEL% NEQ 0 (
 21 |     echo Python is not installed or not in your PATH
 22 |     echo Please install Python 3.6+ from https://www.python.org/downloads/
 23 |     echo Make sure to check "Add Python to PATH" during installation
 24 |     pause
 25 |     exit /b 1
 26 | )
 27 | 
 28 | REM Check if Node.js/npm is installed (warning only)
 29 | where npm >nul 2>nul
 30 | if %ERRORLEVEL% NEQ 0 (
 31 |     echo WARNING: Node.js/npm is not installed or not in your PATH.
 32 |     echo This might cause some features to not work properly.
 33 |     echo You can install Node.js from https://nodejs.org/
 34 |     echo Make sure to check the option to add to PATH during installation.
 35 |     pause
 36 | )
 37 | 
 38 | REM Check if DaVinci Resolve is running - fixed process detection
 39 | echo Checking if DaVinci Resolve is running...
 40 | 
 41 | REM Simple check for Resolve process - avoid complex piping that causes syntax errors
 42 | tasklist /FI "IMAGENAME eq Resolve.exe" 2>nul | find /i "Resolve.exe" >nul
 43 | if not errorlevel 1 (
 44 |     echo DaVinci Resolve is running, continuing...
 45 |     goto :resolve_running
 46 | )
 47 | 
 48 | echo DaVinci Resolve is not running
 49 | echo Please start DaVinci Resolve before running this script
 50 | 
 51 | set /p START_RESOLVE="Would you like to try starting DaVinci Resolve now? (y/n): "
 52 | if /i not "%START_RESOLVE%"=="y" (
 53 |     echo DaVinci Resolve must be running for the MCP server to function properly
 54 |     pause
 55 |     exit /b 1
 56 | )
 57 | 
 58 | REM Try to start DaVinci Resolve
 59 | echo Attempting to start DaVinci Resolve...
 60 |     
 61 | if exist "C:\Program Files\Blackmagic Design\DaVinci Resolve\Resolve.exe" (
 62 |     echo Starting DaVinci Resolve from the correct path...
 63 |     start "" "C:\Program Files\Blackmagic Design\DaVinci Resolve\Resolve.exe"
 64 |     echo Waiting for DaVinci Resolve to start...
 65 |     timeout /t 15 /nobreak >nul
 66 |     echo DaVinci Resolve should be running now.
 67 | ) else (
 68 |     echo Could not find DaVinci Resolve executable at:
 69 |     echo C:\Program Files\Blackmagic Design\DaVinci Resolve\Resolve.exe
 70 |     echo Please start DaVinci Resolve manually
 71 |     pause
 72 |     exit /b 1
 73 | )
 74 | 
 75 | :resolve_running
 76 | REM Create virtual environment if it doesn't exist
 77 | if not exist "%VENV_DIR%\Scripts\python.exe" (
 78 |     echo Creating Python virtual environment...
 79 |     python -m venv "%VENV_DIR%"
 80 |     
 81 |     if %ERRORLEVEL% NEQ 0 (
 82 |         echo Failed to create virtual environment
 83 |         pause
 84 |         exit /b 1
 85 |     )
 86 | )
 87 | 
 88 | REM Check if requirements.txt exists
 89 | if not exist "%ROOT_DIR%\requirements.txt" (
 90 |     echo Error: Could not find requirements.txt at %ROOT_DIR%\requirements.txt
 91 |     pause
 92 |     exit /b 1
 93 | )
 94 | 
 95 | REM Install dependencies from requirements.txt
 96 | echo Installing dependencies from requirements.txt...
 97 | call "%VENV_DIR%\Scripts\pip" install -r "%ROOT_DIR%\requirements.txt"
 98 | 
 99 | REM Check if MCP CLI is installed
100 | if not exist "%VENV_DIR%\Scripts\mcp.exe" (
101 |     echo MCP command not found. Installing MCP[cli]...
102 |     call "%VENV_DIR%\Scripts\pip" install "mcp[cli]"
103 |     
104 |     if %ERRORLEVEL% NEQ 0 (
105 |         echo Failed to install MCP. Please check your internet connection and try again.
106 |         pause
107 |         exit /b 1
108 |     )
109 | )
110 | 
111 | REM Set environment variables
112 | echo Setting environment variables...
113 | set RESOLVE_SCRIPT_API=C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting
114 | set RESOLVE_SCRIPT_LIB=C:\Program Files\Blackmagic Design\DaVinci Resolve\fusionscript.dll
115 | set PYTHONPATH=%PYTHONPATH%;%RESOLVE_SCRIPT_API%\Modules
116 | 
117 | REM Save environment variables for user
118 | setx RESOLVE_SCRIPT_API "%RESOLVE_SCRIPT_API%" >nul
119 | setx RESOLVE_SCRIPT_LIB "%RESOLVE_SCRIPT_LIB%" >nul
120 | setx PYTHONPATH "%RESOLVE_SCRIPT_API%\Modules" >nul
121 | 
122 | REM Check if server script exists
123 | if not exist "%RESOLVE_MCP_SERVER%" (
124 |     echo Error: Server script not found at %RESOLVE_MCP_SERVER%
125 |     pause
126 |     exit /b 1
127 | )
128 | 
129 | REM Start the server
130 | echo Starting DaVinci Resolve MCP Server...
131 | echo Using server script: %RESOLVE_MCP_SERVER%
132 | echo.
133 | 
134 | cd "%ROOT_DIR%"
135 | "%VENV_DIR%\Scripts\mcp" dev "%RESOLVE_MCP_SERVER%"
136 | 
```

--------------------------------------------------------------------------------
/examples/media/import_folder.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | Script to import folder content, organize in a bin, and add to timeline
  4 | """
  5 | 
  6 | import os
  7 | import sys
  8 | import glob
  9 | 
 10 | # Set environment variables for DaVinci Resolve scripting
 11 | RESOLVE_API_PATH = "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
 12 | RESOLVE_LIB_PATH = "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
 13 | RESOLVE_MODULES_PATH = os.path.join(RESOLVE_API_PATH, "Modules")
 14 | 
 15 | os.environ["RESOLVE_SCRIPT_API"] = RESOLVE_API_PATH
 16 | os.environ["RESOLVE_SCRIPT_LIB"] = RESOLVE_LIB_PATH
 17 | 
 18 | # Add the module path to Python's path if it's not already there
 19 | if RESOLVE_MODULES_PATH not in sys.path:
 20 |     sys.path.append(RESOLVE_MODULES_PATH)
 21 | 
 22 | import DaVinciResolveScript as dvr_script
 23 | 
 24 | def main():
 25 |     # Source folder path
 26 |     source_folder = "/Users/samuelgursky/Desktop/20250326"
 27 |     bin_name = os.path.basename(source_folder)
 28 |     
 29 |     print(f"Importing from folder: {source_folder}")
 30 |     print(f"Creating bin: {bin_name}")
 31 |     
 32 |     # Connect to Resolve
 33 |     print("Connecting to DaVinci Resolve...")
 34 |     resolve = dvr_script.scriptapp("Resolve")
 35 |     if not resolve:
 36 |         print("Error: Failed to connect to DaVinci Resolve")
 37 |         return
 38 |     
 39 |     print(f"Connected to: {resolve.GetProductName()} {resolve.GetVersionString()}")
 40 |     
 41 |     # Get project manager and current project
 42 |     project_manager = resolve.GetProjectManager()
 43 |     if not project_manager:
 44 |         print("Error: Failed to get Project Manager")
 45 |         return
 46 |     
 47 |     current_project = project_manager.GetCurrentProject()
 48 |     if not current_project:
 49 |         print("Error: No project currently open")
 50 |         return
 51 |     
 52 |     print(f"Current project: {current_project.GetName()}")
 53 |     
 54 |     # Get media pool
 55 |     media_pool = current_project.GetMediaPool()
 56 |     if not media_pool:
 57 |         print("Error: Failed to get Media Pool")
 58 |         return
 59 |     
 60 |     # Create a bin for the imported content
 61 |     root_folder = media_pool.GetRootFolder()
 62 |     print(f"Creating bin '{bin_name}'...")
 63 |     
 64 |     # Check if bin already exists
 65 |     existing_bins = root_folder.GetSubFolderList()
 66 |     target_bin = None
 67 |     
 68 |     for bin in existing_bins:
 69 |         if bin.GetName() == bin_name:
 70 |             target_bin = bin
 71 |             print(f"Bin '{bin_name}' already exists, using it")
 72 |             break
 73 |     
 74 |     # Create the bin if it doesn't exist
 75 |     if not target_bin:
 76 |         target_bin = media_pool.AddSubFolder(root_folder, bin_name)
 77 |         if not target_bin:
 78 |             print(f"Failed to create bin '{bin_name}', using root folder")
 79 |             target_bin = root_folder
 80 |     
 81 |     # Set the bin as the active folder
 82 |     media_pool.SetCurrentFolder(target_bin)
 83 |     
 84 |     # Import media from the folder
 85 |     print(f"Importing media from {source_folder}...")
 86 |     
 87 |     # Find all media files in the folder
 88 |     media_extensions = [".mov", ".mp4", ".avi", ".mxf", ".wav", ".mp3", ".jpg", ".png", ".tif", ".exr"]
 89 |     media_files = []
 90 |     
 91 |     for ext in media_extensions:
 92 |         media_files.extend(glob.glob(os.path.join(source_folder, f"*{ext}")))
 93 |         media_files.extend(glob.glob(os.path.join(source_folder, f"*{ext.upper()}")))
 94 |     
 95 |     if not media_files:
 96 |         print(f"No media files found in {source_folder}")
 97 |         # Try importing the folder directly
 98 |         print("Trying to import the folder directly...")
 99 |         imported_clips = media_pool.ImportMedia([source_folder])
100 |         if not imported_clips or len(imported_clips) == 0:
101 |             print("Failed to import any media")
102 |             return
103 |     else:
104 |         print(f"Found {len(media_files)} media files")
105 |         imported_clips = media_pool.ImportMedia(media_files)
106 |         
107 |         if not imported_clips or len(imported_clips) == 0:
108 |             print("Failed to import media files")
109 |             return
110 |     
111 |     print(f"Successfully imported {len(imported_clips)} clips")
112 |     
113 |     # Create a new timeline named after the folder
114 |     timeline_name = f"{bin_name}_Timeline"
115 |     print(f"Creating timeline '{timeline_name}'...")
116 |     
117 |     timeline = media_pool.CreateEmptyTimeline(timeline_name)
118 |     if not timeline:
119 |         print(f"Failed to create timeline '{timeline_name}'")
120 |         return
121 |     
122 |     # Make sure the timeline is set as current
123 |     current_project.SetCurrentTimeline(timeline)
124 |     
125 |     # Add all imported clips to the timeline
126 |     print("Adding clips to timeline...")
127 |     result = media_pool.AppendToTimeline(imported_clips)
128 |     
129 |     if result and len(result) > 0:
130 |         print(f"Successfully added {len(result)} clips to timeline")
131 |     else:
132 |         print("Failed to add clips to timeline")
133 |     
134 |     print("Import process complete!")
135 | 
136 | if __name__ == "__main__":
137 |     main() 
```

--------------------------------------------------------------------------------
/tests/test_custom_timeline.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | DaVinci Resolve MCP Server Test Script for Custom Timeline Creation
  4 | ------------------------------------------------------------------
  5 | This script tests the enhanced CreateEmptyTimeline function with custom parameters.
  6 | 
  7 | Usage:
  8 |     python test_custom_timeline.py
  9 | 
 10 | Requirements:
 11 |     - DaVinci Resolve must be running with a project open
 12 |     - DaVinci Resolve MCP Server must be running (after restart)
 13 |     - requests module (pip install requests)
 14 | """
 15 | 
 16 | import sys
 17 | import time
 18 | import requests
 19 | import logging
 20 | from typing import Dict, Any
 21 | 
 22 | # Configure logging
 23 | logging.basicConfig(
 24 |     level=logging.INFO,
 25 |     format='%(asctime)s - %(levelname)s - %(message)s',
 26 |     handlers=[
 27 |         logging.FileHandler("custom_timeline_test.log"),
 28 |         logging.StreamHandler()
 29 |     ]
 30 | )
 31 | logger = logging.getLogger(__name__)
 32 | 
 33 | # Server configuration
 34 | SERVER_URL = "http://localhost:8000/api"
 35 | 
 36 | def send_request(tool_name: str, params: Dict[str, Any]) -> Dict[str, Any]:
 37 |     """Send a request to the MCP server."""
 38 |     try:
 39 |         payload = {
 40 |             "tool": tool_name,
 41 |             "params": params
 42 |         }
 43 |         logger.info(f"Sending request: {tool_name} with params {params}")
 44 |         response = requests.post(SERVER_URL, json=payload)
 45 |         response.raise_for_status()
 46 |         return response.json()
 47 |     except requests.exceptions.RequestException as e:
 48 |         logger.error(f"Request error: {e}")
 49 |         return {"success": False, "error": str(e)}
 50 | 
 51 | def test_basic_timeline_creation():
 52 |     """Test basic timeline creation."""
 53 |     logger.info("Testing basic timeline creation...")
 54 |     
 55 |     # Create a test timeline with default settings
 56 |     timeline_name = f"Basic_Test_Timeline_{int(time.time())}"
 57 |     result = send_request("mcp_davinci_resolve_create_timeline", {"name": timeline_name})
 58 |     
 59 |     if "error" in result and result.get("error"):
 60 |         logger.error(f"❌ Basic timeline creation failed: {result.get('error')}")
 61 |         return False
 62 |     else:
 63 |         logger.info(f"✅ Basic timeline created: {timeline_name}")
 64 |         return True
 65 | 
 66 | def test_custom_timeline_creation():
 67 |     """Test enhanced timeline creation with custom parameters."""
 68 |     logger.info("Testing custom timeline creation...")
 69 |     
 70 |     # Create a custom timeline with specific parameters
 71 |     timeline_name = f"Custom_Test_Timeline_{int(time.time())}"
 72 |     params = {
 73 |         "name": timeline_name,
 74 |         "frame_rate": "23.976",
 75 |         "resolution_width": 3840,
 76 |         "resolution_height": 2160,
 77 |         "start_timecode": "01:00:00:00"
 78 |     }
 79 |     
 80 |     result = send_request("mcp_davinci_resolve_create_empty_timeline", params)
 81 |     
 82 |     if "error" in result and result.get("error"):
 83 |         logger.error(f"❌ Custom timeline creation failed: {result.get('error')}")
 84 |         return False
 85 |     else:
 86 |         logger.info(f"✅ Custom timeline created with parameters: {params}")
 87 |         
 88 |         # Verify the timeline settings
 89 |         logger.info("Retrieving timeline info to verify settings...")
 90 |         
 91 |         # Switch to the created timeline
 92 |         switch_result = send_request("mcp_davinci_resolve_set_current_timeline", {"name": timeline_name})
 93 |         if "error" in switch_result and switch_result.get("error"):
 94 |             logger.error(f"❌ Failed to switch to timeline: {switch_result.get('error')}")
 95 |             return False
 96 |         
 97 |         # Get timeline info
 98 |         get_timeline_result = send_request("mcp_davinci_resolve_get_current_timeline", {})
 99 |         if "error" in get_timeline_result or not isinstance(get_timeline_result, dict):
100 |             logger.error(f"❌ Failed to get timeline info: {get_timeline_result}")
101 |             return False
102 |         
103 |         # Verify settings
104 |         resolution = get_timeline_result.get("resolution", {})
105 |         
106 |         logger.info(f"Timeline info: {get_timeline_result}")
107 |         logger.info(f"Resolution: {resolution}")
108 |         logger.info(f"Framerate: {get_timeline_result.get('framerate')}")
109 |         logger.info(f"Start timecode: {get_timeline_result.get('start_timecode')}")
110 |         
111 |         return True
112 | 
113 | def main():
114 |     """Run the timeline creation tests."""
115 |     logger.info("Starting DaVinci Resolve MCP custom timeline creation tests")
116 |     logger.info("=" * 60)
117 |     
118 |     # Run tests
119 |     basic_result = test_basic_timeline_creation()
120 |     custom_result = test_custom_timeline_creation()
121 |     
122 |     # Summary
123 |     logger.info("=" * 60)
124 |     logger.info(f"Basic timeline creation: {'✅ PASSED' if basic_result else '❌ FAILED'}")
125 |     logger.info(f"Custom timeline creation: {'✅ PASSED' if custom_result else '❌ FAILED'}")
126 |     logger.info("=" * 60)
127 |     
128 |     # Exit with appropriate code
129 |     if basic_result and custom_result:
130 |         logger.info("All tests passed!")
131 |         sys.exit(0)
132 |     else:
133 |         logger.error("Some tests failed. Check the logs for details.")
134 |         sys.exit(1)
135 | 
136 | if __name__ == "__main__":
137 |     main() 
```

--------------------------------------------------------------------------------
/scripts/verify-installation.sh:
--------------------------------------------------------------------------------

```bash
  1 | #!/bin/bash
  2 | # verify-installation.sh
  3 | # Script to verify that the DaVinci Resolve MCP installation has been properly set up
  4 | 
  5 | # Colors for terminal output
  6 | GREEN='\033[0;32m'
  7 | YELLOW='\033[0;33m'
  8 | BLUE='\033[0;34m'
  9 | RED='\033[0;31m'
 10 | NC='\033[0m' # No Color
 11 | 
 12 | # Get the script directory and project root
 13 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
 14 | PROJECT_ROOT="$( cd "$SCRIPT_DIR/.." &> /dev/null && pwd )"
 15 | VENV_DIR="$PROJECT_ROOT/venv"
 16 | 
 17 | echo -e "${BLUE}===============================================${NC}"
 18 | echo -e "${BLUE}  DaVinci Resolve MCP Installation Verification  ${NC}"
 19 | echo -e "${BLUE}===============================================${NC}"
 20 | 
 21 | # Check if virtual environment exists
 22 | check_venv() {
 23 |     echo -ne "${YELLOW}Checking Python virtual environment... ${NC}"
 24 |     if [ -d "$VENV_DIR" ] && [ -f "$VENV_DIR/bin/python" ]; then
 25 |         echo -e "${GREEN}OK${NC}"
 26 |         return 0
 27 |     else
 28 |         echo -e "${RED}MISSING${NC}"
 29 |         echo -e "${RED}Virtual environment not found at: $VENV_DIR${NC}"
 30 |         return 1
 31 |     fi
 32 | }
 33 | 
 34 | # Check if MCP SDK is installed
 35 | check_mcp_sdk() {
 36 |     echo -ne "${YELLOW}Checking MCP SDK installation... ${NC}"
 37 |     if "$VENV_DIR/bin/pip" list | grep -q "mcp"; then
 38 |         echo -e "${GREEN}OK${NC}"
 39 |         return 0
 40 |     else
 41 |         echo -e "${RED}MISSING${NC}"
 42 |         echo -e "${RED}MCP SDK not installed in the virtual environment${NC}"
 43 |         return 1
 44 |     fi
 45 | }
 46 | 
 47 | # Check if Resolve MCP server script exists
 48 | check_server_script() {
 49 |     echo -ne "${YELLOW}Checking server script... ${NC}"
 50 |     if [ -f "$PROJECT_ROOT/src/resolve_mcp_server.py" ]; then
 51 |         echo -e "${GREEN}OK${NC}"
 52 |         return 0
 53 |     else
 54 |         echo -e "${RED}MISSING${NC}"
 55 |         echo -e "${RED}Server script not found at: $PROJECT_ROOT/src/resolve_mcp_server.py${NC}"
 56 |         return 1
 57 |     fi
 58 | }
 59 | 
 60 | # Check if DaVinci Resolve is running
 61 | check_resolve_running() {
 62 |     echo -ne "${YELLOW}Checking if DaVinci Resolve is running... ${NC}"
 63 |     if ps -ef | grep -i "[D]aVinci Resolve" > /dev/null; then
 64 |         echo -e "${GREEN}OK${NC}"
 65 |         return 0
 66 |     else
 67 |         echo -e "${RED}NOT RUNNING${NC}"
 68 |         echo -e "${RED}DaVinci Resolve is not running - please start it${NC}"
 69 |         return 1
 70 |     fi
 71 | }
 72 | 
 73 | # Check Cursor MCP configuration
 74 | check_cursor_config() {
 75 |     echo -ne "${YELLOW}Checking Cursor MCP configuration... ${NC}"
 76 |     CURSOR_CONFIG_FILE="$HOME/.cursor/mcp/config.json"
 77 |     if [ -f "$CURSOR_CONFIG_FILE" ]; then
 78 |         if grep -q "davinci-resolve" "$CURSOR_CONFIG_FILE"; then
 79 |             echo -e "${GREEN}OK${NC}"
 80 |             echo -e "${GREEN}Cursor MCP config found at: $CURSOR_CONFIG_FILE${NC}"
 81 |             return 0
 82 |         else
 83 |             echo -e "${RED}INVALID${NC}"
 84 |             echo -e "${RED}Cursor MCP config does not contain 'davinci-resolve' entry${NC}"
 85 |             return 1
 86 |         fi
 87 |     else
 88 |         echo -e "${RED}MISSING${NC}"
 89 |         echo -e "${RED}Cursor MCP config not found at: $CURSOR_CONFIG_FILE${NC}"
 90 |         return 1
 91 |     fi
 92 | }
 93 | 
 94 | # Check if all environment variables are set
 95 | check_env_vars() {
 96 |     echo -ne "${YELLOW}Checking environment variables... ${NC}"
 97 |     local missing=0
 98 |     
 99 |     if [ -z "$RESOLVE_SCRIPT_API" ]; then
100 |         missing=1
101 |     fi
102 |     
103 |     if [ -z "$RESOLVE_SCRIPT_LIB" ]; then
104 |         missing=1
105 |     fi
106 |     
107 |     if [ -z "$PYTHONPATH" ] || ! echo "$PYTHONPATH" | grep -q "Modules"; then
108 |         missing=1
109 |     fi
110 |     
111 |     if [ $missing -eq 0 ]; then
112 |         echo -e "${GREEN}OK${NC}"
113 |         return 0
114 |     else
115 |         echo -e "${RED}MISSING${NC}"
116 |         echo -e "${RED}One or more required environment variables are not set${NC}"
117 |         return 1
118 |     fi
119 | }
120 | 
121 | # Run all checks
122 | run_all_checks() {
123 |     local passed=0
124 |     local total=0
125 |     
126 |     check_venv
127 |     if [ $? -eq 0 ]; then ((passed++)); fi
128 |     ((total++))
129 |     
130 |     check_mcp_sdk
131 |     if [ $? -eq 0 ]; then ((passed++)); fi
132 |     ((total++))
133 |     
134 |     check_server_script
135 |     if [ $? -eq 0 ]; then ((passed++)); fi
136 |     ((total++))
137 |     
138 |     check_resolve_running
139 |     if [ $? -eq 0 ]; then ((passed++)); fi
140 |     ((total++))
141 |     
142 |     check_cursor_config
143 |     if [ $? -eq 0 ]; then ((passed++)); fi
144 |     ((total++))
145 |     
146 |     check_env_vars
147 |     if [ $? -eq 0 ]; then ((passed++)); fi
148 |     ((total++))
149 |     
150 |     echo -e "${BLUE}=============================================${NC}"
151 |     echo -e "${YELLOW}Results: $passed/$total checks passed${NC}"
152 |     
153 |     if [ $passed -eq $total ]; then
154 |         echo -e "${GREEN}✓ Installation verification completed successfully!${NC}"
155 |         echo -e "${GREEN}✓ You can now use the MCP server with DaVinci Resolve${NC}"
156 |         echo -e "${YELLOW}To start the server, run:${NC}"
157 |         echo -e "${BLUE}  ./run-now.sh${NC}"
158 |         echo -e "${YELLOW}Or for more options:${NC}"
159 |         echo -e "${BLUE}  ./scripts/mcp_resolve-cursor_start${NC}"
160 |         return 0
161 |     else
162 |         echo -e "${RED}✗ Installation verification failed!${NC}"
163 |         echo -e "${YELLOW}Please fix the issues above and run this script again${NC}"
164 |         return 1
165 |     fi
166 | }
167 | 
168 | # Run the verification
169 | run_all_checks
170 | exit $? 
```

--------------------------------------------------------------------------------
/scripts/server.sh:
--------------------------------------------------------------------------------

```bash
  1 | #!/bin/bash
  2 | # Consolidated DaVinci Resolve MCP Server management script
  3 | # Usage: ./scripts/server.sh [start|stop|status|dev]
  4 | 
  5 | # Set current directory to project root
  6 | PROJECT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )/.." && pwd )"
  7 | cd "$PROJECT_ROOT"
  8 | 
  9 | # Define environment variables if not already set
 10 | if [ -z "$RESOLVE_SCRIPT_API" ]; then
 11 |     export RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
 12 | fi
 13 | 
 14 | if [ -z "$RESOLVE_SCRIPT_LIB" ]; then
 15 |     export RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
 16 | fi
 17 | 
 18 | if [ -z "$PYTHONPATH" ]; then
 19 |     export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"
 20 | fi
 21 | 
 22 | # Check if DaVinci Resolve is running
 23 | check_resolve_running() {
 24 |     RESOLVE_PROCESS=$(ps -ef | grep -i "[D]aVinci Resolve")
 25 |     if [ -z "$RESOLVE_PROCESS" ]; then
 26 |         echo "⚠️  DaVinci Resolve is not running."
 27 |         echo "Please start DaVinci Resolve before starting the server."
 28 |         return 1
 29 |     else
 30 |         echo "✅ DaVinci Resolve is running."
 31 |         return 0
 32 |     fi
 33 | }
 34 | 
 35 | # Check if server is already running
 36 | check_server_running() {
 37 |     # Check for any process running our server script, whether via MCP or direct Python
 38 |     if ps aux | grep "resolve_mcp_server\.py" | grep -v grep > /dev/null ; then
 39 |         # Server is running
 40 |         return 0
 41 |     else
 42 |         # Server is not running
 43 |         return 1
 44 |     fi
 45 | }
 46 | 
 47 | # Activate virtual environment if it exists
 48 | activate_venv() {
 49 |     if [ -d "./venv" ]; then
 50 |         source ./venv/bin/activate
 51 |         echo "✅ Virtual environment activated."
 52 |     else
 53 |         echo "⚠️  No virtual environment found. Running with system Python."
 54 |     fi
 55 | }
 56 | 
 57 | # Start the server
 58 | start_server() {
 59 |     if check_server_running; then
 60 |         echo "⚠️  MCP Server is already running."
 61 |         return 0
 62 |     fi
 63 |     
 64 |     if ! check_resolve_running; then
 65 |         read -p "Do you want to continue anyway? (y/n) " choice
 66 |         case "$choice" in
 67 |             y|Y ) echo "Continuing without DaVinci Resolve...";;
 68 |             * ) echo "Aborting server start."; return 1;;
 69 |         esac
 70 |     fi
 71 |     
 72 |     activate_venv
 73 |     echo "🚀 Starting DaVinci Resolve MCP Server..."
 74 |     mkdir -p "$PROJECT_ROOT/logs"
 75 |     
 76 |     # Use direct Python as it's more reliable in background mode
 77 |     nohup python3 "$PROJECT_ROOT/resolve_mcp_server.py" > "$PROJECT_ROOT/logs/server.log" 2>&1 &
 78 |     
 79 |     # Give the server time to start
 80 |     echo "Waiting for server to initialize..."
 81 |     sleep 3
 82 |     
 83 |     if check_server_running; then
 84 |         echo "✅ Server started. Logs available at: $PROJECT_ROOT/logs/server.log"
 85 |         return 0
 86 |     else
 87 |         echo "❌ Server failed to start. Check logs at: $PROJECT_ROOT/logs/server.log"
 88 |         return 1
 89 |     fi
 90 | }
 91 | 
 92 | # Stop the server
 93 | stop_server() {
 94 |     if ! check_server_running; then
 95 |         echo "⚠️  MCP Server is not running."
 96 |         return 0
 97 |     fi
 98 |     
 99 |     echo "🛑 Stopping DaVinci Resolve MCP Server..."
100 |     
101 |     # Kill any processes running the server
102 |     pkill -f "resolve_mcp_server\.py"
103 |     sleep 1
104 |     
105 |     if check_server_running; then
106 |         echo "⚠️  Failed to stop all server processes. Trying with higher force..."
107 |         pkill -9 -f "resolve_mcp_server\.py"
108 |         sleep 1
109 |         
110 |         if check_server_running; then
111 |             echo "❌ Could not stop all server processes. Manual cleanup required."
112 |             echo "   Try running: killall -9 node; killall -9 python"
113 |             return 1
114 |         fi
115 |     fi
116 |     
117 |     echo "✅ Server stopped."
118 |     return 0
119 | }
120 | 
121 | # Start server in development mode
122 | start_dev_mode() {
123 |     if check_server_running; then
124 |         echo "⚠️  An MCP Server is already running. Stopping it..."
125 |         stop_server
126 |     fi
127 |     
128 |     check_resolve_running
129 |     activate_venv
130 |     
131 |     echo "🚀 Starting DaVinci Resolve MCP Server in development mode..."
132 |     python3 "$PROJECT_ROOT/resolve_mcp_server.py"
133 | }
134 | 
135 | # Show server status
136 | show_status() {
137 |     if check_server_running; then
138 |         echo "✅ MCP Server is running."
139 |         # Display process info in a user-friendly way
140 |         echo -e "\nServer process details:"
141 |         ps aux | grep "resolve_mcp_server\.py" | grep -v grep | awk '{print "PID: " $2 "  User: " $1 "  Started: " $9 "  Command: " $11 " " $12 " " $13}'
142 |     else
143 |         echo "❌ MCP Server is not running."
144 |     fi
145 |     
146 |     check_resolve_running
147 | }
148 | 
149 | # Create logs directory if it doesn't exist
150 | mkdir -p "$PROJECT_ROOT/logs"
151 | 
152 | # Parse command line arguments
153 | case "$1" in
154 |     start)
155 |         start_server
156 |         ;;
157 |     stop)
158 |         stop_server
159 |         ;;
160 |     restart)
161 |         stop_server
162 |         sleep 1
163 |         start_server
164 |         ;;
165 |     status)
166 |         show_status
167 |         ;;
168 |     dev)
169 |         start_dev_mode
170 |         ;;
171 |     *)
172 |         echo "Usage: $0 {start|stop|restart|status|dev}"
173 |         echo ""
174 |         echo "  start   - Start the MCP server as a background process"
175 |         echo "  stop    - Stop the running MCP server"
176 |         echo "  restart - Restart the MCP server"
177 |         echo "  status  - Check if the server is running"
178 |         echo "  dev     - Start in development mode (foreground)"
179 |         exit 1
180 |         ;;
181 | esac
182 | 
183 | exit 0 
```

--------------------------------------------------------------------------------
/scripts/utils.sh:
--------------------------------------------------------------------------------

```bash
  1 | #!/bin/bash
  2 | # Utility functions for DaVinci Resolve MCP Server scripts
  3 | 
  4 | # Colors for terminal output
  5 | RED='\033[0;31m'
  6 | GREEN='\033[0;32m'
  7 | YELLOW='\033[0;33m'
  8 | BLUE='\033[0;34m'
  9 | PURPLE='\033[0;35m'
 10 | CYAN='\033[0;36m'
 11 | WHITE='\033[1;37m'
 12 | NC='\033[0m' # No Color
 13 | 
 14 | # Print a section header
 15 | print_header() {
 16 |     local text="$1"
 17 |     echo ""
 18 |     echo -e "${WHITE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
 19 |     echo -e "${WHITE}  $text${NC}"
 20 |     echo -e "${WHITE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
 21 |     echo ""
 22 | }
 23 | 
 24 | # Print a status message
 25 | print_status() {
 26 |     local status="$1"
 27 |     local message="$2"
 28 |     
 29 |     case "$status" in
 30 |         "success")
 31 |             echo -e "${GREEN}✓ $message${NC}"
 32 |             ;;
 33 |         "warning")
 34 |             echo -e "${YELLOW}⚠ $message${NC}"
 35 |             ;;
 36 |         "error")
 37 |             echo -e "${RED}✗ $message${NC}"
 38 |             ;;
 39 |         "info")
 40 |             echo -e "${BLUE}ℹ $message${NC}"
 41 |             ;;
 42 |         *)
 43 |             echo -e "${NC}$message${NC}"
 44 |             ;;
 45 |     esac
 46 | }
 47 | 
 48 | # Check if a command exists
 49 | command_exists() {
 50 |     command -v "$1" &>/dev/null
 51 | }
 52 | 
 53 | # Check if a port is in use
 54 | is_port_in_use() {
 55 |     local port="$1"
 56 |     lsof -i ":$port" &>/dev/null
 57 | }
 58 | 
 59 | # Kill processes using a port
 60 | kill_port_process() {
 61 |     local port="$1"
 62 |     local pids=$(lsof -t -i ":$port")
 63 |     
 64 |     if [ -n "$pids" ]; then
 65 |         print_status "info" "Stopping processes using port $port (PIDs: $pids)..."
 66 |         kill $pids 2>/dev/null
 67 |         sleep 1
 68 |         
 69 |         # Check if they're still running and force kill if needed
 70 |         pids=$(lsof -t -i ":$port")
 71 |         if [ -n "$pids" ]; then
 72 |             print_status "warning" "Forcing termination of processes using port $port..."
 73 |             kill -9 $pids 2>/dev/null
 74 |         fi
 75 |     fi
 76 | }
 77 | 
 78 | # Check if DaVinci Resolve is running
 79 | is_resolve_running() {
 80 |     # Try multiple patterns to detect DaVinci Resolve on macOS
 81 |     if pgrep -i "DaVinci Resolve" &>/dev/null || \
 82 |        pgrep -i "Resolve" &>/dev/null || \
 83 |        ps -ef | grep -i "[D]aVinci Resolve" &>/dev/null || \
 84 |        ps -ef | grep -i "Resolve.app" &>/dev/null; then
 85 |         return 0
 86 |     fi
 87 |     
 88 |     # Check for Resolve process using the application path
 89 |     if [ -d "/Applications/DaVinci Resolve" ] && \
 90 |        ps -ef | grep -i "/Applications/DaVinci Resolve" | grep -v grep &>/dev/null; then
 91 |         return 0
 92 |     fi
 93 |     
 94 |     return 1
 95 | }
 96 | 
 97 | # Function to compare version numbers
 98 | version_compare() {
 99 |     if [[ "$1" == "$2" ]]; then
100 |         return 0
101 |     fi
102 |     
103 |     local IFS=.
104 |     local i ver1=($1) ver2=($2)
105 |     
106 |     # Fill empty fields with zeros
107 |     for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
108 |         ver1[i]=0
109 |     done
110 |     for ((i=${#ver2[@]}; i<${#ver1[@]}; i++)); do
111 |         ver2[i]=0
112 |     done
113 |     
114 |     # Compare version numbers field by field
115 |     for ((i=0; i<${#ver1[@]}; i++)); do
116 |         if [[ ${ver1[i]} -gt ${ver2[i]} ]]; then
117 |             return 1 # ver1 > ver2
118 |         fi
119 |         if [[ ${ver1[i]} -lt ${ver2[i]} ]]; then
120 |             return 2 # ver1 < ver2
121 |         fi
122 |     done
123 |     
124 |     return 0 # ver1 == ver2
125 | }
126 | 
127 | # Check for Python and pip
128 | check_python() {
129 |     if ! command_exists python3; then
130 |         print_status "error" "Python 3 is required but not installed. Please install Python 3 and try again."
131 |         return 1
132 |     fi
133 |     
134 |     # Check version (need 3.6+)
135 |     python_version=$(python3 --version | awk '{print $2}')
136 |     required_version="3.6"
137 |     
138 |     version_compare "$python_version" "$required_version"
139 |     result=$?
140 |     
141 |     if [[ $result -eq 2 ]]; then
142 |         # Version is less than required
143 |         print_status "error" "Python 3.6+ is required. Your version: $python_version"
144 |         return 1
145 |     else
146 |         # Version is equal to or greater than required
147 |         return 0
148 |     fi
149 | }
150 | 
151 | # Check for required environment variables
152 | check_resolve_env() {
153 |     local all_set=true
154 |     local missing=""
155 |     
156 |     if [ -z "$RESOLVE_SCRIPT_API" ]; then
157 |         all_set=false
158 |         missing="$missing RESOLVE_SCRIPT_API"
159 |     fi
160 |     
161 |     if [ -z "$RESOLVE_SCRIPT_LIB" ]; then
162 |         all_set=false
163 |         missing="$missing RESOLVE_SCRIPT_LIB"
164 |     fi
165 |     
166 |     if [ "$all_set" = false ]; then
167 |         return 1
168 |     fi
169 |     
170 |     return 0
171 | }
172 | 
173 | # Set Resolve environment variables
174 | set_resolve_env() {
175 |     export RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
176 |     export RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
177 |     export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"
178 | }
179 | 
180 | # Check if a virtual environment exists
181 | check_venv() {
182 |     local venv_dir="$1"
183 |     
184 |     if [ ! -d "$venv_dir" ]; then
185 |         return 1
186 |     fi
187 |     
188 |     if [ ! -f "$venv_dir/bin/python" ]; then
189 |         return 1
190 |     fi
191 |     
192 |     return 0
193 | }
194 | 
195 | # Check if a package is installed in the virtual environment
196 | is_package_installed() {
197 |     local venv_dir="$1"
198 |     local package="$2"
199 |     
200 |     "$venv_dir/bin/pip" list | grep -q "^$package "
201 | }
202 | 
203 | # Install a package in the virtual environment
204 | install_package() {
205 |     local venv_dir="$1"
206 |     local package="$2"
207 |     
208 |     "$venv_dir/bin/pip" install "$package"
209 | } 
```

--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------

```markdown
  1 | # DaVinci Resolve MCP Integration - Recent Changes
  2 | 
  3 | ## Version 1.3.7 - Installation Experience Improvements
  4 | 
  5 | ### 1. New Unified Installation Process
  6 | 
  7 | - Created a comprehensive one-step installation experience:
  8 |   - `install.sh` for macOS/Linux 
  9 |   - `install.bat` for Windows
 10 | - Added automatic validation and verification
 11 | - Simplified user experience with clear feedback
 12 | - Improved error handling with detailed messages
 13 | 
 14 | ### 2. Fixed Path Resolution Issues
 15 | 
 16 | - Modified scripts to use the directory where they're executed as reference point
 17 | - Resolved issues with incorrect assumptions about directory structure
 18 | - Established consistent path handling across all scripts
 19 | - Added explicit log messages with configured paths
 20 | 
 21 | ### 3. Improved DaVinci Resolve Detection
 22 | 
 23 | - Enhanced process detection methods for macOS and Windows
 24 | - Added retry mechanism with timeout for delayed startup
 25 | - Implemented more robust process matching patterns
 26 | - Added clear feedback when DaVinci Resolve isn't running
 27 | 
 28 | ### 4. Enhanced Configuration Handling
 29 | 
 30 | - Improved configuration file generation with absolute paths
 31 | - Added support for both system-level and project-level configurations
 32 | - Ensured consistent path references between all configuration options
 33 | - Added detailed documentation on configuration options
 34 | 
 35 | ### 5. New Verification Tools
 36 | 
 37 | - Created verification scripts (`verify-installation.sh` and `verify-installation.bat`)
 38 | - Implemented comprehensive checks for all dependencies
 39 | - Added detailed feedback for troubleshooting
 40 | - Enhanced error messages with suggested fixes
 41 | 
 42 | ### 6. Updated Documentation
 43 | 
 44 | - Created comprehensive installation guide (`INSTALL.md`)
 45 | - Added detailed troubleshooting section
 46 | - Enhanced README with new installation options
 47 | - Improved explanations of configuration requirements
 48 | 
 49 | ### 7. New Release Tooling
 50 | 
 51 | - Added scripts for creating versioned release packages
 52 | - Implemented automatic version extraction from VERSION.md
 53 | - Created cross-platform packaging tools for macOS/Linux and Windows
 54 | 
 55 | ### 8. Improved Directory Structure
 56 | 
 57 | - Standardized to a single venv in the root directory
 58 | - Moved `resolve_mcp_server.py` to `src/` directory
 59 | - Restructured configuration files into `config/` directory 
 60 | - Created dedicated `dist/` directory for release packages
 61 | - Moved installation scripts to `scripts/setup/`
 62 | - Reorganized test files into top-level `tests/` directory
 63 | - Created symlinks for backward compatibility
 64 | - Updated all scripts to use new standardized paths
 65 | 
 66 | ## Previous Installation Issues Addressed
 67 | 
 68 | - Fixed issues with incorrect paths in `run-now.sh`
 69 | - Resolved DaVinci Resolve detection problems
 70 | - Improved configuration file generation for absolute paths
 71 | - Enhanced error feedback and logging
 72 | - Added more robust process detection patterns
 73 | - Implemented verification to catch common setup issues
 74 | - Added detailed troubleshooting documentation
 75 | 
 76 | ## Installation Improvements
 77 | 
 78 | Based on troubleshooting experiences, the following improvements have been made to the installation process:
 79 | 
 80 | ### 1. Fixed Path Resolution in Scripts
 81 | 
 82 | - Modified `run-now.sh` to use the directory where the script is located as the reference point
 83 | - Removed incorrect assumptions about directory structure
 84 | - Updated path references to use consistent `SCRIPT_DIR` variable throughout all scripts
 85 | 
 86 | ### 2. Improved DaVinci Resolve Detection
 87 | 
 88 | - Changed detection method from `pgrep -q "DaVinci Resolve"` to `ps -ef | grep -i "[D]aVinci Resolve"` for more reliable detection
 89 | - Added a 10-second wait period with automatic retry when DaVinci Resolve is not detected
 90 | - Implemented more descriptive error messages when DaVinci Resolve is not running
 91 | 
 92 | ### 3. Added Installation Verification
 93 | 
 94 | - Created verification scripts (`verify-installation.sh` and `verify-installation.bat`) to check installation integrity
 95 | - Verification covers Python environment, MCP SDK, configuration files, and DaVinci Resolve status
 96 | - Provides detailed feedback and suggestions for fixing issues
 97 | 
 98 | ### 4. Enhanced Documentation
 99 | 
100 | - Created a comprehensive installation guide (`INSTALL.md`) with step-by-step instructions
101 | - Added detailed troubleshooting section to address common issues
102 | - Updated README.md to reference new resources and include troubleshooting tips
103 | 
104 | ### 5. Improved Configuration Setup
105 | 
106 | - Made the Cursor MCP configuration setup more robust and informative
107 | - Added validation and feedback for environment variables
108 | - Enhanced log file information for easier debugging
109 | 
110 | ## Benefits of These Changes
111 | 
112 | - **More Reliable Installation:** Better path handling and detection methods
113 | - **Easier Troubleshooting:** Verification tools and improved error messages
114 | - **Clearer Documentation:** Step-by-step guide and troubleshooting solutions
115 | - **Consistent Behavior:** Works correctly regardless of installation location
116 | 
117 | ## How to Apply These Updates
118 | 
119 | If you already have a previous installation:
120 | 
121 | 1. Pull the latest changes from the repository
122 | 2. Run the verification script to ensure everything is set up correctly:
123 |    - macOS/Linux: `./scripts/verify-installation.sh`
124 |    - Windows: `scripts\verify-installation.bat`
125 | 3. If verification fails, follow the suggested fixes or refer to the `INSTALL.md` guide
126 | 
127 | For new installations, simply follow the instructions in the `INSTALL.md` file. 
```

--------------------------------------------------------------------------------
/examples/timeline/timeline_check.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | Detailed timeline check to analyze clip positions and timecode mapping
  4 | """
  5 | 
  6 | import os
  7 | import sys
  8 | 
  9 | # Set environment variables for DaVinci Resolve scripting
 10 | RESOLVE_API_PATH = "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
 11 | RESOLVE_LIB_PATH = "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
 12 | RESOLVE_MODULES_PATH = os.path.join(RESOLVE_API_PATH, "Modules")
 13 | 
 14 | os.environ["RESOLVE_SCRIPT_API"] = RESOLVE_API_PATH
 15 | os.environ["RESOLVE_SCRIPT_LIB"] = RESOLVE_LIB_PATH
 16 | sys.path.append(RESOLVE_MODULES_PATH)
 17 | 
 18 | # Import DaVinci Resolve scripting
 19 | import DaVinciResolveScript as dvr_script
 20 | 
 21 | def frame_to_tc(frame, fps):
 22 |     """Convert frame number to timecode"""
 23 |     total_seconds = frame / fps
 24 |     hours = int(total_seconds // 3600)
 25 |     minutes = int((total_seconds % 3600) // 60)
 26 |     seconds = int(total_seconds % 60)
 27 |     frames = int((total_seconds - int(total_seconds)) * fps)
 28 |     return f"{hours:02d}:{minutes:02d}:{seconds:02d}:{frames:02d}"
 29 | 
 30 | def main():
 31 |     print("\n===== DETAILED TIMELINE ANALYSIS =====\n")
 32 |     
 33 |     # Connect to Resolve
 34 |     resolve = dvr_script.scriptapp("Resolve")
 35 |     if not resolve:
 36 |         print("Error: Failed to connect to DaVinci Resolve")
 37 |         return
 38 |     
 39 |     print(f"Connected to: {resolve.GetProductName()} {resolve.GetVersionString()}")
 40 |     
 41 |     # Get project manager
 42 |     project_manager = resolve.GetProjectManager()
 43 |     current_project = project_manager.GetCurrentProject()
 44 |     current_timeline = current_project.GetCurrentTimeline()
 45 |     
 46 |     print(f"Project: {current_project.GetName()}")
 47 |     print(f"Timeline: {current_timeline.GetName()}")
 48 |     
 49 |     # Get timeline settings
 50 |     fps = float(current_timeline.GetSetting("timelineFrameRate"))
 51 |     print(f"Frame rate: {fps}")
 52 |     
 53 |     start_frame = current_timeline.GetStartFrame()
 54 |     end_frame = current_timeline.GetEndFrame()
 55 |     
 56 |     # Calculate real timecodes
 57 |     start_tc = frame_to_tc(start_frame, fps)
 58 |     end_tc = frame_to_tc(end_frame, fps)
 59 |     
 60 |     print(f"\nTimeline spans frames {start_frame} to {end_frame}")
 61 |     print(f"Timeline estimated timecode: {start_tc} to {end_tc}")
 62 |     
 63 |     # Check if we can get actual timecode
 64 |     try:
 65 |         start_timecode = current_timeline.GetStartTimecode()
 66 |         print(f"Timeline actual start timecode: {start_timecode}")
 67 |     except:
 68 |         print("Could not get actual start timecode")
 69 |     
 70 |     # Check timecode display settings
 71 |     tc_drop = current_timeline.GetSetting("timelineDropFrameTimecode")
 72 |     print(f"Drop frame: {tc_drop}")
 73 |     
 74 |     # Get playhead position
 75 |     try:
 76 |         playhead_frame = current_timeline.GetCurrentVideoFrame()
 77 |         playhead_tc = frame_to_tc(playhead_frame, fps)
 78 |         print(f"\nPlayhead at frame {playhead_frame} (approx. TC: {playhead_tc})")
 79 |     except Exception as e:
 80 |         print(f"Error getting playhead: {str(e)}")
 81 |     
 82 |     # Get clips
 83 |     clips = []
 84 |     for track_idx in range(1, 5):  # Check first 4 video tracks
 85 |         try:
 86 |             track_clips = current_timeline.GetItemListInTrack("video", track_idx)
 87 |             if track_clips and len(track_clips) > 0:
 88 |                 clips.extend(track_clips)
 89 |         except:
 90 |             continue
 91 |     
 92 |     print(f"\nFound {len(clips)} clips:")
 93 |     for i, clip in enumerate(clips):
 94 |         clip_name = clip.GetName()
 95 |         start_frame = clip.GetStart()
 96 |         end_frame = clip.GetEnd()
 97 |         
 98 |         # Get the source frame info
 99 |         try:
100 |             source_start = clip.GetLeftOffset()
101 |             source_end = source_start + (end_frame - start_frame)
102 |             print(f"  Clip {i+1}: '{clip_name}'")
103 |             print(f"    Timeline: frames {start_frame}-{end_frame} ({frame_to_tc(start_frame, fps)}-{frame_to_tc(end_frame, fps)})")
104 |             print(f"    Source: frames {source_start}-{source_end}")
105 |         except Exception as e:
106 |             print(f"  Clip {i+1}: '{clip_name}'")
107 |             print(f"    Timeline: frames {start_frame}-{end_frame} ({frame_to_tc(start_frame, fps)}-{frame_to_tc(end_frame, fps)})")
108 |             print(f"    Source info error: {str(e)}")
109 |     
110 |     # Get markers
111 |     markers = current_timeline.GetMarkers() or {}
112 |     print(f"\nFound {len(markers)} markers:")
113 |     
114 |     sorted_markers = sorted(markers.items())
115 |     for frame, marker_data in sorted_markers:
116 |         color = marker_data.get("color", "Unknown") 
117 |         name = marker_data.get("name", "")
118 |         tc = frame_to_tc(frame, fps)
119 |         print(f"  Marker at frame {frame} (TC: {tc}):")
120 |         print(f"    Color: {color}")
121 |         print(f"    Name: {name}")
122 |     
123 |     # Try to determine timeline start offset
124 |     try:
125 |         one_hour_frames = int(fps * 60 * 60)
126 |         print("\nTimeline offset analysis:")
127 |         print(f"  One hour in frames: {one_hour_frames}")
128 |         print(f"  If timeline starts at 01:00:00:00, first frame should be {one_hour_frames}")
129 |         offset = start_frame - one_hour_frames
130 |         print(f"  Detected offset: {offset} frames")
131 |         
132 |         if offset >= 0:
133 |             print(f"  Timeline appears to start at {frame_to_tc(offset + one_hour_frames, fps)}")
134 |         else:
135 |             print(f"  Timeline appears to start at {frame_to_tc(one_hour_frames - abs(offset), fps)}")
136 |     except Exception as e:
137 |         print(f"Error analyzing offset: {str(e)}")
138 |     
139 |     print("\n===== END OF ANALYSIS =====")
140 | 
141 | if __name__ == "__main__":
142 |     main() 
```

--------------------------------------------------------------------------------
/scripts/setup.sh:
--------------------------------------------------------------------------------

```bash
  1 | #!/bin/bash
  2 | # DaVinci Resolve MCP Server Setup Script
  3 | 
  4 | # Colors for terminal output
  5 | RED='\033[0;31m'
  6 | GREEN='\033[0;32m'
  7 | YELLOW='\033[0;33m'
  8 | NC='\033[0m' # No Color
  9 | 
 10 | echo -e "${GREEN}Setting up DaVinci Resolve MCP Server...${NC}"
 11 | 
 12 | # Check if Python 3 is installed
 13 | if ! command -v python3 &> /dev/null; then
 14 |     echo -e "${RED}Error: Python 3 is required but not installed.${NC}"
 15 |     echo "Please install Python 3 and try again."
 16 |     exit 1
 17 | fi
 18 | 
 19 | # Create and activate virtual environment
 20 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
 21 | VENV_DIR="$SCRIPT_DIR/venv"
 22 | 
 23 | echo -e "${YELLOW}Creating Python virtual environment at $VENV_DIR...${NC}"
 24 | python3 -m venv "$VENV_DIR"
 25 | 
 26 | # Activate virtual environment (source doesn't work in scripts)
 27 | VENV_PYTHON="$VENV_DIR/bin/python"
 28 | VENV_PIP="$VENV_DIR/bin/pip"
 29 | 
 30 | # Install MCP SDK in the virtual environment with CLI support
 31 | echo -e "${YELLOW}Installing MCP SDK with CLI support in virtual environment...${NC}"
 32 | "$VENV_PIP" install "mcp[cli]"
 33 | 
 34 | # Check if DaVinci Resolve is installed
 35 | if [ ! -d "/Applications/DaVinci Resolve" ]; then
 36 |     echo -e "${RED}Warning: DaVinci Resolve installation not found at the default location.${NC}"
 37 |     echo "If DaVinci Resolve is installed in a different location, you'll need to manually update the environment variables."
 38 | else
 39 |     echo -e "${GREEN}DaVinci Resolve installation found.${NC}"
 40 | fi
 41 | 
 42 | # Set up environment variables
 43 | RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
 44 | RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
 45 | 
 46 | # Check if Scripting API directory exists
 47 | if [ ! -d "$RESOLVE_SCRIPT_API" ]; then
 48 |     echo -e "${RED}Warning: DaVinci Resolve Scripting API folder not found at the expected location.${NC}"
 49 |     echo "This might be due to a different version of DaVinci Resolve or custom installation."
 50 | else
 51 |     echo -e "${GREEN}DaVinci Resolve Scripting API found.${NC}"
 52 | fi
 53 | 
 54 | # Add environment variables to shell profile
 55 | SHELL_PROFILE=""
 56 | if [ -f "$HOME/.zshrc" ]; then
 57 |     SHELL_PROFILE="$HOME/.zshrc"
 58 | elif [ -f "$HOME/.bash_profile" ]; then
 59 |     SHELL_PROFILE="$HOME/.bash_profile"
 60 | elif [ -f "$HOME/.bashrc" ]; then
 61 |     SHELL_PROFILE="$HOME/.bashrc"
 62 | fi
 63 | 
 64 | if [ -n "$SHELL_PROFILE" ]; then
 65 |     echo -e "${YELLOW}Adding environment variables to $SHELL_PROFILE...${NC}"
 66 |     
 67 |     # Check if variables are already in the profile
 68 |     if grep -q "RESOLVE_SCRIPT_API" "$SHELL_PROFILE"; then
 69 |         echo -e "${YELLOW}Environment variables already exist in $SHELL_PROFILE. Skipping...${NC}"
 70 |     else
 71 |         echo "" >> "$SHELL_PROFILE"
 72 |         echo "# DaVinci Resolve MCP Server environment variables" >> "$SHELL_PROFILE"
 73 |         echo "export RESOLVE_SCRIPT_API=\"$RESOLVE_SCRIPT_API\"" >> "$SHELL_PROFILE"
 74 |         echo "export RESOLVE_SCRIPT_LIB=\"$RESOLVE_SCRIPT_LIB\"" >> "$SHELL_PROFILE"
 75 |         echo "export PYTHONPATH=\"\$PYTHONPATH:\$RESOLVE_SCRIPT_API/Modules/\"" >> "$SHELL_PROFILE"
 76 |         echo -e "${GREEN}Environment variables added to $SHELL_PROFILE${NC}"
 77 |     fi
 78 | else
 79 |     echo -e "${RED}Warning: Could not find a shell profile to update.${NC}"
 80 |     echo "Please manually add the following environment variables to your shell profile:"
 81 |     echo "export RESOLVE_SCRIPT_API=\"$RESOLVE_SCRIPT_API\""
 82 |     echo "export RESOLVE_SCRIPT_LIB=\"$RESOLVE_SCRIPT_LIB\""
 83 |     echo "export PYTHONPATH=\"\$PYTHONPATH:\$RESOLVE_SCRIPT_API/Modules/\""
 84 | fi
 85 | 
 86 | # Create wrapper script to run server with the virtual environment
 87 | cat > "$SCRIPT_DIR/run-server.sh" << EOF
 88 | #!/bin/bash
 89 | # Wrapper script to run the DaVinci Resolve MCP Server with the virtual environment
 90 | 
 91 | # Source environment variables if not already set
 92 | if [ -z "\$RESOLVE_SCRIPT_API" ]; then
 93 |   source "$SHELL_PROFILE"
 94 | fi
 95 | 
 96 | # Activate virtual environment and run server
 97 | "$VENV_DIR/bin/python" "$SCRIPT_DIR/../src/main.py" "\$@"
 98 | EOF
 99 | 
100 | chmod +x "$SCRIPT_DIR/run-server.sh"
101 | 
102 | # Set up Cursor configuration
103 | CURSOR_CONFIG_DIR="$HOME/.cursor"
104 | CURSOR_MCP_CONFIG="$CURSOR_CONFIG_DIR/mcp.json"
105 | 
106 | if [ ! -d "$CURSOR_CONFIG_DIR" ]; then
107 |     echo -e "${YELLOW}Creating Cursor config directory...${NC}"
108 |     mkdir -p "$CURSOR_CONFIG_DIR"
109 | fi
110 | 
111 | # Get the full path to the wrapper script
112 | SERVER_PATH="$SCRIPT_DIR/run-server.sh"
113 | 
114 | # Check if Cursor MCP config exists
115 | if [ -f "$CURSOR_MCP_CONFIG" ]; then
116 |     echo -e "${YELLOW}Found existing Cursor MCP config. Not modifying it.${NC}"
117 |     echo "To manually add the DaVinci Resolve MCP server, edit $CURSOR_MCP_CONFIG and add:"
118 |     echo "{\"mcpServers\": {\"davinci-resolve\": {\"command\": \"$SERVER_PATH\"}}}"
119 | else
120 |     echo -e "${YELLOW}Creating Cursor MCP config...${NC}"
121 |     cat > "$CURSOR_MCP_CONFIG" << EOF
122 | {
123 |   "mcpServers": {
124 |     "davinci-resolve": {
125 |       "command": "$SERVER_PATH"
126 |     }
127 |   }
128 | }
129 | EOF
130 |     echo -e "${GREEN}Created Cursor MCP config at $CURSOR_MCP_CONFIG${NC}"
131 | fi
132 | 
133 | # Make the server script executable
134 | chmod +x "$SCRIPT_DIR/resolve_mcp_server.py"
135 | 
136 | echo -e "${GREEN}Setup completed!${NC}"
137 | echo ""
138 | echo -e "${YELLOW}Important:${NC}"
139 | echo "1. Make sure to restart your terminal or run 'source $SHELL_PROFILE' to apply the environment variables."
140 | echo "2. DaVinci Resolve must be running before starting the MCP server."
141 | echo "3. You can test the server by running: $SCRIPT_DIR/run-server.sh"
142 | echo "   or with the MCP CLI: $VENV_DIR/bin/mcp dev $SCRIPT_DIR/resolve_mcp_server.py"
143 | echo ""
144 | echo -e "${GREEN}Happy editing with DaVinci Resolve and your AI assistant!${NC}" 
```

--------------------------------------------------------------------------------
/examples/timeline/timeline_info.py:
--------------------------------------------------------------------------------

```python
  1 | #!/usr/bin/env python3
  2 | """
  3 | Get detailed timeline information from DaVinci Resolve
  4 | """
  5 | 
  6 | import os
  7 | import sys
  8 | 
  9 | # Set environment variables for DaVinci Resolve scripting
 10 | RESOLVE_API_PATH = "/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
 11 | RESOLVE_LIB_PATH = "/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
 12 | RESOLVE_MODULES_PATH = os.path.join(RESOLVE_API_PATH, "Modules")
 13 | 
 14 | os.environ["RESOLVE_SCRIPT_API"] = RESOLVE_API_PATH
 15 | os.environ["RESOLVE_SCRIPT_LIB"] = RESOLVE_LIB_PATH
 16 | sys.path.append(RESOLVE_MODULES_PATH)
 17 | 
 18 | # Import DaVinci Resolve scripting
 19 | import DaVinciResolveScript as dvr_script
 20 | 
 21 | def main():
 22 |     print("\n===== Timeline Information =====\n")
 23 |     
 24 |     # Connect to Resolve
 25 |     resolve = dvr_script.scriptapp("Resolve")
 26 |     if not resolve:
 27 |         print("Error: Failed to connect to DaVinci Resolve")
 28 |         return
 29 |     
 30 |     print(f"Connected to: {resolve.GetProductName()} {resolve.GetVersionString()}")
 31 |     
 32 |     # Get project manager
 33 |     project_manager = resolve.GetProjectManager()
 34 |     if not project_manager:
 35 |         print("Error: Failed to get Project Manager")
 36 |         return
 37 |     
 38 |     # Get current project
 39 |     current_project = project_manager.GetCurrentProject()
 40 |     if not current_project:
 41 |         print("Error: No project currently open")
 42 |         return
 43 |     
 44 |     print(f"Current project: {current_project.GetName()}")
 45 |     
 46 |     # Get current timeline
 47 |     current_timeline = current_project.GetCurrentTimeline()
 48 |     if not current_timeline:
 49 |         print("Error: No timeline currently active")
 50 |         return
 51 |     
 52 |     timeline_name = current_timeline.GetName()
 53 |     print(f"Current timeline: {timeline_name}")
 54 |     
 55 |     # Get timeline frame rate
 56 |     try:
 57 |         frame_rate = float(current_timeline.GetSetting("timelineFrameRate"))
 58 |         print(f"Timeline frame rate: {frame_rate} fps")
 59 |     except Exception as e:
 60 |         print(f"Error getting frame rate: {str(e)}")
 61 |         frame_rate = 24.0
 62 |     
 63 |     # Get timeline information
 64 |     start_frame = current_timeline.GetStartFrame()
 65 |     end_frame = current_timeline.GetEndFrame()
 66 |     
 67 |     print(f"Timeline frame range: {start_frame} to {end_frame}")
 68 |     
 69 |     # Calculate timecode equivalent of the frame range
 70 |     hours_start = start_frame // (frame_rate * 60 * 60)
 71 |     minutes_start = (start_frame % (frame_rate * 60 * 60)) // (frame_rate * 60)
 72 |     seconds_start = (start_frame % (frame_rate * 60)) // frame_rate
 73 |     frames_start = start_frame % frame_rate
 74 |     
 75 |     hours_end = end_frame // (frame_rate * 60 * 60)
 76 |     minutes_end = (end_frame % (frame_rate * 60 * 60)) // (frame_rate * 60)
 77 |     seconds_end = (end_frame % (frame_rate * 60)) // frame_rate
 78 |     frames_end = end_frame % frame_rate
 79 |     
 80 |     start_tc = f"{int(hours_start):02d}:{int(minutes_start):02d}:{int(seconds_start):02d}:{int(frames_start):02d}"
 81 |     end_tc = f"{int(hours_end):02d}:{int(minutes_end):02d}:{int(seconds_end):02d}:{int(frames_end):02d}"
 82 |     
 83 |     print(f"Timeline approx. timecode range: {start_tc} to {end_tc}")
 84 |     
 85 |     # Calculate various time positions
 86 |     one_hour_frames = int(frame_rate * 60 * 60)
 87 |     print(f"\nTime calculations:")
 88 |     print(f"One hour in frames: {one_hour_frames}")
 89 |     print(f"01:00:00:00 would be frame: {one_hour_frames}")
 90 |     print(f"02:00:00:00 would be frame: {one_hour_frames * 2}")
 91 |     
 92 |     # Get clips in timeline
 93 |     clips = []
 94 |     for track_idx in range(1, 5):  # Check first 4 video tracks
 95 |         try:
 96 |             track_clips = current_timeline.GetItemListInTrack("video", track_idx)
 97 |             if track_clips and len(track_clips) > 0:
 98 |                 clips.extend(track_clips)
 99 |         except:
100 |             continue
101 |     
102 |     print(f"\nFound {len(clips)} clips in timeline:")
103 |     for i, clip in enumerate(clips):
104 |         clip_start = clip.GetStart()
105 |         clip_end = clip.GetEnd()
106 |         clip_name = clip.GetName()
107 |         print(f"Clip {i+1}: '{clip_name}'")
108 |         print(f"  Frame range: {clip_start} to {clip_end}")
109 |         print(f"  Duration: {clip_end - clip_start} frames")
110 |         
111 |         # Calculate timecode equivalent (rough estimate)
112 |         hours_start = clip_start // (frame_rate * 60 * 60)
113 |         minutes_start = (clip_start % (frame_rate * 60 * 60)) // (frame_rate * 60)
114 |         seconds_start = (clip_start % (frame_rate * 60)) // frame_rate
115 |         frames_start = clip_start % frame_rate
116 |         
117 |         tc_start = f"{int(hours_start):02d}:{int(minutes_start):02d}:{int(seconds_start):02d}:{int(frames_start):02d}"
118 |         print(f"  Approx. start TC: {tc_start}")
119 |         print()
120 |     
121 |     # Get existing markers
122 |     markers = current_timeline.GetMarkers() or {}
123 |     print(f"\nFound {len(markers)} markers in timeline:")
124 |     
125 |     sorted_markers = sorted(markers.items())
126 |     for frame, marker_data in sorted_markers:
127 |         color = marker_data.get("color", "Unknown")
128 |         name = marker_data.get("name", "")
129 |         
130 |         # Calculate timecode equivalent (rough estimate)
131 |         hours = frame // (frame_rate * 60 * 60)
132 |         minutes = (frame % (frame_rate * 60 * 60)) // (frame_rate * 60)
133 |         seconds = (frame % (frame_rate * 60)) // frame_rate
134 |         frames = frame % frame_rate
135 |         
136 |         tc = f"{int(hours):02d}:{int(minutes):02d}:{int(seconds):02d}:{int(frames):02d}"
137 |         print(f"Marker at frame {frame} (approx. TC: {tc}):")
138 |         print(f"  Color: {color}")
139 |         print(f"  Name: {name}")
140 |         print()
141 |     
142 |     print("\n===== End of Information =====")
143 | 
144 | if __name__ == "__main__":
145 |     main() 
```
Page 1/5FirstPrevNextLast