davinci-resolve-mcp 2.88.0 → 2.90.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 +143 -0
- package/README.md +1 -1
- package/README.zh-CN.md +2 -2
- package/docs/SKILL.md +10 -1
- package/install.py +1 -1
- package/package.json +1 -1
- package/resolve-advanced/server/aaf_probe.py +327 -11
- package/src/analysis_dashboard.py +2 -1
- package/src/granular/common.py +36 -2
- package/src/granular/folder.py +26 -15
- package/src/granular/media_pool_item.py +29 -21
- package/src/granular/project.py +11 -6
- package/src/granular/resolve_control.py +18 -4
- package/src/granular/timeline.py +7 -4
- package/src/granular/timeline_item.py +1 -1
- package/src/server.py +37 -15
- package/src/utils/cloud_operations.py +5 -3
- package/src/utils/object_inspection.py +4 -2
- package/src/utils/project_properties.py +3 -1
- package/src/utils/resolve_probe.py +68 -0
- package/src/utils/resolve_versions.py +108 -6
- package/src/utils/timeline_kernel_live_probe.py +3 -1
- package/src/utils/timeline_versioning.py +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,149 @@
|
|
|
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.90.0
|
|
6
|
+
|
|
7
|
+
AAF turnovers parsed by `editorial.parse_interchange` on the advanced server now
|
|
8
|
+
carry their animation curves, the transforms nobody had interpreted, and the
|
|
9
|
+
effects that occupy record time while emitting nothing. All three were losses a
|
|
10
|
+
consumer could not see, because the parse reported itself complete.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Keyframe curves ship instead of the word "varying".** A `VaryingValue` was
|
|
15
|
+
read for its values alone, and only to answer "one number or more than one" —
|
|
16
|
+
`ControlPoint.time` was never asked for, so every animated reframe reached a
|
|
17
|
+
consumer as `"varying"`: enough to refuse the clip, never enough to rebuild
|
|
18
|
+
it. Transform stages now carry `keyframes[<AvidParamName>]` and retimes carry
|
|
19
|
+
`speedCurve.playRate` / `speedCurve.sourceOffset`, each with its interpolation
|
|
20
|
+
and its points as `{t, v, frame}`.
|
|
21
|
+
- **`domain` names which rule produced `frame`,** because the two curve families
|
|
22
|
+
do not share a time domain and a single conversion rule would have been wrong
|
|
23
|
+
by an effect's whole length on one of them. Measured over all 2047 control
|
|
24
|
+
points of an 878-event Avid picture turnover: transform params are normalized
|
|
25
|
+
over the effect span with the endpoint inclusive (`frame = t x (length - 1)`,
|
|
26
|
+
which lands 1243 of 1254 points on an integer frame against 278 under
|
|
27
|
+
`length`), while speed maps are already in frames. Keys outside `0..1` are
|
|
28
|
+
kept rather than clamped — 107 of 1254 sit before the first frame or past the
|
|
29
|
+
last, which is what Avid leaves when an animated clip is trimmed. A curve with
|
|
30
|
+
one unreadable point is refused whole; interpolating through a missing key
|
|
31
|
+
produces a confident wrong animation.
|
|
32
|
+
- **`passthrough` stages carry the four uninterpreted transform operations**
|
|
33
|
+
(SBlend_v2, Stabilize_2, MaskImage_2, 2DMatteKey_2) that were previously
|
|
34
|
+
discarded whole — 22 events on the fixture. Their numbers travel in
|
|
35
|
+
`rawParams`, deliberately not `params`: the same parameter *name* carries
|
|
36
|
+
different units on different operations (SBlend's `DVE_POS_X_U` runs to -315
|
|
37
|
+
where Stabilize's runs to -0.92 on the same show), so there is nothing to
|
|
38
|
+
normalize, and a 2DMatteKey `AFX_POS_X_U` of 500 promoted into `params` would
|
|
39
|
+
become a ~960px shift of a clip nobody repositioned.
|
|
40
|
+
- **`effectsWithoutEvents` closes a hole `unhandled` structurally cannot see.**
|
|
41
|
+
An effect can be modelled perfectly and still emit nothing — the group is
|
|
42
|
+
walked, its inputs are walked, and they contain no `SourceClip`. On the
|
|
43
|
+
fixture `unhandled` reads `{}` (a complete parse) while 29 SubCap titles
|
|
44
|
+
occupy real record time and reach the consumer as nothing whatsoever. Charged
|
|
45
|
+
once, to the innermost cause.
|
|
46
|
+
- **`speedRatioFromCurve`** — the rate the offset curve itself implies, emitted
|
|
47
|
+
only when that curve is straight, so no variable timewarp is ever averaged
|
|
48
|
+
into a single number.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- **The declared AAF `SpeedRatio` rational is the source span truncated to whole
|
|
53
|
+
frames, and 7 of 18 constant retimes on the fixture disagree with their own
|
|
54
|
+
curve** — `201/112 = 1.794643` where the curve says `201.6/112 = 1.80`, and at
|
|
55
|
+
worst `31/19 = 1.631579` against a curve reading `1.70`, a 4% speed error in a
|
|
56
|
+
number an operator is handed to type in by hand. Every curve slope lands on a
|
|
57
|
+
rate an editor would actually dial (1.7, 1.8, 2.0, 0.75); every declared value
|
|
58
|
+
is that rate spoiled by rounding. Both ship under their own names and neither
|
|
59
|
+
is substituted for the other.
|
|
60
|
+
- **Variable timewarps are reconstructible.** The offset curve is dense (up to
|
|
61
|
+
387 points at half-frame steps) and describes where every record frame reads
|
|
62
|
+
from, taking the 4 variable timewarps on the fixture from "flagged, rebuild
|
|
63
|
+
from nothing" to fully described — including one reverse ramp whose offset
|
|
64
|
+
runs 301.0 to -0.78. Reverse read off the curve agreed with the declared flag
|
|
65
|
+
9 of 9, in both directions.
|
|
66
|
+
|
|
67
|
+
### Validation
|
|
68
|
+
|
|
69
|
+
- Every pre-existing field is byte-identical on the fixture, verified by a
|
|
70
|
+
structural diff of the full 878-event parse against the previous output; event
|
|
71
|
+
count, `unhandled`, and all existing counters are unchanged.
|
|
72
|
+
- 10 new tests in `resolve-advanced/test/aaf-sequences.test.mjs`.
|
|
73
|
+
- No DaVinci Resolve scripting behavior changed; this is offline interchange
|
|
74
|
+
parsing, so no live Resolve validation was required.
|
|
75
|
+
|
|
76
|
+
## What's New in v2.89.0
|
|
77
|
+
|
|
78
|
+
The build gates this server already enforced are now gates an agent can ask
|
|
79
|
+
about, and the capability probe those gates run on no longer lies. Issue #132,
|
|
80
|
+
reported by @magwa101.
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
|
|
84
|
+
- **`get_version` reports what the connected build is missing.** A new `build`
|
|
85
|
+
block carries `unavailable_on_this_build` — every recorded API surface this
|
|
86
|
+
build does not have — plus `known_gates` and the caveat that an absence from
|
|
87
|
+
that list is not a promise a method exists. #132 happened in a session that
|
|
88
|
+
opened with `get_version` and was told a number and nothing the number ruled
|
|
89
|
+
out. `get_resolve_version_fields` gains the same list on the granular server.
|
|
90
|
+
- **The version-gate registry went from 7 recorded surfaces to 41.**
|
|
91
|
+
`_requires_method(obj, "GetLayoutPresetList", "21.0.4")` appears 44 times
|
|
92
|
+
across the two servers and gates 31 distinct symbols, but
|
|
93
|
+
`check_version_support` — the call `resolve-session` step 2 tells an agent to
|
|
94
|
+
make — answered from a ledger that knew seven of them. So the one question an
|
|
95
|
+
agent is instructed to ask returned `unknown` for surfaces this server was
|
|
96
|
+
already routing on. On Studio 19.1.3.7 the session preflight named 7 missing
|
|
97
|
+
surfaces; it now names 40. The new floors are labelled `documented` rather
|
|
98
|
+
than `measured`: they come from Blackmagic's release documentation, not a live
|
|
99
|
+
bisect here, and an agent relaying one should be able to say which.
|
|
100
|
+
- **`tests/test_version_gate_drift.py`** fails when a call site and the ledger
|
|
101
|
+
disagree, and when a bare method name is gated at two different builds on two
|
|
102
|
+
different classes (which would make a bare-name lookup a coin flip). A table
|
|
103
|
+
copied by hand is exactly what drifts back apart.
|
|
104
|
+
- **`src/utils/resolve_probe.py`** — `has_method` and `api_constant`, with the
|
|
105
|
+
measurement behind them. A companion guard fails the suite on a bare `hasattr`
|
|
106
|
+
with a Resolve-shaped attribute name.
|
|
107
|
+
|
|
108
|
+
### Fixed
|
|
109
|
+
|
|
110
|
+
- **29 capability probes across `src/` used `hasattr` on Resolve API objects,
|
|
111
|
+
where it is a constant `True`** (measured on Studio 19.1.3.7 across 42 checks,
|
|
112
|
+
recorded in `api_truth`; re-confirmed live for this release —
|
|
113
|
+
`hasattr(project, 'GenerateSpeech')` returns `True` on a build that has no
|
|
114
|
+
such method). It failed in two shapes that look nothing alike:
|
|
115
|
+
- `if not hasattr(clip, "RemoveMotionBlur")` is a dead branch, so the
|
|
116
|
+
"requires Resolve 21+" refusal never fired and the call below it raised
|
|
117
|
+
`AttributeError` on an older build. Eleven of these were the granular
|
|
118
|
+
server's Resolve 21 AI guards.
|
|
119
|
+
- `getattr(r, n) if hasattr(r, n) else n` never reaches its `else`, so a build
|
|
120
|
+
without the constant got `None` where the author wrote a string fallback —
|
|
121
|
+
no exception, no refusal, just a `None` travelling on into `Export()`. This
|
|
122
|
+
reached granular timeline export and `ExportLUT`, and three constant
|
|
123
|
+
lookups on the compound server. Confirmed live: a name Resolve does not
|
|
124
|
+
define returned `None` under the old form and now falls back correctly.
|
|
125
|
+
The fallback keys on `is None`, not truthiness, because `EXPORT_AAF` is
|
|
126
|
+
genuinely `0.0`.
|
|
127
|
+
- **The granular AI tools reported a missing Extras pack as success.** Resolve's
|
|
128
|
+
AI methods return the reason as a *string* when the pack is absent, and
|
|
129
|
+
`bool("Required package ... is not installed.")` is `True`. The compound
|
|
130
|
+
server has normalized that since the 21.0.2.4 measurement; the granular one
|
|
131
|
+
had not, so folder and clip audio classification returned `{"success": true}`
|
|
132
|
+
for a call that did not run, and `RemoveMotionBlur` / `GenerateSpeech` walked
|
|
133
|
+
a string into `.GetName()`. All now route through `_ai_result`, which reports
|
|
134
|
+
the failure and carries Resolve's own reason.
|
|
135
|
+
- **`Project.ApplyFairlightPresetToCurrentTimeline` was recorded on `Timeline`.**
|
|
136
|
+
The shipped README lists it under Project and the server calls it there; the
|
|
137
|
+
method's name is what made the wrong attribution look right.
|
|
138
|
+
|
|
139
|
+
### Validation
|
|
140
|
+
|
|
141
|
+
Suite 2560 → 2580. Live-checked against the running Studio 19.1.3.7 for the
|
|
142
|
+
probe semantics, the refusal path, the constant fallback, and the `get_version`
|
|
143
|
+
preflight (40 of 41 gates unavailable, as expected on that build). The Resolve 21
|
|
144
|
+
and 21.0.4 surfaces themselves remain untested here — this machine cannot run
|
|
145
|
+
them — and the Extras-pack failure paths are pinned by a stub that reproduces
|
|
146
|
+
the measured attribute-fabrication behaviour rather than by a live 21 build.
|
|
147
|
+
|
|
5
148
|
## What's New in v2.88.0
|
|
6
149
|
|
|
7
150
|
The twelve Resolve 21.0.4 surfaces that only existed on the compound server now
|
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.
|
|
15
|
+
> 本翻译对应 v2.90.0 版 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
|
@@ -489,7 +489,16 @@ you are on the correct page first.
|
|
|
489
489
|
Key actions:
|
|
490
490
|
- `launch` — connect to or start Resolve; call this first if any tool returns a
|
|
491
491
|
"Not connected" error
|
|
492
|
-
- `get_version` — returns `{product, version, version_string}
|
|
492
|
+
- `get_version` — returns `{product, version, version_string, build, mcp}`.
|
|
493
|
+
`build.unavailable_on_this_build` lists every recorded API surface this build
|
|
494
|
+
does **not** have; read it before offering anything version-gated. An absence
|
|
495
|
+
from that list is not a promise a method exists — most of the API has never
|
|
496
|
+
been version-bisected, so `check_version_support` answers `unknown` for it,
|
|
497
|
+
and `unknown` means probe with `name in dir(obj)`, never bare `hasattr`
|
|
498
|
+
(constant `True` on Resolve objects)
|
|
499
|
+
- `check_version_support(symbol?, resolve_version?)` — is one named symbol on
|
|
500
|
+
this build? Without `symbol`, the same missing-surface list `get_version`
|
|
501
|
+
carries. No connection needed when `resolve_version` is passed
|
|
493
502
|
- `api_truth(query?)` — look up behaviorally-verified facts about quirky/unreliable
|
|
494
503
|
Resolve API behavior (no connection needed); filter by substring
|
|
495
504
|
- `verification_stats` — readback-verification tally (verified/contradicted/
|
package/install.py
CHANGED
|
@@ -36,7 +36,7 @@ from src.utils.update_check import (
|
|
|
36
36
|
|
|
37
37
|
# ─── Version ──────────────────────────────────────────────────────────────────
|
|
38
38
|
|
|
39
|
-
VERSION = "2.
|
|
39
|
+
VERSION = "2.90.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
|