davinci-resolve-mcp 2.67.0 → 2.68.0

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,123 @@
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.68.0
6
+
7
+ Six engines that let an agent judge its own output before shipping it — audio
8
+ loudness, silence calibration, image QC, transcript editing, captions — plus the
9
+ **in-app bridge**, which reaches the **free edition** of DaVinci Resolve, whose
10
+ external scripting API refuses foreign processes entirely.
11
+
12
+ ### Added
13
+
14
+ - **Audio delivery QC.** Delivery targets carry a named loudness contract
15
+ (`web`, `podcast`, `ebu_r128`, `atsc_a85`, `ott_dialogue_gated`) and project it
16
+ into the existing `loudness_qc` vocabulary. Dialogue-gated standards emit no
17
+ gradeable `integrated` figure — `loudness_qc` measures full-program, so grading
18
+ a dialogue-gated number against it produces a verdict that means nothing; it
19
+ travels as advisory metadata with the reason stated. No shipped target names a
20
+ standard, because a ProRes master has no inherent programme loudness.
21
+ `render(action='list_loudness_standards')`.
22
+ - **Auto-calibrated silence gate.** `plan_silence_ripple` derives the threshold
23
+ from each clip's own dynamics instead of a fixed −30 dB. The metric is `astats`
24
+ **RMS trough** paired with RMS peak: `mean_volume` tracks programme level, and
25
+ `Noise floor dB` moved 19 dB between two fixtures sharing an identical noise
26
+ bed purely because one was quieter for longer. Against ground truth the fixed
27
+ threshold was wrong on all four fixtures. When calibration cannot be trusted
28
+ the item is **kept whole** rather than stripped — a fixed threshold applied to
29
+ material it does not suit is not a degraded answer, it is a wrong one.
30
+ - **Image QC.** `media_analysis(action='assess_grade')` gives an agent
31
+ deterministic grounds to reject its own grade: tonal frame, noise
32
+ amplification, banding, highlight posterization and clipping growth, with
33
+ validated **CIEDE2000** (all 33 Sharma/Wu/Dalal reference pairs to 4 dp). A
34
+ clean grade costs zero tokens; vision is spent only where the numbers cannot
35
+ settle it. Non-display-referred working spaces are **refused, never guessed** —
36
+ the right transform depends on camera and project colour management, which a
37
+ frame cannot tell you.
38
+ - **Word-level transcript editing.** `edit_engine(action='plan_transcript_tighten')`
39
+ removes fillers, false starts and over-long pauses at word boundaries with a
40
+ reason per cut, and `search_spoken_content` searches word timings across a
41
+ whole shoot to build selects. A lexical axis alongside `find_similar`'s
42
+ semantic-visual one.
43
+ - **Captions.** `media_analysis(action='generate_captions')` emits SRT and WebVTT
44
+ under broadcast line rules, plus chapters and YouTube description text.
45
+ - **The in-app bridge — live read and write control of the FREE edition.**
46
+ Opt-in with `DAVINCI_RESOLVE_BRIDGE=1`; unset changes nothing for existing
47
+ installs. A script launched from Workspace ▸ Scripts is handed the live
48
+ `resolve` object on any edition and re-exports it over an authenticated
49
+ loopback listener, which `connect_resolve` uses as a third transport beside
50
+ Local and Network. Existing call sites need no changes. This is the documented
51
+ in-app path, not a licence circumvention — but Blackmagic could close it, so
52
+ treat it as supported-until-it-is-not.
53
+ - **`shutdown` and `reload` for the bridge.** The launcher blocks (correctly — a
54
+ Scripts-menu script is a child process, so a daemon thread dies the instant it
55
+ returns), which used to mean a stale in-Resolve copy could only be replaced by
56
+ quitting Resolve. `reload` re-imports the runtime from disk in place, and
57
+ refuses before stopping if the new sources will not compile.
58
+
59
+ ### Fixed
60
+
61
+ - **The bridge was unreachable on the machine it exists for.** `_try_connect`
62
+ returned on `dvr_script is None` before calling `connect_resolve`, the function
63
+ that accepts None in bridge mode. Blackmagic's scripting module ships with the
64
+ *installer*, not the App Store build, so a free-edition-only machine has no
65
+ `Developer/Scripting/Modules` tree and the import fails. Verified by blocking
66
+ the import against a healthy live bridge: `get_resolve()` answered None.
67
+ - **Auto-launch started the wrong Resolve, or one nobody asked for.** The macOS
68
+ path list contained only the installer location, so a free-only machine found
69
+ nothing and a machine with both always started Studio. In bridge mode it now
70
+ refuses outright: launching cannot create a listener that only a Scripts-menu
71
+ run creates.
72
+ - **Interchange export over the bridge was degrading silently.** Resolve's API
73
+ constants (`EXPORT_AAF`, `AUDIO_SYNC_*`) are plain attributes and `dir()` does
74
+ not list them — measured on 21.0.3.7, `dir(resolve)` returns 34 names with no
75
+ `EXPORT_*` among them while the constants read back as real values. The proxy
76
+ could only call methods, so `hasattr` said False and the server fell through to
77
+ handing Resolve the bare string `"EXPORT_AAF"`.
78
+ - **The proxy broke every chain longer than one call.** Every live Resolve object
79
+ reports `type(obj).__name__ == "PyRemoteObject"` — root 34 methods, Project 49,
80
+ TimelineItem 88, one class name — so caching method sets on it let the first
81
+ object touched define `hasattr` for everything after. Method sets are now keyed
82
+ on provenance, and absence is re-verified against the object itself.
83
+ - **Bridge error codes never crossed the transport.** Every surface code was
84
+ flattened to `operation_failed`, so `stale_handle` (re-fetch) and
85
+ `ambiguous_locator` (disambiguate) arrived as one undifferentiated failure.
86
+
87
+ ### Validated live
88
+
89
+ On **DaVinci Resolve 21.0.3.7 (App Store, free, sandboxed)**, with Blackmagic's
90
+ scripting module blocked to reproduce a free-only machine: 34 tools, 583 declared
91
+ actions, **165 read-shaped actions attempted, 145 clean, zero bridge-attributable
92
+ failures**; 109 of the 112 API read methods the tools actually call exercised on
93
+ the live object graph; a render completed to a non-empty file; AAF/DRT/EDL/FCPXML
94
+ all written by `Timeline.Export`; 400 clips appended in 1.23 s and enumerated at
95
+ 0.81 ms/item; an evicted handle refusing with `stale_handle` rather than
96
+ resolving to another object; and reads *and* writes continuing to work with a
97
+ native file dialog open, because the bridge runs in its own process.
98
+
99
+ `scripts/bridge_differential.py --mode differential` diffs the bridge against
100
+ native scripting on one Studio instance. That comparison has **not** been run
101
+ yet, so the evidenced claim is that the bridge carries the surface the tools use
102
+ on the free edition — not that it is byte-identical to native scripting.
103
+
104
+ ## What's New in v2.67.1
105
+
106
+ Documentation correction. No code changes — v2.67.0 already ships the correct
107
+ behavior.
108
+
109
+ ### Changed
110
+
111
+ - **`docs/kernels/render-deliver-kernel.md` no longer quotes a format/codec count
112
+ as portable.** It presented "23 formats and 99 format/codec pairs" as the
113
+ expected probe result; a live probe on Studio 19.1.3.7 found 20 formats and 271
114
+ pairs. Both mentions now carry the build they came from and point at probing
115
+ the machine in hand (`probe_render_matrix`, or `list_delivery_targets` with
116
+ `check_availability`) instead of comparing against a fixed number.
117
+ - The kernel's boundary list now records the two traps the delivery-target work
118
+ verified live: codec **descriptions are not codec ids** (`H.264` vs `H264`, not
119
+ only the ProRes family), and some formats expose **no codecs at all** (`Wave`,
120
+ `GIF` on 19.1.3.7) and cannot be selected through this API.
121
+
5
122
  ## What's New in v2.67.0
6
123
 
7
124
  Adds **delivery targets** — named render intents that carry their own QC spec —
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.67.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.68.0-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)
@@ -22,7 +22,7 @@ A local browser control panel ships with the server for inspecting Resolve state
22
22
  npx davinci-resolve-mcp setup
23
23
  ```
24
24
 
25
- Before connecting, open DaVinci Resolve Studio and set **Preferences > General > External scripting using** to **Local**. The npm launcher installs a managed copy under your user application-data directory, then runs the universal Python installer. The installer creates a virtual environment, detects Resolve paths, and can configure Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, Continue, Cline, Roo Code, OpenCode, and JetBrains IDEs.
25
+ Before connecting, open DaVinci Resolve Studio and set **Preferences > General > External scripting using** to **Local**. (On the **free edition** that preference does not help — see [Free edition](#free-edition-in-app-bridge) below.) The npm launcher installs a managed copy under your user application-data directory, then runs the universal Python installer. The installer creates a virtual environment, detects Resolve paths, and can configure Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, Continue, Cline, Roo Code, OpenCode, and JetBrains IDEs.
26
26
 
27
27
  For source installs:
28
28
 
@@ -36,6 +36,31 @@ For platform paths, client-specific config, and manual setup, see [Installation
36
36
 
37
37
  The installer and server check the latest GitHub release for MCP updates. Checks are best-effort and throttled; the server never blocks MCP startup for a prompt. The installer can prompt, snooze, ignore a release, disable checks, or apply an opt-in safe auto-update for clean git checkouts.
38
38
 
39
+ ## Free edition (in-app bridge)
40
+
41
+ Blackmagic gates *external* scripting to Studio: on the free edition
42
+ `scriptapp("Resolve")` refuses a foreign process, whatever the preference says.
43
+ The **Workspace ▸ Scripts** menu is not gated — a script launched from it is
44
+ handed the live `resolve` object on any edition — so the server can reach the
45
+ free edition through a small script that runs *inside* Resolve and re-exports it
46
+ over an authenticated loopback listener.
47
+
48
+ ```bash
49
+ python scripts/install_resolve_bridge.py
50
+ # restart Resolve, open a project, then: Workspace > Scripts > resolve_bridge
51
+ export DAVINCI_RESOLVE_BRIDGE=1 # opt-in; unset changes nothing
52
+ ```
53
+
54
+ Requires a **framework Python** (python.org). Resolve enumerates `.py` scripts
55
+ only when it finds one — Homebrew, pyenv and conda interpreters are not
56
+ detected, and the script silently never appears in the menu. A Lua canary is
57
+ installed alongside so you can tell that apart from a wrong folder.
58
+
59
+ Validated on free 21.0.3.7 and Studio 19.1.3.7. This is the documented in-app
60
+ path, not a licence circumvention, but Blackmagic could close it — treat it as a
61
+ supported-until-it-is-not tier. Loopback only, HMAC-signed requests, one-use
62
+ nonces.
63
+
39
64
  ## Local Control Panel
40
65
 
41
66
  Launch the single-user local control panel from the repository root:
package/docs/SKILL.md CHANGED
@@ -19,6 +19,26 @@ configured to the Resolve host IP (use `127.0.0.1` on the same machine). The
19
19
  server auto-launches Resolve if it is not running, but that first connection can
20
20
  take up to 60 seconds.
21
21
 
22
+ **Free edition.** Both of those preferences are Studio features; on the free
23
+ edition `scriptapp("Resolve")` refuses a foreign process regardless. A third
24
+ transport reaches it — a script run from **Workspace ▸ Scripts** is handed the
25
+ live `resolve` object on any edition and re-exports it over an authenticated
26
+ loopback listener. Install with `python scripts/install_resolve_bridge.py`, start
27
+ it from that menu, and set `DAVINCI_RESOLVE_BRIDGE=1`. Existing tool call sites
28
+ work unchanged. Two things to know when diagnosing it:
29
+
30
+ - Resolve lists `.py` scripts only when it can find a **framework Python**
31
+ (python.org). Homebrew/pyenv/conda are not detected and the script simply never
32
+ appears, with no error. The installer preflights this and ships a Lua canary,
33
+ which always lists, so "Python not detected" is distinguishable from "wrong
34
+ folder".
35
+ - The in-Resolve runtime is a **copy taken at install time**. After changing the
36
+ repository, re-run the installer and then ask the running bridge to reload —
37
+ it re-imports from disk in place, so Resolve does not need restarting.
38
+
39
+ The bridge is a documented in-app path rather than a licence circumvention, but
40
+ Blackmagic could close it; treat it as a supported-until-it-is-not tier.
41
+
22
42
  Network scripting permits remote control of Resolve. Use Local mode when remote
23
43
  access is unnecessary; otherwise restrict access with host firewall and network
24
44
  controls.
@@ -79,7 +79,17 @@ come from one definition.
79
79
  readback as version/page dependent and still validates and applies settings
80
80
  through `SetRenderSettings`.
81
81
  - Render format and codec availability is machine, OS, license, and plugin
82
- dependent. The final live probe found 23 formats and 99 format/codec pairs.
82
+ dependent, and it varies a lot: a live probe found 23 formats / 99 pairs on one
83
+ build, and 20 formats / 271 pairs on Studio 19.1.3.7. Treat neither figure as
84
+ the expected count — probe the machine you are on
85
+ (`probe_render_matrix`, or `list_delivery_targets` with `check_availability`).
86
+ - Codec **descriptions are not codec ids**. `GetRenderCodecs` returns
87
+ `{description: id}` and every setter wants the id, so the name shown in the
88
+ Deliver page is rejected — for `H.264` (`H264`) just as much as for
89
+ `Apple ProRes 422 HQ` (`ProRes422HQ`). `src/utils/render_ids.py` normalizes
90
+ either form; see `docs/reference/api-limitations.md`.
91
+ - Some formats expose **no codecs at all** (`Wave`, `GIF` on 19.1.3.7) and then
92
+ reject every codec value, so they cannot be selected through this API.
83
93
  - Some settings may be accepted but not readable for coercion checks on builds
84
94
  where `GetRenderSettings` is unavailable.
85
95
  - Quick Export actual execution is intentionally gated behind
@@ -151,6 +161,8 @@ Result:
151
161
 
152
162
  The live harness created and deleted a disposable project named
153
163
  `_mcp_render_deliver_probe_1778342107`, generated synthetic media, probed 23
154
- formats and 99 format/codec pairs, rendered one tiny synthetic output, wrote
164
+ formats and 99 format/codec pairs **on that build** (a later probe on Studio
165
+ 19.1.3.7 saw 20 formats / 271 pairs — the counts are not portable), rendered one
166
+ tiny synthetic output, wrote
155
167
  JSON and Markdown reports, and removed the generated media and render output
156
168
  directories after the report was written.
package/install.py CHANGED
@@ -36,7 +36,7 @@ from src.utils.update_check import (
36
36
 
37
37
  # ─── Version ──────────────────────────────────────────────────────────────────
38
38
 
39
- VERSION = "2.67.0"
39
+ VERSION = "2.68.0"
40
40
  # Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
41
41
  # Resolve's scripting bridge loads into newer interpreters on recent builds
42
42
  # (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.67.0",
3
+ "version": "2.68.0",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",