DaVinci Resolve MCP Server — AI Skill Reference
This document gives AI assistants the context needed to use the DaVinci Resolve MCP server effectively. It covers the tool landscape, page prerequisites, common workflow patterns, error recovery, and known gotchas.
What This Server Does
The DaVinci Resolve MCP server bridges AI assistants to DaVinci Resolve Studio via its official Scripting API. You can control every aspect of a post-production session — projects, timelines, clips, color grading, Fusion compositions, audio, render queues, and more — through natural language.
DaVinci Resolve must be running with Preferences > General > "External scripting using" set to Local. The server auto-launches Resolve if it is not running, but that first connection can take up to 60 seconds.
Workflow Integration plugins/scripts are a separate Resolve-hosted UI mechanism.
They are not required for this MCP server, but docs/integrations/workflow-integrations.md
summarizes when they are useful for optional in-Resolve panels, UIManager
scripts, and render callback companions.
OpenFX plugins are native C++ image-effect plugins, not an MCP control surface.
Use docs/notes/openfx-notes.md when diagnosing insert_ofx_generator failures or
discussing optional OFX plugin development.
LUT files are directly relevant to Color-page graph actions. Use
docs/notes/lut-notes.md when diagnosing graph.set_lut failures, validating .cube
files, or explaining project_settings.refresh_luts.
Fusion templates are relevant to Edit/Cut page insertion actions. Use
docs/notes/fusion-template-notes.md when diagnosing insert_fusion_generator or
insert_fusion_title failures, template paths, .setting files, or .drfx
bundles.
DCTL files are programmable color transforms/effects adjacent to LUT and OpenFX
workflows. Use docs/notes/dctl-notes.md when diagnosing .dctl/.dctle discovery,
ResolveFX DCTL plugin behavior, ACES DCTL IDT/ODT setup, or DCTL-as-LUT usage.
Codec plugins are native IO encode plugins that extend Deliver-page render
formats/codecs. Use docs/notes/codec-plugin-notes.md when diagnosing missing custom
render formats/codecs, .dvcp.bundle packaging, or IOPlugins install paths.
The fuse_plugin, dctl, and script_plugin compound tools (v2.5.0+) write
Fuse plugin source, DCTL files, and Lua/Python scripts into Resolve's install
directories. They are authoring tools — every other tool in this server wraps
Resolve's scripting API, while these three emit and install plugin/script
source. Status: lifecycle-verified in DaVinci Resolve Studio 20.3.2.9 for
MCP-marked install/read/list/remove, regular DCTL refresh_luts, ACES/Fuse
restart-required classification, Python installed-script execution, and
Python/Lua run_inline. Use docs/kernels/extension-authoring-kernel.md for the
kernel boundary map, docs/authoring/fuse-dctl-authoring.md for the Fuse + DCTL coverage
matrix, and docs/authoring/script-plugin-authoring.md for the script DSL spec and the
conversational-execution model. For hand-authoring .setting template files
(Edit effects/transitions/titles/generators and Fusion macros) — the format,
control catalog, thumbnail conventions, install paths, and gotchas, plus copyable
starter templates — see docs/authoring/setting-files/.
Extension Authoring kernel actions (v2.16.0+) are exposed through
script_plugin:
extension_capabilitiesprobe_fuse_lifecycle(name?, kind?, install?, cleanup?)probe_dctl_lifecycle(name?, kind?, category?, install?, refresh_luts?, cleanup?)probe_script_lifecycle(name?, language?, category?, install?, execute?, cleanup?)safe_install_extension(extension_type, name, source?|kind?, dry_run?)safe_remove_extension(extension_type, name, dry_run?)refresh_or_restart_required(extension_type, category?)extension_boundary_report(include_template_matrix?)
Key behavioral notes for script_plugin:
run_inline(source, language)runs ad-hoc Lua/Python in Resolve and returns stdout + result — use this for one-off conversational queries against the Resolve API instead of building+installing a script.languageacceptslua,py, or the human-facing aliasespythonandpython3.execute(name, category, language)runs an installed script; Python stdout and stderr are captured, while installed Lua execution can return false from the Python bridge even when install/read/list/remove worked.- Lua scripts:
fusion.Execute()from the Python bridge is a no-op in Resolve 20.x —_run_inline_luaworks around this withRunScriptagainst a temp file plus completion-sentinel polling onapp:SetData/GetData. - Fuse install path on macOS is
…/DaVinci Resolve/Fusion/Fuses/(NOTSupport/Fusion/Fuses/as the SDK doc lists). The MCP path helpers handle this; if you're staging files manually, use the path the implementation emits. - Resolve picks up new scripts without a restart; new Fuses need a restart
to register; new DCTLs need
project_settings(action='refresh_luts')(regular LUT category) or a restart (ACES IDT/ODT category).
Tool metadata (v2.17.1+) includes MCP ToolAnnotations for read-only,
destructive, idempotent, and external-resource hints. Treat compound tool
annotations as conservative because a single compound tool may expose both probe
and mutation actions behind its action parameter. Continue to prefer
safe_*, dry_run, probe_*, capabilities, and boundary_report actions
before mutating Resolve state.
Two Server Modes
| Mode | Entry point | Tool count | Use when |
|---|---|---|---|
| Compound (default) | src/server.py |
32 tools | Most workflows — keeps context lean |
| Granular (full) | src/server.py --full |
341 tools | Power users needing one tool per API method |
This skill document covers the compound server (the default). Each compound
tool accepts an action string and an optional params object.
The compound server also registers MCP prompts. Use davinci_resolve_workflow
as the compact operating brief, and use analyze_media as a slash-command style
entry point for source-safe project, selected-clip, bin, file, or sequence
analysis. The Analyze Media prompt executes directly by default, persists
inspectable reports/artifacts under the project analysis root, requests
host_chat_paths visual analysis (frames are extracted to disk and the host
chat finalizes each clip via media_analysis(action="commit_vision", ...)),
runs local transcription through the configured backend, and writes metadata
plus source-time Media Pool markers back to the Resolve project unless the
user opts out.
Anti-regression rule: do not silently downgrade media analysis. Source-safe
means source media stays untouched; it does not mean no visuals, no transcript,
no persisted report, no metadata writeback, or no Media Pool markers. Do not
add include_visuals=false, include_transcription=false,
publish_metadata=false, timed_markers=no, session_only=true, or
dry_run=true unless the user explicitly asks for that opt-out, the target is a
raw file path that cannot receive Resolve project writeback. The host_chat_paths
vision protocol is: analyze_* returns a deferred payload with absolute
frame_paths and a JSON schema; you must read those frames as images (Claude
Code's Read tool handles JPG/PNG natively), produce the JSON, and call
commit_vision for each clip. Skipping commit_vision leaves the run in
pending_host_vision_analysis — surface that explicitly; do not call the
analysis complete.
The deferred payload also includes a host_tool_choice_hint block. Hosts that
respect this hint pass it as tool_choice={type:"tool", name:"media_analysis"}
on the next API turn, hard-locking the agent into the correct next call. Hosts
that don't recognize the field ignore it — the flow is unchanged for them.
Local Control Panel
If the user asks to open, launch, or inspect the Resolve MCP control panel, run this from the repository root:
venv/bin/python -m src.control_panel
The command starts the local control panel and opens the default browser. Use
--no-open when running in a headless context, then give the user the printed
localhost URL. The panel is local and single-user; it is an operational surface
for server status, Resolve clips, source-safe analysis jobs, preferences, and
diagnostics as those sections are added.
The Review tab → History button opens the timeline-history surface:
per-timeline version chain, brain-edit deltas, manual archive, and rollback.
Backed by timeline_versioning MCP actions; see that tool's section below for
the underlying primitives.
Editorial Memory And Decision-Making
When the user asks for cutting, pacing, story shape, suspense, comedy timing, or
tonal reframing, operate like an editor, not just a metadata scanner. Use
docs/guides/editorial-decision-guide.md as the project-owned craft reference. The
short version: emotion and story come first, then clarity, rhythm, eye trace,
screen geography, continuity, and coverage variety.
Before analyzing or rebuilding anything, check whether the active project already contains useful evidence:
media_analysis(action="coverage_report", params={"target": {...}})— the pre-flight contract. Pure read; never triggers analysis. Returns per-clip state (analyzed / stale / missing / reuse_blocked / superseded_by_relink), layer presence,source_trusttier, and arecommended_action. The response carries anevidence_basesummary string — lead any editorial or color recommendation with that line, before the creative answer.media_analysis(action="summarize")for project-wide rollup of warnings, motion distribution, and signed-report counts.media_analysis(action="get_report")when a manifest or report path is known.timeline(action="list")timeline(action="get_current")timeline(action="probe_timeline_structure")timeline(action="source_range_report")timeline_markers(action="get_all")media_analysis(action="review_timeline_markers")when marker imagery matters
Reuse prior analysis unless it is stale, incomplete, missing a modality, or
flagged superseded_by_relink because Resolve's source clip was replaced after
analysis ran. Coverage_report surfaces all of these in one read. Do not re-run
visual analysis just because the edit task is new if a current report already
has keyframes, motion variance, and usable visual descriptions. Add
transcription, host_chat_paths vision (followed by commit_vision), marker
review, or source range checks only when that missing evidence changes the
decision. Use force_refresh=true only when the user asks for a fresh read or
when cache signatures show the source, prompt, depth, or requested modality has
changed.
Source-trust filtering: coverage_report accepts min_source_trust (one of
auto, filename, low, medium, high). Clips below the threshold appear
in summary.clips_needs_higher_trust and are reported with
below_min_source_trust=true. Use medium for routine work, high for
shot-matching or look-development passes where confident scene/identity reads
matter.
For finished-video editorial work, scene detection and motion variance are guardrails, not story. Use them to avoid black frames, flash frames, corrupt ranges, and accidental cut points. Let transcript, sound events, complete thoughts, reactions, and decisive visual frames drive the actual edit.
After creating or modifying a timeline variant, do a second pass before calling the work done:
timeline(action="detect_gaps_overlaps")timeline(action="source_range_report")timeline_markers(action="get_thumbnail_image")at important markers and cuts- Compare each marker name against the Resolve-rendered frame; revise the marker or edit if the image contradicts the plan.
Do not depend on personal, external, or workstation-specific editorial context.
For this project, keep the editorial craft reference self-contained in
docs/guides/editorial-decision-guide.md and keep this SKILL.md focused on
operational use of the MCP.
Color Memory And Decision-Making
When the user asks for color correction, shot matching, look development, LUTs,
DCTLs, DRX grades, Gallery stills, or color-group workflows, use
docs/guides/color-decision-guide.md as the project-owned color reference.
Be explicit about the API boundary:
- Directly creatable/control surfaces: CDL values on an existing node, grade versions, color-group assignment, LUT assignment on existing nodes, node enable/cache state, LUT/DCTL assets, Gallery still import/export, and grade copy/export helpers.
- Opaque full-grade surfaces: copied grades, imported/exported
.drxstills, and manually built Resolve node graphs. These can carry full grades, but the MCP applies or copies them as packages. - Not directly creatable from structured params: new node trees, Lift/Gamma/Gain wheel values, log/HDR palette values, curves, qualifiers, power windows, tracking, Color Warper, and detailed ResolveFX/OFX parameter edits.
Before any color recommendation, run
media_analysis(action="coverage_report", params={"target": {...}, "min_source_trust": "medium"}) (use "high" for shot-matching or
look-development passes). Lead the response with the returned evidence_base
line before the grade plan. Coverage_report surfaces relink-superseded clips
that must be re-analyzed before being graded from prior visual descriptions.
For safe color work, start with timeline_item_color(action="grade_boundary_report"),
timeline_item_color(action="grade_version_snapshot"),
timeline_item_color(action="probe_node_graph"), and a Resolve-rendered frame
reference for the target shot or shots. Use thumbnails, contact sheets, Gallery
stills, marker frames, or existing visual analysis reports before writing a
grade, and cite the inspected frames in the response. When the API can safely
provide them, compare matched untreated/bypass, current, and after frames at the
same timecodes, then restore the previous active version or node-enabled state
after any temporary bypass capture. Treat untreated frames as diagnostic
evidence, not as permission to discard an existing creative grade.
Prefer safe_set_cdl for small reversible primary corrections. Use DRX/stills
or grade copy only when the user accepts whole-grade replacement/transfer
semantics. Use DCTL/LUT authoring only for reusable mathematical transforms, not
as a substitute for hand-built windows, qualifiers, or tracked secondaries. Do
not apply blind/global grades unless the user explicitly asks for that. When the
user asks to build on or adjust an existing grade, preserve the current
grade/version as the starting point, create or switch to a recoverable
adjustment version, and apply only incremental changes through supported
controls. Do not reset grades, replace graphs, or apply DRX/copy-grade
whole-grade artifacts unless replacement or transfer semantics are explicitly
accepted. Distinguish Resolve's default one-node graph from an existing creative
grade; only describe a creative grade when active tools, LUTs, or other grade
state are present.
For sequence-wide looks, prefer a duplicated timeline, batch creation of reference/current/look versions across all target clips, and one bulk Resolve script for repeated version, group, or CDL operations. Use color groups for shared scene-level intent only when they fit the work: group pre-clip for shared normalization, clip versions for shot-specific matching, and group post-clip for the creative look. Sampling can guide a first pass, but final handoff should state the reviewed scope; short sequences should be checked shot by shot.
Page Context Requirements
DaVinci Resolve is a page-based application. Certain operations only work on specific pages. Always confirm or switch pages before calling page-sensitive tools.
| Operation category | Required page | How to switch |
|---|---|---|
| Color grading, node graphs, CDL | Color | resolve_control(action="open_page", params={"page": "color"}) |
Gallery stills export, grab_and_export |
Color, Gallery panel open | resolve_control + open Gallery panel in Workspace menu |
| Fusion compositions (page comp) | Fusion | resolve_control(action="open_page", params={"page": "fusion"}) |
| Timeline editing, track operations | Edit or Cut | resolve_control(action="open_page", params={"page": "edit"}) |
| Fairlight audio | Fairlight | resolve_control(action="open_page", params={"page": "fairlight"}) |
| Render / deliver | Deliver | resolve_control(action="open_page", params={"page": "deliver"}) |
| Media import, storage browsing | Media | resolve_control(action="open_page", params={"page": "media"}) |
When a tool returns an unexpected False or an error about context, check whether
you are on the correct page first.
Tool Map
App Control
resolve_control — App-level operations.
Key actions:
launch— connect to or start Resolve; call this first if any tool returns a "Not connected" errorget_version— returns{product, version, version_string}api_truth(query?)— look up behaviorally-verified facts about quirky/unreliable Resolve API behavior (no connection needed); filter by substringverification_stats— readback-verification tally (verified/contradicted/ unverified) since server start (no connection needed)get_page/open_page(page)— read or switch the active pageget_keyframe_mode/set_keyframe_mode(mode)get_fairlight_presets— Resolve 20.2.2+; returns available Fairlight preset namesquit— terminates Resolve (destructive; confirm with user first)
layout_presets — Save, load, export, import, delete UI layout presets.
render_presets — Import and export render and burn-in presets.
Project Management
project_manager — CRUD on projects.
Key actions: list, get_current, create(name, media_location_path?),
load(name), save, close,
delete(name), import_project(path), export_project(name, path), archive,
restore
Project / Database / Archive kernel actions (v2.15.0+) add guarded project lifecycle, settings, database, preset, and archive boundary helpers:
project_capabilitiesprobe_project_lifecycleprobe_project_settings(keys?, try_write?, dry_run?)safe_project_create(name, media_location_path?, dry_run?)safe_project_export(name, path, with_stills_and_luts?, dry_run?)safe_project_import(path, name, dry_run?)safe_project_archive(name, path, src_media=false, render_cache=false, proxy_media=false, dry_run?)safe_project_restore(path, name, dry_run?)safe_project_delete(name, close_current?, dry_run?)safe_set_project_settings(settings, restore?, dry_run?)project_settings_snapshot(name?)database_capabilitiessafe_set_current_database(db_info, dry_run?, allow_switch?)preset_lifecycle_probeproject_boundary_report
Health check and declarative spec (v2.28.0+):
lint— graded project health pre-flight returning{ok, counts, issues}. Issues (error / warning / info) cover: no project, no current timeline, mixed frame rates across timelines, empty timeline, render format unset, color science unmanaged, offline media, and unanalyzed clips. Composed from existing probes; safe read-only.diff_to_spec(spec_path | spec)— preview drift between a declarative spec and the live project WITHOUT mutating. Returns{actions, diff, change_count}.plan_spec(spec_path | spec)— the ordered action list as a dry run.apply_spec(spec_path | spec, dry_run?, run_hooks?, continue_on_error?)— reconcile the project toward the spec. Idempotent (re-runs are no-ops); color/ HDR settings apply in dependency order; markers added only when absent; explicitsettingsoverride a namedcolor_preset; before/after shell hooks run only withrun_hooks=true. The spec is YAML or JSON:{project, color_preset?, settings?, timelines:[{name, fps?, settings?, markers?}], hooks?}. Note:apply_specreconciles the currently open or already-existing project; creating a brand-new project from a spec depends on Resolve'sCreateProjectsucceeding (it can return None when an unsaved project blocks the switch).
Safe project actions require _mcp_ names and temp paths by default. Database
switching dry-runs by default because Resolve closes open projects when
switching databases. Archive source media/cache/proxy flags are rejected unless
explicitly opted in.
project_manager_folders — Navigate project folders.
Key actions: list, get_current, create(name), open(name), goto_root,
goto_parent
project_manager_database — Switch databases.
Key actions: get_current, list, set_current(db_info)
project_manager_cloud — Cloud projects (requires Resolve cloud
infrastructure; most users will not have this).
project_settings — Project metadata, settings, color groups, and misc
operations on the open project.
Key actions: get_name, set_name(name), get_setting(name?),
set_setting(name, value), get_color_groups, add_color_group(name),
delete_color_group(name), export_frame_as_still(path),
load_burnin_preset(name), insert_audio(media_path, ...),
apply_fairlight_preset(preset_name),
project_summary(include_clips?, clip_limit?) — live structural readout
(current page, timeline count, media-pool inventory by type)
Media
media_storage — Browse mounted volumes and import files.
Key actions: get_volumes, get_subfolders(path), get_files(path),
import_to_pool(items) — items is a list of file path strings
media_pool — Full Media Pool management.
Key actions: get_root_folder, get_current_folder, set_current_folder(path),
add_subfolder(name), create_timeline(name), import_timeline(path, options?),
import_media(paths), delete_clips(clip_ids), move_clips(clip_ids, target_path),
setup_multicam_timeline(name, clip_ids|angles, sync_mode?, include_audio?, dry_run?),
get_selected, set_selected(clip_id), export_metadata(path, clip_ids?)
Media Pool / Ingest kernel actions (v2.8.0+) add safer agent-facing workflows:
ingest_capabilities, probe_media_pool, probe_ingest_item,
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,
setup_multicam_timeline, and
media_pool_boundary_report. See
docs/kernels/media-pool-ingest-kernel.md for the live-tested support map.
setup_multicam_timeline is a helper, not a native multicam API wrapper. It
creates a source-safe stacked prep timeline with one angle per video track,
optional matching audio tracks, and stack_start, source_timecode, or
explicit record_frame placement. Native multicam clip creation, angle
switching, and flattening remain Resolve UI workflows; see
docs/guides/multicam-setup-guide.md.
Note: folder path arguments use slash notation like "Master/SubFolder".
"Master" or "/" refers to the root folder.
folder — Operations on a specific Media Pool folder.
Key actions: get_clips(path?), get_subfolders(path?), export(path?, export_path),
transcribe_audio(path?, use_speaker_detection?), clear_transcription(path?),
perform_audio_classification(path?), analyze_for_intellisearch(path?, identify_faces?, is_better_mode?),
analyze_for_slate(path?, marker_color?), remove_motion_blur(path?, deblur_option?) (Resolve 21+;
the last three need AI Extras, and remove_motion_blur is confirm-token gated)
media_pool_item — Read/write clip metadata and properties. All actions
require a clip_id (the UUID returned by GetUniqueId()).
Key actions: get_name, get_metadata(key?), set_metadata(key, value),
get_clip_property(key?), set_clip_property(key, value), get_clip_color,
set_clip_color(color), link_proxy(proxy_path), replace_clip(path),
set_name(name), link_full_resolution_media(path),
replace_clip_preserve_sub_clip(path), monitor_growing_file,
transcribe_audio(use_speaker_detection?), clear_transcription,
get_transcription (read back {text, truncated, status, has_transcription};
truncated flags when Resolve's preview cut the text off),
perform_audio_classification,
analyze_for_intellisearch(identify_faces?, is_better_mode?), analyze_for_slate(marker_color?),
remove_motion_blur(deblur_option?) (Resolve 21+; AI Extras / confirm-token gated as noted above),
get_audio_mapping, get_mark_in_out, set_mark_in_out
media_pool_item_markers — Markers and flags on clips in the Media Pool.
All actions require a clip_id.
Key actions: add(frame, color, name, note, duration), get_all, delete_by_color(color),
delete_at_frame(frame), add_flag(color), get_flags, set_name(name)
media_analysis — Project-scoped media intelligence and guarded metadata publishing.
Media Analysis and editorial-assist actions (v2.17.0+) add source-safe planning,
report reuse, persisted analysis execution, host_chat_paths visual review
(finalized per clip via commit_vision), transcription, default Resolve
metadata/marker writeback, and timeline-level editorial helpers.
Key actions: capabilities, install_guidance, resolve_output_root, plan,
coverage_report, analyze_file, analyze_clip, analyze_bin,
analyze_project, detect_sync_events, add_sync_event_markers,
publish_clip_metadata, commit_vision, summarize, get_report,
build_index, index_status, query_index, start_batch_job,
run_batch_job_slice, batch_job_status, list_batch_jobs,
cancel_batch_job, resume_batch_job, review_timeline_markers,
cleanup_artifacts, db_status, db_ingest, get_panel_state,
set_panel_state, session_start_context, update_clip_field,
update_shot_field, get_field_history, revert_field,
list_corrections, deepen, commit_shot_vision, vision_pending_sweep,
build_embeddings, find_similar, detect_entities, commit_entities,
list_entities, prepare_bin_briefing, commit_bin_summary,
detect_shot_relationships, commit_shot_relationships, and
list_shot_relationships.
Cross-clip entities + bin briefing v2 (v2.44.0+). Recurring people/places/props across a project's media, found cheaply and confirmed with ONE vision call per cluster:
detect_entities(threshold?, min_cluster_size?)clusters the v10 CLIP frame vectors (build visual embeddings first), writes provisional entity rows + appearances, and returns a deferred payload with one representative frame per cluster (caps pre-checked, estimate inlined). The host chat reads those frames and callscommit_entities(entities=[{entity_index, kind, label, description, confidence, merge_with?}], vision_token)— conservative labels only (describe what's visible; never guess names).merge_withcollapses clusters that show the same entity.list_entitiesreturns labeled entities with per-clip/shot appearances; the panel's Review page shows a "Recurring across this bin" card.prepare_bin_briefingreturns entities + per-clip summaries (text-only, no vision cost); the host writes a colleague-style markdown briefing and callscommit_bin_summary(briefing, briefing_token), which lands inmemory/bin_summary.mdabove the v2.0 aggregate.
Cross-shot relationships (v2.49.0+). Pattern recognition only (spec §4 —
no editorial suggestions): same_setup_as / alt_take_of (symmetric) and
continues_from (directional; the source shot continues from the target).
detect_shot_relationships(setup_threshold?, alt_take_threshold?, continues_band?, max_candidates?)— pairwise cosine over the per-shot visual vectors (build visual embeddings first; raisemax_frames_per_clipif shot coverage is partial), plus transcript continuity as a second signal forcontinues_from. Returns a deferred payload with a representative frame PAIR per candidate (caps pre-checked, two frames per candidate). Candidates live only in the detection-state stash until committed — re-detect replaces them.- The host chat reads BOTH frames of each pair and calls
commit_shot_relationships(relationships=[{candidate_index, verdict: confirm|reject, relationship_type?, confidence?}], vision_token). Confirm only what the frames show; reject lookalikes. Overriding the suggested type is allowed. Committed rows supersede prior machine rows for the same pair. list_shot_relationships(clip_id?, shot_uuid?, relationship_type?)— current rows with clip/shot context on both ends. The shot page's Relationships group fills from these rows, andplan_swapprefers confirmedalt_take_ofalternates over raw cosine (the rationale states which basis ranked each alternate).
Embeddings + similarity (v2.43.0+). Local-compute semantic search; no
vendor tokens, so nothing here touches the caps ledger. Backends are
detected, never installed (capabilities lists them with install guidance):
text = ollama serving nomic-embed-text or sentence-transformers; visual =
open_clip (ViT-B-32, needs torch); audio (v2.51.0+) = CLAP via
transformers (laion/clap-htsat-unfused, preferred) or the laion_clap
package — needs torch + ffmpeg.
build_embeddings(kinds=["text","visual","audio"]?, clip_id?)— idempotent; embeds clip summaries, shot descriptions (+ deep field groups), transcript segments, and sampled frames (per-shot visual vector = mean of its frames').kinds=["audio"]embeds one CLAP window per shot (center-cropped to ~10s, piped from the source media as raw PCM — read-only, no temp files) plus a clip-level mean vector; clips whose media is offline are reported inskipped_missing_media. Only re-embeds entities whose content changed.find_similar(text=… | clip_id=… | clip_id+shot_index, kind="text"|"visual"|"audio", entity_types?, limit?)— brute-force cosine over the project's vectors. Free-text visual queries use the CLIP text encoder ("cracked windshield" finds the frame); free-text audio queries use the CLAP text encoder ("engine revving" finds the shot). Results carry scores plus clip/shot/segment context. The panel search box gains aSemantictoggle when a text backend is detected. Vectors live in the per-project DB (schema v10).
Deep shot-level vision tier (v2.42.0+). Opt-in, estimate-first. Two entry points share one per-shot schema (Visual / Content / Production / Editorial / Cuttability / description / confidence):
depth="deep"on any analyze action extends the deferred host-vision payload withdeep_shot_schema; eachshot_descriptionsentry must carry the field groups. The first deep run returnsconfirmation_requiredwith a token-cost estimate — re-call withconfirm_deep=true. Caps still apply.deepen(clip_id|clip_dir, shot_index?|shot_indices?)runs the pass post-hoc on an already-analyzed clip. First call returns the estimate +confirm_token; re-call with the token to get the deferred payload, read itsframe_paths, and commit viacommit_shot_vision(clip_id, shots=[{shot_index, ...groups...}], vision_token). Deep fields land asvision_deep_v1provenance rows; human corrections always survive. Shots with no sampled frames on disk get 1–2 frames re-extracted via ffmpeg (read-only on source media).vision_pending_sweep(expire?, max_age_days?, reoffer?)lists clips stuck inpending_host_analysis;reoffer=truereturns each clip's stored deferred payload to finish the run,expire=truestamps themexpired_host_analysisso pendings never linger silently.
DB-canonical analysis store (v2.41.0+). The per-project SQLite DB
(_soul/timeline_brain.sqlite, schema v9+) is the source of truth for clip
analysis; analysis.json is a derived export written in lockstep. Analysis
runs write rows first (clips, shots, per-field subjective provenance,
transcript segments, sampled frames, QC observations) and then export the
JSON. Human corrections recorded via update_clip_field / update_shot_field
live as row-level provenance and always survive re-analysis. Readers
(panel API, exports) load DB-first and fall back to analysis.json for
reports that predate v9. db_status reports schema version + row counts;
db_ingest migrates an existing project's JSON reports (and
corrections.json sidecars) into the DB — run it once on older analysis
roots.
The tool never installs
dependencies and validates that outputs stay under
davinci-resolve-mcp-analysis project roots rather than beside source media.
Executed Resolve-target analysis defaults to running, persisting inspectable
artifacts, and publishing metadata plus Media Pool clip markers. Use
dry_run=true, publish_metadata=false, timed_markers=no, or
session_only=true with keep_artifacts=false to disable those defaults for a
run. Persisted analysis refreshes the local SQLite search index automatically unless
auto_build_index=false is set; build_index remains the manual rebuild action
for existing reports. quick uses ffprobe metadata; standard adds ffmpeg
read-through checks,
cut-boundary analysis from full-stream scene detection, flash-frame candidates,
motion/variance scoring, analysis keyframes, and sidecar reports.
depth controls which layers run; a separate sampling_mode controls how many
frames each clip gets for visual analysis (and thus token cost): fixed
(Economy, flat content-blind frames), per_minute (Balanced, frames scale with
duration), adaptive_capped (Thorough, content-aware bounded to
[frame_floor, frame_ceiling] — recommended/default), or adaptive (Thorough
uncapped). When no default is saved, the first analyze returns
confirmation_required with a sampling_mode_prompt; choosing a mode saves it
as the default. Pass sampling_mode per call for a one-off. The mode owns frame
count — analysis_caps.frames_per_clip is a safety ceiling above it, not the
primary dial.
By default, planning checks the active project's analysis root and bounded
related project-version roots for existing reports, then marks matching clips
skip_execution=true when those reports already contain the requested
technical, motion, transcription, and vision layers.
Resolve clip records also carry the published third-party
davinci_resolve_mcp.analysis_report_path when metadata writeback has run; use
that provenance as a first-class reuse hint even if the report lives under a
previous project-version analysis root.
The planner also maintains an analysis_registry.json under the analysis base
root. This registry indexes report paths by source path, clip id, media id, and
signature so project renames and versioned Resolve projects can still find prior
work quickly.
Reports include cache signatures with source stat, depth, frame budget, prompt
hash, and requested modalities. Use force_refresh=true for a fresh read,
max_report_age_days for freshness limits, and reuse_policy="fresh" when
unsigned older reports should not be reused. Pass reuse_existing=false only
when the user explicitly wants to ignore memory; pass
search_related_project_roots=false only for intentionally isolated runs.
If Resolve metadata shows prior MCP analysis but the planner cannot validate a
matching report, execution returns status="reuse_blocked" instead of silently
reanalyzing. Treat that as a project-memory integrity warning; restore the
report or pass force_refresh=true only when the user explicitly wants fresh
analysis.
Transcription, visual analysis, metadata writeback, and Media Pool marker
writeback are default-on. Vision uses
vision.provider="host_chat_paths": analyze actions extract representative
frames to disk under the project analysis root and return a deferred payload
containing absolute frame_paths, a shot_table mapping each detected shot
range to its in-shot frame_indices, the JSON schema, and a commit_action.
The host chat must read those frames as local images, produce JSON per the
schema (including one shot_descriptions entry per shot_index in the
shot_table, grounded only in the frames listed for that shot), and call
media_analysis(action="commit_vision", params={clip_id, visual, vision_token}) per clip to merge the visual report, rebuild Media Pool clip
markers, and publish vision-dependent metadata to Resolve. Each Resolve shot
marker inherits its description from shot_descriptions[shot_index]; missing
entries fall back to an in-range analysis_keyframe and finally to a
clip-summary-tagged fallback — never to a neighbour shot's description. The manifest exposes
vision_pending=True and pending_action so callers know what is incomplete.
Pass include_visuals=false, include_transcription=false,
publish_metadata=false, or timed_markers=no to opt out. Agents must not add
those opt-out flags preemptively; use them only when requested or when a target
boundary requires it. Standard/deep runs prioritize first/last usable frames
plus before/after cut-boundary frames as the sampled set. Skipping
commit_vision leaves the run in pending_host_vision_analysis — that is a
failure mode to surface, not a silent downgrade. The local mock providers are
for tests and do not send frames off-machine.
When creating timelines through media_pool, use if_exists="reuse" for
idempotent reruns, if_exists="version" for deliberate alternate cuts, and
if_exists="fail" when duplicate names indicate a workflow error.
Use detect_sync_events before multicam setup, deliverable QC, or single-camera
sync review when the user needs likely 2-pop or slate-clap locations. It reads
source audio through FFmpeg/FFprobe only, returns advisory frames/timecodes and
per-file record_offset suggestions, and never installs FFmpeg automatically.
It also returns marker suggestions; add_sync_event_markers remains an explicit
marker-write action for standalone sync detections.
Use publish_clip_metadata when the user wants analysis to become searchable
inside Resolve. It analyzes or reuses reports, proposes field-specific merges
for Description, Comments, Keywords, People, and optional slate-derived
fields, stores provenance in third-party metadata, and writes metadata plus
source-time markers by default for executed Resolve-target analysis. Disable a
write run with dry_run=true, publish_metadata=false, or timed_markers=no.
review_timeline_markers creates a labeled
Resolve-rendered marker contact sheet plus JSON sidecar; with
vision.enabled=true it returns a host_chat_paths review payload (image_path +
prompt) so the host chat can read the sheet and answer inline — no commit step
required for marker review.
Before calling analyze_*, prefer summarize and get_report to discover
existing reports for the active project. If reports exist, use them as the
working memory for edit decisions and only request fresh analysis when a missing
layer changes the decision. If a user is
making story or audio-spine decisions and transcription is available but disabled,
tell them that transcript analysis may materially improve the edit instead of
silently skipping it. Resolve-native transcription changes project state; use it
only when that mutation is intentional.
Timelines
edit_engine — Evidence-driven edit loops (v2.45.0+): selects assembly,
tighten, swap.
Every loop is plan → confirm → execute. plan_* actions are dry-run by
construction: they query the DB-canonical analysis store and return a
per-decision rationale plus a stored plan_id (plans persist under
memory/edit_plans/ with a content fingerprint, so a stale
…(truncated)