davinci-resolve-mcp 2.95.3 → 2.97.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 +140 -0
- package/README.md +5 -5
- package/README.zh-CN.md +6 -6
- package/docs/SKILL.md +85 -17
- package/docs/contributing.md +1 -1
- package/docs/install.md +17 -1
- package/docs/reference/api-coverage.md +2 -2
- package/docs/reference/api-limitations.md +17 -1
- package/install.py +383 -4
- package/package.json +1 -1
- package/resolve-advanced/server/aaf_probe.py +117 -14
- package/resolve-advanced/server/tools/project_read.mjs +35 -2
- package/src/granular/common.py +1 -1
- package/src/server.py +668 -15
- package/src/utils/api_truth.py +49 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,146 @@
|
|
|
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.97.0
|
|
6
|
+
|
|
7
|
+
**`timeline_frame(action="capture")` now renders the frame.** v2.96.0 shipped it
|
|
8
|
+
reading Resolve's thumbnail API; live validation on Studio 19.1.3.7 showed that
|
|
9
|
+
API cannot do the job, so the default route changed. Callers using `preview` or
|
|
10
|
+
`full` keep working and now get a frame-accurate image.
|
|
11
|
+
|
|
12
|
+
### Measured — the thumbnail API is per-CLIP, not per-frame
|
|
13
|
+
|
|
14
|
+
`GetCurrentClipThumbnailImage` returns the same image for every frame of a clip.
|
|
15
|
+
Seeking to 00:00, 01:00, 02:00 and 04:00 within one clip returned
|
|
16
|
+
**byte-identical data every time**; the image changed only when the playhead
|
|
17
|
+
crossed a clip boundary. Two further conditions make it fail silently:
|
|
18
|
+
|
|
19
|
+
- It returns `None` whenever Resolve is **not the frontmost application**, at any
|
|
20
|
+
delay, even on the Color page with a clip under the playhead.
|
|
21
|
+
- The first read after a page switch or a playhead move can be empty while the
|
|
22
|
+
viewer catches up, so a single failed read proves nothing.
|
|
23
|
+
|
|
24
|
+
None of this is distinguishable from "no frame here."
|
|
25
|
+
|
|
26
|
+
### Measured — `ExportStills` needs the Gallery panel open
|
|
27
|
+
|
|
28
|
+
It returns a bare `False`, writing nothing, unless the Gallery panel is visible
|
|
29
|
+
on the Color page — across png/jpg/tif/dpx, three destination folders, settle
|
|
30
|
+
delays of 0.5s/1.5s/3.0s, with Resolve frontmost. `GrabStill` succeeds; only the
|
|
31
|
+
export fails. No scripting call can open that panel.
|
|
32
|
+
|
|
33
|
+
### So `capture` renders one frame
|
|
34
|
+
|
|
35
|
+
`MarkIn == MarkOut` on a still-image render. Frame-exact, full resolution, well
|
|
36
|
+
under a second, and it needs no GUI panel and no foreground window. Verified
|
|
37
|
+
live: three timecodes produced three different images, and the rendered burn-in
|
|
38
|
+
matched the requested frame.
|
|
39
|
+
|
|
40
|
+
`quality` is now `frame` (default), `preview` (same render bounded to 1280px),
|
|
41
|
+
`thumbnail` (the instant per-clip image), and `still` (Gallery still). `full` and
|
|
42
|
+
`preview` from the original issue schema both map to the render.
|
|
43
|
+
|
|
44
|
+
**The cost, stated rather than hidden:** render settings are project-level.
|
|
45
|
+
Format and codec are snapshotted and restored, the render job is deleted, and
|
|
46
|
+
the Deliver page and playhead that rendering pulls Resolve onto are put back —
|
|
47
|
+
but `TargetDir`, `CustomName` and the mark range cannot be read back on builds
|
|
48
|
+
without `GetRenderSettings`, so they are reset to the full timeline rather than
|
|
49
|
+
truly restored. `quality="thumbnail"` remains for callers who need a strictly
|
|
50
|
+
side-effect-free read and can live with per-clip granularity. A capture also
|
|
51
|
+
refuses while another render is running.
|
|
52
|
+
|
|
53
|
+
### Corrected — docs that claimed per-frame accuracy
|
|
54
|
+
|
|
55
|
+
`docs/SKILL.md` said `get_thumbnail` "reflects the current frame as rendered by
|
|
56
|
+
Resolve." It reflects the clip. `timeline(action="thumbnail_contact_sheet")`
|
|
57
|
+
samples the same API, so it is a shot inventory, not frame evidence; both are
|
|
58
|
+
now described accurately. Both API findings are recorded in `api_truth` and
|
|
59
|
+
regenerated into `docs/reference/api-limitations.md`.
|
|
60
|
+
|
|
61
|
+
### Fixed — thumbnail reads poll instead of trusting one call
|
|
62
|
+
|
|
63
|
+
`timeline_markers(action="get_thumbnail")` and `get_thumbnail_image` now hold the
|
|
64
|
+
Color page, poll for the viewer to catch up, and name the foreground requirement
|
|
65
|
+
when the read stays empty.
|
|
66
|
+
|
|
67
|
+
## What's New in v2.96.0
|
|
68
|
+
|
|
69
|
+
New tool **`timeline_frame`** — the assistant can look at what Resolve is
|
|
70
|
+
rendering instead of inferring it from metadata. Closes
|
|
71
|
+
[#146](https://github.com/samuelgursky/davinci-resolve-mcp/issues/146).
|
|
72
|
+
|
|
73
|
+
### `timeline_frame(action="capture")`
|
|
74
|
+
|
|
75
|
+
Returns the timeline frame as MCP image content — grade, Fusion, titles,
|
|
76
|
+
transitions, as composited. (For the raw camera file, `media_analysis(action=
|
|
77
|
+
"extract_frames")` is still the right call.)
|
|
78
|
+
|
|
79
|
+
- `timecode` / `frame` — capture anywhere, not just the playhead. Accepts
|
|
80
|
+
absolute (`01:00:15:12`) or elapsed (`00:00:15:12`) timecode, matching the
|
|
81
|
+
marker-parameter contract.
|
|
82
|
+
- `quality` — `preview` (Resolve's thumbnail; fast, writes nothing) or `full`
|
|
83
|
+
(full resolution via a Gallery still, removed again afterwards).
|
|
84
|
+
- `max_width` — bound the context cost. Preview downscales in-process with an
|
|
85
|
+
area average; `full` rescales with ffmpeg, and **fails rather than silently
|
|
86
|
+
returning a full-size frame** when ffmpeg is missing.
|
|
87
|
+
- `format` — `png` (default), `jpg`, or `tif` on the `full` path.
|
|
88
|
+
- `timeline_name` — capture from another timeline; it is made current for the
|
|
89
|
+
read and the original restored after.
|
|
90
|
+
|
|
91
|
+
A capture is a read: the Color page, playhead, current timeline, and Gallery all
|
|
92
|
+
come back as the caller left them.
|
|
93
|
+
|
|
94
|
+
### Why a separate tool rather than an action on `timeline`
|
|
95
|
+
|
|
96
|
+
FastMCP derives an output schema from a tool's return annotation and validates
|
|
97
|
+
returns against it, so a `-> Dict[str, Any]` tool cannot return image content.
|
|
98
|
+
`timeline_frame` is annotated `-> Any` for that reason — the same reason
|
|
99
|
+
`timeline_markers` already was. The issue asked for a top-level tool, and the
|
|
100
|
+
schema constraint independently forces one.
|
|
101
|
+
|
|
102
|
+
### Fixed — thumbnail reads no longer misreport a page problem as a missing frame
|
|
103
|
+
|
|
104
|
+
`GetCurrentClipThumbnailImage` returns `None` on every page except Color, with
|
|
105
|
+
nothing to distinguish that from "no frame here."
|
|
106
|
+
`timeline_markers(action="get_thumbnail")` and `get_thumbnail_image` called it
|
|
107
|
+
bare, so off the Color page they reported a missing thumbnail. Both now hold the
|
|
108
|
+
Color page for the read and restore the previous page — the mitigation
|
|
109
|
+
`thumbnail_contact_sheet` already used. When the switch genuinely cannot happen
|
|
110
|
+
(headless, page locked), the error names the Color-page requirement instead.
|
|
111
|
+
|
|
112
|
+
`get_thumbnail_image` now shares the `timeline_frame` capture path, so it picks
|
|
113
|
+
up the fix; its contract is unchanged.
|
|
114
|
+
|
|
115
|
+
### Fixed — the installer configures Codex CLI
|
|
116
|
+
|
|
117
|
+
The installer claimed Codex support but never wrote its config, so a successful
|
|
118
|
+
install left no `davinci-resolve` entry in `~/.codex/config.toml` — everything
|
|
119
|
+
else (venv, Resolve paths, bridge, server) was in place and only the
|
|
120
|
+
registration was missing. Codex keys MCP servers under a TOML
|
|
121
|
+
`[mcp_servers.<name>]` table, and the installer only knew how to write JSON.
|
|
122
|
+
Closes [#39](https://github.com/samuelgursky/davinci-resolve-mcp/issues/39).
|
|
123
|
+
|
|
124
|
+
`codex` is now a selectable client (included in `--clients all`), writing
|
|
125
|
+
`$CODEX_HOME/config.toml` (default `~/.codex/config.toml`), and `--manual`
|
|
126
|
+
prints a ready-to-paste TOML block.
|
|
127
|
+
|
|
128
|
+
The merge is a text splice, not a parse-and-rewrite, so comments and hand
|
|
129
|
+
formatting survive; an existing `[mcp_servers.davinci-resolve]` table has its
|
|
130
|
+
`command`/`args`/`env` replaced in place. Sub-tables of that entry are kept:
|
|
131
|
+
hand-written Codex configs put per-tool approval modes in
|
|
132
|
+
`[mcp_servers.davinci-resolve.tools.<tool>]`, and an installer that dropped them
|
|
133
|
+
would quietly widen what the agent may do without asking. An
|
|
134
|
+
`[mcp_servers.davinci-resolve.env]` sub-table is regenerated in that same shape
|
|
135
|
+
rather than replaced with an inline `env` — TOML rejects a file that spells one
|
|
136
|
+
key both ways.
|
|
137
|
+
|
|
138
|
+
Paths are escaped as TOML basic strings (Windows backslashes would otherwise
|
|
139
|
+
corrupt the file). The installer refuses to touch a config that is already
|
|
140
|
+
invalid TOML, one that defines the server as an inline key it cannot safely
|
|
141
|
+
rewrite, or a merge result that would not parse — the same
|
|
142
|
+
never-wipe-a-user-config policy the JSON clients follow. Writes are backed up to
|
|
143
|
+
`config.toml.backup` first.
|
|
144
|
+
|
|
5
145
|
## What's New in v2.95.3
|
|
6
146
|
|
|
7
147
|
Closes the retime entry's explicit `UNTESTED` warning: **reverse and
|
package/README.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
English | [简体中文](README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
[](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
|
|
6
6
|
[](https://www.npmjs.com/package/davinci-resolve-mcp)
|
|
7
7
|
[](docs/reference/api-coverage.md)
|
|
8
|
-
[-blue.svg)](#server-modes)
|
|
9
9
|
[-18%20tools-blueviolet.svg)](#server-modes)
|
|
10
10
|
[](docs/reference/api-coverage.md#test-results)
|
|
11
11
|
[](https://www.blackmagicdesign.com/products/davinciresolve)
|
|
@@ -24,7 +24,7 @@ A local browser control panel ships with the server for inspecting Resolve state
|
|
|
24
24
|
npx davinci-resolve-mcp setup
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Before connecting, open DaVinci Resolve Studio and set **Preferences > General > External scripting using** to **Local**. (On the **free edition** that preference does not help — see [Free edition](#free-edition-in-app-bridge) below.) The npm launcher installs a managed copy under your user application-data directory, then runs the universal Python installer. The installer creates a virtual environment, detects Resolve paths, and can configure Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, Continue, Cline, Roo Code, OpenCode, and JetBrains IDEs.
|
|
27
|
+
Before connecting, open DaVinci Resolve Studio and set **Preferences > General > External scripting using** to **Local**. (On the **free edition** that preference does not help — see [Free edition](#free-edition-in-app-bridge) below.) The npm launcher installs a managed copy under your user application-data directory, then runs the universal Python installer. The installer creates a virtual environment, detects Resolve paths, and can configure Claude Desktop, Claude Code, Cursor, VS Code, Windsurf, Zed, Continue, Cline, Roo Code, OpenCode, Codex CLI, and JetBrains IDEs.
|
|
28
28
|
|
|
29
29
|
For source installs:
|
|
30
30
|
|
|
@@ -109,7 +109,7 @@ The command starts a localhost server and opens the control panel in your browse
|
|
|
109
109
|
|
|
110
110
|
| Mode | Entry point | Tools | Best for |
|
|
111
111
|
|------|-------------|-------|----------|
|
|
112
|
-
| Compound | `src/server.py` |
|
|
112
|
+
| Compound | `src/server.py` | 35 | Default mode for most assistants. Related Resolve operations are grouped behind action parameters to keep context usage low. |
|
|
113
113
|
| Full / granular | `src/server.py --full` or `src/resolve_mcp_server.py` | 353 | Power users who want one MCP tool per Resolve API method. |
|
|
114
114
|
|
|
115
115
|
The compound server is recommended unless you specifically need the granular one-tool-per-method surface.
|
|
@@ -272,7 +272,7 @@ The default server is a local stdio process launched by your MCP client; it does
|
|
|
272
272
|
|
|
273
273
|
| Metric | Value |
|
|
274
274
|
|--------|-------|
|
|
275
|
-
| MCP Tools | **
|
|
275
|
+
| MCP Tools | **35** compound / **353** granular (live server) |
|
|
276
276
|
| Advanced (offline) tools | **18** — .drp/.drt/.drx + DB authoring, no Resolve running |
|
|
277
277
|
| Kernel Actions | **136** guarded workflow actions across 9 compound tools |
|
|
278
278
|
| API Methods Covered | **361/361** (100%) |
|
package/README.zh-CN.md
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
[English](README.md) | 简体中文
|
|
4
4
|
|
|
5
|
-
[](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
|
|
6
6
|
[](https://www.npmjs.com/package/davinci-resolve-mcp)
|
|
7
7
|
[](docs/reference/api-coverage.md)
|
|
8
|
-
[-blue.svg)](#服务器模式)
|
|
9
9
|
[-18%20tools-blueviolet.svg)](#服务器模式)
|
|
10
10
|
[](docs/reference/api-coverage.md#test-results)
|
|
11
11
|
[](https://www.blackmagicdesign.com/products/davinciresolve)
|
|
12
12
|
[](https://www.python.org/downloads/)
|
|
13
13
|
[](https://opensource.org/licenses/MIT)
|
|
14
14
|
|
|
15
|
-
> 本翻译对应 v2.
|
|
15
|
+
> 本翻译对应 v2.97.0 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
|
|
16
16
|
|
|
17
17
|
一个 Model Context Protocol (MCP) 服务器,让 AI 助手通过官方脚本 API 控制 DaVinci Resolve Studio(达芬奇)。它提供完整的 API 覆盖,外加带护栏的工作流助手,涵盖剪辑、媒体池整理、渲染设置、审阅标记、调色、Fusion、Fairlight、项目生命周期任务、扩展开发,以及不碰源媒体的媒体分析。
|
|
18
18
|
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
npx davinci-resolve-mcp setup
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
连接之前,先打开 DaVinci Resolve Studio,把 **Preferences > General > External scripting using** 设为 **Local**。(**免费版**上这个偏好设置不起作用——见下文 [免费版](#免费版应用内桥接)。)npm 启动器会在你的用户应用数据目录下安装一份托管副本,然后运行通用 Python 安装器。安装器会创建虚拟环境、检测 Resolve 路径,并可自动配置 Claude Desktop、Claude Code、Cursor、VS Code、Windsurf、Zed、Continue、Cline、Roo Code、OpenCode 和 JetBrains 系列 IDE。
|
|
29
|
+
连接之前,先打开 DaVinci Resolve Studio,把 **Preferences > General > External scripting using** 设为 **Local**。(**免费版**上这个偏好设置不起作用——见下文 [免费版](#免费版应用内桥接)。)npm 启动器会在你的用户应用数据目录下安装一份托管副本,然后运行通用 Python 安装器。安装器会创建虚拟环境、检测 Resolve 路径,并可自动配置 Claude Desktop、Claude Code、Cursor、VS Code、Windsurf、Zed、Continue、Cline、Roo Code、OpenCode、Codex CLI 和 JetBrains 系列 IDE。
|
|
30
30
|
|
|
31
31
|
从源码安装:
|
|
32
32
|
|
|
@@ -81,7 +81,7 @@ venv/bin/python -m src.control_panel
|
|
|
81
81
|
|
|
82
82
|
| 模式 | 入口 | 工具数 | 适合谁 |
|
|
83
83
|
|------|------|--------|--------|
|
|
84
|
-
| Compound(复合) | `src/server.py` |
|
|
84
|
+
| Compound(复合) | `src/server.py` | 35 | 大多数助手的默认模式。相关的 Resolve 操作按 action 参数分组,压低上下文占用。 |
|
|
85
85
|
| Full / granular(细粒度) | `src/server.py --full` 或 `src/resolve_mcp_server.py` | 353 | 想要"一个 Resolve API 方法 = 一个 MCP 工具"的重度用户。 |
|
|
86
86
|
|
|
87
87
|
除非你明确需要一方法一工具的细粒度界面,否则推荐复合模式。
|
|
@@ -196,7 +196,7 @@ DRX 调色写入**针对 Resolve Studio 做过实机校准**:调色参数默
|
|
|
196
196
|
|
|
197
197
|
| 指标 | 数值 |
|
|
198
198
|
|------|------|
|
|
199
|
-
| MCP 工具 | **
|
|
199
|
+
| MCP 工具 | **35** 复合 / **353** 细粒度(实时服务器) |
|
|
200
200
|
| Advanced(离线)工具 | **18**——.drp/.drt/.drx + 数据库创作,无需 Resolve 运行 |
|
|
201
201
|
| 内核 action | 9 个复合工具下 **136** 个带护栏的工作流 action |
|
|
202
202
|
| API 方法覆盖 | **361/361**(100%) |
|
package/docs/SKILL.md
CHANGED
|
@@ -162,7 +162,7 @@ before mutating Resolve state.
|
|
|
162
162
|
|
|
163
163
|
| Mode | Entry point | Tool count | Use when |
|
|
164
164
|
|---|---|---|---|
|
|
165
|
-
| Compound (default) | `src/server.py` |
|
|
165
|
+
| Compound (default) | `src/server.py` | 35 tools | Most workflows — keeps context lean |
|
|
166
166
|
| Granular (full) | `src/server.py --full` | 353 tools | Power users needing one tool per API method |
|
|
167
167
|
|
|
168
168
|
This skill document covers the **compound server** (the default). Each compound
|
|
@@ -393,7 +393,7 @@ the work done:
|
|
|
393
393
|
|
|
394
394
|
- `timeline(action="detect_gaps_overlaps")`
|
|
395
395
|
- `timeline(action="source_range_report")`
|
|
396
|
-
- `
|
|
396
|
+
- `timeline_frame(action="capture")` at important markers and cuts
|
|
397
397
|
- Compare each marker name against the Resolve-rendered frame; revise the marker
|
|
398
398
|
or edit if the image contradicts the plan.
|
|
399
399
|
|
|
@@ -1393,10 +1393,12 @@ Key actions:
|
|
|
1393
1393
|
crop/composite/audio/property groups to many timeline items in one call
|
|
1394
1394
|
- `apply_look_to_items(target_ids, cdl?|copy_from_item_id?, dry_run?)` — apply a
|
|
1395
1395
|
normalized CDL and/or copy a source grade to multiple video items
|
|
1396
|
-
- `thumbnail_contact_sheet` / `marker_thumbnail_review` — sample Resolve
|
|
1397
|
-
thumbnails under the project analysis root
|
|
1398
|
-
|
|
1399
|
-
|
|
1396
|
+
- `thumbnail_contact_sheet` / `marker_thumbnail_review` — sample Resolve
|
|
1397
|
+
thumbnails under the project analysis root. These are CLIP thumbnails, so the
|
|
1398
|
+
sheet is effectively one image per clip, not per sampled frame — a shot
|
|
1399
|
+
inventory rather than frame evidence. Resolve only serves them on the Color
|
|
1400
|
+
page and only while it is frontmost; the tool switches page automatically and
|
|
1401
|
+
restores the previous one. Expect a page flash in the GUI,
|
|
1400
1402
|
and note that landing on Color can kick off cache/render work for the current
|
|
1401
1403
|
clip — on a large timeline the switch is not free
|
|
1402
1404
|
- `edit_kernel_capabilities` — report supported, partially supported, and
|
|
@@ -1486,13 +1488,57 @@ The compound tool accepts `frame`, `frame_id`, and `frameId` aliases.
|
|
|
1486
1488
|
|
|
1487
1489
|
Note: `get_thumbnail` returns raw pixel data from `GetCurrentClipThumbnailImage()`.
|
|
1488
1490
|
The dictionary includes `data` (raw bytes as a Python bytes-like object),
|
|
1489
|
-
`format`, `width`, `height`, `noOfComponents`, and `depth`. This reflects
|
|
1490
|
-
|
|
1491
|
-
|
|
1491
|
+
`format`, `width`, `height`, `noOfComponents`, and `depth`. This reflects Resolve's processed
|
|
1492
|
+
output — including color grading and effects — rather than the source file. It
|
|
1493
|
+
is the CLIP's thumbnail, though: every frame of a clip returns the same image, so
|
|
1494
|
+
it cannot verify a specific frame. Use `timeline_frame(action="capture")` for
|
|
1495
|
+
that.
|
|
1492
1496
|
|
|
1493
1497
|
Use `get_thumbnail_image` when the MCP client can display image content directly.
|
|
1494
1498
|
It converts the same Resolve thumbnail payload to PNG bytes without writing a
|
|
1495
|
-
file to disk.
|
|
1499
|
+
file to disk. Both actions hold the Color page for the read, restore the
|
|
1500
|
+
previous page, and poll rather than trusting a single read; both still need
|
|
1501
|
+
Resolve to be the frontmost application. Prefer `timeline_frame(action="capture")`
|
|
1502
|
+
for new work — it renders the frame you actually asked for.
|
|
1503
|
+
|
|
1504
|
+
**`timeline_frame`** — Capture a timeline frame as viewable image content.
|
|
1505
|
+
|
|
1506
|
+
Key actions: `capture(timecode?|frame?, quality?, max_width?, format?, timeline_name?)`,
|
|
1507
|
+
`capabilities`
|
|
1508
|
+
|
|
1509
|
+
Returns MCP image content, so a multimodal assistant can look at what Resolve is
|
|
1510
|
+
rendering — grade, Fusion, titles, transitions — rather than inferring it from
|
|
1511
|
+
metadata. (For the raw camera file instead, use
|
|
1512
|
+
`media_analysis(action="extract_frames")`.)
|
|
1513
|
+
|
|
1514
|
+
- `quality="frame"` (default) renders exactly that frame — the only
|
|
1515
|
+
frame-accurate route. Full resolution, well under a second, works headless.
|
|
1516
|
+
`preview` is the same render bounded to 1280px.
|
|
1517
|
+
- `quality="thumbnail"` is instant and touches nothing, but returns the **clip's**
|
|
1518
|
+
thumbnail — identical for every frame of that clip. Use it to see which clip is
|
|
1519
|
+
under the playhead, never to judge a specific frame. Needs the Color page *and*
|
|
1520
|
+
Resolve frontmost.
|
|
1521
|
+
- `quality="still"` uses a Gallery still; requires the Gallery panel to be open.
|
|
1522
|
+
- `max_width` caps the width to conserve context (needs ffmpeg; without it the
|
|
1523
|
+
call fails rather than quietly returning a full-size frame). `format` is `jpg`
|
|
1524
|
+
(default), `png`, or `tif`.
|
|
1525
|
+
- `timecode` accepts absolute (`01:00:15:12`) or elapsed (`00:00:15:12`) time;
|
|
1526
|
+
`frame` is the absolute timeline frame. Omit both to capture the playhead.
|
|
1527
|
+
|
|
1528
|
+
The playhead, page, current timeline and Gallery are restored. The render route
|
|
1529
|
+
additionally touches project render settings: format and codec are restored and
|
|
1530
|
+
the render job is deleted, but `TargetDir`/`CustomName`/mark range cannot be read
|
|
1531
|
+
back on builds without `GetRenderSettings`, so they are reset to the full
|
|
1532
|
+
timeline rather than restored. Reach for `quality="thumbnail"` when zero side
|
|
1533
|
+
effects matter more than accuracy.
|
|
1534
|
+
|
|
1535
|
+
```
|
|
1536
|
+
timeline_frame(action="capture", params={"timecode": "01:00:15:12", "max_width": 1280})
|
|
1537
|
+
```
|
|
1538
|
+
|
|
1539
|
+
This tool is separate from `timeline` because a tool that returns image content
|
|
1540
|
+
cannot declare a `Dict[str, Any]` output schema — FastMCP validates returns
|
|
1541
|
+
against it, and image content fails that validation.
|
|
1496
1542
|
|
|
1497
1543
|
**`timeline_ai`** — AI/ML analysis on the current timeline.
|
|
1498
1544
|
|
|
@@ -2046,15 +2092,37 @@ clip's comp, always pass `clip_id`, `timeline_item_id`, or `timeline_item`.
|
|
|
2046
2092
|
|
|
2047
2093
|
## Seeing What Resolve Sees (Visual Context)
|
|
2048
2094
|
|
|
2049
|
-
The server provides
|
|
2050
|
-
including color grading, effects, and compositing — not just the raw source
|
|
2095
|
+
The server provides several mechanisms to inspect a frame as Resolve has processed
|
|
2096
|
+
it, including color grading, effects, and compositing — not just the raw source
|
|
2097
|
+
file.
|
|
2098
|
+
|
|
2099
|
+
**Start here: `timeline_frame(action="capture")`** — Returns the frame at the
|
|
2100
|
+
playhead (or at any `timecode`/`frame` you name) as MCP image content, so a
|
|
2101
|
+
multimodal assistant can simply look at it. It renders that one frame, which is
|
|
2102
|
+
what makes it frame-accurate; `max_width` bounds the context cost.
|
|
2103
|
+
|
|
2104
|
+
```
|
|
2105
|
+
timeline_frame(action="capture", params={"timecode": "01:00:15:12", "max_width": 1280})
|
|
2106
|
+
```
|
|
2107
|
+
|
|
2108
|
+
⚠️ **The thumbnail API is per-clip, not per-frame.** `GetCurrentClipThumbnailImage`
|
|
2109
|
+
returns the same image for every frame of a given clip — verified by seeking
|
|
2110
|
+
within one clip and getting byte-identical data, with the image changing only at
|
|
2111
|
+
a clip boundary. It also returns nothing unless Resolve is the frontmost app.
|
|
2112
|
+
Everything below is built on it, so none of it can confirm what a *specific*
|
|
2113
|
+
frame looks like. Use `timeline_frame` for that.
|
|
2114
|
+
|
|
2115
|
+
**`timeline_markers(action="get_thumbnail")`** — Raw thumbnail data for the clip
|
|
2116
|
+
under the playhead: `data`, `format`, `width`, `height`, `noOfComponents`,
|
|
2117
|
+
`depth`. Use it when you need pixel data for tooling.
|
|
2051
2118
|
|
|
2052
|
-
**`timeline_markers(action="
|
|
2053
|
-
|
|
2054
|
-
|
|
2119
|
+
**`timeline_markers(action="get_thumbnail_image")`** — The same clip thumbnail as
|
|
2120
|
+
image content; equivalent to `timeline_frame(action="capture", params={"quality":
|
|
2121
|
+
"thumbnail"})`. Kept for existing callers.
|
|
2055
2122
|
|
|
2056
|
-
**`
|
|
2057
|
-
|
|
2123
|
+
**`timeline(action="thumbnail_contact_sheet")`** — A labeled PNG sheet written to
|
|
2124
|
+
the analysis root. Because it samples the same API, it is effectively one image
|
|
2125
|
+
per clip; treat it as a shot inventory, not as frame evidence.
|
|
2058
2126
|
|
|
2059
2127
|
**`gallery_stills(action="grab_and_export", params={...})`** — Grabs a still from
|
|
2060
2128
|
the current frame on the Color page and returns the image encoded as base64 in the
|
package/docs/contributing.md
CHANGED
|
@@ -63,7 +63,7 @@ This MCP server controls DaVinci Resolve via its Scripting API. Some tools perfo
|
|
|
63
63
|
davinci-resolve-mcp/
|
|
64
64
|
├── install.py # Universal installer (macOS/Windows/Linux)
|
|
65
65
|
├── src/
|
|
66
|
-
│ ├── server.py # Compound MCP server —
|
|
66
|
+
│ ├── server.py # Compound MCP server — 35 tools (default)
|
|
67
67
|
│ ├── resolve_mcp_server.py # Thin full-server entrypoint — 353 tools
|
|
68
68
|
│ ├── granular/ # Modular full-server implementation
|
|
69
69
|
│ └── utils/ # Platform detection, Resolve connection helpers
|
package/docs/install.md
CHANGED
|
@@ -88,6 +88,7 @@ The installer can automatically configure any of these clients:
|
|
|
88
88
|
| Zed | `~/.config/zed/settings.json` |
|
|
89
89
|
| Continue | `~/.continue/config.json` |
|
|
90
90
|
| OpenCode | `~/.config/opencode/opencode.json` (or project-root `opencode.json`) |
|
|
91
|
+
| Codex CLI | `~/.codex/config.toml` (or `$CODEX_HOME/config.toml`) — TOML `[mcp_servers.davinci-resolve]` |
|
|
91
92
|
| JetBrains IDEs | Manual (Settings > Tools > AI Assistant > MCP) |
|
|
92
93
|
|
|
93
94
|
You can configure multiple clients at once, or use `--clients manual` to get copy-paste config snippets.
|
|
@@ -132,7 +133,7 @@ The MCP server comes in two modes:
|
|
|
132
133
|
|
|
133
134
|
| Mode | File | Tools | Best For |
|
|
134
135
|
|------|------|-------|----------|
|
|
135
|
-
| **Compound** (default) | `src/server.py` |
|
|
136
|
+
| **Compound** (default) | `src/server.py` | 35 | Most users — fast, clean, low context usage |
|
|
136
137
|
| **Full** | `src/resolve_mcp_server.py` | 353 | Power users who want one tool per API method |
|
|
137
138
|
|
|
138
139
|
The compound server's `timeline_item` tool includes dedicated actions for common workflows:
|
|
@@ -196,6 +197,21 @@ If you prefer to set things up yourself, add to your MCP client config:
|
|
|
196
197
|
}
|
|
197
198
|
```
|
|
198
199
|
|
|
200
|
+
Codex CLI uses TOML instead. Add to `~/.codex/config.toml` (or
|
|
201
|
+
`$CODEX_HOME/config.toml`):
|
|
202
|
+
|
|
203
|
+
```toml
|
|
204
|
+
[mcp_servers.davinci-resolve]
|
|
205
|
+
command = "/path/to/venv/bin/python"
|
|
206
|
+
args = ["/path/to/davinci-resolve-mcp/src/server.py"]
|
|
207
|
+
env = { RESOLVE_SCRIPT_API = "/path/to/DaVinci Resolve/Developer/Scripting", RESOLVE_SCRIPT_LIB = "/path/to/fusionscript.so-or-dll", PYTHONPATH = "/path/to/DaVinci Resolve/Developer/Scripting/Modules" }
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Paths must be absolute — Codex does not expand `~`. Run
|
|
211
|
+
`python install.py --clients codex` to have the installer write this block for
|
|
212
|
+
you (it merges into an existing config and leaves your other servers and
|
|
213
|
+
comments alone).
|
|
214
|
+
|
|
199
215
|
On Windows, installer-generated configs also include `PYTHONHOME`. That scopes Resolve's Python binding to the selected interpreter and avoids the Resolve 20.3 multi-Python crash reported in [Issue #26](https://github.com/samuelgursky/davinci-resolve-mcp/issues/26).
|
|
200
216
|
|
|
201
217
|
For Resolve's **Network** scripting mode, add
|
|
@@ -6,7 +6,7 @@ Complete Resolve scripting API coverage, live-test status, and method-by-method
|
|
|
6
6
|
|
|
7
7
|
| Metric | Value |
|
|
8
8
|
|--------|-------|
|
|
9
|
-
| MCP Tools | **
|
|
9
|
+
| MCP Tools | **35** compound (default) / **353** granular |
|
|
10
10
|
| Kernel Actions | **136** guarded MCP workflow actions across 9 compound tools |
|
|
11
11
|
| API Methods Covered | **361/361** (100%) |
|
|
12
12
|
| Methods Live Tested | **338/361** (93.6%) |
|
|
@@ -17,7 +17,7 @@ Complete Resolve scripting API coverage, live-test status, and method-by-method
|
|
|
17
17
|
|
|
18
18
|
## API Coverage
|
|
19
19
|
|
|
20
|
-
Every non-deprecated method in the DaVinci Resolve Scripting API is covered. The default compound server exposes **
|
|
20
|
+
Every non-deprecated method in the DaVinci Resolve Scripting API is covered. The default compound server exposes **35 tools** that group related operations by action parameter, keeping LLM context windows lean. The full granular server provides **353 individual tools** for power users. Both modes cover all 13 API object classes. MCP-level kernel actions are tracked separately in [Kernel Action Coverage](../kernels/README.md).
|
|
21
21
|
|
|
22
22
|
The 34th compound tool is `timeline_versioning` (C6) — an MCP-level workflow
|
|
23
23
|
tool, not a wrapper around a Resolve API method. It surfaces the
|
|
@@ -12,7 +12,7 @@ that none exists).
|
|
|
12
12
|
|
|
13
13
|
**Verified on:** DaVinci Resolve Studio 21.0.2
|
|
14
14
|
|
|
15
|
-
**Totals:** 27 missing capabilities,
|
|
15
|
+
**Totals:** 27 missing capabilities, 35 bugs / unreliable behaviors.
|
|
16
16
|
|
|
17
17
|
The authoritative source is the runtime-queryable `api_truth` ledger
|
|
18
18
|
(`resolve_control api_truth "<query>"`); this document is generated from
|
|
@@ -360,6 +360,22 @@ values, or automation-hostile modal prompts.
|
|
|
360
360
|
- **Workaround / current handling:** Use comp.CurrentFrame.FlowView.SetPos(tool, x, y); confirm with GetPosTable and a liberal position parser.
|
|
361
361
|
- **Tags:** fusion, unreliable-return
|
|
362
362
|
|
|
363
|
+
### Timeline.GetCurrentClipThumbnailImage (foreground only)
|
|
364
|
+
|
|
365
|
+
- **Object:** `Timeline`
|
|
366
|
+
- **Signature:** `() -> {width, height, format, data} | None`
|
|
367
|
+
- **Behavior:** Being on the Color page is necessary but NOT sufficient: the call also returns None whenever Resolve is not the frontmost application. Measured on Studio 19.1.3.7 — with the Color page open, a clip under the playhead, and GetCurrentVideoItem returning that clip, every read came back None while Resolve sat behind a terminal window, at delays from 0 to 2 seconds; bringing Resolve to the front made the very next read return a 288x162 'RGB 8 bit' thumbnail. Separately, the first read after a page switch or a playhead move can be None while the viewer catches up, so a single failed read proves nothing. The two failure modes are indistinguishable from 'no thumbnail exists' and from each other.
|
|
368
|
+
- **Workaround / current handling:** Poll the read a few times before concluding it failed (src/server.py:_playhead_thumbnail_settled), and when it stays empty, name the foreground requirement in the error rather than reporting a missing frame. Headless callers cannot use this API at all; there is no scripting call to raise Resolve, so a background agent must fall back to a Gallery still or a render.
|
|
369
|
+
- **Tags:** timeline, thumbnail, silent-failure, focus-dependent
|
|
370
|
+
|
|
371
|
+
### GalleryStillAlbum.ExportStills (Gallery panel must be visible)
|
|
372
|
+
|
|
373
|
+
- **Object:** `GalleryStillAlbum`
|
|
374
|
+
- **Signature:** `(stills, folder, prefix, format) -> bool`
|
|
375
|
+
- **Behavior:** Returns a bare False, writing nothing, unless the Gallery panel is actually open on the Color page. Measured on Studio 19.1.3.7: Timeline.GrabStill() succeeded and the still landed in the album (count 0 -> 1), yet ExportStills returned False for png, jpg, tif and dpx alike, into three different destination folders, at settle delays of 0.5s, 1.5s and 3.0s, and with Resolve frontmost. Panel visibility is not readable or settable from the scripting API, so a script cannot establish the precondition it depends on, nor distinguish this from a permissions or format failure.
|
|
376
|
+
- **Workaround / current handling:** Treat False as 'the Gallery panel is probably closed' and say so in the error; ask the user to open Workspace > Gallery on the Color page. Do not retry formats hoping one sticks — when the panel is closed they all fail.
|
|
377
|
+
- **Tags:** gallery, stills, silent-failure, ui-dependent
|
|
378
|
+
|
|
363
379
|
### MediaPoolItem.GetClipProperty('Transcription')
|
|
364
380
|
|
|
365
381
|
- **Object:** `MediaPoolItem`
|