davinci-resolve-mcp 2.24.0 → 2.25.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,135 @@
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.25.0
6
+
7
+ **Agentic flow improvements** — A second-pass review against the Claude
8
+ Certified Architect study material drove a sweep of correctness gains. Every
9
+ tool error now returns a structured envelope (`code` / `category` /
10
+ `retryable` / `reason` / `remediation` / `message`); `retryable` defaults are
11
+ locked per category so a host can make a one-shot retry decision without
12
+ inference. Compound-tool descriptions for `media_analysis` and
13
+ `timeline_item_color` adopt XML semantic tags (`<when_to_use>`, `<actions>`,
14
+ `<returns>`) for cheaper per-turn parsing. Repeated failures on the same
15
+ `(scope, action)` pair attach an `escalation` block on the 3rd response —
16
+ halts auto-retry loops with a `suggested_action` for the host. Batch
17
+ manifests now always carry `partial_success`, `completed_clip_ids`, and
18
+ `failed_clip_ids` for safe targeted retry.
19
+
20
+ **MCP resources surface** — 8 read-only resource URIs the host can poll
21
+ without paying a tool-turn cost: `status://mcp_version`,
22
+ `status://resolve_connection`, `status://current_project`,
23
+ `status://current_timeline`, `status://caps_preset`,
24
+ `analysis://recent_reports`, `capabilities://installed_tools`,
25
+ `capabilities://install_guidance`. Paired tools still work for hosts that
26
+ don't consume resources.
27
+
28
+ **MCP prompts surface** — 5 slash-command workflow templates:
29
+ `/davinci-resolve:analyze_and_propose_grade`,
30
+ `/davinci-resolve:match_bin_to_hero`,
31
+ `/davinci-resolve:verify_timeline_coverage`,
32
+ `/davinci-resolve:open_and_analyze_selection`,
33
+ `/davinci-resolve:prep_color_handoff`. First-class agentic intent, no
34
+ re-derivation from SKILL.md prose.
35
+
36
+ **Color-grading evidence base** — `timeline_item_color.grade_evidence_base`
37
+ composes `version_snapshot` + `node_graph` + `color_group` + coverage report
38
+ into a single `evidence_base` summary string; the SKILL guide now teaches
39
+ agents to lead any color recommendation with that line.
40
+ `timeline_item_color.propose_grade` formalizes a recommendation as a
41
+ validated structured plan (returns `plan_id` + `preview_path`; requires
42
+ explicit `execute=true` re-call). `bulk_match_to_hero` drives CDL-delta or
43
+ copy-grade across many targets with a `confirm_token` gate and dry-run
44
+ preview.
45
+
46
+ **Analysis caps layer** — Token-budget governance for analysis. 7 cap
47
+ dimensions across vision/transcription/job/clip/day scopes, 4 named presets
48
+ (`minimal` / `standard` / `generous` / `unlimited`), pre-call refusal with
49
+ `CAPS_REFUSAL` / `budget_exhausted` / `retryable: false`. New
50
+ `media_analysis` actions: `get_caps`, `set_caps_preset`. Token usage table
51
+ in the analysis DB plus a control-panel widget with gauges + override
52
+ inputs. Wall-clock timeout helper wraps vision/transcription call sites.
53
+
54
+ **Timeline versioning + analysis↔timeline marriage** — New
55
+ `timeline_versioning` MCP tool: every destructive timeline edit
56
+ auto-archives the current timeline into an Archive bin (compound, captions,
57
+ ripple, gap close, etc.), so versions can be diffed and rolled back. Run
58
+ scoping, schema v4 migrations, concurrency safety, structural snapshots,
59
+ action filtering, strict mode, auto-save preference, media-pool destructive
60
+ coverage, thumbnails. Backed by new modules `timeline_versioning.py`,
61
+ `timeline_brain_db.py`, `brain_edits.py`, `analysis_runs.py`,
62
+ `media_pool_changes.py`, `destructive_hook.py`. Surfaced in the control
63
+ panel's Review → History view.
64
+
65
+ **Async opt-in for long-running ops** — `analyze_clip` / `analyze_file` /
66
+ `commit_vision` accept `prefer_handle: true`. When set (and the estimated
67
+ runtime exceeds the configured threshold), the response is a fast handoff
68
+ with `job_id` + `status: "queued"`; poll `batch_job_status({job_id})`.
69
+ Default behavior unchanged.
70
+
71
+ **Aggregated provenance** — `summarize`,
72
+ `review_timeline_markers`, and `grade_evidence_base` now return a
73
+ `provenance` block: `source_reports[]` (clip_id, signature, report_path,
74
+ analyzed_at), `missing_reports[]` (per reason: `no_report` / `stale_report`
75
+ / `caps_refused`), and inline `[ref:<clip_id>]` citations in the human
76
+ summary text. Multi-clip claims are now traceable.
77
+
78
+ **Confirm-token gates on destructive batches** — `propose_grade`,
79
+ `bulk_match_to_hero`, and other multi-target writes now require an explicit
80
+ `confirm_token` on first execute (returned on the dry-run), with a
81
+ `pending_user_decision` error if missing.
82
+
83
+ **Action-help indirection** — `action_help(name=...)` returns the long-form
84
+ guidance for a single action, keeping the top-level tool descriptions
85
+ compact while preserving full per-action documentation.
86
+
87
+ **Tool-choice hint emission** — Analyze responses include a
88
+ `host_tool_choice_hint` block. Hosts that respect it pass
89
+ `tool_choice={type:"tool", name:"media_analysis"}` on the next API turn,
90
+ hard-locking the agent into the correct next call.
91
+
92
+ **Update process hardening** — Five improvements layered onto the
93
+ update-check path: active-job lock prevents updates mid-analysis, auto-stash
94
+ strategy preserves uncommitted work across updates, restart-needed marker
95
+ surfaces to the host, channels (`stable` / `beta` / `dev`), pre-update
96
+ breaking-change scan, integrity SHA verification of downloaded artifacts,
97
+ update history table, eager DB migration on update, and rollback to the
98
+ previous build. New `analysis_caps.py` + `update_check.py` revisions.
99
+
100
+ **Source-safe guardrails** — `destructive_hook.py` + decorator coverage
101
+ tests ensure every destructive surface goes through the auto-archive path
102
+ and never modifies, transcodes, or creates derivatives of source media.
103
+
104
+ **Test surface** — 30+ new test modules covering error envelopes,
105
+ failure tracking, partial-success manifests, `prefer_handle`, MCP resources,
106
+ MCP prompts, provenance, XML description shape, `action_help`,
107
+ `grade_evidence_base`, `propose_grade`, `bulk_match_to_hero`,
108
+ `confirm_token`, the analysis caps layer, caps integration / events /
109
+ history, timeline versioning, the timeline-brain DB, destructive decorator
110
+ coverage, the destructive hook, update hardening, and update history.
111
+
112
+ **Validation** — `tests/test_import.py`, `scripts/audit_api_parity.py`,
113
+ `node bin/davinci-resolve-mcp.mjs --version`, `npm pack --dry-run`, and
114
+ `git diff --check` all pass. 375 focused unit tests pass. Live Resolve
115
+ validation covered the D1–F2 surface end-to-end against project CKY /
116
+ Timeline 7 (D1 `retryable`, D2 XML descriptions, D3 partial-success on
117
+ plans + CAPS_REFUSAL manifests, E1 8 MCP resource URIs, E2 escalation on
118
+ 3× repeated failure, E3 `prefer_handle` job handoff with
119
+ `batch_job_status` polling, F1 provenance block) — 6/6 PASS on the
120
+ fourteenth-attempt smoke test. No source media was modified.
121
+
122
+ ## What's New in v2.24.1
123
+
124
+ **`npx davinci-resolve-mcp` no longer breaks MCP clients when invoked without a
125
+ subcommand.** The npm bootstrapper previously defaulted to `--help`, which wrote
126
+ usage text to stdout and exited 0. MCP stdio clients (Hermes Agent, Claude
127
+ Desktop, Cursor, etc.) read that as malformed JSON-RPC, retried three times,
128
+ then dropped the connection. `bin/davinci-resolve-mcp.mjs` now defaults to the
129
+ `server` subcommand when no arguments are supplied. Explicit `--help`, `-h`,
130
+ `help`, `--version`, and `-v` continue to print to stdout as before, and
131
+ existing configs that already pass `server` explicitly are unaffected. Reported
132
+ in [#41](https://github.com/samuelgursky/davinci-resolve-mcp/issues/41).
133
+
5
134
  ## What's New in v2.24.0
6
135
 
7
136
  **Host-chat vision protocol (V2)** — `analyze_*` actions now use
@@ -88,10 +217,7 @@ ffprobe/ffmpeg resolve even when the MCP server is launched by a GUI app
88
217
  Mandatory" section. `docs/SKILL.md` rewrites the `analyze_media` prompt
89
218
  guidance for the host-chat-paths protocol and adds the anti-regression rule.
90
219
  `docs/guides/media-analysis-guide.md` covers the deferred vision payload and
91
- commit step. New design docs under `docs/design/`:
92
- `v2-control-panel-design.md`, `v2-db-schema.sql`,
93
- `v2-implementation-gameplan.md`, `v2-shot-schema-spec.md`,
94
- `control-panel-polish-gameplan.md`.
220
+ commit step.
95
221
 
96
222
  **Validation**: static import checks, API parity audit, focused
97
223
  media-analysis + marker/range/v232/v233 unit tests, npm CLI smoke,
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.24.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
3
+ [![Version](https://img.shields.io/badge/version-2.25.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-32%20(329%20full)-blue.svg)](#server-modes)
@@ -11,6 +11,10 @@
11
11
 
12
12
  A Model Context Protocol (MCP) server that lets AI assistants control DaVinci Resolve Studio through the official Scripting API. It provides full API coverage plus guarded workflow helpers for editing, media pool organization, render setup, review markers, grading, Fusion, Fairlight, project lifecycle tasks, extension authoring, and source-safe media analysis.
13
13
 
14
+ [![Local control panel](docs/images/control-panel/01-overview.png)](docs/guides/control-panel.md)
15
+
16
+ A local browser control panel ships with the server for inspecting Resolve state, running source-safe analysis, drilling into analyzed clips and shots, and editing analysis output inline. See the [Control Panel Guide](docs/guides/control-panel.md) for the full tour.
17
+
14
18
  ## Quick Start
15
19
 
16
20
  ```bash
@@ -114,6 +118,7 @@ For method-by-method status, see [API Coverage and Test Results](docs/reference/
114
118
  | [API Coverage and Test Results](docs/reference/api-coverage.md) | Key stats, API coverage table, live-test status, full method reference |
115
119
  | [Kernel Action Coverage](docs/kernels/README.md) | Current guarded workflow action map |
116
120
  | [AI Skill Reference](docs/SKILL.md) | Operational context for AI assistants using the compound server |
121
+ | [Control Panel Guide](docs/guides/control-panel.md) | Local browser panel tour: Overview, Review (bin/clip/shot), Analyze, Setup, Preferences |
117
122
  | [Media Analysis Guide](docs/guides/media-analysis-guide.md) | Source-safe FFprobe, FFmpeg, Whisper, sidecar, and analysis-root workflows |
118
123
  | [Multicam Setup Helper Guide](docs/guides/multicam-setup-guide.md) | Stacked timeline prep, helper/API boundary, and Resolve UI conversion steps |
119
124
  | [Editorial Decision Guide](docs/guides/editorial-decision-guide.md) | Project-owned editorial craft guidance for analysis and timeline decisions |
@@ -336,7 +336,10 @@ function commandControlPanel(args) {
336
336
  }
337
337
 
338
338
  function main() {
339
- const [command = "--help", ...args] = process.argv.slice(2);
339
+ const argv = process.argv.slice(2);
340
+ // No args → run the MCP stdio server. Anything printed to stdout would
341
+ // otherwise be parsed as JSON-RPC by MCP clients and break the connection.
342
+ const [command = "server", ...args] = argv;
340
343
 
341
344
  try {
342
345
  if (command === "--help" || command === "-h" || command === "help") {
package/docs/SKILL.md CHANGED
@@ -131,6 +131,11 @@ Code's Read tool handles JPG/PNG natively), produce the JSON, and call
131
131
  `pending_host_vision_analysis` — surface that explicitly; do not call the
132
132
  analysis complete.
133
133
 
134
+ The deferred payload also includes a `host_tool_choice_hint` block. Hosts that
135
+ respect this hint pass it as `tool_choice={type:"tool", name:"media_analysis"}`
136
+ on the next API turn, hard-locking the agent into the correct next call. Hosts
137
+ that don't recognize the field ignore it — the flow is unchanged for them.
138
+
134
139
  ## Local Control Panel
135
140
 
136
141
  If the user asks to open, launch, or inspect the Resolve MCP control panel, run
@@ -146,6 +151,11 @@ localhost URL. The panel is local and single-user; it is an operational surface
146
151
  for server status, Resolve clips, source-safe analysis jobs, preferences, and
147
152
  diagnostics as those sections are added.
148
153
 
154
+ The **Review tab → History** button opens the timeline-history surface:
155
+ per-timeline version chain, brain-edit deltas, manual archive, and rollback.
156
+ Backed by `timeline_versioning` MCP actions; see that tool's section below for
157
+ the underlying primitives.
158
+
149
159
  ---
150
160
 
151
161
  ## Editorial Memory And Decision-Making
@@ -159,8 +169,15 @@ screen geography, continuity, and coverage variety.
159
169
  Before analyzing or rebuilding anything, check whether the active project already
160
170
  contains useful evidence:
161
171
 
162
- - `media_analysis(action="summarize")`
163
- - `media_analysis(action="get_report")` when a manifest or report path is known
172
+ - `media_analysis(action="coverage_report", params={"target": {...}})` — the
173
+ pre-flight contract. Pure read; never triggers analysis. Returns per-clip
174
+ state (analyzed / stale / missing / reuse_blocked / superseded_by_relink),
175
+ layer presence, `source_trust` tier, and a `recommended_action`. The response
176
+ carries an `evidence_base` summary string — **lead any editorial or color
177
+ recommendation with that line, before the creative answer.**
178
+ - `media_analysis(action="summarize")` for project-wide rollup of warnings,
179
+ motion distribution, and signed-report counts.
180
+ - `media_analysis(action="get_report")` when a manifest or report path is known.
164
181
  - `timeline(action="list")`
165
182
  - `timeline(action="get_current")`
166
183
  - `timeline(action="probe_timeline_structure")`
@@ -168,15 +185,24 @@ contains useful evidence:
168
185
  - `timeline_markers(action="get_all")`
169
186
  - `media_analysis(action="review_timeline_markers")` when marker imagery matters
170
187
 
171
- Reuse prior analysis unless it is stale, incomplete, or missing the modality the
172
- user is asking for. For example, do not re-run visual analysis just because the
173
- edit task is new if a current report already has keyframes, motion variance, and
174
- usable visual descriptions. Add transcription, host_chat_paths vision (followed
175
- by commit_vision), marker review, or source range checks only when that missing
176
- evidence changes the decision. Use `force_refresh=true` only when the user asks for a fresh read or
188
+ Reuse prior analysis unless it is stale, incomplete, missing a modality, or
189
+ flagged `superseded_by_relink` because Resolve's source clip was replaced after
190
+ analysis ran. Coverage_report surfaces all of these in one read. Do not re-run
191
+ visual analysis just because the edit task is new if a current report already
192
+ has keyframes, motion variance, and usable visual descriptions. Add
193
+ transcription, host_chat_paths vision (followed by commit_vision), marker
194
+ review, or source range checks only when that missing evidence changes the
195
+ decision. Use `force_refresh=true` only when the user asks for a fresh read or
177
196
  when cache signatures show the source, prompt, depth, or requested modality has
178
197
  changed.
179
198
 
199
+ Source-trust filtering: `coverage_report` accepts `min_source_trust` (one of
200
+ `auto`, `filename`, `low`, `medium`, `high`). Clips below the threshold appear
201
+ in `summary.clips_needs_higher_trust` and are reported with
202
+ `below_min_source_trust=true`. Use `medium` for routine work, `high` for
203
+ shot-matching or look-development passes where confident scene/identity reads
204
+ matter.
205
+
180
206
  For finished-video editorial work, scene detection and motion variance are
181
207
  guardrails, not story. Use them to avoid black frames, flash frames, corrupt
182
208
  ranges, and accidental cut points. Let transcript, sound events, complete
@@ -217,6 +243,13 @@ Be explicit about the API boundary:
217
243
  wheel values, log/HDR palette values, curves, qualifiers, power windows,
218
244
  tracking, Color Warper, and detailed ResolveFX/OFX parameter edits.
219
245
 
246
+ Before any color recommendation, run
247
+ `media_analysis(action="coverage_report", params={"target": {...},
248
+ "min_source_trust": "medium"})` (use `"high"` for shot-matching or
249
+ look-development passes). Lead the response with the returned `evidence_base`
250
+ line before the grade plan. Coverage_report surfaces relink-superseded clips
251
+ that must be re-analyzed before being graded from prior visual descriptions.
252
+
220
253
  For safe color work, start with `timeline_item_color(action="grade_boundary_report")`,
221
254
  `timeline_item_color(action="grade_version_snapshot")`,
222
255
  `timeline_item_color(action="probe_node_graph")`, and a Resolve-rendered frame
@@ -415,12 +448,13 @@ report reuse, persisted analysis execution, host_chat_paths visual review
415
448
  metadata/marker writeback, and timeline-level editorial helpers.
416
449
 
417
450
  Key actions: `capabilities`, `install_guidance`, `resolve_output_root`, `plan`,
418
- `analyze_file`, `analyze_clip`, `analyze_bin`, `analyze_project`,
419
- `detect_sync_events`, `add_sync_event_markers`, `publish_clip_metadata`,
420
- `commit_vision`, `summarize`, `get_report`, `build_index`, `index_status`,
421
- `query_index`, `start_batch_job`, `run_batch_job_slice`, `batch_job_status`,
422
- `list_batch_jobs`, `cancel_batch_job`, `resume_batch_job`,
423
- `review_timeline_markers`, and `cleanup_artifacts`.
451
+ `coverage_report`, `analyze_file`, `analyze_clip`, `analyze_bin`,
452
+ `analyze_project`, `detect_sync_events`, `add_sync_event_markers`,
453
+ `publish_clip_metadata`, `commit_vision`, `summarize`, `get_report`,
454
+ `build_index`, `index_status`, `query_index`, `start_batch_job`,
455
+ `run_batch_job_slice`, `batch_job_status`, `list_batch_jobs`,
456
+ `cancel_batch_job`, `resume_batch_job`, `review_timeline_markers`, and
457
+ `cleanup_artifacts`.
424
458
  The tool never installs
425
459
  dependencies and validates that outputs stay under
426
460
  `davinci-resolve-mcp-analysis` project roots rather than beside source media.
@@ -434,14 +468,29 @@ for existing reports. `quick` uses ffprobe metadata; `standard` adds ffmpeg
434
468
  read-through checks,
435
469
  cut-boundary analysis from full-stream scene detection, flash-frame candidates,
436
470
  motion/variance scoring, analysis keyframes, and sidecar reports.
437
- By default, planning checks the active project's analysis root for existing
438
- reports and marks matching clips `skip_execution=true` when those reports already
439
- contain the requested technical, motion, transcription, and vision layers.
471
+ By default, planning checks the active project's analysis root and bounded
472
+ related project-version roots for existing reports, then marks matching clips
473
+ `skip_execution=true` when those reports already contain the requested
474
+ technical, motion, transcription, and vision layers.
475
+ Resolve clip records also carry the published third-party
476
+ `davinci_resolve_mcp.analysis_report_path` when metadata writeback has run; use
477
+ that provenance as a first-class reuse hint even if the report lives under a
478
+ previous project-version analysis root.
479
+ The planner also maintains an `analysis_registry.json` under the analysis base
480
+ root. This registry indexes report paths by source path, clip id, media id, and
481
+ signature so project renames and versioned Resolve projects can still find prior
482
+ work quickly.
440
483
  Reports include cache signatures with source stat, depth, frame budget, prompt
441
484
  hash, and requested modalities. Use `force_refresh=true` for a fresh read,
442
485
  `max_report_age_days` for freshness limits, and `reuse_policy="fresh"` when
443
486
  unsigned older reports should not be reused. Pass `reuse_existing=false` only
444
- when the user explicitly wants to ignore memory.
487
+ when the user explicitly wants to ignore memory; pass
488
+ `search_related_project_roots=false` only for intentionally isolated runs.
489
+ If Resolve metadata shows prior MCP analysis but the planner cannot validate a
490
+ matching report, execution returns `status="reuse_blocked"` instead of silently
491
+ reanalyzing. Treat that as a project-memory integrity warning; restore the
492
+ report or pass `force_refresh=true` only when the user explicitly wants fresh
493
+ analysis.
445
494
  Transcription, visual analysis, metadata writeback, and Media Pool marker
446
495
  writeback are default-on. Vision uses
447
496
  `vision.provider="host_chat_paths"`: analyze actions extract representative
@@ -466,6 +515,10 @@ plus before/after cut-boundary frames as the sampled set. Skipping
466
515
  `commit_vision` leaves the run in `pending_host_vision_analysis` — that is a
467
516
  failure mode to surface, not a silent downgrade. The local mock providers are
468
517
  for tests and do not send frames off-machine.
518
+
519
+ When creating timelines through `media_pool`, use `if_exists="reuse"` for
520
+ idempotent reruns, `if_exists="version"` for deliberate alternate cuts, and
521
+ `if_exists="fail"` when duplicate names indicate a workflow error.
469
522
  Use `detect_sync_events` before multicam setup, deliverable QC, or single-camera
470
523
  sync review when the user needs likely 2-pop or slate-clap locations. It reads
471
524
  source audio through FFmpeg/FFprobe only, returns advisory frames/timecodes and
@@ -497,6 +550,111 @@ only when that mutation is intentional.
497
550
 
498
551
  ### Timelines
499
552
 
553
+ **`timeline_versioning`** — Version-on-mutate, archive, rollback, brain-edit history (C6).
554
+
555
+ Every destructive timeline op (compound, captions, ripple delete, gap close,
556
+ retime, marker batch, track add/delete, take swaps, color grade, etc.) auto-
557
+ archives the working timeline to the `Archive` bin under an `analysis_run_id`
558
+ before the mutation runs. This tool surfaces and controls that history.
559
+
560
+ Key actions:
561
+ - `begin_run(label?, initiator?, analysis_run_id?)` — open a multi-step run.
562
+ Subsequent destructive calls auto-thread this run's ID, so a brain
563
+ operation that touches 5 clips creates ONE archive + 5 logged edits
564
+ instead of 5 separate archives.
565
+ - `end_run(analysis_run_id?)` — close the run; aggregates brain_edits into
566
+ per-metric rollup in `analysis_runs.summary_json`.
567
+ - `list_runs(limit?)` — recent runs newest first with their summaries.
568
+ - `archive_current(reason?, analysis_run_id?)` — manual checkpoint of the
569
+ current timeline. Idempotent within an `analysis_run_id`. Also captures a
570
+ structural snapshot (every clip's placement, written to `timeline_clip_usage`)
571
+ and a thumbnail (when the Color page has a current clip).
572
+ - `list_versions(timeline_name)` — version chain, oldest first. Each row
573
+ includes `archived_timeline_name`, `created_at`, `analysis_run_id`,
574
+ `initiator`, `thumbnail_path`, and `drt_export_path` (set when the version
575
+ was retention-collapsed to disk).
576
+ - `diff_versions(timeline_name, from_version, to_version)` — structural diff
577
+ between two snapshots: `{added, removed, moved}` lists of clips by
578
+ media_pool_item_id and timeline position.
579
+ - `get_history(timeline_name?, analysis_run_id?, limit?)` — brain-edit rows
580
+ with `edit_type`, `target_metric`, `before_value`, `after_value`, `delta`,
581
+ `rationale`, and `initiator`. Filter by timeline or run; defaults to 50.
582
+ - `media_pool_changes(analysis_run_id?, media_pool_action?, limit?)` —
583
+ destructive media-pool history (deletes, replaces, relinks) from the
584
+ `media_pool_changes` table. Separate from brain_edits because the
585
+ addressable entity is a media_pool_item, not a timeline.
586
+ - `rollback(timeline_name, version, analysis_run_id?)` — archive current first,
587
+ then duplicate the archived version back as a new `<name>_rolled_back_<HHMMSS>`.
588
+ - `prune(timeline_name, keep_n=10)` — collapse old versions to `.drt` exports
589
+ under `<project>/_soul/timeline_versions/<slug>/` and remove them from the
590
+ bin. DB row preserved with `drt_export_path` populated for later rollback.
591
+ - `registry()` — cross-project brain-edits registry that lives at the analysis
592
+ base root (one level above each project_root). Mirrors `analysis_registry.json`.
593
+
594
+ **Strict mode** — `timeline.delete_timelines`, `timeline.delete_track`, and
595
+ `timeline.delete_clips(ripple=True)` REFUSE to run when the pre-mutation
596
+ archive can't be created. Pass `strict=true` on any destructive op to opt in.
597
+ This prevents catastrophic ops from proceeding when versioning is broken.
598
+
599
+ **Action filtering** — `timeline_item.set_property(key='Notes')` and
600
+ `timeline.set_clip_property(key='Notes'|'Comments')` bypass versioning because
601
+ free-text metadata isn't worth archiving. See `NO_ARCHIVE_ON_KEYS` in
602
+ `src/utils/destructive_hook.py` to add more.
603
+
604
+ **Preferences** — `timeline_versioning_auto_save_after_archive` (default false)
605
+ triggers `project.SaveProject()` after every archive so Resolve crashes don't
606
+ lose history. Configure via the `setup` tool's preferences.
607
+
608
+ ### Analysis Caps
609
+
610
+ `media_analysis` honors a project-wide caps preset that controls 7 dimensions
611
+ of analysis cost: response payload size, frames per clip, vision tokens per
612
+ clip / per job / per day, wall-clock seconds per call, and the maximum frame
613
+ image dimension before upload. Four named presets, plus per-field overrides.
614
+
615
+ | Dimension | minimal | standard | generous | unlimited |
616
+ |------------------------------:|--------:|---------:|----------:|----------:|
617
+ | response_chars | 5,000 | 25,000 | 100,000 | none |
618
+ | vision_tokens_per_clip | 5,000 | 25,000 | 100,000 | none |
619
+ | frames_per_clip | 4 | 8 | 24 | none |
620
+ | vision_tokens_per_job | 50,000 | 250,000 | 1,000,000 | none |
621
+ | vision_tokens_per_day | 100,000 | 500,000 | 2,000,000 | none |
622
+ | wall_clock_seconds_per_call | 30 | 90 | 300 | none |
623
+ | max_frame_dim_pixels | 512 | 768 | 1280 | none |
624
+
625
+ Default preset: `standard`. Set via `media_analysis(action="set_caps_preset",
626
+ preset=…, overrides={...})` or the dashboard's **Preferences → Analysis Caps**
627
+ panel. Inspect via `media_analysis(action="get_caps")` which returns the
628
+ effective values + a usage rollup (clip / job / day) with percent-consumed.
629
+ `media_analysis(action="get_usage", scope="day"|"job"|"clip")` returns raw
630
+ counts for one scope. Usage is tracked in
631
+ `<project>/_soul/timeline_brain.sqlite` (`analysis_token_usage` table).
632
+
633
+ The caps layer:
634
+ - Slices `frame_paths` to `frames_per_clip` before the host LLM sees them.
635
+ - Downscales each sampled frame in place to `max_frame_dim_pixels` (Pillow;
636
+ degrades silently to original-resolution upload if not installed).
637
+ - Trims the analysis response payload to `response_chars`, dropping the
638
+ largest list/string fields first and marking the trim under `_trimmed`.
639
+ - Records actual token usage from the host's `commit_vision` payload's
640
+ optional `usage: {vision_tokens, ...}` block. Hosts that don't report
641
+ tokens still get `frames_uploaded` recorded.
642
+
643
+ Wall-clock timeout + cumulative-budget refusal are implemented in
644
+ `src/utils/analysis_caps.py` and ready to hook at additional call sites in
645
+ the analysis pipeline; the initial integration is at frame sampling +
646
+ response construction + commit_vision usage recording.
647
+
648
+ **Declared edits** — when the brain (or an agent acting deliberately) wants to
649
+ measure an edit, pass `metric`, `direction`, and `rationale` in the params of
650
+ the destructive call. The hook captures `before_value` and `after_value` from
651
+ the live timeline (using the metric vocabulary in `brain_edits.py`) and writes
652
+ them to the `brain_edits` row. Without these, the edit is still logged but with
653
+ null metric — gives history without requiring deliberate intent.
654
+
655
+ Supported metrics: `duration_seconds`, `avg_performance_score`, `clip_count`,
656
+ `gap_count`, `total_gap_seconds`, `redundancy_score`.
657
+
500
658
  **`timeline`** — Timeline operations: tracks, clips, import/export, generators.
501
659
 
502
660
  Key actions:
@@ -345,6 +345,45 @@ Do not promise node labels or node colors unless the available API path can
345
345
  actually write them. Existing labels, LUTs, tools, and cache state can be
346
346
  inspected and reported.
347
347
 
348
+ ## Pre-flight Coverage Check (required)
349
+
350
+ Before answering any shot-matching, look-development, or per-clip grade question,
351
+ call `timeline_item_color(action="grade_evidence_base", params={...})` against the
352
+ target clip. The action is a pure read — it never mutates and never triggers
353
+ analysis. It composes the version snapshot, node graph, color group, and
354
+ `coverage_report` for the underlying media pool item into a single one-line
355
+ `evidence_base` string. **Lead your response with that line — before any grade
356
+ recommendation.**
357
+
358
+ For sequence-wide checks (multiple clips, bin, timeline), use
359
+ `media_analysis(action="coverage_report")` as before — the broader pre-flight
360
+ covers all targets in one call.
361
+
362
+ The response carries an `evidence_base` string and per-clip details: layer
363
+ presence, source-trust tier, staleness reasons, relink supersedure, and a
364
+ `recommended_action`. **Lead your response to the user with the `evidence_base`
365
+ line — before any grade recommendation.**
366
+
367
+ For color work, source-trust matters more than for editorial. Use the
368
+ `min_source_trust` parameter to gate recommendations:
369
+
370
+ - `coverage_report(min_source_trust="medium")` for routine corrections.
371
+ - `coverage_report(min_source_trust="high")` for hero shots, look-development
372
+ passes, and any decision that depends on confident scene/lighting recognition.
373
+
374
+ Clips below the threshold appear in `summary.clips_needs_higher_trust` and
375
+ should be re-analyzed with an explicit higher `source_trust` before being graded
376
+ from their visual descriptions.
377
+
378
+ Relink-superseded clips (`superseded_by_relink=true`) must never be reasoned
379
+ about as if the prior analysis still describes the current media. The prior
380
+ report is preserved for reference, but a re-analysis is required before
381
+ shot-matching or look development is grounded.
382
+
383
+ If existing analysis flags exposure issues, clipped highlights, color cast
384
+ warnings, or scene-of-interest notes, surface those before proposing CDL or
385
+ node-graph changes.
386
+
348
387
  ## Agent Response Rules
349
388
 
350
389
  When answering a color request, classify the requested operation:
@@ -368,6 +407,7 @@ DCTL, or CDL is equivalent to a full colorist pass.
368
407
 
369
408
  ## Useful MCP Calls
370
409
 
410
+ - `media_analysis(action="coverage_report", params={...})` — pre-flight evidence-base check
371
411
  - `resolve_control(action="open_page", params={"page": "color"})`
372
412
  - `timeline_item_color(action="grade_boundary_report", params={...})`
373
413
  - `timeline_item_color(action="probe_grade_item", params={...})`
@@ -0,0 +1,128 @@
1
+ # Local Control Panel
2
+
3
+ The DaVinci Resolve MCP ships with a local, single-user browser control panel for
4
+ inspecting Resolve state, running source-safe media analysis, drilling into
5
+ analyzed clips and shots, fixing analysis output inline, and managing
6
+ preferences.
7
+
8
+ The panel is a local HTTP server (default `http://127.0.0.1:8765`). It does not
9
+ expose a network listener beyond loopback and does not modify source media.
10
+
11
+ ## Launching the panel
12
+
13
+ ```bash
14
+ # From source
15
+ venv/bin/python -m src.control_panel
16
+
17
+ # From the npm package
18
+ npx davinci-resolve-mcp control-panel
19
+
20
+ # From a chat client via MCP
21
+ resolve_control(action="open_control_panel")
22
+ ```
23
+
24
+ Once running, you can `resolve_control(action="control_panel_status")` to check
25
+ the pidfile or `resolve_control(action="close_control_panel")` to stop it.
26
+
27
+ ## Tour
28
+
29
+ ### Overview
30
+
31
+ ![Control panel overview](../images/control-panel/01-overview.png)
32
+
33
+ The Overview tab is the at-a-glance summary for the active project: Resolve
34
+ connection state, source clip counts, analysis progress, search index size,
35
+ and the source-media safety status.
36
+
37
+ ### Analysis → Analyze
38
+
39
+ ![Analyze view](../images/control-panel/06-analyze.png)
40
+
41
+ The Analyze view inventories the Resolve media pool read-only and lets you
42
+ queue source-safe analysis jobs. Filters cover bin, media type, clip status,
43
+ and analysis status. Resolve media stays read-only; analysis outputs land under
44
+ the configured analysis root.
45
+
46
+ ### Analysis → Review (bin grid)
47
+
48
+ ![Review bin grid](../images/control-panel/02-review-bin-grid.png)
49
+
50
+ The Review surface is the browser for analyzed clips. Each card shows a
51
+ representative thumbnail, summary one-liner, primary use, shot count, and tags.
52
+ Click into a card to drill down.
53
+
54
+ ### Clip detail
55
+
56
+ ![Clip detail with shot strip](../images/control-panel/03-clip-detail.png)
57
+
58
+ The clip view shows the full summary, tags, editorial notes, and a strip of
59
+ every detected shot with thumbnails. From here you can open the clip in
60
+ Resolve, jump to the transcript, or click into any shot for the full V2 field
61
+ breakdown.
62
+
63
+ ### Transcript
64
+
65
+ ![Transcript view with word-level timing](../images/control-panel/04-transcript.png)
66
+
67
+ The transcript view is reachable from the clip detail (top-right `Transcript`
68
+ button). Each segment shows its start timecode, the cleaned sentence, and the
69
+ word-level transcription beneath. The segment filter narrows by text; clicking
70
+ a segment can jump the Resolve playhead to that source time. `Re-transcribe
71
+ with words` re-runs the configured local transcription backend (Whisper by
72
+ default) without re-doing visual analysis, and `corrections.json` captures
73
+ inline edits so they survive future re-runs.
74
+
75
+ ### Shot detail with inline correction
76
+
77
+ ![Shot detail with V2 fields and frames](../images/control-panel/05-shot-detail.png)
78
+
79
+ The shot view shows every V2 schema field (shot size, framing, camera height,
80
+ motion direction, lens character, lighting, composition notes, and more)
81
+ alongside the frames the vision pass actually saw. Each subjective field is
82
+ editable inline — edits land in `corrections.json` with an append-only
83
+ changelog and are merged on top of the next re-analysis so human notes survive
84
+ fresh vision runs. `Open in Resolve` bounces you straight to the clip in the
85
+ source viewer with the shot's mark in/out set.
86
+
87
+ ### Setup → Resolve diagnostic
88
+
89
+ ![Setup / Resolve diagnostic](../images/control-panel/07-diagnostics-resolve.png)
90
+
91
+ The Resolve diagnostic page reports the live connection, product/version,
92
+ active page, project identity, and media pool inventory. Useful when chat
93
+ sessions need to confirm Resolve is reachable before issuing scripted
94
+ operations.
95
+
96
+ ### Preferences → Analysis
97
+
98
+ ![Preferences / Analysis defaults](../images/control-panel/08-preferences-analysis.png)
99
+
100
+ Server-wide analysis defaults: vision on/off, transcription default, slate
101
+ detection, source-trust grading (`auto` / `filename` / `low` / `medium` /
102
+ `high`), default analysis depth, default sample frame count, persistence
103
+ behavior, summary style, and report format. These are the defaults the
104
+ `analyze_media` prompt uses when not overridden per call.
105
+
106
+ ## Chat ↔ panel state sharing
107
+
108
+ The panel and chat share focus state through `panel_state.json` (under the
109
+ active project's analysis root). MCP actions:
110
+
111
+ - `media_analysis(action="get_panel_state")` — read current focus (project,
112
+ clip, shot)
113
+ - `media_analysis(action="set_panel_state", params={...})` — set focus from
114
+ chat
115
+ - `media_analysis(action="session_start_context")` — bootstrap a chat session
116
+ with the panel's current focus
117
+
118
+ The dashboard polls `/api/panel_state` every 2 seconds, so changes from chat
119
+ appear in the UI without a refresh.
120
+
121
+ ## Open in Resolve
122
+
123
+ The shot view and clip view both have an Open-in-Resolve action. Under the
124
+ hood this calls `media_pool_item(action="open_in_viewer", params={clip_id,
125
+ mark_in, mark_out})`, which selects the clip on the Media page, loads it into
126
+ the source viewer, sets mark in/out, and brings Resolve to the foreground via
127
+ an OS-level window activation (AppleScript on macOS, PowerShell `AppActivate`
128
+ on Windows, wmctrl/xdotool on Linux).