davinci-resolve-mcp 2.57.3 → 2.57.4

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  Release history for the DaVinci Resolve MCP Server. The latest release is summarized in the root README; older entries live here to keep the README focused.
4
4
 
5
+ ## What's New in v2.57.4
6
+
7
+ Live mutating verification of the catalogued API gaps.
8
+
9
+ - **Added** `tests/live_api_gap_verification.py` — attempts each catalogued
10
+ "missing capability" against a disposable project built from synthetic ffmpeg
11
+ media, recording the failing call alongside a positive control that succeeds.
12
+ All 8 surface-audited gaps confirmed missing on Resolve Studio 21.0.0:
13
+ `SetProperty('Speed', …)` / audio-level keys return False while
14
+ `RetimeProcess` / video-transform keys succeed; trim/move/split/proxy/node-
15
+ graph/Smart-Bin methods are absent (by `dir()`), while append/CDL/AddSubFolder
16
+ controls work.
17
+ - **Added** a new bug entry: `hasattr()`/`getattr()` are unusable on Resolve
18
+ objects — the Python bridge fabricates a callable for ANY attribute name, so
19
+ capability detection must use `dir()`. (Discovered when the first harness pass
20
+ reported nonexistent methods as present.) Report now lists 14 missing + 10 bugs.
21
+ - **Changed** the report's Scope note to record the live mutating-harness
22
+ methodology and the `hasattr` caveat. Strengthened the clip-speed and
23
+ Fairlight-audio entries with the live `SetProperty` rejection evidence (and
24
+ noted that `'Pan'` is the video-transform key, not audio pan).
25
+
5
26
  ## What's New in v2.57.3
6
27
 
7
28
  Expanded the API-limitations catalogue with a live surface audit.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # DaVinci Resolve MCP Server
2
2
 
3
- [![Version](https://img.shields.io/badge/version-2.57.3-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.57.4-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
4
4
  [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
5
5
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
6
6
  [![Tools](https://img.shields.io/badge/MCP%20Tools-34%20(341%20full)-blue.svg)](#server-modes)
@@ -12,7 +12,7 @@ that none exists).
12
12
 
13
13
  **Verified on:** DaVinci Resolve Studio 21.0.0
14
14
 
15
- **Totals:** 14 missing capabilities, 9 bugs / unreliable behaviors.
15
+ **Totals:** 14 missing capabilities, 10 bugs / unreliable behaviors.
16
16
 
17
17
  The authoritative source is the runtime-queryable `api_truth` ledger
18
18
  (`resolve_control api_truth "<query>"`); this document is generated from
@@ -21,14 +21,21 @@ it and stays in sync via a drift guard.
21
21
  ### Scope & completeness
22
22
 
23
23
  This list is **not guaranteed exhaustive.** It combines (a) issues hit
24
- while building this MCP server and (b) a `dir()` surface audit of the live
24
+ while building this MCP server, (b) a `dir()` surface audit of the live
25
25
  Resolve API objects (ProjectManager, Project, MediaPool, MediaPoolItem,
26
- Timeline, TimelineItem, Graph) diffed against Resolve's UI feature set.
26
+ Timeline, TimelineItem, Graph) diffed against Resolve's UI feature set,
27
+ and (c) a live mutating harness (`tests/live_api_gap_verification.py`)
28
+ that attempts each operation against a disposable project built from
29
+ synthetic media and confirms it fails while a related control succeeds.
27
30
  That catches absent methods and documented constraints, but not subtler
28
31
  issues: parameters that exist yet misbehave, version-specific regressions,
29
32
  or capabilities we simply never exercised. New findings are added as
30
33
  `submit`-tagged `api_truth` entries and this document is regenerated.
31
34
 
35
+ Note: `hasattr()`/`getattr()` cannot be used to probe this API — the
36
+ Python bridge fabricates a callable for any attribute name (see the
37
+ `hasattr` bug below). Method existence here was checked with `dir()`.
38
+
32
39
  ## Missing Capabilities (please add)
33
40
 
34
41
  Functionality that exists in the Resolve UI but has no scripting API
@@ -95,7 +102,7 @@ equivalent, blocking full automation.
95
102
  ### Clip speed / retime ratio and speed ramps
96
103
 
97
104
  - **Object:** `TimelineItem`
98
- - **Behavior:** SetProperty exposes only retime *quality* (RetimeProcess, MotionEstimation) and transform/crop/composite/opacity keys — not the speed value itself. There is no way to set a clip to a given % speed, reverse it, or author a speed ramp. Verified against the documented SetProperty key list (21.0.0).
105
+ - **Behavior:** SetProperty exposes only retime *quality* (RetimeProcess, MotionEstimation) and transform/crop/composite/opacity keys — not the speed value itself. There is no way to set a clip to a given % speed, reverse it, or author a speed ramp. Verified against the documented SetProperty key list AND by live mutating attempt on 21.0.0: SetProperty('Speed'|'PlaybackSpeed'|'RetimeSpeed'|'ClipSpeed', 50) all return False, while SetProperty('RetimeProcess', 1) returns True.
99
106
  - **Workaround / current handling:** Set clip speed/retime in the Resolve UI; no scripted equivalent exists.
100
107
  - **Tags:** missing-method, timeline, retime, speed
101
108
 
@@ -109,7 +116,7 @@ equivalent, blocking full automation.
109
116
  ### Fairlight audio levels / pan / EQ / automation / FairlightFX
110
117
 
111
118
  - **Object:** `TimelineItem / Timeline`
112
- - **Behavior:** There is no API to set clip or track volume, pan, EQ, audio automation, or to add/configure FairlightFX. SetProperty covers video transform only; the audio surface is read-only (GetSourceAudioChannelMapping, GetAudioMapping, voice isolation). Verified via dir() + SetProperty docs (21.0.0).
119
+ - **Behavior:** There is no API to set clip or track volume, pan, EQ, audio automation, or to add/configure FairlightFX. SetProperty covers video transform only; the audio surface is read-only (GetSourceAudioChannelMapping, GetAudioMapping, voice isolation). Verified via dir() + SetProperty docs AND by live mutating attempt on 21.0.0: SetProperty('Volume'|'Level'|'Gain'|'AudioVolume', 0) all return False (note 'Pan' is the VIDEO transform key, not audio pan, so it misleadingly succeeds).
113
120
  - **Workaround / current handling:** Mix in the Fairlight UI; only voice-isolation state and channel-mapping reads are scriptable.
114
121
  - **Tags:** missing-method, audio, fairlight
115
122
 
@@ -206,3 +213,10 @@ values, or automation-hostile modal prompts.
206
213
  - **Behavior:** Returns None and pops a modal 'Save Current Project' dialog when the current unsaved/Untitled project blocks the switch. SaveProject() on an Untitled project re-triggers the same modal.
207
214
  - **Workaround / current handling:** CloseProject(current) to discard the untitled project without a prompt, then CreateProject; restore with LoadProject afterward.
208
215
  - **Tags:** project, modal, silent-failure
216
+
217
+ ### hasattr() / getattr() on Resolve API objects (attribute fabrication)
218
+
219
+ - **Object:** `(all Resolve scripting objects)`
220
+ - **Behavior:** The Python bridge returns a callable for ANY attribute name, so hasattr(obj, 'TotallyMadeUpMethod') is always True and getattr never raises. This makes capability detection by hasattr impossible — verified on 21.0.0 (hasattr reported SetStart, Razor, AddNode, GenerateProxy, AddSmartBin etc. as present though none exist). Only dir() lists the real methods.
221
+ - **Workaround / current handling:** Never probe method existence with hasattr/getattr; test membership against dir(obj) instead. Calling a fabricated method typically returns None/False with no error.
222
+ - **Tags:** bridge, introspection, silent-failure
package/install.py CHANGED
@@ -35,7 +35,7 @@ from src.utils.update_check import (
35
35
 
36
36
  # ─── Version ──────────────────────────────────────────────────────────────────
37
37
 
38
- VERSION = "2.57.3"
38
+ VERSION = "2.57.4"
39
39
  # Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
40
40
  # Resolve's scripting bridge loads into newer interpreters on recent builds
41
41
  # (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "davinci-resolve-mcp",
3
- "version": "2.57.3",
3
+ "version": "2.57.4",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",
@@ -85,14 +85,21 @@ def render() -> str:
85
85
  "### Scope & completeness",
86
86
  "",
87
87
  "This list is **not guaranteed exhaustive.** It combines (a) issues hit",
88
- "while building this MCP server and (b) a `dir()` surface audit of the live",
88
+ "while building this MCP server, (b) a `dir()` surface audit of the live",
89
89
  "Resolve API objects (ProjectManager, Project, MediaPool, MediaPoolItem,",
90
- "Timeline, TimelineItem, Graph) diffed against Resolve's UI feature set.",
90
+ "Timeline, TimelineItem, Graph) diffed against Resolve's UI feature set,",
91
+ "and (c) a live mutating harness (`tests/live_api_gap_verification.py`)",
92
+ "that attempts each operation against a disposable project built from",
93
+ "synthetic media and confirms it fails while a related control succeeds.",
91
94
  "That catches absent methods and documented constraints, but not subtler",
92
95
  "issues: parameters that exist yet misbehave, version-specific regressions,",
93
96
  "or capabilities we simply never exercised. New findings are added as",
94
97
  "`submit`-tagged `api_truth` entries and this document is regenerated.",
95
98
  "",
99
+ "Note: `hasattr()`/`getattr()` cannot be used to probe this API — the",
100
+ "Python bridge fabricates a callable for any attribute name (see the",
101
+ "`hasattr` bug below). Method existence here was checked with `dir()`.",
102
+ "",
96
103
  "## Missing Capabilities (please add)",
97
104
  "",
98
105
  "Functionality that exists in the Resolve UI but has no scripting API",
@@ -80,7 +80,7 @@ if not logging.getLogger().handlers:
80
80
  handlers=[logging.StreamHandler()],
81
81
  )
82
82
 
83
- VERSION = "2.57.3"
83
+ VERSION = "2.57.4"
84
84
  logger = logging.getLogger("davinci-resolve-mcp")
85
85
  logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
86
86
  logger.info(f"Detected platform: {get_platform()}")
package/src/server.py CHANGED
@@ -11,7 +11,7 @@ Usage:
11
11
  python src/server.py --full # Start the 341-tool granular server instead
12
12
  """
13
13
 
14
- VERSION = "2.57.3"
14
+ VERSION = "2.57.4"
15
15
 
16
16
  import base64
17
17
  import os
@@ -290,7 +290,10 @@ API_TRUTH: List[Dict[str, Any]] = [
290
290
  "MotionEstimation) and transform/crop/composite/opacity keys — "
291
291
  "not the speed value itself. There is no way to set a clip to a "
292
292
  "given % speed, reverse it, or author a speed ramp. Verified "
293
- "against the documented SetProperty key list (21.0.0).",
293
+ "against the documented SetProperty key list AND by live "
294
+ "mutating attempt on 21.0.0: SetProperty('Speed'|'PlaybackSpeed'"
295
+ "|'RetimeSpeed'|'ClipSpeed', 50) all return False, while "
296
+ "SetProperty('RetimeProcess', 1) returns True.",
294
297
  "recommended": "Set clip speed/retime in the Resolve UI; no scripted "
295
298
  "equivalent exists.",
296
299
  "tags": ["missing-method", "timeline", "retime", "speed"],
@@ -319,7 +322,10 @@ API_TRUTH: List[Dict[str, Any]] = [
319
322
  "automation, or to add/configure FairlightFX. SetProperty covers "
320
323
  "video transform only; the audio surface is read-only "
321
324
  "(GetSourceAudioChannelMapping, GetAudioMapping, voice "
322
- "isolation). Verified via dir() + SetProperty docs (21.0.0).",
325
+ "isolation). Verified via dir() + SetProperty docs AND by live "
326
+ "mutating attempt on 21.0.0: SetProperty('Volume'|'Level'|'Gain'"
327
+ "|'AudioVolume', 0) all return False (note 'Pan' is the VIDEO "
328
+ "transform key, not audio pan, so it misleadingly succeeds).",
323
329
  "recommended": "Mix in the Fairlight UI; only voice-isolation state and "
324
330
  "channel-mapping reads are scriptable.",
325
331
  "tags": ["missing-method", "audio", "fairlight"],
@@ -360,6 +366,21 @@ API_TRUTH: List[Dict[str, Any]] = [
360
366
  "tags": ["missing-method", "media-pool", "bins"],
361
367
  "submit": "missing",
362
368
  },
369
+ {
370
+ "symbol": "hasattr() / getattr() on Resolve API objects (attribute fabrication)",
371
+ "object": "(all Resolve scripting objects)",
372
+ "reality": "The Python bridge returns a callable for ANY attribute name, so "
373
+ "hasattr(obj, 'TotallyMadeUpMethod') is always True and getattr "
374
+ "never raises. This makes capability detection by hasattr "
375
+ "impossible — verified on 21.0.0 (hasattr reported SetStart, "
376
+ "Razor, AddNode, GenerateProxy, AddSmartBin etc. as present "
377
+ "though none exist). Only dir() lists the real methods.",
378
+ "recommended": "Never probe method existence with hasattr/getattr; test "
379
+ "membership against dir(obj) instead. Calling a fabricated "
380
+ "method typically returns None/False with no error.",
381
+ "tags": ["bridge", "introspection", "silent-failure"],
382
+ "submit": "bug",
383
+ },
363
384
  {
364
385
  "symbol": "subprocess inheriting stdin under the MCP stdio server",
365
386
  "object": "(server runtime)",