LLMSkillHub
mirroredCopied from samuelgursky/davinci-resolve-mcp under MIT. samuelgursky has not claimed this page, and is not affiliated with LLM SkillHub.

samuelgursky / resolve-color

Color grading and look work in the DaVinci Resolve MCP. Apply when grading, correcting, matching shots, developing looks, or applying/modifying LUTs, CDLs, DRX grades, or copied grades — live in a running Resolve OR offline against .drx/.drp files. Routes to the live Python color tools, the offline advanced grading/QC catalog, and the project's color craft guidance.

0
SKILL.md
7.6 KB

Resolve Color / Grade

Bridges color craft to this repo's tools. This skill does not duplicate the
manuals — it tells you which one to open and the rules that cross both servers.

  • Craft / taste — docs/guides/color-decision-guide.md (project-owned color
    guidance and API boundaries). The global colorist / colorist-assistant
    skills add colorist philosophy; use them for how to see, not tool mechanics.

  • Live tool mechanics — docs/kernels/color-grade-kernel.md (the
    timeline_item_color boundary layer).

  • Offline grade compute — resolve-advanced/README.md → the drx grading/QC
    catalog (the "Advanced (offline) server" section of the color kernel).

Two servers, one grade

JobServerTools
Drive a running Resolvedavinci-resolve (Python, live)timeline_item_color, graph, gallery_stills, color_group
Compute a grade offline from frames, or read/write .drx/.drp grades with no Resolve opendavinci-resolve-advanced (Node)drx, drp, project_db, provenance

Division of labor: the advanced server computes a grade and writes an
apply-ready .drx; applying it is the live server's job
(timeline_item_color.safe_apply_drx). Node never drives Resolve.

What this build cannot do (check before you offer it)

The scripting API changes per patch release, so "Resolve 21" is not a usable
label. Read resolve_control get_version → build.unavailable_on_this_build
before offering a gated surface; check_version_support asks about one named
symbol. Gated in this domain:

SurfaceNeedsIf absent
TimelineItem.ResetAllNodeColors20.2Clear node colors one at a time via the graph node-color setter, or leave them

An empty unavailable_on_this_build means nothing recorded is missing, not
that everything exists — most of the API has never been version-bisected. A
symbol with no gate returns unknown, which means probe it. Probe with
name in dir(obj), never bare hasattr: on a Resolve object hasattr returns
True for every name, real or invented, so it can only say yes.

The offline drx / project_db routes are not version-gated this way —
they read and write files, so they work regardless of the build attached, and
are the fallback when a live surface turns out to be missing.

The frame-first rule (non-negotiable — see AGENTS.md)

Before applying any grade, look, shot match, LUT, CDL, DRX, or copied grade to a
real timeline, inspect representative Resolve-rendered frames (thumbnails,
contact sheets, Gallery stills, marker frames, or a scratch-only visual report).
Compare bypass/current/after at matched timecodes when the API allows, and
restore the prior version/node state after any temporary bypass. Never grade
from metadata, graph availability, or a style label alone unless the user
explicitly asks for a blind/global pass. Preserve a recoverable grade version and
report which frames informed the change. Frames extracted for offline compute go
to scratch/analysis locations only — never touch source media (AGENTS.md).

Offline grading / QC catalog (drx actions)

Frame-stats → arithmetic → .drx. All local, deterministic, guarded (they
refuse to fabricate a match rather than emit a silent no-op). Extraction and
apply are the caller's job. Pick by intent:

  • Match toward a reference still — match_to_reference (affine mean/std,
    skin-line gated, luma-preserving).

  • Within-camera drift — level_clips (exposure/WB to a group hero).
  • Cross-camera skin cohesion — skin_match (skin-gated; throws on
    log/wrong-space frames).

  • B-roll cohesion — shot_match (gray-world neutralize or hero match).
  • Known-neutral patch / gray card — white_balance_match.
  • Black/white points to a hero — contrast_normalize.
  • Saturation cohesion — saturation_match. Shadow cast — black_balance.
  • Import ASC CDL (.cc/.ccc/.cdl) — cdl_io. Copy a Body look —
    grade_transfer. Attach a .cube LUT to a node — lut_apply.

  • Season/host look — author_look / carry_look.
  • Read frames — scope_read (parade/vectorscope/black-balance/clip%),
    intent_tags (lowkey / motivatedwarm, to exclude from neutralize),
    gamut_legal (broadcast-legal, measurement only).

  • Verify — verify_grade (intended vs applied → landed/drifted/missing).

Did the grade damage the image? (media_analysis assess_grade)

verify_grade asks did Resolve apply what I asked. This asks *is the result
any good* — a grade can land perfectly and still be flat, milky, crunchy or
banded.

mediaanalysis(action='assessgrade', params={
sourcepath, gradedpath | lutpath, timeseconds, working_space })

Deterministic numpy on a decoded frame of the real result (a rendered file,
or the source pushed through the LUT by ffmpeg) — never a simulated transform,
because LUT interpolation and encode rounding are where banding is introduced.
Returns acceptable, flags (each with a remedy), the raw measurements, and a
grade_shift_delta_e2000 magnitude.

  • Flags: flat, milky, washed_out, noisy, clipped, posterized,
    banding. Read them and reject your own grade rather than shipping the
    first look that rendered.

  • Display-referred only. ACEScct / S-Log3 / LogC are refused, not
    converted — the right transform depends on camera and project colour
    management, which a frame cannot tell you. Convert first, then re-run.

  • vision in the result says whether a paid second opinion is warranted.
    Content-dependent flags (banding on a real sky gradient, a deliberate
    washed_out) escalate; unambiguous damage does not. A clean grade costs zero
    tokens.

Cross-server gotchas that bite

  • Grade value space. drx generate/merge default to space:'ui'
    (Resolve PANEL units; saturation 0–100, neutral 50). Pass space:'drx' only
    for raw internal floats. Decoded values are ground truth only for the
    calibrated set — check the valueFidelity marker
    (resolve-advanced/vendor/drx-parameters/CALIBRATION-STATUS.md).

  • Hue-axis curves. Naive [0,1] point lists are auto-canonicalized into the
    verified bezier cage. If a result carries a warnings array, the curve went
    through raw and will render FLAT — surface it, do not ship silently.

  • Apply targeting. safe_apply_drx defaults to video track 1 / item 0 —
    always pass track_type/track_index/item_index explicitly, and grab a
    still/.drx backup first (it does not snapshot). ApplyGradeFromDRX replaces
    the graph — no append mode.

  • Relayout ("Cleanup Node Graph," no UI API). Single clip, live: grab still →
    drx(action="relayout") → graph.reset_all_grades → safe_apply_drx with
    explicit indices (a same-structure apply keeps the OLD layout — the reset is
    required). Whole project, offline: project_db(action="relayout_node_graphs").

  • Guards are load-bearing. A thrown "refused" error usually means wrong input
    space, log-encoded frames, or missing media — read it before retrying. The
    grading catalog needs sharp; call the advanced capabilities tool for live
    status + install hints.