davinci-resolve-mcp 2.68.2 → 2.69.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,147 @@
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.69.0
6
+
7
+ The free edition is documented as reachable, silence ripple stops clipping
8
+ speech at the cut, and the editorial surface grows a set of review-first
9
+ planners: dead-space markers, craft-aware cut points, conform QC, colour
10
+ pre-balance, beat detection, turnover manifests, and a project journal.
11
+
12
+ Two themes run through the additions. **Nothing new executes** — every planner
13
+ proposes and reports, and the existing plan → confirm → execute path is
14
+ unchanged. And **unverified is never reported as clean**: an item that could not
15
+ be analysed, a check that could not run, a handle that could not be measured and
16
+ a take with no transcript are each reported as such rather than folded into a
17
+ passing result.
18
+
19
+ ### Changed
20
+
21
+ - **`plan_silence_ripple` guard bands are now 2 pre-head / 4 post-tail frames**
22
+ (previously 0 and 1 — effectively none). This changes default output for any
23
+ caller that does not pass explicit handles.
24
+
25
+ The old defaults cut exactly on `silencedetect`'s gate crossings, which are not
26
+ word boundaries. `s` is marked when amplitude falls below the gate, but a
27
+ word's decay and the room reverb after it stay audible below it, so cutting
28
+ from `s` clipped the release. `e` is marked when amplitude rises back above the
29
+ gate, and a soft attack (s, f, th, or any unstressed syllable) crosses later
30
+ than the word actually begins, so `e` sat *inside* the next word and cutting up
31
+ to it ate the onset.
32
+
33
+ The onset guard is the larger of the two because that is the asymmetry users
34
+ hear: reviewers of the first public tutorial for this project independently
35
+ reported that "the first split seconds of your clips are trimmed so the audio
36
+ is a bit cut off". At 24 fps the new guards are 83 ms and 167 ms; at 30 fps,
37
+ 67 ms and 133 ms — both inside the range dialogue editors use by hand.
38
+
39
+ Pass `pre_head_frames` / `post_tail_frames` explicitly to restore the previous
40
+ behaviour.
41
+
42
+ ### Fixed
43
+
44
+ - **The docs told free-edition users the door was closed.** v2.68.0 shipped the
45
+ in-app bridge, which reaches the free edition through the ungated
46
+ **Workspace > Scripts** menu, but README's Requirements section still said "the
47
+ free edition does not support external scripting" 195 lines below the section
48
+ documenting the bridge, and `docs/install.md` said the same with no mention of
49
+ the bridge at all. The claim is true about *external* scripting and false as
50
+ users read it — the first large public tutorial for this project pinned a
51
+ correction telling viewers the method "REQUIRES the Studio Version".
52
+
53
+ README, `docs/install.md`, `install.py` and the MCP server's own `instructions`
54
+ now state the limit and the remedy together. `install.py` also grew the branch
55
+ it was missing: Resolve running, healthy interpreter, no connection is the
56
+ free-edition signature, and it used to print "Not running — start Resolve".
57
+
58
+ ### Added
59
+
60
+ **Editorial**
61
+
62
+ - `edit_engine.plan_dead_space_markers` — **the review gate.** Finds dead space
63
+ with the same calibrated detection as `plan_silence_ripple`, but proposes
64
+ Resolve markers instead of assembling a variant, so an editor can see every
65
+ gap before agreeing to lose it. Red = confident; yellow = the gate only just
66
+ cleared its separation floor. Items that could not be analysed are reported
67
+ and are explicitly **not** certified clean.
68
+ - `tightness` (`generous` default | `balanced` | `tight`) on the dead-space
69
+ planner. The default is deliberately the loosest: a first assembly is meant to
70
+ run long, because trimming is fast and visible while recovering material the
71
+ machine discarded is slow and invisible. Guard bands are floored regardless of
72
+ preset — `tight` removes more *gaps*, never more *speech*.
73
+ - Syntactic pause classification in `plan_transcript_tighten`. A pause after a
74
+ full stop must be markedly longer before it is proposed for removal than the
75
+ acoustically identical pause mid-phrase; the first is usually breathing room
76
+ and the second usually is not. Unpunctuated transcripts are flagged low
77
+ confidence rather than treated as all-removable.
78
+ - `edit_engine.rank_takes` — ranks takes on **measurable fluency** (fillers,
79
+ restarts, script coverage) and states in every response that fluency is not
80
+ quality. It never names a best take.
81
+ - `edit_engine.plan_beat_cuts` — beat, bar and phrase cut points for
82
+ music-driven cutting, frame-snapped. Requires the optional `librosa` extra and
83
+ honest-refuses without it.
84
+ - `edit_engine.plan_string_out` / `propose_structure` — assembly for footage
85
+ with no speech, from shots and motion rather than silence; and a no-script
86
+ mode that proposes a structure and requires approval.
87
+ - `edit_engine.plan_broll` — places B-roll against A-roll beats. Placement only:
88
+ relevance is the caller's and is never re-scored, protected beats are never
89
+ covered, and an explicit beat choice is honoured or refused, never moved.
90
+ - `edit_engine.rule_of_six_audit` and `split_edit_audit` — audits against the
91
+ classical weighted cut criteria, and J/L-cut classification. The audit is
92
+ explicit that the two heaviest criteria are not measurable and reports its own
93
+ coverage; there is deliberately no composite score.
94
+
95
+ **Finishing and colour**
96
+
97
+ - `edit_engine.conform_lint` — the online editor's pre-turnover checklist:
98
+ frame-rate mismatch, offline media, duplicate source timecode, buried layers,
99
+ fragile effects, missing reel names, duplicate usage. Checks that could not run
100
+ are listed in `not_checked`.
101
+ - `edit_engine.plan_prebalance` and `plan_reference_match` — neutral technical
102
+ pre-balance, and matching to a graded reference still. Curves, vignettes,
103
+ saturation, qualifiers and windows are refused **in code**; midtones are left
104
+ warm by design. Reference matching is end-points-only and says so.
105
+ - `edit_engine.plan_turnover` — sound / VFX / colour turnover manifests with
106
+ per-destination handle floors and a timecode-burned picture reference required
107
+ in all three. Manifests, not exports.
108
+ - Plans now carry a `handle_report`: keep ranges that leave too little source
109
+ media at a join for a dissolve, a slip or an audio crossfade.
110
+
111
+ **Reporting**
112
+
113
+ - `edit_engine.plan_report` and `include_report` on every audit — Markdown
114
+ renderings covering what would change (in timecode, with a reason per cut),
115
+ what was deliberately left alone, what could not be verified, and what needs a
116
+ human. Off by default for token cost; every audit advertises it.
117
+ - `journal` — ingest log, append-only known issues, session-prep summary with
118
+ value figures, technical handoff document, status summary, and a picture-lock
119
+ fingerprint with drift detection.
120
+ - `first_impression` — timestamped capture of a first viewing, sealed once
121
+ locked. There is deliberately no unlock.
122
+
123
+ **Documentation**
124
+
125
+ - **Optional extras are now documented up front** — README and `docs/install.md`
126
+ list what each extra unlocks and under which licence, and `scripts/doctor.py`
127
+ reports which are present. Four of the features added in this release need
128
+ `numpy` or `librosa`; they refuse honestly with the install line, but a user
129
+ reading the README previously had no way to know before hitting the refusal.
130
+ "Setup too hard" was one of the loudest complaints this release answers, and
131
+ shipping features behind an undocumented `pip install` is the same failure.
132
+
133
+ **Guards**
134
+
135
+ - `tests/test_free_edition_docs_drift.py` — a guard that does not forbid stating
136
+ the free-edition limitation, but requires that any file stating it also names
137
+ the bridge. Broad enough to catch a new phrasing rather than only the sentences
138
+ fixed here, and it asserts the remedy exists (the README anchor and the
139
+ installer script the docs promise).
140
+ - `tests/test_attribution_drift.py` — keeps named third parties out of the
141
+ committed tree entirely. Stores SHA-256 digests rather than the names it
142
+ forbids, so the guard is not itself the one file containing them.
143
+ - `resolve-advanced` now carries an MIT `LICENSE` in its published tarball, and
144
+ the three vendored workspaces declare `"license": "MIT"`.
145
+
5
146
  ## What's New in v2.68.2
6
147
 
7
148
  Bug fixes. The server no longer opens a second DaVinci Resolve, and a failed
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.68.2-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.69.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)
@@ -185,6 +185,47 @@ The open-source servers are complete and fully functional on their own.
185
185
  | Render and deliver | Format/codec matrix probing, render settings validation, queued job lifecycle checks, guarded Quick Export |
186
186
  | Extension authoring | Fuse, DCTL, ACES DCTL, and Resolve-page Lua/Python script lifecycle helpers with safe MCP-marked install/remove |
187
187
 
188
+ ## Optional Extras
189
+
190
+ The core install is deliberately small: Python, ffmpeg, and the Resolve scripting
191
+ API. Some features need more, and **each one refuses honestly with its own
192
+ install line rather than degrading into a guess** — a fabricated tempo or an
193
+ invented level produces confident, wrong output, which is worse than no feature.
194
+
195
+ Run `python scripts/doctor.py` to see which of these you have.
196
+
197
+ | Extra | Unlocks | Licence |
198
+ |---|---|---|
199
+ | **ffmpeg** on PATH | Silence detection, dead-space markers, level measurement, audio analysis. The single most useful thing to install. | LGPL/GPL — invoked as a subprocess, never bundled |
200
+ | `pip install numpy` | Colour pre-balance, reference-still matching, sound-density audit | BSD |
201
+ | `pip install librosa` | Beat, bar and phrase detection for music-driven cutting | ISC |
202
+ | `pip install -U openai-whisper` | Transcription, and everything word-level built on it | MIT |
203
+ | `pip install open_clip_torch` | Visual similarity and `find_similar` | MIT |
204
+ | `pip install transformers` | CLAP audio embeddings | Apache-2.0 |
205
+ | `pip install opencv-python` | Additional frame analysis | Apache-2.0 |
206
+
207
+ `media_analysis` action `capabilities` reports the analysis stack in detail and
208
+ tells you what each missing piece would enable.
209
+
210
+ **Nothing here is bundled.** Model weights carry their own licences separate from
211
+ the code that loads them; check them before commercial use.
212
+
213
+ ## What This Does Not Do
214
+
215
+ Knowing where a tool stops is worth as much as knowing what it does, and it is
216
+ cheaper to read it here than to discover it mid-project.
217
+
218
+ | Not supported | Why, and what you get instead |
219
+ |---|---|
220
+ | **Choosing the best take** | Performance is most of what makes a take right, and none of it is measurable from a waveform or a transcript. `rank_takes` ranks *fluency* — fillers, restarts, script coverage — and says so in every response. The take that plays is regularly the least fluent one, because the hesitation is often the acting. Use it to find the clean safety take, not to choose the read. |
221
+ | **Cutting to music** | No beat or downbeat detection yet. Speech-driven tools will read a music bed as one long region and are the wrong instrument for it. |
222
+ | **Judging a cut** | Nothing here has an opinion about whether an edit is good. Every destructive action is plan → review → confirm for that reason. |
223
+ | **Replacing an editor** | The output is a first-pass assembly, in the assistant-editor sense: ingest, sync, organize, string out, flag problems. It is a starting point you cut, not a finished cut. Defaults are deliberately **generous** — a first assembly is supposed to run long, because trimming is fast and visible while recovering discarded material is slow and invisible. |
224
+ | **Modifying your source media** | By design and without exception — see below. |
225
+
226
+ Anything analyzed but unverifiable is reported as unverified, never folded into
227
+ "fine". An empty result means "nothing found", never "nothing to find".
228
+
188
229
  ## Source Media Safety
189
230
 
190
231
  This project treats camera originals and source media as immutable. Analysis tools read source files and write reports only to sidecar, scratch, or project analysis directories; confirmed metadata publishing writes only to Resolve's project database. The server must not modify, transcode, proxy, or create derivatives of source media unless the user explicitly asks for that. See [Media Analysis Guide](docs/guides/media-analysis-guide.md) for the detailed source-safe workflow.
@@ -231,9 +272,11 @@ Extension authoring references live in [docs/authoring](docs/authoring/). Resolv
231
272
 
232
273
  ## Requirements
233
274
 
234
- - DaVinci Resolve Studio 18.5+ on macOS, Windows, or Linux. The free edition does not support external scripting.
275
+ - DaVinci Resolve 18.5+ on macOS, Windows, or Linux. **Studio** supports external scripting directly. The **free edition** does not Blackmagic gates external scripting to Studio — but it is still reachable through the [in-app bridge](#free-edition-in-app-bridge), which runs inside Resolve from the ungated **Workspace ▸ Scripts** menu.
235
276
  - Python 3.10+ (3.10-3.12 is the lowest-risk range). Python 3.13/3.14 also work on recent Resolve builds (verified on Studio 20.3.2); older builds may fail to connect on 3.13+, in which case use 3.10-3.12.
236
- - Resolve external scripting set to **Local**.
277
+ - Resolve external scripting set to **Local** (Studio). On the free edition this
278
+ preference has no effect — use the [in-app bridge](#free-edition-in-app-bridge)
279
+ instead.
237
280
 
238
281
  Resolve 19.1.3 remains the compatibility baseline. Resolve 20.x scripting calls are additive, version-guarded, and live-tested on 20.3.2. Resolve 21.0 scripting additions (audio classification, speaker-detection transcription, IntelliSearch, slate analysis, motion-deblur, speech generation, session background-task control) are exposed behind runtime capability detection, so they stay inert on older builds and activate automatically on Resolve 21+.
239
282
 
package/docs/SKILL.md CHANGED
@@ -850,11 +850,191 @@ clip-count readback plus `brain_edits` rationale rows.
850
850
  min_strip_frames?, pre_head_frames?, post_tail_frames?, include_audio?)` —
851
851
  waveform silence strips via ffmpeg `silencedetect`, mirroring Resolve's
852
852
  *Clip → Audio Operations → Ripple Delete Silence* (defaults: −30 dB,
853
- 10-frame minimum strip, 0 pre-head, 1 post-tail frame). Items without
853
+ 10-frame minimum strip, 2 pre-head, 4 post-tail frames guard bands that
854
+ keep the cut off the outgoing word's decay and the incoming word's attack).
855
+ Items without
854
856
  readable file paths ride along whole (reported in `skipped`), so the
855
857
  variant never silently loses content. `execute_silence_ripple(plan_id)`
856
858
  assembles a tightened VARIANT timeline from keep ranges — same safety model
857
859
  as `execute_tighten` (original untouched, confirm token, audio mirroring).
860
+ - `plan_dead_space_markers(timeline_name?, track_index?, threshold_db?,
861
+ tightness?, min_strip_frames?, pre_head_frames?, post_tail_frames?)` —
862
+ **review before you cut.** Finds dead space with the *same* calibrated gate as
863
+ `plan_silence_ripple` but proposes Resolve **markers** instead of an edit, so
864
+ an editor can look at every gap, delete the markers they disagree with, and
865
+ only then tighten. Reach for this whenever the ask is "show me the gaps
866
+ first" — it is the review gate, and without it an agent will invent its own
867
+ detection and mark the wrong spots. Red = confident; **Yellow = the gate only
868
+ just cleared its separation floor, so speech and room are close together and
869
+ the call deserves a second look.** Nothing is written: pair the returned
870
+ marker specs with `timeline_markers`. Items in `skipped` were *not* analyzed
871
+ and are explicitly **not** certified clean.
872
+ `tightness` (`generous` default | `balanced` | `tight`) scales the guard bands
873
+ and the minimum gap length — see below.
874
+ - `plan_report(plan_id, max_detail_rows?)` — **render any plan as a reviewable
875
+ Markdown report.** A 340-entry `keep_ranges` array is not reviewable, and the
876
+ rational response to a machine you cannot audit is to re-check it by hand,
877
+ which is the cost the tool was meant to remove. The report states: what would
878
+ change (in **timecode**, with a reason per cut), what was **deliberately left
879
+ alone** (invisible in the output, and the half people distrust most), what
880
+ could **not** be verified (never folded into "fine"), and what **needs a
881
+ human**. Returns both `report_markdown` and a one-line `summary` for chat.
882
+ Every plan kind renders, including ones this renderer does not know about.
883
+ - `rank_takes(clip_refs[], script?)` — rank several clips of the same material by
884
+ **measurable fluency**: filler density, stammered restarts, longest clean run,
885
+ and (with a `script`) how much of the intended line got said. **It ranks
886
+ fluency, not quality, and says so in every response.** Performance is most of
887
+ what makes a take right and none of it is measurable here — the take that
888
+ plays is regularly the least fluent one, because the hesitation is often the
889
+ acting. Use it to find the clean safety take or skip the warm-ups, never to
890
+ choose the read. Clips without transcripts are listed in `unavailable`
891
+ (**absent from the ranking, not last in it**), and takes too short to score
892
+ are flagged rather than dropped.
893
+ - `plan_beat_cuts(clip_ref | media_path, mode?, beats_per_bar?, bars_per_phrase?,
894
+ beat_offset?, min_shot_seconds?, timeline_fps?)` — **cut points from the music's
895
+ own pulse**, for footage with no speech. The speech tools find edit points in
896
+ words and pauses; music has neither, and pointing a silence gate at it makes
897
+ engine noise read as content and quiet read as dead space. `mode`: `beat` (every
898
+ beat — relentless), `bar` (downbeats), **`phrase` (default)** — music resolves at
899
+ phrase boundaries, which is what makes a cut feel inevitable rather than merely
900
+ synchronised. Frame-snapped. **Downbeats are inferred, not detected** (the first
901
+ beat is assumed to start a bar) — a track with a pickup needs `beat_offset`, and
902
+ that is the first thing to check if cuts feel consistently one beat early.
903
+ Reports its own tracking confidence. Requires the optional `librosa` extra
904
+ (`pip install librosa`, ISC) and **honest-refuses without it** rather than
905
+ inventing a tempo. Returns cut POINTS, not an assembly.
906
+ - `plan_prebalance(timeline_name?, track_index?, max_items?)` — **neutral technical
907
+ pre-balance**, the assistant colorist's highest-leverage pass. Measures black and
908
+ white points per channel off a mid-shot frame, groups by setup, picks a hero, and
909
+ proposes one bypassable **`ASST: Balance`** node per clip. Black balance on the
910
+ parade first, then white point. **Midtones are deliberately left warm** — skin
911
+ belongs near 11 o'clock on the vectorscope, and neutralizing midtones is the
912
+ fastest way to make everyone grey. Curves, vignettes, saturation, qualifiers and
913
+ windows are **refused in code**, not merely discouraged. Clipped highlights and
914
+ crushed shadows are flagged as `ASST: TECH/CREATIVE` markers, never silently
915
+ fixed. It has scopes and no eyes: numeric balance is defensible, look development
916
+ is not, and it cannot know the dim shot was dim on purpose.
917
+ - `rule_of_six_audit(timeline_name?, track_index?)` — audits a timeline against
918
+ the **Rule of Six** — the classical weighted cut criteria — and is loud about
919
+ what it cannot see. Those weights
920
+ are inverted against measurability: **everything computable is the bottom 26%**.
921
+ So **emotion (51%) and story (23%) appear in every response as `NOT_ASSESSED`
922
+ and cannot be suppressed**, criteria this build does not compute report
923
+ `NOT_IMPLEMENTED` (never a pass), and coverage is stated outright — *"1 of 6
924
+ criteria assessed, covering 10% of the decision."* **There is deliberately no
925
+ composite score**; averaging 26% into one number implies it describes the cut.
926
+ Findings order by scope ("movie first, scene second, moment third")
927
+ then by criterion weight — never by volume, so a rhythm problem (10%) always
928
+ outranks a screen-geography one (5%). Rhythm is implemented: metronomic runs
929
+ are flagged, and a pattern break landing on a marker is reported as **craft,
930
+ not a finding** — the break is where meaning lives. Cuts/min is compared to
931
+ the 14–16 commonly observed in dialogue, explicitly **descriptive not
932
+ prescriptive**.
933
+ - `split_edit_audit(timeline_name?, track_index?)` — **sound leads picture**.
934
+ The ear is faster than the eye, so the classical advice is to treat the cut as
935
+ a sound event first. Classifies every join: **L-cut** (audio edit later — outgoing
936
+ sound lingers), **J-cut** (audio earlier — incoming sound pulls forward), or
937
+ straight. A picture cut with no nearby audio edit is reported as **unpaired,
938
+ not straight** — sound running continuously across a join is a *stronger* form
939
+ of sound carrying picture. Flags a timeline where every join is straight: that
940
+ is where the NLE puts audio edits by default, and a dialogue sequence with no
941
+ split edits anywhere is usually one nobody has listened to yet. **No correct
942
+ ratio is suggested and none exists** — a montage, a two-hander and an
943
+ interview all want different distributions.
944
+ - `sound_density_audit(track_media, stream_limit?, duration_seconds?)` — the
945
+ **two-and-a-half rule**: an audience follows roughly 2.5 simultaneous sound
946
+ streams before the rest becomes texture. The distinction that makes this usable
947
+ is **competing vs. layered** — a music bed under dialogue is one stream plus
948
+ texture, not two competitors, and a version that counted active tracks would
949
+ flag every mixed timeline ever made. A stream within 12 dB of the loudest
950
+ counts as competing; further under counts as a bed. **2.5 is a long-standing
951
+ observation in sound editing, not a measured constant** — it is a parameter and its provenance
952
+ travels with every result. Pass rendered stems for a true reading; source clips
953
+ give a reading of the sources, and the response says which it got.
954
+ - `setup_sheet(timeline_name?, track_index?)` — **the wall of stills**: one
955
+ representative frame per *setup*, not per shot, so twenty images stand for the
956
+ whole film instead of two hundred reproducing the timeline at higher
957
+ resolution. Frame taken from the middle of that setup's longest usage (heads
958
+ and tails catch fades, slates and handles); ordered by **first appearance** so
959
+ the sheet reads in the direction the film does. Grouping is reel-name-else-
960
+ folder — a stated proxy for lighting setup, which Resolve does not expose.
961
+ - `first_impression(op=start|record|lock|get|list|diff, …)` — the editor is the
962
+ only person who gets to be a first-time audience, and that perception is
963
+ destroyed by the second viewing. Captures timestamped reactions during a first
964
+ pass and then **seals them**. `record` on a locked log raises; **there is
965
+ deliberately no unlock** — an impression that can be revised later is
966
+ worthless, because by then what changed is the viewer, not the film. Free text,
967
+ **no schema and no sentiment scoring** — the words are the artifact. `diff`
968
+ reports whether a later pass **revisited** each reaction and explicitly refuses
969
+ to claim anything was *fixed*.
970
+ - `plan_reference_match(reference_media, reference_at_seconds?, timeline_name?, max_items?)`
971
+ — match clips to a **graded reference still**, the way a colorist actually
972
+ communicates ("make it look like this one"). Reuses `prebalance.validate_plan`
973
+ rather than reimplementing the guardrails, so this path cannot permit what the
974
+ neutral path forbids. **END POINTS ONLY, stated in every response** — it puts
975
+ a shot in the reference's tonal neighbourhood and does **not** transfer the
976
+ reference's grade; curves, vignettes and secondaries stay where they are.
977
+ Matching across dissimilar subject matter (night exterior vs white cyc) is
978
+ reported as **low confidence** rather than delivered with a straight face.
979
+ - `plan_string_out(shots, order?)` — assembly for footage that does not talk.
980
+ Speechless material is cut from **shots and motion**, not silence: point a
981
+ speech gate at motorsport and engine noise reads as content while a quiet
982
+ straight reads as dead space. `order`: `chronological` (default) or
983
+ `activity`. **Unmeasured motion is never treated as static**, a locked-off
984
+ shot is described rather than penalised, and ranking by movement is a
985
+ measurement not an edit — the most important shot may rank last. Returns a
986
+ string-out, never a cut.
987
+ - `propose_structure(topics)` — **no-script mode**. Orders topics by coverage,
988
+ which measures what was *shot* and not what matters, and says so.
989
+ `requires_approval` is always true: a structure inferred from clustering is a
990
+ hypothesis about what the piece is, and the decision least safe to take
991
+ silently.
992
+ - `plan_broll(beats, candidates, allow_reuse?)` — place B-roll against A-roll
993
+ beats. **Placement only: relevance is whatever your matcher said and is never
994
+ re-scored here**, because whether a shot illustrates a line is not something
995
+ this can see. Cutaways sit *inside* a beat rather than straddling one; a beat
996
+ marked `protected` is never covered; an explicit `beat_index` is honoured
997
+ there or not at all, never silently moved somewhere it fits better.
998
+ - `plan_turnover(destinations, contents, version?, handle_frames?)` — validate
999
+ **sound / VFX / colour turnover manifests** against spec. Per-destination
1000
+ handle floors (sound 48 frames, picture 8 — crossfades and room tone reach
1001
+ past the picture cut), and a **timecode-burned picture reference is required
1002
+ in all three**, its absence a blocker: without one the receiving editor cannot
1003
+ verify anything against your intent. Includes the burn-in spec (both source
1004
+ *and* record timecode). **Manifests, not exports** — an export that runs
1005
+ perfectly and omits the textless is still a failed turnover, and rendering
1006
+ needs a live Resolve.
1007
+ - `journal(op=append|read|known_issues|ingest_log|session_prep|handoff|status|
1008
+ picture_lock|check_lock, …)` — the paperwork every craft role keeps and every
1009
+ tool skips. **Append-only:** resolving an issue appends a resolution and never
1010
+ deletes the issue, so the one nobody got round to is still there when someone
1011
+ asks why a shot shipped soft. `session_prep` carries open issues plus the value
1012
+ figures (prep hours, hours saved, rate) because the prep has to justify itself
1013
+ in the next budget round. `handoff` prints missing fields as **NOT STATED**
1014
+ rather than omitting them — a handoff that silently drops the frame rate reads
1015
+ as complete and the gap surfaces after work has started. `picture_lock` records
1016
+ a fingerprint of the cut and `check_lock` reports drift; the fingerprint hashes
1017
+ the **edit points**, not just counts and totals, so shots redistributed inside
1018
+ an unchanged runtime — exactly what a trim pass produces — still trip it.
1019
+ - **All audits accept `include_report=true`** for a Markdown rendering (what
1020
+ changed, what was deliberately left alone, what could not be verified, what
1021
+ needs a human). Off by default because rendering costs tokens on every call;
1022
+ every audit advertises it in `report_available`.
1023
+ - `conform_lint(timeline_name?, track_index?)` — **the online editor's checklist,
1024
+ run before turnover** instead of discovered after picture lock in someone else's
1025
+ suite. Blockers: frame-rate mismatch, offline media, two sources claiming one
1026
+ source timecode (misnamed cards — the most common reason a relink fails).
1027
+ Warnings: items buried under opaque layers, track overlaps, missing reel names,
1028
+ and effects that will not survive interchange (Premiere's *Scale to Frame Size*
1029
+ is the classic — its sizing data does not reach Resolve at all). It reports, it
1030
+ does not fix, and **checks that could not run for want of data are listed in
1031
+ `not_checked`** rather than counted as passes.
1032
+ - Plans now carry a **`handle_report`**: keep ranges that leave too little source
1033
+ media at a join for a dissolve, a slip or an audio crossfade. Picture floor 8
1034
+ frames, audio 48 — audio is far larger because crossfades and room tone reach
1035
+ past the picture cut. It reports rather than blocks (cutting to the head of a
1036
+ clip is often unavoidable), but **an unverified handle is never reported as a
1037
+ passing one**.
858
1038
  - `plan_swap(timeline_start_frame | item_name, kind="visual"|"text",
859
1039
  limit?)` — alternates for one timeline item via the similarity index,
860
1040
  filtered to shots long enough to fill the slot exactly.
package/docs/install.md CHANGED
@@ -4,13 +4,39 @@ This guide covers Resolve requirements, the universal installer, supported MCP c
4
4
 
5
5
  ## Requirements
6
6
 
7
- - **DaVinci Resolve Studio** 18.5+ (macOS, Windows, or Linux) the free edition does not support external scripting
7
+ - **DaVinci Resolve** 18.5+ (macOS, Windows, or Linux). **Studio** supports
8
+ external scripting directly. The **free edition** does not — Blackmagic gates
9
+ external scripting to Studio — but it is still reachable through the
10
+ [free-edition in-app bridge](../README.md#free-edition-in-app-bridge), which
11
+ runs inside Resolve from the ungated **Workspace ▸ Scripts** menu. Everything
12
+ below assumes Studio unless the bridge is in use
8
13
  - **Python 3.10+** (the MCP SDK requires 3.10). **3.10–3.12 is the lowest-risk
9
14
  choice**; 3.13/3.14 also work on recent Resolve builds — see below
10
15
  - DaVinci Resolve running with **Preferences > General > "External scripting using"**
11
16
  set to **Local**, or **Network** with `RESOLVE_SCRIPT_HOST` set to the Resolve
12
17
  host IP (`127.0.0.1` when Resolve and the MCP run on the same machine)
13
18
 
19
+ ### Optional extras
20
+
21
+ The core install needs only Python, ffmpeg and the Resolve scripting API.
22
+ Several features need an additional package and **refuse with the install line
23
+ rather than guessing** if it is absent:
24
+
25
+ | Extra | Unlocks | Licence |
26
+ |---|---|---|
27
+ | **ffmpeg** on PATH | silence detection, dead-space markers, level measurement | LGPL/GPL, subprocess only |
28
+ | `numpy` | `plan_prebalance`, `plan_reference_match`, `sound_density_audit` | BSD |
29
+ | `librosa` | `plan_beat_cuts` (beat / bar / phrase detection) | ISC |
30
+ | `openai-whisper` | transcription and the word-level tools built on it | MIT |
31
+ | `open_clip_torch` | visual similarity, `find_similar` | MIT |
32
+ | `transformers` | CLAP audio embeddings | Apache-2.0 |
33
+ | `opencv-python` | additional frame analysis | Apache-2.0 |
34
+
35
+ `python scripts/doctor.py` reports which are present. `media_analysis`
36
+ `capabilities` covers the analysis stack in more detail.
37
+
38
+ Model weights carry their own licences, separate from the code that loads them.
39
+
14
40
  > **Python 3.13 / 3.14:** these are **allowed** — setup will use them and warn.
15
41
  > Python 3.14 is verified working against DaVinci Resolve Studio 20.3.2. On
16
42
  > *older* Resolve builds the scripting bridge may fail to load on 3.13+
package/install.py CHANGED
@@ -36,7 +36,7 @@ from src.utils.update_check import (
36
36
 
37
37
  # ─── Version ──────────────────────────────────────────────────────────────────
38
38
 
39
- VERSION = "2.68.2"
39
+ VERSION = "2.69.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
@@ -1721,6 +1721,31 @@ def main():
1721
1721
  f" This can happen on Python 3.13+ with older Resolve builds. "
1722
1722
  f"If MCP tools fail, recreate the venv with Python 3.10-3.12."
1723
1723
  )
1724
+ elif resolve_running:
1725
+ # Running, healthy interpreter, still no connection. Reporting
1726
+ # "Not running — start Resolve" here (as this branch used to)
1727
+ # is both wrong and a dead end: Resolve *is* running. This is
1728
+ # the free-edition signature — external scripting is gated to
1729
+ # Studio — and the bridge is the way through, so say so
1730
+ # rather than sending the user to restart an app that is up.
1731
+ print(
1732
+ f" Resolve: {yellow('Running, but external scripting returned no connection')}"
1733
+ )
1734
+ print(
1735
+ " On Studio: Preferences > General > "
1736
+ "'External scripting using' = Local."
1737
+ )
1738
+ print(
1739
+ " On the free edition: external scripting is gated to Studio, "
1740
+ "but the in-app bridge works —"
1741
+ )
1742
+ print(
1743
+ " python scripts/install_resolve_bridge.py"
1744
+ )
1745
+ print(
1746
+ " then Workspace > Scripts > resolve_bridge, "
1747
+ "and set DAVINCI_RESOLVE_BRIDGE=1"
1748
+ )
1724
1749
  else:
1725
1750
  print(f" Resolve: {yellow('Not running')} — start Resolve to use MCP tools")
1726
1751
  else:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "davinci-resolve-mcp",
3
- "version": "2.68.2",
3
+ "version": "2.69.0",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 DaVinci Resolve MCP Contributors and Bradford Operations LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -15,7 +15,8 @@
15
15
  "files": [
16
16
  "server/**/*.mjs",
17
17
  "vendor/**",
18
- "README.md"
18
+ "README.md",
19
+ "LICENSE"
19
20
  ],
20
21
  "dependencies": {
21
22
  "@modelcontextprotocol/sdk": "^1.27.1",
@@ -4,6 +4,7 @@
4
4
  "description": "Conform QC & repair engine: parse a turnover, derive the frame the target tool actually shows (the Oracle), frame-compare to a reference (brightness-robust), repair resourcefully, and deliver a verified package. Pure core + injected adapters. See docs/design/conform-qc-repair-engine-2026-06-16.md.",
5
5
  "main": "./index.js",
6
6
  "private": true,
7
+ "license": "MIT",
7
8
  "scripts": {
8
9
  "test": "node --test test/"
9
10
  },
@@ -4,6 +4,7 @@
4
4
  "description": "DaVinci Resolve DRP (Project) format \u2014 XML/binary serialization, asset packaging, grade node encoders/decoders, validation. Layer 2 (drp-validator + grade-node-extractor read from fs / zip archives).",
5
5
  "main": "./index.js",
6
6
  "private": true,
7
+ "license": "MIT",
7
8
  "scripts": {
8
9
  "test": "echo 'see grade-encoder.test.js \u2014 runs via root jest config' && exit 0"
9
10
  },
@@ -4,6 +4,7 @@
4
4
  "description": "DaVinci Resolve DRT (Timeline-only) format — same SeqContainer/MpFolder schema as DRP, no project shell. Parser + builder + validator delegate to drp-format primitives.",
5
5
  "main": "./index.js",
6
6
  "private": true,
7
+ "license": "MIT",
7
8
  "scripts": {
8
9
  "test": "node --test __tests__/"
9
10
  },