davinci-resolve-mcp 2.98.5 → 2.98.6
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 +63 -0
- package/README.md +1 -1
- package/README.zh-CN.md +2 -2
- package/docs/SKILL.md +7 -4
- package/docs/reference/api-limitations.md +1 -1
- 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 +13 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,69 @@
|
|
|
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.98.6
|
|
6
|
+
|
|
7
|
+
**Correcting the scope of the v2.98.5 Fusion fix, and covering all six paths
|
|
8
|
+
with a render.** v2.98.5 removed a `Comp.Lock()` from six Fusion value writes and
|
|
9
|
+
described all six as the same bug. Only two of them were proven with a render at
|
|
10
|
+
the time; the other four were changed by inference. Extending the live harness to
|
|
11
|
+
cover the remaining four showed that inference was too broad.
|
|
12
|
+
|
|
13
|
+
Every site was mutation-checked by reintroducing the lock and re-rendering on
|
|
14
|
+
Studio 19.1.3.7:
|
|
15
|
+
|
|
16
|
+
| call path | with the lock back |
|
|
17
|
+
| --- | --- |
|
|
18
|
+
| `set_input` | **PSNR inf — suppressed** |
|
|
19
|
+
| `safe_set_inputs` | **PSNR inf — suppressed** |
|
|
20
|
+
| `bulk_set_inputs` | unchanged, still rendered |
|
|
21
|
+
| `bulk_set_expressions` | unchanged, still rendered |
|
|
22
|
+
| `add_fusion_mask` | unchanged, still rendered |
|
|
23
|
+
| `set_text_plus` | unchanged, still rendered |
|
|
24
|
+
|
|
25
|
+
The two that break are the two where the locked write is the only thing the call
|
|
26
|
+
does. The four that survive each do something else in the same call that appears
|
|
27
|
+
to invalidate the graph anyway — `bulk_set_inputs` and `bulk_set_expressions`
|
|
28
|
+
wrap the write in `StartUndo`/`EndUndo`, `add_fusion_mask` performs an `AddTool`,
|
|
29
|
+
and `set_text_plus` writes a string rather than a number. **Which of those is the
|
|
30
|
+
rescuing mechanism is not established** — only that the four do not reproduce.
|
|
31
|
+
|
|
32
|
+
No code changed back. Removing the lock from a single write buys nothing and
|
|
33
|
+
costs nothing, and treating the four as merely unexplained rather than proven
|
|
34
|
+
safe is the conservative reading. What changed is the claim: `api_truth`,
|
|
35
|
+
`docs/SKILL.md` and the AST guard's failure message now state the measured scope
|
|
36
|
+
instead of "any value write".
|
|
37
|
+
|
|
38
|
+
If you read the v2.98.5 notes and concluded every Fusion parameter this server
|
|
39
|
+
ever wrote was ignored at render, that was overstated — it was true for
|
|
40
|
+
`set_input` and `safe_set_inputs`.
|
|
41
|
+
|
|
42
|
+
### Tests
|
|
43
|
+
|
|
44
|
+
`tests/live_fusion_value_write_validation.py` grows from two cases to six,
|
|
45
|
+
covering every site the fix touched:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
set_input: PSNR 24.375987 -> APPLIED at render
|
|
49
|
+
safe_set_inputs: PSNR 24.375987 -> APPLIED at render
|
|
50
|
+
set_text_plus: PSNR 13.33844 -> APPLIED at render
|
|
51
|
+
bulk_set_expressions: PSNR 24.375987 -> APPLIED at render
|
|
52
|
+
bulk_set_inputs: PSNR 24.375987 -> APPLIED at render
|
|
53
|
+
add_fusion_mask: PSNR 30.369794 -> APPLIED at render
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The `set_text_plus` case builds a rooted `MediaIn -> Merge -> MediaOut` graph
|
|
57
|
+
with the Text+ in the foreground — a comp whose MediaOut is fed only by a Text+
|
|
58
|
+
is bypassed at render for an unrelated reason and would have failed for the
|
|
59
|
+
wrong cause. The `add_fusion_mask` case cannot use a baseline/after comparison,
|
|
60
|
+
because a default-sized mask still changes the render; it builds the same graph
|
|
61
|
+
twice, once with a default mask and once with an explicitly tiny one, and
|
|
62
|
+
requires the two renders to differ.
|
|
63
|
+
|
|
64
|
+
Four of the six cases do not discriminate the lock. They are kept because they
|
|
65
|
+
still prove the write reaches the render — the property that matters, and the
|
|
66
|
+
one no readback can check.
|
|
67
|
+
|
|
5
68
|
## What's New in v2.98.5
|
|
6
69
|
|
|
7
70
|
**Every Fusion parameter this server wrote was ignored at render.** A value
|
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.98.
|
|
15
|
+
> 本翻译对应 v2.98.6 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
|
|
16
16
|
|
|
17
17
|
一个 Model Context Protocol (MCP) 服务器,让 AI 助手通过官方脚本 API 控制 DaVinci Resolve Studio(达芬奇)。它提供完整的 API 覆盖,外加带护栏的工作流助手,涵盖剪辑、媒体池整理、渲染设置、审阅标记、调色、Fusion、Fairlight、项目生命周期任务、扩展开发,以及不碰源媒体的媒体分析。
|
|
18
18
|
|
package/docs/SKILL.md
CHANGED
|
@@ -1691,10 +1691,13 @@ Target a comp either from a timeline item (pass `clip_id`, `timeline_item_id`, o
|
|
|
1691
1691
|
page comp (omit timeline scope).
|
|
1692
1692
|
|
|
1693
1693
|
READBACK IS NOT PROOF FOR FUSION PARAMETERS. Up to v2.98.4 every value write
|
|
1694
|
-
here ran inside a `Comp.Lock()
|
|
1695
|
-
in the graph and returned by `get_input` while
|
|
1696
|
-
(Studio 19.1.3.7: PSNR inf vs the no-comp
|
|
1697
|
-
bit-identical to no comp at all).
|
|
1694
|
+
here ran inside a `Comp.Lock()`. For `set_input` and `safe_set_inputs` that was
|
|
1695
|
+
load-bearing: the value is stored in the graph and returned by `get_input` while
|
|
1696
|
+
the RENDER ignores it entirely (Studio 19.1.3.7: PSNR inf vs the no-comp
|
|
1697
|
+
baseline — the delivered file was bit-identical to no comp at all). The other
|
|
1698
|
+
four locked paths did not reproduce it, so the blast radius was narrower than
|
|
1699
|
+
first reported; the locks came off all six regardless. Fixed in v2.98.5
|
|
1700
|
+
(measurement corrected in v2.98.6), and guarded by
|
|
1698
1701
|
`tests/test_fusion_value_write_lock.py` plus the rendered-frame harness
|
|
1699
1702
|
`tests/live_fusion_value_write_validation.py`. The lesson outlives the bug: a
|
|
1700
1703
|
Fusion parameter that reads back correctly has proven nothing about the output,
|
|
@@ -343,7 +343,7 @@ values, or automation-hostile modal prompts.
|
|
|
343
343
|
|
|
344
344
|
- **Object:** `Composition (Fusion, via TimelineItem comps)`
|
|
345
345
|
- **Signature:** `Lock() / Unlock()`
|
|
346
|
-
- **Behavior:** A
|
|
346
|
+
- **Behavior:** A numeric tool.SetInput() performed between Comp.Lock() and Comp.Unlock(), when that write is the only thing the call does, is stored in the graph and reads back correctly from GetInput() but is NOT applied when the timeline is rendered. Measured live on Studio 19.1.3.7 (2026-08-21) with MediaIn -> Blur(XBlurSize 20) -> MediaOut on a media-backed clip: written under the lock the delivered H.264 render is bit-identical to the no-comp baseline (ffmpeg PSNR inf); the identical write with the lock removed renders at PSNR 24.38 dB and the file shrinks 2.0 MB -> 727 KB, as a blur should. The variable was isolated against the comp handle (AddFusionComp, GetFusionCompByIndex and GetFusionCompByName all render), the node name, and the write form (attribute assignment and SetInput both render unlocked). STRUCTURAL edits are unaffected: AddTool and ConnectInput inside a lock render normally, so the lock is not broadly unsafe — it suppresses the parameter-change invalidation that a value write depends on. Lock() is widely recommended for batching Fusion edits, which is how this reaches production code. SCOPE, measured by reintroducing the lock at each site and re-rendering: it reproduces for a bare numeric SetInput (2 of 6 call paths tested) and does NOT reproduce when the same call also wraps the write in StartUndo/EndUndo, performs an AddTool, or writes a string to StyledText (4 of 6). Which of those rescues the write is not established — only that they do. Treat the safe cases as unexplained rather than proven safe, and keep value writes outside the lock everywhere.
|
|
347
347
|
- **Workaround / current handling:** Never hold a comp lock across a value write. Lock only structural work (AddTool/ConnectInput) and set inputs outside it. Because every readback the API offers agrees with the value that was written, this failure is invisible without a render — prove Fusion parameter changes with a delivered frame or gallery_stills grab_and_export, never with GetInput.
|
|
348
348
|
- **Tags:** fusion, silent-failure, render, readback
|
|
349
349
|
|
package/install.py
CHANGED
|
@@ -37,7 +37,7 @@ from src.utils.update_check import (
|
|
|
37
37
|
|
|
38
38
|
# ─── Version ──────────────────────────────────────────────────────────────────
|
|
39
39
|
|
|
40
|
-
VERSION = "2.98.
|
|
40
|
+
VERSION = "2.98.6"
|
|
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.98.
|
|
90
|
+
VERSION = "2.98.6"
|
|
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
|
@@ -407,10 +407,10 @@ API_TRUTH: List[Dict[str, Any]] = [
|
|
|
407
407
|
"symbol": "Composition.Lock (suppresses render invalidation for value writes)",
|
|
408
408
|
"object": "Composition (Fusion, via TimelineItem comps)",
|
|
409
409
|
"signature": "Lock() / Unlock()",
|
|
410
|
-
"reality": "A
|
|
411
|
-
"Comp.Unlock()
|
|
412
|
-
"stored in the graph and reads back correctly
|
|
413
|
-
"GetInput()
|
|
410
|
+
"reality": "A numeric tool.SetInput() performed between Comp.Lock() "
|
|
411
|
+
"and Comp.Unlock(), when that write is the only thing the "
|
|
412
|
+
"call does, is stored in the graph and reads back correctly "
|
|
413
|
+
"from GetInput() but is NOT applied when the timeline is "
|
|
414
414
|
"rendered. Measured live on Studio 19.1.3.7 (2026-08-21) "
|
|
415
415
|
"with MediaIn -> Blur(XBlurSize 20) -> MediaOut on a "
|
|
416
416
|
"media-backed clip: written under the lock the delivered "
|
|
@@ -427,7 +427,15 @@ API_TRUTH: List[Dict[str, Any]] = [
|
|
|
427
427
|
"suppresses the parameter-change invalidation that a value "
|
|
428
428
|
"write depends on. Lock() is widely recommended for "
|
|
429
429
|
"batching Fusion edits, which is how this reaches "
|
|
430
|
-
"production code."
|
|
430
|
+
"production code. SCOPE, measured by reintroducing the lock "
|
|
431
|
+
"at each site and re-rendering: it reproduces for a bare "
|
|
432
|
+
"numeric SetInput (2 of 6 call paths tested) and does NOT "
|
|
433
|
+
"reproduce when the same call also wraps the write in "
|
|
434
|
+
"StartUndo/EndUndo, performs an AddTool, or writes a string "
|
|
435
|
+
"to StyledText (4 of 6). Which of those rescues the write is "
|
|
436
|
+
"not established — only that they do. Treat the safe cases as "
|
|
437
|
+
"unexplained rather than proven safe, and keep value writes "
|
|
438
|
+
"outside the lock everywhere.",
|
|
431
439
|
"recommended": "Never hold a comp lock across a value write. Lock only "
|
|
432
440
|
"structural work (AddTool/ConnectInput) and set inputs "
|
|
433
441
|
"outside it. Because every readback the API offers "
|