davinci-resolve-mcp 2.145.0 → 2.145.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,24 @@
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.145.1 — bridge config override, honored end to end
6
+
7
+ ### Fixed
8
+
9
+ - **The free-edition bridge installer now honors
10
+ `DAVINCI_RESOLVE_BRIDGE_CONFIG`** — adapted from
11
+ [PR #177](https://github.com/samuelgursky/davinci-resolve-mcp/pull/177) by
12
+ @altiss. The bridge client already resolved the override, but the installer
13
+ always wrote and embedded the fixed default path, so a client configured
14
+ with an override could look in one place while the in-app bridge was
15
+ installed with another — both sides "successfully" installed yet never
16
+ sharing a token. The installer resolves the effective path at call time
17
+ with the client's exact semantics (env wins, `~` expands, default
18
+ otherwise) across create, report, runtime copy, and launcher embed. One
19
+ correction on top of the PR: the step-4 probe guidance keeps pointing at
20
+ the FIXED default directory — the probe runs inside Resolve, which never
21
+ inherits the shell's environment, so it always writes there.
22
+
5
23
  ## What's New in v2.145.0 — whole projects, assembled offline
6
24
 
7
25
  ### 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.145.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-2.145.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)
@@ -52,6 +52,11 @@ python scripts/install_resolve_bridge.py
52
52
  # restart Resolve, open a project, then: Workspace > Scripts > resolve_bridge
53
53
  ```
54
54
 
55
+ The installer and MCP client use `~/.config/davinci-resolve-mcp/bridge.json`
56
+ by default. To keep the authenticated bridge config elsewhere, set
57
+ `DAVINCI_RESOLVE_BRIDGE_CONFIG` while running the installer and in the MCP
58
+ client environment; both sides will use that path.
59
+
55
60
  Once that listener is running it is used **automatically** whenever external
56
61
  scripting is unavailable — no environment variable required. Setting
57
62
  `DAVINCI_RESOLVE_BRIDGE=1` *forces* the bridge instead: it becomes the only
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.145.0-blue.svg)](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
5
+ [![Version](https://img.shields.io/badge/version-2.145.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.145.0 版 README。如与英文原版有出入,以 [英文原版](README.md) 为准。
15
+ > 本翻译对应 v2.145.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.145.0"
40
+ VERSION = "2.145.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.145.0",
3
+ "version": "2.145.1",
4
4
  "description": "NPM bootstrapper for the DaVinci Resolve MCP Server.",
5
5
  "license": "MIT",
6
6
  "author": "Samuel Gursky <samgursky@gmail.com>",
@@ -24,10 +24,17 @@ import sys
24
24
  from pathlib import Path
25
25
 
26
26
  REPO = Path(__file__).resolve().parent.parent
27
- CONFIG_DIR = Path.home() / ".config/davinci-resolve-mcp"
28
- CONFIG_PATH = CONFIG_DIR / "bridge.json"
27
+ DEFAULT_CONFIG_PATH = Path.home() / ".config/davinci-resolve-mcp/bridge.json"
28
+ ENV_CONFIG_PATH = "DAVINCI_RESOLVE_BRIDGE_CONFIG"
29
29
  DEFAULT_PORT = 49632
30
30
 
31
+
32
+ def config_path() -> Path:
33
+ """Bridge config written by this installer and read by the MCP client."""
34
+ override = os.environ.get(ENV_CONFIG_PATH)
35
+ return Path(override).expanduser() if override else DEFAULT_CONFIG_PATH
36
+
37
+
31
38
  _SCRIPTS_SUFFIX = "Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Utility"
32
39
 
33
40
  #: A sandboxed (App Store) build sees its container as HOME, so Resolve's
@@ -448,10 +455,11 @@ def python_preflight() -> dict:
448
455
 
449
456
 
450
457
  def ensure_config(port: int, rotate: bool) -> dict:
458
+ path = config_path()
451
459
  existing: dict = {}
452
- if CONFIG_PATH.exists():
460
+ if path.exists():
453
461
  try:
454
- existing = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
462
+ existing = json.loads(path.read_text(encoding="utf-8"))
455
463
  except (OSError, ValueError):
456
464
  existing = {}
457
465
  token = existing.get("token")
@@ -469,12 +477,12 @@ def ensure_config(port: int, rotate: bool) -> dict:
469
477
  "allowed_media_roots": existing_media or [str(Path.home())],
470
478
  "allowed_output_roots": existing_output or [str(Path.home() / "Movies")],
471
479
  }
472
- CONFIG_DIR.mkdir(mode=0o700, parents=True, exist_ok=True)
473
- tmp = CONFIG_PATH.with_suffix(".tmp")
480
+ path.parent.mkdir(mode=0o700, parents=True, exist_ok=True)
481
+ tmp = path.with_suffix(".tmp")
474
482
  tmp.write_text(json.dumps(config, indent=2, sort_keys=True), encoding="utf-8")
475
483
  os.chmod(tmp, 0o600)
476
- tmp.replace(CONFIG_PATH)
477
- os.chmod(CONFIG_PATH, 0o600)
484
+ tmp.replace(path)
485
+ os.chmod(path, 0o600)
478
486
  return config
479
487
 
480
488
 
@@ -525,8 +533,9 @@ def install(*, probe_only: bool, port: int, rotate: bool) -> dict:
525
533
  )
526
534
  result["skipped"] = [path for path, _ in skipped]
527
535
  if not probe_only:
528
- loaded = json.loads(CONFIG_PATH.read_text(encoding="utf-8"))
529
- result["config"] = {"path": str(CONFIG_PATH),
536
+ path = config_path()
537
+ loaded = json.loads(path.read_text(encoding="utf-8"))
538
+ result["config"] = {"path": str(path),
530
539
  **{k: v for k, v in loaded.items() if k != "token"}}
531
540
  return result
532
541
 
@@ -558,9 +567,10 @@ def _install_to(target: Path, *, probe_only: bool, installed: list[str]) -> None
558
567
  # unreachable by construction (measured: "Operation not permitted").
559
568
  # The runtime dir is already inside the container, so the config goes
560
569
  # beside the modules. Same token, so the out-of-sandbox client still
561
- # authenticates against ~/.config.
570
+ # authenticates against the selected config path.
562
571
  runtime_config = runtime / "bridge.json"
563
- shutil.copy2(CONFIG_PATH, runtime_config)
572
+ path = config_path()
573
+ shutil.copy2(path, runtime_config)
564
574
  os.chmod(runtime_config, 0o600)
565
575
  installed.append(str(runtime_config))
566
576
  # The launcher IS the menu entry. Without it the modules sit in the
@@ -571,7 +581,7 @@ def _install_to(target: Path, *, probe_only: bool, installed: list[str]) -> None
571
581
  base64.urlsafe_b64encode(str(runtime).encode("utf-8")).decode("ascii"),
572
582
  ).replace(
573
583
  "@@CONFIG_PATH_B64@@",
574
- base64.urlsafe_b64encode(str(CONFIG_PATH).encode("utf-8")).decode("ascii"),
584
+ base64.urlsafe_b64encode(str(path).encode("utf-8")).decode("ascii"),
575
585
  )
576
586
  launcher_path = target / "resolve_bridge.py"
577
587
  launcher_path.write_text(launcher, encoding="utf-8")
@@ -605,6 +615,9 @@ def main() -> int:
605
615
  print(" 1. Restart DaVinci Resolve so it re-scans the Scripts folders.")
606
616
  print(" 2. Open a saved project (the Scripts menu is empty in Project Manager).")
607
617
  print(" 3. Workspace > Scripts > resolve_bridge_probe — run it TWICE.")
618
+ # The probe runs INSIDE Resolve, which never sees the shell's
619
+ # DAVINCI_RESOLVE_BRIDGE_CONFIG — it always writes to the fixed default
620
+ # directory, so the guidance must not follow the override.
608
621
  print(" 4. Read ~/.config/davinci-resolve-mcp/host-model-probe.json")
609
622
  return 0
610
623
 
@@ -87,7 +87,7 @@ if not logging.getLogger().handlers:
87
87
  handlers=[logging.StreamHandler()],
88
88
  )
89
89
 
90
- VERSION = "2.145.0"
90
+ VERSION = "2.145.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.145.0"
14
+ VERSION = "2.145.1"
15
15
 
16
16
  import base64
17
17
  import os