iflow-mcp_tooflex-davinci-resolve-mcp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,304 @@
1
+ Metadata-Version: 2.4
2
+ Name: iflow-mcp_tooflex-davinci-resolve-mcp
3
+ Version: 0.1.0
4
+ Summary: Add your description here
5
+ Requires-Python: >=3.10
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: mcp[cli]>=1.4.1
8
+ Requires-Dist: pydantic>=2.10.6
9
+
10
+ Here’s an updated version of the README with enhancements reflecting the expanded functionality of the `ResolveAPI` class, improved clarity, and additional details for setup and usage. The structure remains consistent with your original README, but I’ve incorporated the new features (e.g., gallery management, track control, audio adjustments, playback, etc.) and refined the instructions for `uv` installation and Claude integration.
11
+
12
+ ---
13
+
14
+ # DaVinci Resolve MCP Server
15
+
16
+ A Model Context Protocol (MCP) server that enables AI assistants like Claude to interact with DaVinci Resolve Studio, providing advanced control over editing, color grading, audio, and more.
17
+
18
+ ## Overview
19
+
20
+ This server implements the MCP protocol to create a bridge between AI assistants and DaVinci Resolve. It allows AI assistants to:
21
+
22
+ - Create, load, and manage DaVinci Resolve projects
23
+ - Manipulate timelines, tracks, and clips
24
+ - Import and organize media files
25
+ - Access and modify Fusion compositions
26
+ - Perform color grading and manage stills in the Gallery
27
+ - Adjust audio settings and control playback
28
+ - Navigate between Resolve pages (Media, Edit, Fusion, Color, Fairlight, Deliver)
29
+ - Execute custom Python and Lua scripts
30
+ - Export and import projects
31
+
32
+ ## Requirements
33
+
34
+ - DaVinci Resolve Studio 18.0 or newer
35
+ - Python 3.10 or newer
36
+ - Access to the DaVinci Resolve scripting API
37
+
38
+ ## Installation with uv
39
+
40
+ [uv](https://github.com/astral-sh/uv) is a fast, modern Python package installer and resolver that outperforms pip. Follow these steps to install and set up the DaVinci Resolve MCP server using `uv`:
41
+
42
+ ### 1. Install uv
43
+
44
+ If `uv` is not installed:
45
+
46
+ ```bash
47
+ # Using pip (ensure pip is for Python 3.10+)
48
+ pip install uv
49
+
50
+ # Using Homebrew (macOS)
51
+ brew install uv
52
+
53
+ # Using Conda
54
+ conda install -c conda-forge uv
55
+ ```
56
+
57
+ Verify installation:
58
+
59
+ ```bash
60
+ uv --version
61
+ ```
62
+
63
+ ### 2. Create a Virtual Environment
64
+
65
+ Create and activate a virtual environment to isolate dependencies:
66
+
67
+ ```bash
68
+ uv venv
69
+ source .venv/bin/activate # On Windows: .venv\Scripts\activate
70
+ ```
71
+
72
+ ### 3. Install the DaVinci Resolve MCP Server
73
+
74
+ Install the server and its dependencies from the project directory:
75
+
76
+ ```bash
77
+ # From the project directory (editable install for development)
78
+ uv install -e .
79
+
80
+ # Or directly from GitHub (replace with your repo URL)
81
+ uv install git+https://github.com/yourusername/davinci-resolve-mcp.git
82
+ ```
83
+
84
+ ### 4. Install Dependencies
85
+
86
+ Ensure `requirements.txt` includes:
87
+
88
+ ```
89
+ mcp
90
+ pydantic
91
+ ```
92
+
93
+ Install them:
94
+
95
+ ```bash
96
+ uv install -r requirements.txt
97
+ ```
98
+
99
+ ## Configuration
100
+
101
+ Before running the server, ensure:
102
+
103
+ 1. DaVinci Resolve Studio is running.
104
+ 2. Python can access the DaVinci Resolve scripting API (handled automatically by `ResolveAPI` in most cases).
105
+
106
+ ### API Access Configuration
107
+
108
+ The `ResolveAPI` class dynamically locates the scripting API, but you may need to configure it manually in some cases:
109
+
110
+ #### macOS
111
+
112
+ The API is typically available at:
113
+
114
+ - `/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules`
115
+ - Or user-specific: `~/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules`
116
+
117
+ No additional setup is usually required.
118
+
119
+ #### Windows
120
+
121
+ Add the API path if not detected:
122
+
123
+ ```python
124
+ import sys
125
+ sys.path.append("C:\\ProgramData\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\Modules")
126
+ ```
127
+
128
+ #### Linux
129
+
130
+ Set the environment variable:
131
+
132
+ ```bash
133
+ export PYTHONPATH=$PYTHONPATH:/opt/resolve/Developer/Scripting/Modules
134
+ ```
135
+
136
+ Alternatively, set a custom path via an environment variable:
137
+
138
+ ```bash
139
+ export RESOLVE_SCRIPT_PATH="/custom/path/to/scripting/modules"
140
+ ```
141
+
142
+ ## Running the Server
143
+
144
+ Start the MCP server:
145
+
146
+ ```bash
147
+ # Run directly with Python
148
+ python -m resolve_mcp.server
149
+
150
+ # Or with uv
151
+ uv run resolve_mcp/server.py
152
+ ```
153
+
154
+ The server will launch and connect to DaVinci Resolve, logging output like:
155
+
156
+ ```
157
+ 2025-03-19 ... - resolve_mcp - INFO - Successfully connected to DaVinci Resolve.
158
+ ```
159
+
160
+ ### Claude Integration Configuration
161
+
162
+ To integrate with Claude Desktop, update your `claude_desktop_config.json` (e.g., `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
163
+
164
+ ```json
165
+ {
166
+ "mcpServers": {
167
+ "davinci-resolve": {
168
+ "command": "/path/to/uv",
169
+ "args": [
170
+ "run",
171
+ "--directory",
172
+ "/path/to/davinci-resolve-mcp",
173
+ "resolve_mcp/server.py"
174
+ ]
175
+ }
176
+ }
177
+ }
178
+ ```
179
+
180
+ - Replace `/path/to/uv` with the path to your `uv` executable (e.g., `/usr/local/bin/uv` or `C:\Users\username\.cargo\bin\uv.exe`).
181
+ - Replace `/path/to/davinci-resolve-mcp` with the absolute path to your project directory.
182
+
183
+ Restart Claude Desktop to enable the server. Look for a hammer icon in the input box to confirm integration.
184
+
185
+ ## Troubleshooting
186
+
187
+ ### Connection Issues
188
+
189
+ If the server fails to connect:
190
+
191
+ 1. Ensure DaVinci Resolve Studio is running.
192
+ 2. Check Resolve’s preferences to confirm scripting is enabled.
193
+ 3. Verify Python version compatibility (3.10+ recommended):
194
+ ```bash
195
+ python --version
196
+ ```
197
+ 4. Confirm API paths are accessible (see logs in `~/Library/Logs/Claude/mcp*.log` on macOS or `%userprofile%\AppData\Roaming\Claude\Logs\` on Windows).
198
+
199
+ ### Dependency Issues
200
+
201
+ If modules like `mcp` or `pydantic` are missing:
202
+
203
+ ```bash
204
+ uv install mcp pydantic
205
+ ```
206
+
207
+ ### Python Version Compatibility
208
+
209
+ Switch to a compatible version with `pyenv` if needed:
210
+
211
+ ```bash
212
+ pyenv install 3.10.12
213
+ pyenv shell 3.10.12
214
+ uv install -r requirements.txt
215
+ ```
216
+
217
+ ## Available Tools and Resources
218
+
219
+ The MCP server provides extensive functionality through the `ResolveAPI` class:
220
+
221
+ ### Project Management
222
+
223
+ - Create new projects (`create_project`)
224
+ - Load existing projects (`load_project`)
225
+ - Save current projects (`save_project`)
226
+ - Export/import projects (`export_project`, `import_project`)
227
+ - Get/set project settings (`get_project_settings`, `set_project_setting`)
228
+
229
+ ### Timeline Operations
230
+
231
+ - Create new timelines (`create_timeline`)
232
+ - Set/get current timeline (`set_current_timeline`, `get_current_timeline`)
233
+ - Add/manage tracks (`add_track`, `set_track_name`, `enable_track`)
234
+ - Get timeline items (`get_timeline_items`)
235
+ - Set clip properties (`set_clip_property`)
236
+ - Add markers (`add_timeline_marker`)
237
+
238
+ ### Media Management
239
+
240
+ - Import media files (`add_items_to_media_pool`)
241
+ - Create media pool folders (`add_sub_folder`)
242
+ - Create timelines from clips (`create_timeline_from_clips`)
243
+ - Get clip metadata (`get_clip_metadata`)
244
+
245
+ ### Fusion Integration
246
+
247
+ - Add Fusion compositions to clips (`create_fusion_node`)
248
+ - Create/manage Fusion nodes (`create_fusion_node`)
249
+ - Access current composition (`get_current_comp`)
250
+
251
+ ### Color Grading
252
+
253
+ - Get/add color nodes (`get_color_page_nodes`, `add_color_node`)
254
+ - Save/apply stills (`save_still`, `apply_still`)
255
+ - Manage gallery albums (`get_gallery_albums`)
256
+
257
+ ### Audio Control
258
+
259
+ - Get/set clip audio volume (`get_audio_volume`, `set_audio_volume`)
260
+ - Set track volume (`set_track_volume`)
261
+
262
+ ### Playback Control
263
+
264
+ - Play/stop playback (`play`, `stop`)
265
+ - Get/set playhead position (`get_current_timecode`, `set_playhead_position`)
266
+
267
+ ### Rendering
268
+
269
+ - Start rendering (`start_render`)
270
+ - Get render status (`get_render_status`)
271
+
272
+ ### Navigation
273
+
274
+ - Open specific pages (`open_page`: Media, Edit, Fusion, Color, Fairlight, Deliver)
275
+
276
+ ### Advanced Operations
277
+
278
+ - Execute custom Python code (`execute_python`)
279
+ - Execute Lua scripts in Fusion (`execute_lua`)
280
+
281
+ ## Development
282
+
283
+ To contribute:
284
+
285
+ 1. Fork the repository: `https://github.com/yourusername/davinci-resolve-mcp`
286
+ 2. Create a feature branch: `git checkout -b feature-name`
287
+ 3. Install dependencies: `uv install -e .`
288
+ 4. Make changes and test: `uv run resolve_mcp/server.py`
289
+ 5. Submit a pull request.
290
+
291
+ ## License
292
+
293
+ [MIT License](LICENSE)
294
+
295
+ ---
296
+
297
+ ### Key Updates
298
+
299
+ - **Expanded Features**: Added new capabilities like gallery management, track control, audio adjustments, playback, and project export/import to the “Available Tools and Resources” section.
300
+ - **Installation Clarity**: Improved `uv` instructions with verification steps and explicit paths for Claude integration.
301
+ - **Troubleshooting**: Enhanced with specific commands and log locations for debugging.
302
+ - **Configuration**: Updated API access notes to reflect the dynamic path handling in `ResolveAPI`.
303
+
304
+ This README now fully aligns with the enhanced `ResolveAPI` class, providing a comprehensive guide for users and developers. Let me know if you’d like further adjustments!
@@ -0,0 +1,9 @@
1
+ resolve_mcp/__init__.py,sha256=GySdU8ZrBKfj_b32XvfBClGTcxSZ_brxzaT5_jm7GSk,25
2
+ resolve_mcp/mock_resolve_api.py,sha256=0E2FpS2Mv0jrooEHOjqOquPnTaCDkhQUmtVXINMFG_I,5553
3
+ resolve_mcp/resolve_api.py,sha256=PKSYlbDOjcHb-du34q-zoWLpwerTIcC8KG22CE99NdQ,38315
4
+ resolve_mcp/server.py,sha256=SKiFZb9NIrMDQjkoXlZzgdnCl98c0t3fKHOkiirbRC0,19956
5
+ iflow_mcp_tooflex_davinci_resolve_mcp-0.1.0.dist-info/METADATA,sha256=Hjt8w2rBheAkYM_tbTUtGWa66Bf6xsQpgW7EhiW7MAo,8628
6
+ iflow_mcp_tooflex_davinci_resolve_mcp-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
7
+ iflow_mcp_tooflex_davinci_resolve_mcp-0.1.0.dist-info/entry_points.txt,sha256=hF12jsXx2zVSwUO7BMMn-Cgy7ZdotKaOL6MxWbXl5w0,64
8
+ iflow_mcp_tooflex_davinci_resolve_mcp-0.1.0.dist-info/top_level.txt,sha256=WH9_lrQukrwzuuXHKPXaHC6vjo3CUwke3u5IIptduQg,12
9
+ iflow_mcp_tooflex_davinci_resolve_mcp-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ davinci-resolve-mcp = resolve_mcp.server:main
@@ -0,0 +1 @@
1
+ from .server import main
@@ -0,0 +1,206 @@
1
+ """
2
+ Mock DaVinci Resolve API for testing without actual DaVinci Resolve installation.
3
+ """
4
+
5
+ import logging
6
+ from typing import Optional, Dict, List, Any
7
+
8
+ logger = logging.getLogger("MockResolveAPI")
9
+
10
+ class MockResolveAPI:
11
+ """Mock Resolve API for testing purposes."""
12
+
13
+ def __init__(self):
14
+ """Initialize mock API."""
15
+ self.resolve = "mock"
16
+ self.fusion = "mock"
17
+ self.project_manager = "mock"
18
+ self.current_project = "mock"
19
+ self.media_storage = "mock"
20
+ self.media_pool = "mock"
21
+ logger.info("Using mock Resolve API for testing")
22
+
23
+ def refresh(self) -> None:
24
+ """Refresh mock state."""
25
+ logger.info("Mock refreshed")
26
+
27
+ def is_connected(self) -> bool:
28
+ """Always return True for mock."""
29
+ return True
30
+
31
+ def get_project_manager(self):
32
+ return self.project_manager
33
+
34
+ def get_current_project(self):
35
+ return self.current_project
36
+
37
+ def get_media_storage(self):
38
+ return self.media_storage
39
+
40
+ def get_media_pool(self):
41
+ return self.media_pool
42
+
43
+ def get_fusion(self):
44
+ return self.fusion
45
+
46
+ def open_page(self, page_name: str) -> bool:
47
+ return True
48
+
49
+ def create_project(self, project_name: str) -> bool:
50
+ return True
51
+
52
+ def load_project(self, project_name: str) -> bool:
53
+ return True
54
+
55
+ def save_project(self) -> bool:
56
+ return True
57
+
58
+ def get_project_name(self) -> Optional[str]:
59
+ return "Mock Project"
60
+
61
+ def create_timeline(self, timeline_name: str) -> bool:
62
+ return True
63
+
64
+ def get_current_timeline(self):
65
+ return None
66
+
67
+ def get_timeline_count(self) -> int:
68
+ return 0
69
+
70
+ def get_timeline_by_index(self, index: int):
71
+ return None
72
+
73
+ def set_current_timeline(self, timeline) -> bool:
74
+ return True
75
+
76
+ def get_mounted_volumes(self) -> List[str]:
77
+ return []
78
+
79
+ def get_sub_folders(self, folder_path: str) -> List[str]:
80
+ return []
81
+
82
+ def get_files(self, folder_path: str) -> List[str]:
83
+ return []
84
+
85
+ def add_items_to_media_pool(self, file_paths: List[str]) -> List[Any]:
86
+ return []
87
+
88
+ def get_root_folder(self):
89
+ return None
90
+
91
+ def get_current_folder(self):
92
+ return None
93
+
94
+ def add_sub_folder(self, parent_folder, folder_name: str):
95
+ return None
96
+
97
+ def get_folder_clips(self, folder) -> List[Any]:
98
+ return []
99
+
100
+ def get_folder_name(self, folder) -> Optional[str]:
101
+ return None
102
+
103
+ def get_folder_sub_folders(self, folder) -> List[Any]:
104
+ return []
105
+
106
+ def append_to_timeline(self, clips: List[Any]) -> bool:
107
+ return True
108
+
109
+ def create_timeline_from_clips(self, timeline_name: str, clips: List[Any]):
110
+ return None
111
+
112
+ def import_timeline_from_file(self, file_path: str):
113
+ return None
114
+
115
+ def execute_lua(self, script: str) -> Any:
116
+ return "Mock Lua execution"
117
+
118
+ def create_fusion_node(self, node_type: str, inputs: Dict[str, Any] = None) -> Any:
119
+ return None
120
+
121
+ def get_current_comp(self) -> Any:
122
+ return None
123
+
124
+ def get_timeline_items(self, track_type: str = "video", track_index: int = 1) -> List[Any]:
125
+ return []
126
+
127
+ def set_clip_property(self, clip, property_name: str, value: Any) -> bool:
128
+ return True
129
+
130
+ def get_color_page_nodes(self) -> List[Any]:
131
+ return []
132
+
133
+ def add_color_node(self, node_type: str = "Corrector") -> Optional[Any]:
134
+ return None
135
+
136
+ def get_project_settings(self) -> Dict[str, Any]:
137
+ return {}
138
+
139
+ def set_project_setting(self, key: str, value: Any) -> bool:
140
+ return True
141
+
142
+ def start_render(self, preset_name: str = None, render_path: str = None) -> bool:
143
+ return True
144
+
145
+ def get_render_status(self) -> Dict[str, Any]:
146
+ return {"IsRenderInProgress": False, "CompletionPercentage": 0}
147
+
148
+ def add_timeline_marker(self, frame: int, color: str = "Blue", name: str = "", note: str = "") -> bool:
149
+ return True
150
+
151
+ def get_clip_metadata(self, clip) -> Dict[str, Any]:
152
+ return {}
153
+
154
+ def get_gallery(self) -> Any:
155
+ return None
156
+
157
+ def get_gallery_albums(self) -> List[Any]:
158
+ return []
159
+
160
+ def save_still(self, album_name: str = "Stills") -> Optional[Any]:
161
+ return None
162
+
163
+ def apply_still(self, still, clip=None) -> bool:
164
+ return True
165
+
166
+ def add_track(self, track_type: str = "video") -> bool:
167
+ return True
168
+
169
+ def set_track_name(self, track_type: str, track_index: int, name: str) -> bool:
170
+ return True
171
+
172
+ def enable_track(self, track_type: str, track_index: int, enable: bool = True) -> bool:
173
+ return True
174
+
175
+ def set_audio_volume(self, clip_name: str, volume: float) -> bool:
176
+ return True
177
+
178
+ def set_track_volume(self, track_index: int, volume: float) -> bool:
179
+ return True
180
+
181
+ def set_current_version(self, clip_name: str, version_index: int, version_type: str = "color") -> str:
182
+ return "Mock version set"
183
+
184
+ def play(self) -> bool:
185
+ return True
186
+
187
+ def stop(self) -> bool:
188
+ return True
189
+
190
+ def set_playhead_position(self, frame: int) -> bool:
191
+ return True
192
+
193
+ def get_current_timecode(self) -> Optional[str]:
194
+ return "00:00:00:00"
195
+
196
+ def export_project(self, project_name: str, file_path: str) -> bool:
197
+ return True
198
+
199
+ def import_project(self, file_path: str) -> bool:
200
+ return True
201
+
202
+ def play_timeline(self) -> str:
203
+ return "Playback started (mock)."
204
+
205
+ def stop_timeline(self) -> str:
206
+ return "Playback stopped (mock)."