davinci-resolve-mcp 2.99.1 → 2.99.2
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 +34 -0
- package/README.md +1 -1
- package/README.zh-CN.md +2 -2
- package/docs/reference/api-limitations.md +10 -2
- package/install.py +1 -1
- package/package.json +1 -1
- package/src/granular/common.py +1 -1
- package/src/server.py +1 -1
- package/src/utils/api_truth.py +38 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
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.99.2
|
|
6
|
+
|
|
7
|
+
**The Fusion comp-lock question is closed on Resolve 21.** The v2.98.5–v2.98.8
|
|
8
|
+
work isolated the bug on Studio 19.1.3.7 only, and the open caveat was whether
|
|
9
|
+
the "renders on 19.1.3.7, ignored on 21.0.4.5" split reported in
|
|
10
|
+
[#156](https://github.com/samuelgursky/davinci-resolve-mcp/pull/156) had a
|
|
11
|
+
version component on top of it. It does not.
|
|
12
|
+
|
|
13
|
+
Measured on **DaVinci Resolve 21.0.3.7**, driven through the in-app bridge: the
|
|
14
|
+
same wired `MediaIn -> Blur(XBlurSize 20) -> MediaOut` comp, with the value
|
|
15
|
+
written through the fixed `fusion_comp set_input`, **renders** — PSNR 24.38 dB
|
|
16
|
+
against the no-comp baseline, file shrinking 2,017,973 → 727,261 bytes. That is
|
|
17
|
+
the *same* PSNR figure measured on 19.1.3.7 from the same source and blur.
|
|
18
|
+
|
|
19
|
+
So the split was the `Composition.Lock` bug on both sides, and "a wired comp
|
|
20
|
+
renders" now holds across both Resolve generations tested. The `AddFusionComp`
|
|
21
|
+
entry in `api_truth` records it.
|
|
22
|
+
|
|
23
|
+
**Caveat, stated because it matters:** the 21 confirmation is a **free-edition
|
|
24
|
+
21.0.3.7**, not the Studio 21.0.4.5 the original report used — no Studio 21 was
|
|
25
|
+
available. The graph was also wired with raw proxy calls rather than
|
|
26
|
+
`fusion_comp add_tool`, for the reason below; the value write, which is the step
|
|
27
|
+
that carried the bug, did go through the real server path.
|
|
28
|
+
|
|
29
|
+
### Documented
|
|
30
|
+
|
|
31
|
+
- **`fusion_comp add_tool` cannot run on the free edition.** The in-app bridge's
|
|
32
|
+
proxy exposes `SetInput`/`GetInput`/`ConnectInput`/`FindMainInput` on a Fusion
|
|
33
|
+
tool but not `GetAttrs`/`SetAttrs`, and `add_tool` calls `GetAttrs()`
|
|
34
|
+
unconditionally to build its return value. Comp-level calls all work, so a
|
|
35
|
+
graph can still be wired with raw `comp.AddTool`/`ConnectInput` and driven
|
|
36
|
+
with `fusion_comp` for value writes. New `api_truth` entry; making `add_tool`
|
|
37
|
+
tolerate a missing `GetAttrs` would restore the action there.
|
|
38
|
+
|
|
5
39
|
## What's New in v2.99.1
|
|
6
40
|
|
|
7
41
|
**`bulk_set_item_properties` could not set a clip colour on its own.** Reported
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
English | [简体中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
[](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
|
|
6
6
|
[](https://www.npmjs.com/package/davinci-resolve-mcp)
|
|
7
7
|
[](docs/reference/api-coverage.md)
|
|
8
8
|
[-blue.svg)](#server-modes)
|
package/README.zh-CN.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 简体中文
|
|
4
4
|
|
|
5
|
-
[](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
|
|
6
6
|
[](https://www.npmjs.com/package/davinci-resolve-mcp)
|
|
7
7
|
[](docs/reference/api-coverage.md)
|
|
8
8
|
[-blue.svg)](#服务器模式)
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://www.python.org/downloads/)
|
|
13
13
|
[](https://opensource.org/licenses/MIT)
|
|
14
14
|
|
|
15
|
-
> 本翻译对应 v2.99.
|
|
15
|
+
> 本翻译对应 v2.99.2 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
|
|
16
16
|
|
|
17
17
|
一个 Model Context Protocol (MCP) 服务器,让 AI 助手通过官方脚本 API 控制 DaVinci Resolve Studio(达芬奇)。它提供完整的 API 覆盖,外加带护栏的工作流助手,涵盖剪辑、媒体池整理、渲染设置、审阅标记、调色、Fusion、Fairlight、项目生命周期任务、扩展开发,以及不碰源媒体的媒体分析。
|
|
18
18
|
|
|
@@ -12,7 +12,7 @@ that none exists).
|
|
|
12
12
|
|
|
13
13
|
**Verified on:** DaVinci Resolve Studio 21.0.2
|
|
14
14
|
|
|
15
|
-
**Totals:** 29 missing capabilities,
|
|
15
|
+
**Totals:** 29 missing capabilities, 38 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
|
|
@@ -355,6 +355,14 @@ values, or automation-hostile modal prompts.
|
|
|
355
355
|
- **Workaround / current handling:** Author OTIO for Resolve by mirroring what Resolve itself exports, and give every event its media timecode origin. editorial.convert_to_interchange (target 'otio') does this and reports any event whose origin had to be assumed in `mediaOriginAssumed` — a non-empty list means the file will only import if that media really starts at 00:00:00:00. To debug a refusal, export any timeline with EXPORT_OTIO and diff your document against it; do NOT chase missing media or reach for sanitize_media, which cannot even parse a .otio (it is JSON, not XML).
|
|
356
356
|
- **Tags:** timeline, import, interchange, otio, silent-failure, conform
|
|
357
357
|
|
|
358
|
+
### Fusion tool GetAttrs / SetAttrs (unreachable over the in-app bridge)
|
|
359
|
+
|
|
360
|
+
- **Object:** `Fusion Tool (via the free-edition bridge)`
|
|
361
|
+
- **Signature:** `GetAttrs() -> dict / SetAttrs(dict) -> None`
|
|
362
|
+
- **Behavior:** The in-app bridge's transparent proxy exposes SetInput, GetInput, ConnectInput and FindMainInput on a Fusion tool, but NOT GetAttrs or SetAttrs - the client raises AttributeError('... has no attribute SetAttrs in this Resolve build'). Measured 2026-08-22 on free 21.0.3.7. Because fusion_comp's add_tool calls tool.GetAttrs() unconditionally to build its return value, and SetAttrs whenever a name is passed, `fusion_comp add_tool` cannot run at all on the free edition, which takes connect/set_input with it for any graph the caller wanted to build through the server. Comp-level calls (AddFusionComp, GetFusionCompByIndex, FindTool, AddTool) work, so the graph can still be wired with raw proxy calls.
|
|
363
|
+
- **Workaround / current handling:** On the free edition, wire Fusion graphs with raw comp.AddTool/ConnectInput and use fusion_comp only for value writes. Making add_tool tolerate a missing GetAttrs (fall back to the requested tool_type and a FindTool-based name) would restore the action there.
|
|
364
|
+
- **Tags:** fusion, bridge, free-edition
|
|
365
|
+
|
|
358
366
|
### Composition.Lock (suppresses render invalidation for value writes)
|
|
359
367
|
|
|
360
368
|
- **Object:** `Composition (Fusion, via TimelineItem comps)`
|
|
@@ -366,7 +374,7 @@ values, or automation-hostile modal prompts.
|
|
|
366
374
|
### TimelineItem.AddFusionComp / LoadFusionCompByName
|
|
367
375
|
|
|
368
376
|
- **Object:** `TimelineItem (media-backed clip)`
|
|
369
|
-
- **Behavior:** A Fusion composition created on a media clip through the API is not applied at render WHEN MEDIAOUT HAS NO PATH FROM MEDIAIN. The original blanket form of this entry — 'never applied at render' — was too broad and was corrected on 2026-08-02: a comp wired MediaIn -> Blur -> MediaOut, created entirely through the API on an ordinary media clip, DOES render. PSNR between the plain and Fusion renders of the same timeline was 22.7 dB (identical would be infinite), the file shrank 22.5 MB -> 14.8 MB as a blur should, and the output was frame-for-frame identical in GUI and headless. A first attempt that wired ONLY MediaOut -> Blur, leaving the Blur with no source, made the render job come back 'Failed' with an 887-byte file — so an unrooted graph does not merely get bypassed, it can take the render down. What still stands is the original observation for the configuration it actually tested, which is retained below and has NOT been re-measured: AddFusionComp() returns the comp, AddTool/Connect/SetInput all succeed, and the whole graph reads back correctly (GetCompCount 1, MediaOut1.Input wired to the new tool, StyledText returning the value just set) — but the rendered output is byte-for-byte the untouched source media. Verified live on Studio 19.1.3.7 with the strongest form of the test: MediaOut1 fed ONLY by a Text+, with no path from MediaIn at all, still rendered the unmodified clip. LoadFusionCompByName on the sole comp does not activate it either. Contrast InsertFusionTitleIntoTimeline, whose comp DOES render — text set via SetInput('StyledText') appears in the output — so this is specific to comps attached to media-backed clips, not to Fusion through the API generally. REPRODUCED 2026-08-21 on Studio 19.1.3.7: a rooted MediaIn -> Blur -> MediaOut comp built entirely through the API renders (PSNR 24.38 dB vs the no-comp baseline), so the 2026-08-02 correction stands. Note that an important share of 'the comp was ignored' readings are NOT this entry at all but the Composition.Lock bug above — a parameter written under a comp lock reads back correctly and never reaches the render, which looks identical from the API side. That is what an independent 2026-08-20 report on Studio 21.0.4.5 was measuring: a wired MediaIn -> Blur -> MediaOut comp, and a Transform variant, both delivered renders bit-identical to the no-comp baseline (PSNR inf) when built and set through this server. It was read at the time as a version regression (19.1.3.7 honours a wired comp, 21.0.4.5 does not); with the lock bug identified, the simpler reading is that the same defect reproduces on 21.0.4.5 — and since the lock bug has only been isolated on 19.1.3.7, that report is the only evidence it is not build-specific.
|
|
377
|
+
- **Behavior:** A Fusion composition created on a media clip through the API is not applied at render WHEN MEDIAOUT HAS NO PATH FROM MEDIAIN. The original blanket form of this entry — 'never applied at render' — was too broad and was corrected on 2026-08-02: a comp wired MediaIn -> Blur -> MediaOut, created entirely through the API on an ordinary media clip, DOES render. PSNR between the plain and Fusion renders of the same timeline was 22.7 dB (identical would be infinite), the file shrank 22.5 MB -> 14.8 MB as a blur should, and the output was frame-for-frame identical in GUI and headless. A first attempt that wired ONLY MediaOut -> Blur, leaving the Blur with no source, made the render job come back 'Failed' with an 887-byte file — so an unrooted graph does not merely get bypassed, it can take the render down. What still stands is the original observation for the configuration it actually tested, which is retained below and has NOT been re-measured: AddFusionComp() returns the comp, AddTool/Connect/SetInput all succeed, and the whole graph reads back correctly (GetCompCount 1, MediaOut1.Input wired to the new tool, StyledText returning the value just set) — but the rendered output is byte-for-byte the untouched source media. Verified live on Studio 19.1.3.7 with the strongest form of the test: MediaOut1 fed ONLY by a Text+, with no path from MediaIn at all, still rendered the unmodified clip. LoadFusionCompByName on the sole comp does not activate it either. Contrast InsertFusionTitleIntoTimeline, whose comp DOES render — text set via SetInput('StyledText') appears in the output — so this is specific to comps attached to media-backed clips, not to Fusion through the API generally. REPRODUCED 2026-08-21 on Studio 19.1.3.7: a rooted MediaIn -> Blur -> MediaOut comp built entirely through the API renders (PSNR 24.38 dB vs the no-comp baseline), so the 2026-08-02 correction stands. Note that an important share of 'the comp was ignored' readings are NOT this entry at all but the Composition.Lock bug above — a parameter written under a comp lock reads back correctly and never reaches the render, which looks identical from the API side. That is what an independent 2026-08-20 report on Studio 21.0.4.5 was measuring: a wired MediaIn -> Blur -> MediaOut comp, and a Transform variant, both delivered renders bit-identical to the no-comp baseline (PSNR inf) when built and set through this server. It was read at the time as a version regression (19.1.3.7 honours a wired comp, 21.0.4.5 does not); with the lock bug identified, the simpler reading is that the same defect reproduces on 21.0.4.5 — and since the lock bug has only been isolated on 19.1.3.7, that report is the only evidence it is not build-specific. SETTLED 2026-08-22 on DaVinci Resolve 21.0.3.7 (free edition, driven through the in-app bridge): the same wired MediaIn -> Blur(XBlurSize 20) -> MediaOut comp, with the value written through this server's fixed set_input, RENDERS - PSNR 24.38 dB vs the no-comp baseline and the file shrinking 2,017,973 -> 727,261 bytes, the same figure measured on 19.1.3.7 from the same source. So the 'renders on 19.1.3.7, ignored on 21' split was the Composition.Lock bug on both sides, not a version regression, and 'a wired comp renders' now holds across both Resolve generations tested. The 21 confirmation is a free-edition 21.0.3.7 rather than the Studio 21.0.4.5 the original report used; no Studio 21 was available to test.
|
|
370
378
|
- **Workaround / current handling:** Wire the graph so MediaOut descends from MediaIn — that is the difference between a comp that renders and one that is silently bypassed, and it is what made this look like 'Fusion never renders from the API'. Never leave a tool unrooted: a MediaOut fed by a tool with no source failed the render job outright. For text or effects over picture, insert a Fusion title/generator as its own timeline clip and set its Text+ (fusion_comp set_text_plus), rather than attaching a comp to the media clip. Note the destination track cannot be chosen from the API (see the Track Selector entry), so overlaying onto an existing clip's track is not currently reachable end-to-end. Building the comp in the Fusion page UI works; only the API-created comp is ignored. Never claim a Fusion effect from comp readback alone — prove it with a rendered frame (gallery_stills grab_and_export before/after, or a delivered render). On setups where even the wired comp does not render (see the 2026-08-20 measurement), treat per-item Fusion effects as HITL (a human builds or activates the comp in the UI) and bake stills motion with ffmpeg when unattended output is required.
|
|
371
379
|
- **Tags:** fusion, silent-failure, render, readback, hitl
|
|
372
380
|
|
package/install.py
CHANGED
|
@@ -37,7 +37,7 @@ from src.utils.update_check import (
|
|
|
37
37
|
|
|
38
38
|
# ─── Version ──────────────────────────────────────────────────────────────────
|
|
39
39
|
|
|
40
|
-
VERSION = "2.99.
|
|
40
|
+
VERSION = "2.99.2"
|
|
41
41
|
# Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
|
|
42
42
|
# Resolve's scripting bridge loads into newer interpreters on recent builds
|
|
43
43
|
# (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds
|
package/package.json
CHANGED
package/src/granular/common.py
CHANGED
|
@@ -87,7 +87,7 @@ if not logging.getLogger().handlers:
|
|
|
87
87
|
handlers=[logging.StreamHandler()],
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
-
VERSION = "2.99.
|
|
90
|
+
VERSION = "2.99.2"
|
|
91
91
|
logger = logging.getLogger("davinci-resolve-mcp")
|
|
92
92
|
logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
|
|
93
93
|
logger.info(f"Detected platform: {get_platform()}")
|
package/src/server.py
CHANGED
package/src/utils/api_truth.py
CHANGED
|
@@ -403,6 +403,31 @@ API_TRUTH: List[Dict[str, Any]] = [
|
|
|
403
403
|
"tags": ["timeline", "import", "interchange", "otio", "silent-failure", "conform"],
|
|
404
404
|
"submit": "bug",
|
|
405
405
|
},
|
|
406
|
+
{
|
|
407
|
+
"symbol": "Fusion tool GetAttrs / SetAttrs (unreachable over the in-app bridge)",
|
|
408
|
+
"object": "Fusion Tool (via the free-edition bridge)",
|
|
409
|
+
"signature": "GetAttrs() -> dict / SetAttrs(dict) -> None",
|
|
410
|
+
"reality": "The in-app bridge's transparent proxy exposes SetInput, "
|
|
411
|
+
"GetInput, ConnectInput and FindMainInput on a Fusion tool, "
|
|
412
|
+
"but NOT GetAttrs or SetAttrs - the client raises "
|
|
413
|
+
"AttributeError('... has no attribute SetAttrs in this "
|
|
414
|
+
"Resolve build'). Measured 2026-08-22 on free 21.0.3.7. "
|
|
415
|
+
"Because fusion_comp's add_tool calls tool.GetAttrs() "
|
|
416
|
+
"unconditionally to build its return value, and SetAttrs "
|
|
417
|
+
"whenever a name is passed, `fusion_comp add_tool` cannot "
|
|
418
|
+
"run at all on the free edition, which takes "
|
|
419
|
+
"connect/set_input with it for any graph the caller wanted "
|
|
420
|
+
"to build through the server. Comp-level calls "
|
|
421
|
+
"(AddFusionComp, GetFusionCompByIndex, FindTool, AddTool) "
|
|
422
|
+
"work, so the graph can still be wired with raw proxy calls.",
|
|
423
|
+
"recommended": "On the free edition, wire Fusion graphs with raw "
|
|
424
|
+
"comp.AddTool/ConnectInput and use fusion_comp only for "
|
|
425
|
+
"value writes. Making add_tool tolerate a missing "
|
|
426
|
+
"GetAttrs (fall back to the requested tool_type and a "
|
|
427
|
+
"FindTool-based name) would restore the action there.",
|
|
428
|
+
"tags": ["fusion", "bridge", "free-edition"],
|
|
429
|
+
"submit": "bug",
|
|
430
|
+
},
|
|
406
431
|
{
|
|
407
432
|
"symbol": "Composition.Lock (suppresses render invalidation for value writes)",
|
|
408
433
|
"object": "Composition (Fusion, via TimelineItem comps)",
|
|
@@ -506,8 +531,19 @@ API_TRUTH: List[Dict[str, Any]] = [
|
|
|
506
531
|
"that the same defect reproduces on 21.0.4.5 — and since "
|
|
507
532
|
"the lock bug has only been isolated on 19.1.3.7, that "
|
|
508
533
|
"report is the only evidence it is not build-specific. "
|
|
509
|
-
"
|
|
510
|
-
"
|
|
534
|
+
"SETTLED 2026-08-22 on DaVinci Resolve 21.0.3.7 (free "
|
|
535
|
+
"edition, driven through the in-app bridge): the same wired "
|
|
536
|
+
"MediaIn -> Blur(XBlurSize 20) -> MediaOut comp, with the "
|
|
537
|
+
"value written through this server's fixed set_input, "
|
|
538
|
+
"RENDERS - PSNR 24.38 dB vs the no-comp baseline and the "
|
|
539
|
+
"file shrinking 2,017,973 -> 727,261 bytes, the same figure "
|
|
540
|
+
"measured on 19.1.3.7 from the same source. So the "
|
|
541
|
+
"'renders on 19.1.3.7, ignored on 21' split was the "
|
|
542
|
+
"Composition.Lock bug on both sides, not a version "
|
|
543
|
+
"regression, and 'a wired comp renders' now holds across "
|
|
544
|
+
"both Resolve generations tested. The 21 confirmation is a "
|
|
545
|
+
"free-edition 21.0.3.7 rather than the Studio 21.0.4.5 the "
|
|
546
|
+
"original report used; no Studio 21 was available to test.",
|
|
511
547
|
"recommended": "Wire the graph so MediaOut descends from MediaIn — that "
|
|
512
548
|
"is the difference between a comp that renders and one "
|
|
513
549
|
"that is silently bypassed, and it is what made this look "
|