davinci-resolve-mcp 2.63.0 → 2.63.2
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 +40 -0
- package/README.md +1 -1
- package/docs/install.md +10 -1
- package/docs/notes/dctl-notes.md +6 -1
- package/docs/notes/lut-notes.md +38 -5
- package/docs/reference/api-limitations.md +10 -1
- package/install.py +33 -2
- package/package.json +1 -1
- package/src/granular/common.py +1 -1
- package/src/server.py +1 -1
- package/src/utils/api_truth.py +29 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,46 @@
|
|
|
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.63.2
|
|
6
|
+
|
|
7
|
+
Installer fix for Windows MSIX builds of Claude Desktop (issue #93, reported by
|
|
8
|
+
@corolorn). No tool-surface change.
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Installer writes Claude Desktop config to the MSIX-virtualized path on
|
|
13
|
+
Windows** — Claude Desktop for Windows ships as an MSIX package (even from
|
|
14
|
+
the official website), and MSIX filesystem virtualization redirects the
|
|
15
|
+
app's config to
|
|
16
|
+
`%LOCALAPPDATA%\Packages\Claude_<publisherhash>\LocalCache\Roaming\Claude\claude_desktop_config.json`.
|
|
17
|
+
The installer previously wrote to the documented `%APPDATA%\Claude\` path,
|
|
18
|
+
which the MSIX-packaged app never reads, so the server silently never
|
|
19
|
+
appeared. The installer now detects the containerized path (publisher hash
|
|
20
|
+
globbed, not hard-coded) and writes there when present, falling back to
|
|
21
|
+
`%APPDATA%\Claude\` for non-MSIX installs. Documented both locations in
|
|
22
|
+
`docs/install.md`.
|
|
23
|
+
|
|
24
|
+
## What's New in v2.63.1
|
|
25
|
+
|
|
26
|
+
Documentation-only. Records the `Graph.SetLUT` master-LUT-dir behavior (from the
|
|
27
|
+
v2.62.3 fix) in the canonical reference surfaces. No code or tool-surface change.
|
|
28
|
+
|
|
29
|
+
### Documentation
|
|
30
|
+
|
|
31
|
+
- **`api_truth` + api-limitations report** — added a `Graph.SetLUT` entry
|
|
32
|
+
(`submit: bug`, #90): `SetLUT` resolves LUT paths only against the master
|
|
33
|
+
(system) LUT dir and configured custom paths, never the per-user dir the
|
|
34
|
+
`dctl` tool installs to; an absolute user-dir path fails too, and
|
|
35
|
+
`RefreshLUTList()` does not help, while a master-subfolder path resolves.
|
|
36
|
+
Verified live on Studio 19.1.3.7 (same behavior reported on 21.0.2 in #90).
|
|
37
|
+
Regenerated `docs/reference/api-limitations.md`.
|
|
38
|
+
- **`docs/notes/lut-notes.md`** — corrected a misleading claim that any valid
|
|
39
|
+
absolute path resolves (an absolute path into the user LUT dir does not),
|
|
40
|
+
added a "master LUT dir only" section, and documented the per-user install
|
|
41
|
+
location.
|
|
42
|
+
- **`docs/notes/dctl-notes.md`** — noted the same caveat on the `set_lut`
|
|
43
|
+
action, including that `set_lut` now auto-relocates into the master dir.
|
|
44
|
+
|
|
5
45
|
## What's New in v2.63.0
|
|
6
46
|
|
|
7
47
|
Waveform silence ripple for the edit engine (PR #91, by @EliteSystemsAI),
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DaVinci Resolve MCP Server
|
|
2
2
|
|
|
3
|
-
[](https://github.com/samuelgursky/davinci-resolve-mcp/releases)
|
|
4
4
|
[](https://www.npmjs.com/package/davinci-resolve-mcp)
|
|
5
5
|
[](docs/reference/api-coverage.md)
|
|
6
6
|
[-blue.svg)](#server-modes)
|
package/docs/install.md
CHANGED
|
@@ -50,7 +50,7 @@ The installer can automatically configure any of these clients:
|
|
|
50
50
|
|
|
51
51
|
| Client | Config Written To |
|
|
52
52
|
|--------|-------------------|
|
|
53
|
-
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) |
|
|
53
|
+
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS); `%APPDATA%\Claude\claude_desktop_config.json` (Windows, see MSIX note below) |
|
|
54
54
|
| Claude Code | `.mcp.json` (project root) |
|
|
55
55
|
| Cursor | `~/.cursor/mcp.json` |
|
|
56
56
|
| VS Code (Copilot) | `.vscode/mcp.json` (workspace) |
|
|
@@ -64,6 +64,15 @@ The installer can automatically configure any of these clients:
|
|
|
64
64
|
|
|
65
65
|
You can configure multiple clients at once, or use `--clients manual` to get copy-paste config snippets.
|
|
66
66
|
|
|
67
|
+
> **Windows MSIX note (Claude Desktop):** Claude Desktop for Windows is
|
|
68
|
+
> distributed as an MSIX package — even when downloaded from the official
|
|
69
|
+
> website. MSIX filesystem virtualization redirects the app's config to
|
|
70
|
+
> `%LOCALAPPDATA%\Packages\Claude_<publisherhash>\LocalCache\Roaming\Claude\claude_desktop_config.json`,
|
|
71
|
+
> and the app never reads the documented `%APPDATA%\Claude\` path (which may
|
|
72
|
+
> still exist on disk). The installer detects the virtualized location and
|
|
73
|
+
> writes there automatically. If the server does not appear in Claude Desktop
|
|
74
|
+
> after a manual setup, check both locations.
|
|
75
|
+
|
|
67
76
|
For [Autohand Code](https://github.com/autohandai/code-cli/), register the managed launcher after setup:
|
|
68
77
|
|
|
69
78
|
```bash
|
package/docs/notes/dctl-notes.md
CHANGED
|
@@ -19,7 +19,12 @@ Relevant existing actions:
|
|
|
19
19
|
Resolve's LUT folders.
|
|
20
20
|
- `graph(action="set_lut", params={"node_index": 1, "lut_path": "..."})`
|
|
21
21
|
wraps `Graph.SetLUT(nodeIndex, lutPath)`. DCTLs that Resolve exposes through
|
|
22
|
-
LUT selection follow the same discovery constraints as LUTs.
|
|
22
|
+
LUT selection follow the same discovery constraints as LUTs. **Caveat:**
|
|
23
|
+
`install` writes to the per-user LUT dir, but `SetLUT` resolves only against
|
|
24
|
+
the *master* LUT dir (not even an absolute user-dir path works, and
|
|
25
|
+
`refresh_luts` does not help). `set_lut` now auto-relocates the file into an
|
|
26
|
+
`MCP/` subfolder of the master dir and retries — see `docs/notes/lut-notes.md`
|
|
27
|
+
("master LUT dir only") and the `Graph.SetLUT` entry in `api_truth.py`.
|
|
23
28
|
- `graph(action="get_lut", params={"node_index": 1})` wraps `Graph.GetLUT()`.
|
|
24
29
|
- `graph(action="get_tools_in_node", ...)` may report ResolveFX tools present
|
|
25
30
|
in a Color page node, but the scripting API does not expose a general
|
package/docs/notes/lut-notes.md
CHANGED
|
@@ -21,8 +21,32 @@ The scripting API already exposes the important LUT operations:
|
|
|
21
21
|
can include LUTs in a `.drp` export.
|
|
22
22
|
|
|
23
23
|
`SetLUT()` uses 1-based node indexes and succeeds only for LUT paths Resolve has
|
|
24
|
-
already discovered.
|
|
25
|
-
|
|
24
|
+
already discovered.
|
|
25
|
+
|
|
26
|
+
### `SetLUT` resolves against the master LUT dir only
|
|
27
|
+
|
|
28
|
+
Resolve resolves the `lut_path` given to `SetLUT()` **only against the master
|
|
29
|
+
(system) LUT directory and its configured custom LUT paths — not the per-user
|
|
30
|
+
LUT directory** that the `dctl` tool and Project-level LUT installs write to.
|
|
31
|
+
This trips up the obvious workflow (install a LUT/DCTL, then apply it):
|
|
32
|
+
|
|
33
|
+
- A bare basename that lives only in the user LUT dir returns `False`.
|
|
34
|
+
- An **absolute path into the user LUT dir also returns `False`** — absolute
|
|
35
|
+
paths are not a workaround.
|
|
36
|
+
- `project_settings(action="refresh_luts")` (`RefreshLUTList()`) does **not**
|
|
37
|
+
change this; the file is discovered but still not resolvable by `SetLUT`.
|
|
38
|
+
- A **subfolder-relative** path under the master root (e.g. `MCP/Foo.cube`)
|
|
39
|
+
*does* resolve.
|
|
40
|
+
|
|
41
|
+
Verified live on Studio 19.1.3.7; the same behavior was reported on 21.0.2
|
|
42
|
+
(PR #90), so it is not version-specific. See the `Graph.SetLUT` entry in
|
|
43
|
+
`src/utils/api_truth.py`.
|
|
44
|
+
|
|
45
|
+
`graph.set_lut` (and the granular `graph_set_lut`) handle this automatically:
|
|
46
|
+
on a `False` return they stage the LUT into an `MCP/` subfolder of the master
|
|
47
|
+
LUT dir, refresh, and retry, returning `resolved_lut` on success. If you call
|
|
48
|
+
`Graph.SetLUT` directly, relocate the file into the master dir yourself first
|
|
49
|
+
(`src.utils.lut_paths.ensure_lut_in_master`).
|
|
26
50
|
|
|
27
51
|
## Cube LUT Format
|
|
28
52
|
|
|
@@ -100,16 +124,25 @@ Blackmagic's examples live in the installed LUT folder:
|
|
|
100
124
|
Example built-in LUT categories include `VFX IO`, `Blackmagic Design`, and
|
|
101
125
|
`ACES`.
|
|
102
126
|
|
|
127
|
+
The `dctl` tool and Project-level LUT installs instead write to the **per-user**
|
|
128
|
+
LUT dir (macOS `~/Library/Application Support/Blackmagic Design/DaVinci Resolve/LUT`,
|
|
129
|
+
Windows `%APPDATA%\Blackmagic Design\DaVinci Resolve\Support\LUT`). Files there
|
|
130
|
+
are discovered by the LUT browser but are **not** resolvable by `SetLUT` until
|
|
131
|
+
relocated into the master dir above — see "master LUT dir only".
|
|
132
|
+
|
|
103
133
|
## Practical Failure Checks
|
|
104
134
|
|
|
105
135
|
If `graph.set_lut` fails or `graph.get_lut` returns empty:
|
|
106
136
|
|
|
107
137
|
- Confirm the current page/context has a valid Color graph and the node index is
|
|
108
138
|
1-based.
|
|
109
|
-
- Confirm the LUT
|
|
110
|
-
|
|
139
|
+
- Confirm the LUT is in the **master** LUT folder (or a configured custom LUT
|
|
140
|
+
path) — not just the per-user LUT dir. A file only in the user dir fails even
|
|
141
|
+
by absolute path (see "master LUT dir only" above). `graph.set_lut` relocates
|
|
142
|
+
it for you; a direct `Graph.SetLUT` call does not.
|
|
111
143
|
- Call `project_settings(action="refresh_luts")` after adding or changing LUT
|
|
112
|
-
files
|
|
144
|
+
files (note: refresh alone does not make a user-dir LUT resolvable by
|
|
145
|
+
`SetLUT`).
|
|
113
146
|
- Check the `.cube` header and row count. 3D LUTs must contain exactly
|
|
114
147
|
`N * N * N` rows.
|
|
115
148
|
- Confirm the file extension is `.cube` and the content is plain text.
|
|
@@ -12,7 +12,7 @@ that none exists).
|
|
|
12
12
|
|
|
13
13
|
**Verified on:** DaVinci Resolve Studio 21.0.0
|
|
14
14
|
|
|
15
|
-
**Totals:** 19 missing capabilities,
|
|
15
|
+
**Totals:** 19 missing capabilities, 12 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
|
|
@@ -265,3 +265,12 @@ values, or automation-hostile modal prompts.
|
|
|
265
265
|
- **Workaround / current handling:** After writing 'Reel Name', read it back with GetClipProperty('Reel Name') and refuse to report success on mismatch; surface the project-setting gate to the caller (server._verify_clip_property_writeback).
|
|
266
266
|
- **Reference:** [issue #77](https://github.com/samuelgursky/davinci-resolve-mcp/issues/77)
|
|
267
267
|
- **Tags:** unreliable-return, silent-failure, metadata, reel-name
|
|
268
|
+
|
|
269
|
+
### Graph.SetLUT (master-LUT-dir-only resolution)
|
|
270
|
+
|
|
271
|
+
- **Object:** `Graph`
|
|
272
|
+
- **Signature:** `(nodeIndex, lutPath) -> bool`
|
|
273
|
+
- **Behavior:** SetLUT resolves lutPath ONLY against the master (system) LUT directory and its configured custom LUT paths -- NOT the per-user LUT dir that the dctl tool / Project LUT install writes to. A bare basename in the user dir returns False, and so does an ABSOLUTE path pointing into the user dir; RefreshLUTList() does not change this. A subfolder-relative path under the master root (e.g. 'MCP/Foo.cube') DOES resolve. Net effect: a LUT/DCTL the dctl tool just installed can never be applied by SetLUT as-is, so set_lut used to always return {success: false}. Verified live on Studio 19.1.3.7 (basename and absolute user-dir path both False, before and after RefreshLUTList; master-dir and master-subfolder paths True); the originating report (PR #90) observed the same on 21.0.2, so it is not version-specific.
|
|
274
|
+
- **Workaround / current handling:** On a False return, locate the LUT, copy it into a namespaced subfolder of the master LUT dir (MCP/, so it does not clobber stock LUTs by basename), call RefreshLUTList(), and retry with the master-relative path. graph.set_lut and the granular graph_set_lut now do this automatically via src.utils.lut_paths.ensure_lut_in_master.
|
|
275
|
+
- **Reference:** [issue #90](https://github.com/samuelgursky/davinci-resolve-mcp/issues/90)
|
|
276
|
+
- **Tags:** color, lut, path-resolution, silent-failure
|
package/install.py
CHANGED
|
@@ -35,7 +35,7 @@ from src.utils.update_check import (
|
|
|
35
35
|
|
|
36
36
|
# ─── Version ──────────────────────────────────────────────────────────────────
|
|
37
37
|
|
|
38
|
-
VERSION = "2.63.
|
|
38
|
+
VERSION = "2.63.2"
|
|
39
39
|
# Only hard floor: mcp[cli] requires Python 3.10+. There is no upper bound —
|
|
40
40
|
# Resolve's scripting bridge loads into newer interpreters on recent builds
|
|
41
41
|
# (Python 3.14 verified against Resolve Studio 20.3.2). Older Resolve builds
|
|
@@ -282,6 +282,37 @@ def appdata():
|
|
|
282
282
|
"""Windows %APPDATA% equivalent."""
|
|
283
283
|
return Path(os.environ.get("APPDATA", home() / "AppData" / "Roaming"))
|
|
284
284
|
|
|
285
|
+
def localappdata():
|
|
286
|
+
"""Windows %LOCALAPPDATA% equivalent."""
|
|
287
|
+
return Path(os.environ.get("LOCALAPPDATA", home() / "AppData" / "Local"))
|
|
288
|
+
|
|
289
|
+
def windows_claude_desktop_config():
|
|
290
|
+
"""Resolve the Claude Desktop config path on Windows, MSIX-aware (issue #93).
|
|
291
|
+
|
|
292
|
+
Claude Desktop for Windows ships as an MSIX package (even when downloaded
|
|
293
|
+
from the official website, not the Store). MSIX filesystem virtualization
|
|
294
|
+
redirects the app's %APPDATA% reads/writes into a per-package container,
|
|
295
|
+
so the app actually uses:
|
|
296
|
+
|
|
297
|
+
%LOCALAPPDATA%\\Packages\\Claude_<publisherhash>\\LocalCache\\Roaming\\Claude\\
|
|
298
|
+
|
|
299
|
+
A config written to the documented %APPDATA%\\Claude\\ location is invisible
|
|
300
|
+
to the app -- the server silently never appears. Prefer the containerized
|
|
301
|
+
path whenever a Claude MSIX package directory with that structure exists;
|
|
302
|
+
fall back to %APPDATA%\\Claude\\ otherwise. The publisher-hash suffix is
|
|
303
|
+
globbed rather than hard-coded so a re-signed package still matches.
|
|
304
|
+
"""
|
|
305
|
+
packages = localappdata() / "Packages"
|
|
306
|
+
try:
|
|
307
|
+
candidates = sorted(packages.glob("Claude_*"))
|
|
308
|
+
except OSError:
|
|
309
|
+
candidates = []
|
|
310
|
+
for pkg in candidates:
|
|
311
|
+
virtual = pkg / "LocalCache" / "Roaming" / "Claude"
|
|
312
|
+
if virtual.is_dir():
|
|
313
|
+
return virtual / "claude_desktop_config.json"
|
|
314
|
+
return appdata() / "Claude" / "claude_desktop_config.json"
|
|
315
|
+
|
|
285
316
|
def xdg_config():
|
|
286
317
|
"""Linux XDG_CONFIG_HOME or default."""
|
|
287
318
|
return Path(os.environ.get("XDG_CONFIG_HOME", home() / ".config"))
|
|
@@ -314,7 +345,7 @@ MCP_CLIENTS = [
|
|
|
314
345
|
"name": "Claude Desktop",
|
|
315
346
|
"get_path": lambda: {
|
|
316
347
|
"Darwin": home() / "Library" / "Application Support" / "Claude" / "claude_desktop_config.json",
|
|
317
|
-
"Windows":
|
|
348
|
+
"Windows": windows_claude_desktop_config(),
|
|
318
349
|
"Linux": xdg_config() / "Claude" / "claude_desktop_config.json",
|
|
319
350
|
}.get(SYSTEM),
|
|
320
351
|
"config_key": "mcpServers",
|
package/package.json
CHANGED
package/src/granular/common.py
CHANGED
|
@@ -80,7 +80,7 @@ if not logging.getLogger().handlers:
|
|
|
80
80
|
handlers=[logging.StreamHandler()],
|
|
81
81
|
)
|
|
82
82
|
|
|
83
|
-
VERSION = "2.63.
|
|
83
|
+
VERSION = "2.63.2"
|
|
84
84
|
logger = logging.getLogger("davinci-resolve-mcp")
|
|
85
85
|
logger.info(f"Starting DaVinci Resolve MCP Server v{VERSION}")
|
|
86
86
|
logger.info(f"Detected platform: {get_platform()}")
|
package/src/server.py
CHANGED
package/src/utils/api_truth.py
CHANGED
|
@@ -564,6 +564,35 @@ API_TRUTH: List[Dict[str, Any]] = [
|
|
|
564
564
|
"when mirroring keep-ranges into clipInfos.",
|
|
565
565
|
"tags": ["timeline", "edit", "off-by-one", "readback"],
|
|
566
566
|
},
|
|
567
|
+
{
|
|
568
|
+
"symbol": "Graph.SetLUT (master-LUT-dir-only resolution)",
|
|
569
|
+
"object": "Graph",
|
|
570
|
+
"signature": "(nodeIndex, lutPath) -> bool",
|
|
571
|
+
"reality": "SetLUT resolves lutPath ONLY against the master (system) LUT "
|
|
572
|
+
"directory and its configured custom LUT paths -- NOT the "
|
|
573
|
+
"per-user LUT dir that the dctl tool / Project LUT install "
|
|
574
|
+
"writes to. A bare basename in the user dir returns False, and "
|
|
575
|
+
"so does an ABSOLUTE path pointing into the user dir; "
|
|
576
|
+
"RefreshLUTList() does not change this. A subfolder-relative "
|
|
577
|
+
"path under the master root (e.g. 'MCP/Foo.cube') DOES resolve. "
|
|
578
|
+
"Net effect: a LUT/DCTL the dctl tool just installed can never "
|
|
579
|
+
"be applied by SetLUT as-is, so set_lut used to always return "
|
|
580
|
+
"{success: false}. Verified live on Studio 19.1.3.7 (basename "
|
|
581
|
+
"and absolute user-dir path both False, before and after "
|
|
582
|
+
"RefreshLUTList; master-dir and master-subfolder paths True); "
|
|
583
|
+
"the originating report (PR #90) observed the same on 21.0.2, "
|
|
584
|
+
"so it is not version-specific.",
|
|
585
|
+
"recommended": "On a False return, locate the LUT, copy it into a "
|
|
586
|
+
"namespaced subfolder of the master LUT dir (MCP/, so it "
|
|
587
|
+
"does not clobber stock LUTs by basename), call "
|
|
588
|
+
"RefreshLUTList(), and retry with the master-relative path. "
|
|
589
|
+
"graph.set_lut and the granular graph_set_lut now do this "
|
|
590
|
+
"automatically via src.utils.lut_paths.ensure_lut_in_master.",
|
|
591
|
+
"tags": ["color", "lut", "path-resolution", "silent-failure"],
|
|
592
|
+
"submit": "bug",
|
|
593
|
+
"issue": 90,
|
|
594
|
+
"mitigation": ["_ensure_lut_in_master"],
|
|
595
|
+
},
|
|
567
596
|
]
|
|
568
597
|
|
|
569
598
|
|