davinci-resolve-mcp 2.212.4 → 2.213.1
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/AGENTS.md +15 -6
- package/CHANGELOG.md +146 -0
- package/README.md +1 -1
- package/README.zh-CN.md +2 -2
- package/docs/SKILL.md +2 -1
- package/docs/kernels/README.md +1 -1
- package/docs/kernels/color-grade-kernel.md +3 -1
- package/docs/kernels/timeline-conform-interchange-kernel.md +6 -2
- package/docs/reference/api-limitations.md +5 -12
- package/docs/reference/readwrite-symmetry.md +3 -3
- package/install.py +1 -1
- package/package.json +1 -1
- package/resolve-advanced/README.md +7 -1
- package/resolve-advanced/server/tools/color_trace.mjs +221 -38
- package/resolve-advanced/server/tools/project_read.mjs +28 -1
- package/src/granular/common.py +1 -1
- package/src/server.py +290 -8
- package/src/utils/api_truth.py +62 -13
- package/src/utils/destructive_hook.py +2 -0
- package/src/utils/execution_lifecycle.py +3 -0
- package/src/utils/resolve_versions.py +3 -1
package/AGENTS.md
CHANGED
|
@@ -78,12 +78,21 @@ semantics.
|
|
|
78
78
|
limitation, add a `submit`-tagged entry to `src/utils/api_truth.py` and
|
|
79
79
|
regenerate with `scripts/gen_api_limitations.py` (a drift guard enforces it)
|
|
80
80
|
- Bundled Resolve API text: `docs/reference/resolve_scripting_api.txt` — refresh
|
|
81
|
-
it by copying the shipped
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
it by copying the shipped scripting README over it wholesale, never by
|
|
82
|
+
hand-adding the lines you already know about. The file's only value is that a
|
|
83
|
+
diff against it is trustworthy; a hand-patch carries a newer `Last Updated:`
|
|
84
|
+
header while still hiding everything you did not know to look for. That is
|
|
85
|
+
exactly how it sat eight weeks stale at 26 May 2026 while ten documented
|
|
86
|
+
21.0.4 methods went unwired (PR #139).
|
|
87
|
+
**The shipped README moved in 21.1.** `Developer/Scripting/README.txt` is
|
|
88
|
+
gone; the pack is now `README.md`, a typed `DaVinciResolveScript.pyi` (the
|
|
89
|
+
full signature surface, which the old README never carried) and a
|
|
90
|
+
`CHANGELOG.md` of per-version additions. Copying `README.md` over the bundled
|
|
91
|
+
file is still the right refresh, but it renumbers every line — and
|
|
92
|
+
`scripts/audit_api_parity.py`, `tests/test_resolve_bridge.py` and a few dozen
|
|
93
|
+
`resolve_scripting_api.txt line N` comments in `src/` read it. Re-run the
|
|
94
|
+
parity audit and re-anchor those comments in the same change, or leave the
|
|
95
|
+
file at its 21.0 revision and cite the `.pyi` for new work
|
|
87
96
|
|
|
88
97
|
## Key Paths
|
|
89
98
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,152 @@
|
|
|
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.213.1 — Fusion keyframes reach the render; the contact sheet waits for the viewer; the ledger learns Resolve 21.1
|
|
6
|
+
|
|
7
|
+
Reported in #196 by @JosephConroy93, with a repro precise enough to reproduce
|
|
8
|
+
on the first run.
|
|
9
|
+
|
|
10
|
+
### Fixed — Fusion keyframes (#196)
|
|
11
|
+
|
|
12
|
+
- **`fusion_comp add_keyframe` wrote the keyframe under `comp.Lock()`, so it
|
|
13
|
+
read back correctly and never rendered.** This is the comp-lock class this
|
|
14
|
+
repo documented in v2.98.5 for `set_input` — a value write under a lock
|
|
15
|
+
lands in the graph, `GetKeyFrames` lists it, Fusion's own page playback
|
|
16
|
+
interpolates it, and the delivered render ignores it — and `add_keyframe`
|
|
17
|
+
was the site that never got the fix. Measured on Studio 19.1.3.7 with a
|
|
18
|
+
Transform `Size` keyframed 2.0 → 1.0 over 47 frames on a media-backed clip:
|
|
19
|
+
through the shipped handler the render was bit-identical to the no-comp
|
|
20
|
+
baseline (PSNR inf); the identical writes with the lock removed rendered the
|
|
21
|
+
zoom (PSNR 13.3 dB against baseline, and frame 46 back within 44 dB of the
|
|
22
|
+
baseline as `Size` returned to 1.0). Four unlocked variants all rendered —
|
|
23
|
+
modifier locked with the write outside, `StartUndo`/`EndUndo` around both,
|
|
24
|
+
nothing wrapped, and a spline assigned directly — so the write pattern is
|
|
25
|
+
not the variable, the lock is. The handler now wraps the spline attach and
|
|
26
|
+
the first key in `StartUndo`/`EndUndo`, the escape `bulk_set_inputs`
|
|
27
|
+
already uses, which also gives the user one undo step per keyframe.
|
|
28
|
+
- **`delete_keyframe` moved off the lock for consistency, not because it was
|
|
29
|
+
broken.** It was mutation-checked: re-locking the delete and rendering still
|
|
30
|
+
removed the key from the output (frame 46 stayed at the 2.0 zoom, 5.7 dB
|
|
31
|
+
from baseline). The lock does not suppress a spline delete on 19.1.3.7.
|
|
32
|
+
|
|
33
|
+
### Notes on the report
|
|
34
|
+
|
|
35
|
+
- The reporter's own patch — write outside the lock, modifier still inside —
|
|
36
|
+
made their render fail outright on Windows 19.1.3.7 and 21.0.4.5. That
|
|
37
|
+
variant rendered correctly here on macOS 19.1.3.7, so the failure was not
|
|
38
|
+
reproduced and its cause is unknown; the shipped fix uses the undo-wrapped
|
|
39
|
+
shape instead, which rendered on every attempt.
|
|
40
|
+
- Priming (an unrelated unlocked write first) did not rescue it for the
|
|
41
|
+
reporter. That matches the v2.98.8 mechanism only partly and was not
|
|
42
|
+
re-tested here.
|
|
43
|
+
|
|
44
|
+
### Validation — #196
|
|
45
|
+
|
|
46
|
+
- `tests/test_fusion_value_write_lock.py` now recognises the keyframe write
|
|
47
|
+
shape (`tool[input][time] = value`) under a lock, and fails against the
|
|
48
|
+
pre-fix server naming `add_keyframe`'s line — the guard was confirmed to
|
|
49
|
+
fail before it was confirmed to pass.
|
|
50
|
+
- Live render witness on Studio 19.1.3.7 through the real `fusion_comp`
|
|
51
|
+
handlers: `add_keyframe` animates, `delete_keyframe` removes, `get_keyframes`
|
|
52
|
+
reads the written values. Full offline Python suite, drift guards and the
|
|
53
|
+
advanced Node suite green.
|
|
54
|
+
|
|
55
|
+
#197 and #198 contributed by @billcarroll, on the day Resolve 21.1 shipped. Also on landing: `timeline_markers get_thumbnail` read the thumbnail once too and now goes through the same settle helper; live-validated on the same scratch timeline (two of two reads), with the guard covering both sites.
|
|
56
|
+
|
|
57
|
+
### Fixed — contact sheet and get_thumbnail (#198)
|
|
58
|
+
|
|
59
|
+
- **`timeline thumbnail_contact_sheet` returned "No thumbnail available" for
|
|
60
|
+
every frame.** It moved the playhead and read the thumbnail once,
|
|
61
|
+
immediately; the viewer has not caught up when the scripting call that
|
|
62
|
+
follows a playhead move lands, so each sample came back empty. The sheet now
|
|
63
|
+
reads through `_playhead_thumbnail_settled`, the polling helper the
|
|
64
|
+
single-frame path already used — it was the one caller not switched over.
|
|
65
|
+
Live-validated on Studio 19.1.3.7: three samples across a scratch timeline,
|
|
66
|
+
all three returned thumbnails. A static guard now fails the suite if any
|
|
67
|
+
`GetCurrentClipThumbnailImage` read appears outside that helper. (#198)
|
|
68
|
+
|
|
69
|
+
### Documentation — Resolve 21.1 in the API ledger (#197)
|
|
70
|
+
|
|
71
|
+
- **Three `api_truth` entries corrected for Resolve 21.1** (#197), on the
|
|
72
|
+
strength of the contributor's attribute probe of Studio 21.1.0.14. Native
|
|
73
|
+
multicam clip creation is withdrawn as a gap (`MediaPool.CreateMulticamClip`,
|
|
74
|
+
`TimelineItem.FlattenMulticam`, `PerformMulticamSmartSwitch`,
|
|
75
|
+
`Timeline.AutoAlignClips` resolve on 21.1); transition **creation** is fixed
|
|
76
|
+
by `TimelineItem.AddTransition` while readback and cloning stay missing; and
|
|
77
|
+
the truncated `GetClipProperty('Transcription')` now has a real route around
|
|
78
|
+
it in `MediaPoolItem.GetTranscription()`, which returns per-word timing and
|
|
79
|
+
speakers for the source clip. `docs/reference/api-limitations.md` regenerated
|
|
80
|
+
(42 → 41 missing capabilities).
|
|
81
|
+
- **Provenance is stated in each entry.** No 21.1 build exists on the
|
|
82
|
+
maintainer's machine, so the entries record these as *reported by the
|
|
83
|
+
contributor, not reproduced here*, following the ledger's existing
|
|
84
|
+
measured / reported distinction. None of the methods was invoked; the claim
|
|
85
|
+
is existence and signature only, and each entry says what would falsify it.
|
|
86
|
+
- **The shipped scripting README moved in 21.1.** `Developer/Scripting/README.txt`
|
|
87
|
+
is gone in favour of `README.md`, a typed `DaVinciResolveScript.pyi` and a
|
|
88
|
+
`CHANGELOG.md`. `tests/live_resolve21_validation.py` reads either name, and
|
|
89
|
+
`AGENTS.md` explains why the bundled API text is not refreshed in the same
|
|
90
|
+
change (every `resolve_scripting_api.txt line N` anchor in `src/` would move).
|
|
91
|
+
|
|
92
|
+
### Validation — #197 and #198
|
|
93
|
+
|
|
94
|
+
- Full offline Python suite, drift guards (api-limitations, agent rules,
|
|
95
|
+
release surfaces), the advanced Node suite. Contact sheet live-validated as
|
|
96
|
+
above; the api_truth change is documentation and needs no Resolve run.
|
|
97
|
+
|
|
98
|
+
## What's New in v2.213.0 — a ColorTrace that matches on media, then applies
|
|
99
|
+
|
|
100
|
+
### Added
|
|
101
|
+
|
|
102
|
+
- **`color_trace` matches on media identity, names last.** Native ColorTrace
|
|
103
|
+
keys on timecode, clip name and order inside one project, so a renamed clip,
|
|
104
|
+
a reordered cut, or a stringout cut into graded sections defeats it. The
|
|
105
|
+
advanced server's `color_trace plan` now reads both timelines from their
|
|
106
|
+
`Project.db` (any two projects, read-only, no Resolve) and matches in tiers:
|
|
107
|
+
same media (pool item id or file path) with the same in-point and duration;
|
|
108
|
+
same media with overlapping source range (the best overlap wins, so each
|
|
109
|
+
section of a stringout finds its own grade); same reel plus overlap; same
|
|
110
|
+
file name plus overlap (relocated media); then, only as a fallback, exact and
|
|
111
|
+
normalised clip names. Every match reports its `method`, `confidence`,
|
|
112
|
+
`sourceOverlap` and an `ambiguous` flag when two candidates tie.
|
|
113
|
+
- **`plan.json` + a lossless `.drx` per graded match.** With `emitDir` set the
|
|
114
|
+
plan writes one `.drx` per match by copying the source clip's grade body
|
|
115
|
+
byte for byte (no decode/re-encode, so OFX/ResolveFX nodes survive) and a
|
|
116
|
+
`plan.json` that names each target clip by (name, record start, duration).
|
|
117
|
+
- **`timeline_item_color.apply_trace_plan` — the live half.** Resolves every
|
|
118
|
+
plan entry to a clip on the CURRENT timeline, returns a dry-run resolution
|
|
119
|
+
table (`apply` or `skip` with a reason: `live_item_not_found`,
|
|
120
|
+
`ambiguous_live_item`, `below_min_confidence`, `drx_missing`,
|
|
121
|
+
`drx_path_not_temp`, `no-source-grade`, `unmatched`), then behind one
|
|
122
|
+
`confirm_token` for the whole batch runs `ApplyGradeFromDRX` per clip.
|
|
123
|
+
Registered as a destructive action (timeline archived to the Archive bin
|
|
124
|
+
first, rated with the other whole-grade replacements, native dry-run).
|
|
125
|
+
`version_name` adds a local version per clip before applying so the previous
|
|
126
|
+
grade stays intact; `min_confidence` (default 0.8) gates the name-only tiers
|
|
127
|
+
out unless you lower it. Unresolved entries are reported, never guessed.
|
|
128
|
+
|
|
129
|
+
### Changed
|
|
130
|
+
|
|
131
|
+
- **`project_read.timeline_clips` reads the ACTIVE grade version.** The clip
|
|
132
|
+
join now follows the version table's `pActive` and dedupes to one row per
|
|
133
|
+
item, so a clip carrying several corrected versions no longer reads back as
|
|
134
|
+
several clips. Rows also carry the pool item id (`poolId`) and `hasGrade`.
|
|
135
|
+
- **Name normalisation only strips `v`-prefixed version tokens.** Stripping any
|
|
136
|
+
trailing number folded `SHOT_010` and `SHOT_020` onto one key, so a
|
|
137
|
+
name-tier match could cross shots.
|
|
138
|
+
|
|
139
|
+
### What was checked
|
|
140
|
+
|
|
141
|
+
- Offline: 11 new match-engine tests (stringout sections by overlap, straddling
|
|
142
|
+
ranges, ties → ambiguous, pool-id vs path, reel and basename tiers,
|
|
143
|
+
unreadable in-point degrading to `media-only`, name fallbacks, active-version
|
|
144
|
+
dedupe) and 9 driver tests (resolution reasons, stacked clips disambiguated
|
|
145
|
+
by duration, ambiguous live items skipped, token → apply with `version_name`,
|
|
146
|
+
partial failure reported, dispatch without an item). Both full suites green.
|
|
147
|
+
- **Not yet live-validated:** the end-to-end trace onto a real target timeline
|
|
148
|
+
with a render check afterwards. The plan step was live-verified against a
|
|
149
|
+
scratch DB in v2.136; the apply step is unit-tested against stubs only.
|
|
150
|
+
|
|
5
151
|
## What's New in v2.212.4 — both dependency manifests move together again
|
|
6
152
|
|
|
7
153
|
### Changed
|
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.213.1 版 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
|
@@ -1857,7 +1857,8 @@ Key actions:
|
|
|
1857
1857
|
Color / Grade kernel actions (v2.11.0+) add safer grade inspection and
|
|
1858
1858
|
boundary helpers: `grade_capabilities`, `probe_grade_item`,
|
|
1859
1859
|
`probe_node_graph`, `safe_set_cdl`, `safe_copy_grade`, `safe_apply_drx`,
|
|
1860
|
-
`
|
|
1860
|
+
`apply_trace_plan` (the live half of the advanced server's identity-matched
|
|
1861
|
+
`color_trace`), `safe_export_lut`, `grade_version_snapshot`, `grade_version_restore`,
|
|
1861
1862
|
`color_group_capabilities`, `gallery_capabilities`, and
|
|
1862
1863
|
`grade_boundary_report`. See `docs/kernels/color-grade-kernel.md` for the live-tested
|
|
1863
1864
|
support map, and `docs/guides/color-decision-guide.md` for the practical distinction
|
package/docs/kernels/README.md
CHANGED
|
@@ -14,7 +14,7 @@ Current kernel coverage: **136 actions** across **9 compound MCP tools**.
|
|
|
14
14
|
| Media Pool / ingest | `media_pool` | `ingest_capabilities`, `setup_multicam_timeline`, `probe_ingest_item`, `probe_media_pool`, `safe_import_media`, `safe_import_sequence`, `safe_import_folder`, `organize_clips`, `copy_metadata`, `normalize_metadata`, `probe_clip_properties`, `metadata_field_inventory`, `safe_relink`, `safe_unlink`, `link_proxy_checked`, `link_full_resolution_checked`, `set_clip_marks`, `clear_clip_marks`, `copy_clip_annotations`, `media_pool_boundary_report` |
|
|
15
15
|
| Render / Deliver | `render` | `render_capabilities`, `probe_render_matrix`, `probe_render_settings`, `validate_render_settings`, `safe_set_render_settings`, `prepare_render_job`, `render_job_lifecycle_probe`, `quick_export_capabilities`, `safe_quick_export`, `export_render_boundary_report` |
|
|
16
16
|
| Review annotations | `timeline_markers` | `annotation_capabilities`, `probe_annotations`, `normalize_marker_payload`, `copy_annotations`, `move_annotations`, `sync_marker_custom_data`, `clear_annotations_by_scope`, `export_review_report`, `annotation_boundary_report` |
|
|
17
|
-
| Color / Grade | `timeline_item_color` | `grade_capabilities`, `probe_grade_item`, `probe_node_graph`, `safe_set_cdl`, `safe_copy_grade`, `safe_apply_drx`, `safe_export_lut`, `grade_version_snapshot`, `grade_version_restore`, `color_group_capabilities`, `gallery_capabilities`, `grade_boundary_report` |
|
|
17
|
+
| Color / Grade | `timeline_item_color` | `grade_capabilities`, `probe_grade_item`, `probe_node_graph`, `safe_set_cdl`, `safe_copy_grade`, `safe_apply_drx`, `apply_trace_plan`, `safe_export_lut`, `grade_version_snapshot`, `grade_version_restore`, `color_group_capabilities`, `gallery_capabilities`, `grade_boundary_report` |
|
|
18
18
|
| Fusion composition | `fusion_comp` | `fusion_graph_capabilities`, `probe_fusion_comp`, `probe_fusion_tool`, `safe_add_tool`, `safe_set_inputs`, `safe_connect_tools`, `fusion_boundary_report` |
|
|
19
19
|
| Conform / interchange | `timeline` | `conform_capabilities`, `probe_timeline_structure`, `detect_gaps_overlaps`, `source_range_report`, `export_timeline_checked`, `import_timeline_checked`, `compare_timelines`, `probe_interchange_roundtrip`, `detect_missing_media`, `build_relink_plan`, `conform_boundary_report` |
|
|
20
20
|
| Audio / Fairlight | `timeline` | `audio_capabilities`, `probe_audio_item`, `probe_audio_track`, `safe_set_audio_properties`, `audio_mix_capability_report`, `voice_isolation_capabilities`, `audio_mapping_report`, `safe_auto_sync_audio`, `transcription_capabilities`, `subtitle_generation_probe`, `fairlight_boundary_report` |
|
|
@@ -33,6 +33,7 @@ All actions are exposed through `timeline_item_color`.
|
|
|
33
33
|
| `safe_set_cdl` | Validate and normalize CDL payloads before calling `SetCDL`; supports dry run. |
|
|
34
34
|
| `safe_copy_grade` | Resolve target timeline item IDs before calling `CopyGrades`; supports dry run. |
|
|
35
35
|
| `safe_apply_drx` | Validate DRX file existence and temp-path guard before calling `ApplyGradeFromDRX`. |
|
|
36
|
+
| `apply_trace_plan` | Apply the advanced server's `color_trace` plan to the current timeline: resolve each entry to a live clip by (name, record start, duration), dry-run resolution table, one confirm_token for the batch, timeline archived first, then `ApplyGradeFromDRX` per clip; `version_name` adds a local version per clip so the previous grade survives. Unresolved entries are reported, never guessed. |
|
|
36
37
|
| `safe_export_lut` | Resolve LUT export type aliases and require temp output paths by default. |
|
|
37
38
|
| `grade_version_snapshot` | Read current, local, and remote grade version names. |
|
|
38
39
|
| `grade_version_restore` | Safely load a named local/remote version after verifying it exists. |
|
|
@@ -114,7 +115,8 @@ The live actions above drive a *running* Resolve. The companion advanced server
|
|
|
114
115
|
(`davinci-resolve-advanced`, see `resolve-advanced/README.md`) *computes* grades
|
|
115
116
|
offline from extracted frames and reads/writes `.drx`/`.drp` grades with **no
|
|
116
117
|
Resolve running**. It emits an apply-ready `.drx`; **applying it is this kernel's
|
|
117
|
-
job** (`safe_apply_drx`
|
|
118
|
+
job** (`safe_apply_drx` for one clip, `apply_trace_plan` for a whole `color_trace`
|
|
119
|
+
plan). Node never drives Resolve.
|
|
118
120
|
|
|
119
121
|
`drx` grading/QC actions (frame-stats → arithmetic → `.drx`, all local,
|
|
120
122
|
deterministic, guarded — they refuse to fabricate a match rather than emit a
|
|
@@ -138,8 +138,12 @@ files and the project DB.
|
|
|
138
138
|
reference-render, scale-corrected, red/yellow/cyan verdicts; each cut is
|
|
139
139
|
compared clear of its transition windows, and Resolve's own FCP7 export
|
|
140
140
|
ingests with its `-1` edges resolved and its missing ticks tolerated).
|
|
141
|
-
- **`color_trace`** — cross-project clip matching
|
|
142
|
-
|
|
141
|
+
- **`color_trace`** — cross-project clip matching on media identity (pool id /
|
|
142
|
+
file path / reel / file name + source-range overlap; names last) → a trace
|
|
143
|
+
plan with a lossless `.drx` per graded match and a `plan.json`. The live half
|
|
144
|
+
is `timeline_item_color.apply_trace_plan` (dry-run resolution table → one
|
|
145
|
+
confirm_token → ApplyGradeFromDRX per resolved clip, timeline archived first).
|
|
146
|
+
Pairs with the color kernel's `drx grade_transfer` for single looks.
|
|
143
147
|
- **`offline_ref`** — offline-reference clips have **no scripting API** but live
|
|
144
148
|
inside `.drp`/`.drt` as `<OfflineClip>` entries; patch them here.
|
|
145
149
|
- **`editorial`** — `parse_interchange` (EDL/OTIO/XMEML natively; **AAF via pyaaf2**,
|
|
@@ -12,7 +12,7 @@ that none exists).
|
|
|
12
12
|
|
|
13
13
|
**Verified on:** DaVinci Resolve Studio 21.0.2
|
|
14
14
|
|
|
15
|
-
**Totals:**
|
|
15
|
+
**Totals:** 41 missing capabilities, 50 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
|
|
@@ -79,18 +79,11 @@ equivalent, blocking full automation.
|
|
|
79
79
|
- **Reference:** [issue #73](https://github.com/samuelgursky/davinci-resolve-mcp/issues/73)
|
|
80
80
|
- **Tags:** missing-method, audio, channel
|
|
81
81
|
|
|
82
|
-
### Native multicam clip creation
|
|
83
|
-
|
|
84
|
-
- **Object:** `MediaPool`
|
|
85
|
-
- **Behavior:** There is no method to create a native multicam clip from a set of angles. Angles can be stacked onto tracks programmatically, but the multicam-clip conversion is a UI-only step.
|
|
86
|
-
- **Workaround / current handling:** Prepare a stacked timeline (media_pool setup_multicam_timeline) and finish the multicam-clip conversion in the Resolve UI.
|
|
87
|
-
- **Tags:** missing-method, media-pool, multicam
|
|
88
|
-
|
|
89
82
|
### Transition create / copy / clone
|
|
90
83
|
|
|
91
84
|
- **Object:** `Timeline / TimelineItem`
|
|
92
|
-
- **Behavior:** There is no method to ADD or CLONE an edit transition — no AddTransition/CreateTransition/AddVideoTransition on Timeline or TimelineItem (dir(), 21.0.4.5). CORRECTION, measured on Studio 21.0.4.5 (2026-08-12): this entry previously said transitions applied in the UI are 'invisible to and unmodifiable by scripts'. BOTH HALVES WERE WRONG and are withdrawn. A transition IS a first-class timeline item: a 12-frame Cross Dissolve applied through the Edit-page right-click menu enumerates in GetItemListInTrack('video', 1) as GetName()=='Cross Dissolve', GetStart()==86426, GetDuration()==12 — centered on a cut at 86432 — with a stable GetUniqueId() and a working GetTrackTypeAndIndex(). A transition authored offline into a .drp and imported reads IDENTICALLY, so the route that created it does not matter. It is also REMOVABLE: Timeline.DeleteClips([transition], False) returns True and deletes it, leaving both adjacent clips at their original starts and durations. THE DISCRIMINATOR between a transition item and a clip item is GetProperty(): a transition returns an EMPTY dict where a video clip returns 26 transform keys; it also has no MediaPoolItem and no Fusion comp. WHAT IS GENUINELY MISSING: creation
|
|
93
|
-
- **Workaround / current handling:** Automated QC of existing transitions IS possible and is the main practical need — enumerate GetItemListInTrack, treat any item whose GetProperty() is empty and whose GetMediaPoolItem() is None as a transition, and read its name, start and duration. Removal is scriptable via Timeline.DeleteClips. To CREATE one, either apply it in the Resolve UI, or author it offline and import: the advanced server's drp place_transition writes a cross dissolve at an abutting cut ({track, atFrame, durationFrames}) and it round-trips into Resolve 21.0.4.5 reading back at the expected centered range.
|
|
85
|
+
- **Behavior:** CREATION IS FIXED IN 21.1, READBACK IS NOT. Reported by @billcarroll (PR #197) from an attribute probe on Studio 21.1.0.14 (2026-09-08; not reproduced here, no 21.1 install): TimelineItem.AddTransition resolves to a <BlackmagicFusion.PyFunctionCall object>, not None. Its stub signature is AddTransition(transitionOptions) -> TimelineItem | None, where transitionOptions carries type (e.g. 'Cross Dissolve'), category ('simple'|'fusion'|'ofx'|'audio'), position ('start'|'end'), alignment ('left'|'center'|'right') and an optional duration in frames. It was NOT invoked (a call mutates the user's timeline), so this entry claims existence and signature only. WHAT REMAINS MISSING ON 21.1: reading a transition back. There is still no accessor for an existing transition's type, alignment or duration beyond its name string and frame range, and no clone verb — alignment and duration are write-only arguments to AddTransition. The pre-21.1 statement, kept as the historical record: there was no method to ADD or CLONE an edit transition — no AddTransition/CreateTransition/AddVideoTransition on Timeline or TimelineItem (dir(), 21.0.4.5). CORRECTION, measured on Studio 21.0.4.5 (2026-08-12): this entry previously said transitions applied in the UI are 'invisible to and unmodifiable by scripts'. BOTH HALVES WERE WRONG and are withdrawn. A transition IS a first-class timeline item: a 12-frame Cross Dissolve applied through the Edit-page right-click menu enumerates in GetItemListInTrack('video', 1) as GetName()=='Cross Dissolve', GetStart()==86426, GetDuration()==12 — centered on a cut at 86432 — with a stable GetUniqueId() and a working GetTrackTypeAndIndex(). A transition authored offline into a .drp and imported reads IDENTICALLY, so the route that created it does not matter. It is also REMOVABLE: Timeline.DeleteClips([transition], False) returns True and deletes it, leaving both adjacent clips at their original starts and durations. THE DISCRIMINATOR between a transition item and a clip item is GetProperty(): a transition returns an EMPTY dict where a video clip returns 26 transform keys; it also has no MediaPoolItem and no Fusion comp. WHAT IS GENUINELY MISSING (pre-21.1: creation too; on 21.1+ read the paragraph above): cloning, and any type/alignment/parameter detail — the transition's kind is knowable ONLY from its name string, and there is no way to read its alignment (centered/start/end) or edit its duration. AUDIO NUANCE (measured 2026-09-01 on 19.1.3.7, E113): an audio cross-fade enumerates in GetItemListInTrack('audio', n) with an EMPTY GetName() (24 frames, centered on the cut, between the two clips) — so on audio lanes even the kind is not readable from the name. The discriminator that holds for BOTH: GetMediaPoolItem() is None AND GetProperty() is empty — BUT a Solid Color generator AND a subtitle item read the same way (GetProperty() None, no MediaPoolItem; measured E115), so that pair only separates clips from non-clips. What separates a transition from a generator is GEOMETRY: a transition straddles a cut (one neighbour ends inside its span, another starts inside it) while a generator owns its span. timeline.get_items reports `kind` on that basis.
|
|
86
|
+
- **Workaround / current handling:** Automated QC of existing transitions IS possible and is the main practical need — enumerate GetItemListInTrack, treat any item whose GetProperty() is empty and whose GetMediaPoolItem() is None as a transition, and read its name, start and duration. Removal is scriptable via Timeline.DeleteClips. To CREATE one, either apply it in the Resolve UI, or author it offline and import: the advanced server's drp place_transition writes a cross dissolve at an abutting cut ({track, atFrame, durationFrames}) and it round-trips into Resolve 21.0.4.5 reading back at the expected centered range. On 21.1+ prefer TimelineItem.AddTransition, which takes the type, category, edge, alignment and duration directly.
|
|
94
87
|
- **Tags:** missing-method, timeline, transition
|
|
95
88
|
|
|
96
89
|
### Cloud project enumeration / export / user management
|
|
@@ -514,8 +507,8 @@ values, or automation-hostile modal prompts.
|
|
|
514
507
|
### MediaPoolItem.GetClipProperty('Transcription')
|
|
515
508
|
|
|
516
509
|
- **Object:** `MediaPoolItem`
|
|
517
|
-
- **Behavior:** Returns a PREVIEW of the transcription that ends in an ellipsis when the full transcript is longer than the property exposes.
|
|
518
|
-
- **Workaround / current handling:**
|
|
510
|
+
- **Behavior:** Returns a PREVIEW of the transcription that ends in an ellipsis when the full transcript is longer than the property exposes. Reported still true on Studio 21.1.0.14 by @billcarroll (PR #197; not reproduced here, no 21.1 install) — the property is not the fix. 21.1 adds a SEPARATE method that is not truncated: MediaPoolItem.GetTranscription(useNestedClipTranscription=False) -> {language, segments[{start, end, text, speaker, words[{start, end, text}]}]}, with timecode strings rather than frame numbers. The contributor measured it on a live 21.1.0.14 against an already-transcribed interview clip: 1550 segments, per-word start/end timecodes, a populated `speaker` field, and '(...)' as Resolve's own silence marker. Note the transcript is of the SOURCE clip, so timeline positions must be mapped through GetStart()/GetSourceStartFrame() on the timeline item.
|
|
511
|
+
- **Workaround / current handling:** On 21.1+, call MediaPoolItem.GetTranscription() instead of reading the property. On 21.0.x and earlier, treat a trailing ellipsis as truncation (see media_pool_item get_transcription's `truncated` flag).
|
|
519
512
|
- **Tags:** transcription, truncation
|
|
520
513
|
|
|
521
514
|
### ProjectManager.CreateProject (blocked by the current project)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Read/Write Symmetry Audit
|
|
4
4
|
|
|
5
|
-
- write-style action occurrences scanned: **
|
|
5
|
+
- write-style action occurrences scanned: **117**
|
|
6
6
|
- write-style action occurrences with a matching read: **71**
|
|
7
7
|
- distinct high-signal `set_` actions without a direct/known readback: **4**
|
|
8
8
|
|
|
@@ -13,6 +13,6 @@
|
|
|
13
13
|
- `set_keyframe_interpolation`
|
|
14
14
|
- `set_node_enabled`
|
|
15
15
|
|
|
16
|
-
## Low-signal (create/add/insert/apply/import — usually expected):
|
|
16
|
+
## Low-signal (create/add/insert/apply/import — usually expected): 41 distinct names
|
|
17
17
|
|
|
18
|
-
`add_clip_mattes`, `add_comp`, `add_fusion_mask`, `add_subfolder`, `add_sync_event_markers`, `add_timeline_mattes`, `add_track`, `add_version`, `apply_arri_cdl_lut`, `apply_cuts`, `apply_fairlight_preset`, `apply_grade_from_drx`, `apply_look_to_items`, `apply_spec`, `create_compound_clip`, `create_fusion_clip`, `create_magic_mask`, `create_stereo_clip`, `create_subtitles`, `create_timeline`, `create_timeline_from_clips`, `create_variant_from_ranges`, `import_comp`, `import_folder`, `import_from_drp`, `import_into_timeline`, `import_media`, `import_preset`, `import_project`, `import_render`, `import_timeline`, `import_timeline_checked`, `import_to_pool`, `insert_audio`, `insert_fusion_composition`, `insert_fusion_generator`, `insert_fusion_title`, `insert_generator`, `insert_ofx_generator`, `insert_title`
|
|
18
|
+
`add_clip_mattes`, `add_comp`, `add_fusion_mask`, `add_subfolder`, `add_sync_event_markers`, `add_timeline_mattes`, `add_track`, `add_version`, `apply_arri_cdl_lut`, `apply_cuts`, `apply_fairlight_preset`, `apply_grade_from_drx`, `apply_look_to_items`, `apply_spec`, `apply_trace_plan`, `create_compound_clip`, `create_fusion_clip`, `create_magic_mask`, `create_stereo_clip`, `create_subtitles`, `create_timeline`, `create_timeline_from_clips`, `create_variant_from_ranges`, `import_comp`, `import_folder`, `import_from_drp`, `import_into_timeline`, `import_media`, `import_preset`, `import_project`, `import_render`, `import_timeline`, `import_timeline_checked`, `import_to_pool`, `insert_audio`, `insert_fusion_composition`, `insert_fusion_generator`, `insert_fusion_title`, `insert_generator`, `insert_ofx_generator`, `insert_title`
|
package/install.py
CHANGED
|
@@ -37,7 +37,7 @@ from src.utils.update_check import (
|
|
|
37
37
|
|
|
38
38
|
# ─── Version ──────────────────────────────────────────────────────────────────
|
|
39
39
|
|
|
40
|
-
VERSION = "2.
|
|
40
|
+
VERSION = "2.213.1"
|
|
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
|
@@ -82,7 +82,13 @@ Each dispatches on an `action`. Highlights:
|
|
|
82
82
|
- **`conform`** — offline conform/relink QC engine (frame-oracle math, not filename matching),
|
|
83
83
|
reverse-clip DB repair, sequence lineage store + diff, per-cut frame QC (sampled clear of
|
|
84
84
|
transition windows; ingests Resolve's own FCP7 export — `-1` edges → junctions, no ticks needed).
|
|
85
|
-
- **`color_trace`** —
|
|
85
|
+
- **`color_trace`** — a ColorTrace that works: matches a graded SOURCE timeline against a TARGET
|
|
86
|
+
timeline (any two projects, from `Project.db`, read-only, no Resolve) on **media identity** —
|
|
87
|
+
pool item id / file path / reel / file name plus source-range overlap, so a stringout cut into
|
|
88
|
+
graded sections, a renamed clip, or relinked media still traces; clip names are the last resort.
|
|
89
|
+
Emits one lossless `.drx` per graded match plus a `plan.json`; the live server's
|
|
90
|
+
`timeline_item_color.apply_trace_plan` applies it (dry-run resolution table, one
|
|
91
|
+
confirm_token for the batch, timeline archived first).
|
|
86
92
|
- **`project_read` / `project_db`** — read/patch the Resolve project DB (SQLite or Postgres).
|
|
87
93
|
Includes `list_subtitle_styles` / `set_subtitle_style` — caption font family/size/weight/italic
|
|
88
94
|
and normalised position, which the scripting API cannot touch at all. Whole-track (not
|