davinci-resolve-mcp 2.214.0 → 2.214.1

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,31 @@
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.214.1 — grade calls fail silently off the Color page; apply_trace_plan switches for you
6
+
7
+ ### Fixed
8
+
9
+ - **`apply_trace_plan` grades on the Color page and restores your page after.**
10
+ Measured on Studio 19.1.3.7 during the second live pass of the conform trace:
11
+ with the GUI on the Edit page, `TimelineItem.AddVersion` and
12
+ `Graph.ApplyGradeFromDRX` returned False for all 12 clips of a batch, with no
13
+ exception and no other signal; `OpenPage("color")` and nothing else, then 12
14
+ of 12 applied. The earlier 254-clip batch had succeeded only because the page
15
+ happened to be Color. The driver now reads `GetCurrentPage()` before the
16
+ batch, switches to Color, puts the page back afterwards, and reports
17
+ `page: {before, switched, restored}`; if the switch fails it refuses with
18
+ `PAGE_SWITCH_FAILED` before touching a clip.
19
+ - **api_truth records the page dependence** ("TimelineItem.AddVersion /
20
+ Graph.ApplyGradeFromDRX (page-dependent)"), so the False can be told apart
21
+ from a bad `.drx` or a locked clip.
22
+
23
+ ### Live-validated
24
+
25
+ - The 12 name-only matches from the v2.214.0 run (same files, sections the
26
+ source never graded) applied with `min_confidence: 0.6`: 12 of 12, version
27
+ `traced V07 Sizing` added per clip, node graphs read back with the source's
28
+ tools.
29
+
5
30
  ## What's New in v2.214.0 — color_trace reads exported .drp files, and the trace is live-validated
6
31
 
7
32
  ### Added
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  English | [简体中文](README.zh-CN.md)
4
4
 
5
- [![Version](https://img.shields.io/badge/version-2.214.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-2.214.1-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
6
6
  [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
7
7
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
8
8
  [![Tools](https://img.shields.io/badge/MCP%20Tools-36%20(353%20full)-blue.svg)](#server-modes)
package/README.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) | 简体中文
4
4
 
5
- [![Version](https://img.shields.io/badge/version-2.214.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-2.214.1-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
6
6
  [![npm](https://img.shields.io/npm/v/davinci-resolve-mcp.svg?label=npm&color=CB3837)](https://www.npmjs.com/package/davinci-resolve-mcp)
7
7
  [![API Coverage](https://img.shields.io/badge/API%20Coverage-100%25-brightgreen.svg)](docs/reference/api-coverage.md)
8
8
  [![Tools](https://img.shields.io/badge/MCP%20Tools-36%20(353%20full)-blue.svg)](#服务器模式)
@@ -12,7 +12,7 @@
12
12
  [![Python](https://img.shields.io/badge/python-3.10+-green.svg)](https://www.python.org/downloads/)
13
13
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
14
14
 
15
- > 本翻译对应 v2.214.0 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
15
+ > 本翻译对应 v2.214.1 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
16
16
 
17
17
  一个 Model Context Protocol (MCP) 服务器,让 AI 助手通过官方脚本 API 控制 DaVinci Resolve Studio(达芬奇)。它提供完整的 API 覆盖,外加带护栏的工作流助手,涵盖剪辑、媒体池整理、渲染设置、审阅标记、调色、Fusion、Fairlight、项目生命周期任务、扩展开发,以及不碰源媒体的媒体分析。
18
18
 
package/install.py CHANGED
@@ -37,7 +37,7 @@ from src.utils.update_check import (
37
37
 
38
38
  # ─── Version ──────────────────────────────────────────────────────────────────
39
39
 
40
- VERSION = "2.214.0"
40
+ VERSION = "2.214.1"
41
41
  # Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
42
42
  # Resolve's scripting bridge loads into newer interpreters on recent builds
43
43
  # (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "davinci-resolve-mcp",
3
- "version": "2.214.0",
3
+ "version": "2.214.1",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",
@@ -87,7 +87,7 @@ if not logging.getLogger().handlers:
87
87
  handlers=[logging.StreamHandler()],
88
88
  )
89
89
 
90
- VERSION = "2.214.0"
90
+ VERSION = "2.214.1"
91
91
  logger = logging.getLogger("davinci-resolve-mcp")
92
92
  logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
93
93
  logger.info(f"Detected platform: {get_platform()}")
package/src/server.py CHANGED
@@ -11,7 +11,7 @@ Usage:
11
11
  python src/server.py --full # Start the 353-tool granular server instead
12
12
  """
13
13
 
14
- VERSION = "2.214.0"
14
+ VERSION = "2.214.1"
15
15
 
16
16
  import base64
17
17
  import os
@@ -27194,28 +27194,62 @@ def _apply_trace_plan(p: Dict[str, Any]) -> Dict[str, Any]:
27194
27194
  if blocked:
27195
27195
  return blocked
27196
27196
 
27197
- applied: List[Dict[str, Any]] = []
27198
- failed: List[Dict[str, Any]] = []
27199
- for r in to_apply:
27200
- item = r["_item"]
27201
- rec = {k: v for k, v in r.items() if not k.startswith("_")}
27202
- ok = False
27197
+ # Measured on Studio 19.1.3.7 (2026-09-08): with the GUI on the EDIT page,
27198
+ # TimelineItem.AddVersion and Graph.ApplyGradeFromDRX both return False for
27199
+ # every clip — 12/12 failed, then 12/12 applied after OpenPage("color") with
27200
+ # nothing else changed. Grade the batch on the color page and put the page
27201
+ # back afterwards; refuse up front rather than hand back 254 "returned
27202
+ # False" rows.
27203
+ page: Dict[str, Any] = {"before": None, "switched": False, "restored": None}
27204
+ resolve = get_resolve()
27205
+ try:
27206
+ page["before"] = resolve.GetCurrentPage() if resolve else None
27207
+ except Exception as exc:
27208
+ page["read_error"] = str(exc)
27209
+ if page["before"] and page["before"] != "color":
27203
27210
  try:
27204
- if version_name:
27205
- # AddVersion switches the item to the NEW version, so the apply
27206
- # lands there and the previous version stays intact.
27207
- rec["version_added"] = bool(item.AddVersion(version_name, 0))
27208
- graph = item.GetNodeGraph()
27209
- if not _has_method(graph, "ApplyGradeFromDRX"):
27210
- rec["error"] = "item graph does not expose ApplyGradeFromDRX"
27211
- else:
27212
- ok = bool(graph.ApplyGradeFromDRX(r["drx_path"], grade_mode))
27213
- if not ok:
27214
- rec["error"] = "ApplyGradeFromDRX returned False"
27211
+ page["switched"] = bool(resolve.OpenPage("color"))
27215
27212
  except Exception as exc:
27216
- rec["error"] = str(exc)
27217
- rec["status"] = "applied" if ok else "failed"
27218
- (applied if ok else failed).append(rec)
27213
+ page["switch_error"] = str(exc)
27214
+ if not page["switched"]:
27215
+ err = _err(
27216
+ f"Resolve is on the {page['before']!r} page and could not switch to the color page; "
27217
+ "AddVersion and ApplyGradeFromDRX return False from any other page (19.1.3.7).",
27218
+ code="PAGE_SWITCH_FAILED", category="resolve_api_failed", retryable=True,
27219
+ remediation="resolve_control(action='open_page', params={'page': 'color'}) then re-call.",
27220
+ )
27221
+ err["page"] = page
27222
+ return err
27223
+
27224
+ applied: List[Dict[str, Any]] = []
27225
+ failed: List[Dict[str, Any]] = []
27226
+ try:
27227
+ for r in to_apply:
27228
+ item = r["_item"]
27229
+ rec = {k: v for k, v in r.items() if not k.startswith("_")}
27230
+ ok = False
27231
+ try:
27232
+ if version_name:
27233
+ # AddVersion switches the item to the NEW version, so the apply
27234
+ # lands there and the previous version stays intact.
27235
+ rec["version_added"] = bool(item.AddVersion(version_name, 0))
27236
+ graph = item.GetNodeGraph()
27237
+ if not _has_method(graph, "ApplyGradeFromDRX"):
27238
+ rec["error"] = "item graph does not expose ApplyGradeFromDRX"
27239
+ else:
27240
+ ok = bool(graph.ApplyGradeFromDRX(r["drx_path"], grade_mode))
27241
+ if not ok:
27242
+ rec["error"] = "ApplyGradeFromDRX returned False"
27243
+ except Exception as exc:
27244
+ rec["error"] = str(exc)
27245
+ rec["status"] = "applied" if ok else "failed"
27246
+ (applied if ok else failed).append(rec)
27247
+ finally:
27248
+ if page["switched"]:
27249
+ try:
27250
+ page["restored"] = bool(resolve.OpenPage(page["before"]))
27251
+ except Exception as exc:
27252
+ page["restore_error"] = str(exc)
27219
27253
  summary.update({"applied": len(applied), "failed": len(failed)})
27220
27254
  skipped = [r for r in public if r["status"] != "apply"]
27221
27255
  report_path = _trace_report(p, plan, "apply", {"summary": summary, "applied": applied, "failed": failed, "skipped": skipped})
@@ -27224,6 +27258,7 @@ def _apply_trace_plan(p: Dict[str, Any]) -> Dict[str, Any]:
27224
27258
  "timeline": live_name,
27225
27259
  "plan_source": plan.get("source"),
27226
27260
  "report_path": report_path,
27261
+ "page": page,
27227
27262
  "applied": _trace_compact(applied, max_rows),
27228
27263
  "failed": failed, # never truncated: every failure is actionable
27229
27264
  "skipped": _trace_compact(skipped, max_rows),
@@ -1916,6 +1916,26 @@ API_TRUTH: List[Dict[str, Any]] = [
1916
1916
  "pass-through.",
1917
1917
  "tags": ["silent-failure", "color", "node-graph", "layout", "drx"],
1918
1918
  },
1919
+ {
1920
+ "symbol": "TimelineItem.AddVersion / Graph.ApplyGradeFromDRX (page-dependent)",
1921
+ "object": "TimelineItem / Graph",
1922
+ "signature": "AddVersion(name, type) -> bool; ApplyGradeFromDRX(path, gradeMode) -> bool",
1923
+ "reality": "Both return False for every clip while the GUI sits on the "
1924
+ "EDIT page, with no exception and no other signal. Measured on "
1925
+ "Studio 19.1.3.7 (2026-09-08) on a live conform: 12 of 12 "
1926
+ "clips failed from the edit page, then 12 of 12 applied after "
1927
+ "OpenPage('color') with nothing else changed; an earlier "
1928
+ "254-clip batch on the same timeline had succeeded while the "
1929
+ "page was color. Read-side calls (GetNodeGraph, GetNumNodes, "
1930
+ "GetVersionNameList) answer normally from the edit page, so "
1931
+ "the False cannot be told apart from a bad .drx or a locked "
1932
+ "clip without checking the page.",
1933
+ "recommended": "Read GetCurrentPage() before any grade mutation; OpenPage"
1934
+ "('color') for the batch and restore the page afterwards. "
1935
+ "timeline_item_color.apply_trace_plan does this itself and "
1936
+ "reports {page: {before, switched, restored}}.",
1937
+ "tags": ["silent-failure", "color", "grade", "page", "drx", "version"],
1938
+ },
1919
1939
  {
1920
1940
  "symbol": "MediaPool.AppendToTimeline clipInfo endFrame (exclusive bound)",
1921
1941
  "object": "MediaPool",