ResolveMCP-ext

io.github.CaptRauti由 GitHub 账号 CaptRauti 发布v1.0.2更新于 Nov 7, 2026

Resolve MCP gaps: clip effects, Paste Attributes, frame export, photo albums, camera layouts.

发布方自己的服务:Resolve

已验证STDIO仅桌面开发者工具媒体与设计

概览

AI 生成的概览

为助手提供 DaVinci Resolve 21.1.2 中主流 Resolve MCP 服务器未覆盖的脚本能力:片段特效、粘贴属性、导出帧、相册与多机位布局。

可以做什么
  • 列出、应用、移除、启用/停用和重排片段特效,并读取特效属性
  • 在片段之间复制属性(粘贴属性),并读取片段当前属性
  • 从时间线片段或媒体池项目导出静帧,并查询片段或文件夹所在的素材箱
  • 管理相册:创建、重命名、删除、评分、标记、版本、静帧与照片节点图
  • 编辑节点图:标签、颜色、启用状态、LUT 与缓存;读取渲染预设、音频格式与片段转录
  • 构建多机位对比布局(2x2、分屏、自定义变换)、机位标记与按机位分箱;读取片段位置与手柄偏移
适用场景
当你已经通过助手操作 DaVinci Resolve Studio,并需要其他 Resolve MCP 服务器未提供的 21.1.2 新脚本接口时使用。它设计为与 Blackmagic 自带的 ResolveMCP 及社区版 davinci-resolve-mcp 并行运行,而非替代它们。
运行要求
本地安装:Python 3.10+ 与 resolve-ext 包(pip 或 uvx),以及 DaVinci Resolve Studio 21.1.2 或更高版本,因为外部脚本是 Studio 专属功能。Resolve 需运行中,并在偏好设置中将外部脚本设为 Local。脚本 API 路径会自动检测;RESOLVE_SCRIPT_API 与 RESOLVE_SCRIPT_LIB 仅在非标准安装时作为可选覆盖。可用 doctor 命令检查环境。
安装前请注意
许多工具会写入 Resolve 工程:应用或移除特效、复制属性、创建和删除相册、设置节点标签与颜色、将片段移入素材箱以及构建时间线。在 21.1.2 上部分调用具有破坏性或不可靠,例如 SetLeftOffset 无法通过 API 撤销,reset_grades 会清除整个调色;服务器已将部分此类调用排除或要求确认。导出帧会向磁盘写入文件。

安装

在 SourceWeft 中

  1. 打开 控制台中的 ResolveMCP-ext,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

resolve-ext

An MCP server that adds the DaVinci Resolve 21.1.2 scripting surfaces the mainstream Resolve MCP servers do not cover — clip effects, effect properties, Paste-Attributes, frame export and media-pool folder lookups.

It is deliberately an extension, not a replacement: register it alongside the other two Resolve MCP servers and you get a larger surface with no overlap — see the full setup. Everything it exposes is measured against a live Resolve, and calls that turn out to be broken are reported as broken rather than wrapped in a success.

effects              apply/list/remove/toggle/reorder clip effectsclip_attrs           copy attributes between clips (Paste Attributes)export_frame         stills from a clip or media-pool itemfolder_ops           which bin does this clip/folder live inphoto_albums         albums, photos, ratings, flags, versions, stillsnode_graph           node labels, colours, enable state, LUTs, cacheproject_extras       render presets, audio render formats, transcriptioncamera_comparison    2x2 / split layouts, camera labels, markersclip_position        read placement + handle offsets; flags broken APIsresolve_ext_status   health check

The full Resolve MCP setup — three servers, all of them

Resolve is not covered by one MCP server. Three independent servers do different jobs, and full coverage means running all three. This project is the third; the other two are not optional extras.

ServerOriginToolsWhat it is for
Blackmagic's own
ResolveMCP.exe
Ships with DaVinci Resolve 21 — nothing to download14A meta-server: it provides Resolve's scripting-API stubs and a Python sandbox (run_script, search_scripting_api, get_whats_new) plus LUT/DCTL management. It performs no Resolve actions itself.
community
samuelgursky/davinci-resolve-mcp
npx or git37
(390 with --full)
The workhorse: editing, media pool, render, markers, grading, Fusion — one granular tool per task. Ships a second davinci-resolve-advanced server (18 Node tools) for source-safe media analysis.
this project
resolve-ext
pip10The gaps the other two leave — see the table below.

All three talk to the same Resolve through the same single-client scripting API. They coexist without overlap; registering one and wondering why a capability is missing is the usual disappointment.

bash
# 1. Blackmagic's — already on disk, just register it:#    %ProgramFiles%\Blackmagic Design\DaVinci Resolve\ResolveMCP.exe   (Windows)#    /Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Applications/ResolveMCP#    /opt/resolve/bin/ResolveMCP                                       (Linux)
# 2. the community server (use --clients manual when driving it non-interactively):npx davinci-resolve-mcp setup
# 3. this project:pip install https://github.com/CaptRauti/ResolveMCP-ext/releases/download/v1.0.0/resolve_ext-1.0.0-py3-none-any.whlresolve-ext doctor

Full procedure, per-platform paths, the Windows "Resolve is on another drive" case, and the failure modes of each: AGENTS.md — written so an AI agent can install all three unattended.

Why this exists

DaVinci Resolve 21.1.2 (22 Oct 2026) added a batch of scripting APIs. The popular MCP servers do not implement them — verified two ways: searching their source for each symbol, and probing live Resolve objects with hasattr (a type stub documents the API; only the live object proves your build has it).

Resolve 21.1.2 symbolIn mainstream MCP servers
Resolve.GetEffectsListabsent
TimelineItem.AddEffect / GetEffects / DeleteEffectsabsent
Effect.GetInfo / Get/SetIsEnabled / Get/SetIndexabsent
TimelineItem.CopyAttributesabsent
TimelineItem.ExportFrame / MediaPoolItem.ExportFrameabsent
MediaPoolItem.GetParentFolder / Folder.GetParentFolderabsent
TimelineItem.Get/SetLeftOffset / GetPositionabsent
Timeline.MoveItems / DeleteGaps / Get/SetIsEnabledabsent
Photo Album APIs (PhotoAlbum, PhotoAlbumItem, 53 methods)absent
Graph.SetNodeLabel / Get/SetNodeColor / SetNodeEnabledabsent
Project.GetAudioRenderFormats / GetAudioRenderCodecsabsent
Project.UpdateRenderPreset / SetQuickExportEnabledForRenderPresetabsent
MediaPoolItem.SetTranscriptionabsent

TimelineItem alone exposes 113 methods on 21.1.2; a large share of them were unreachable through MCP before this server.

Install

Installing this with an AI agent? Point it at AGENTS.md — it is a step-by-step procedure written for agents, including the failure cases. This section is the human-facing version.

Requires Python 3.10+ and DaVinci Resolve Studio (external scripting is a Studio feature — the free build refuses it).

From a release (recommended)

Download the wheel from the releases page and install it:

bash
pip install resolve_ext-1.0.0-py3-none-any.whl

The wheel is pure Python and platform-independent — the same file works on Windows, macOS and Linux.

From a git checkout

bash
pip install git+https://github.com/CaptRauti/ResolveMCP-ext

Or from a local clone:

bash
git clone https://github.com/CaptRauti/ResolveMCP-extcd ResolveMCP-extpip install .

mcp 2.x breaks FastMCP, so the dependency is pinned <2. That pin is in the package metadata — you do not need to add it yourself.

Verify the installation

bash
resolve-ext doctor
resolve-ext 1.0.0
--- Python ---  3.12.4 at /usr/bin/python3  ok (3.10+)
--- DaVinci Resolve scripting API ---platform      linuxapi_path      /opt/resolve/Developer/Scripting  (found)lib_path      /opt/resolve/libs/fusionscript.so  (found)
--- Import test ---  ok: DaVinciResolveScript imports
--- Live connection ---  ok: connected to Resolve; project = My Project
--- Result ---  All checks passed.

doctor exits 0 when everything works and 1 otherwise, so it is usable in a setup script. When something is wrong it names the exact path that is missing and what to enable.

Register with your MCP client

The server finds Resolve's scripting API by itself, so on a default installation there is nothing to configure:

json
{  "mcpServers": {    "resolve-ext": { "command": "resolve-ext" }  }}

For a non-standard Resolve location, or to see the explicit form, run:

bash
resolve-ext env

which prints the configuration for the machine it runs on — including the exact RESOLVE_SCRIPT_API, RESOLVE_SCRIPT_LIB and PYTHONPATH values — as generic JSON and as a hermes mcp add command.

When merging into an existing client config, the server entry sits flat under the client's own mcpServers key. Do not wrap it in a second mcpServers level — that silently disables tool discovery.

Resolve settings

Resolve must be running with Preferences → System → General → External scripting using → Local.

Tools

effects

list_available(media_type?)          video (default) | photo | audiolist_applied(item_id?|name?, category?)apply(item_id?|name?, category, id)remove(item_id?|name?, category, indices?)set_enabled(item_id?|name?, index, enabled, category?)reorder(item_id?|name?, index, new_index, category?)

Address a timeline item with item_id (GetUniqueId) or with name plus the track it sits on (track_type default video, track_index default 1).

Always call list_available first — apply needs the category and id it returns. On a stock 21.1.2 Studio that is 36 fusion + 98 ofx effects for video, plus the Fairlight set for audio. Fusion ids look like Fusion/Effects/<category>/<name>.

clip_attrs

options()                                    the full option vocabularycopy(source_id?|source_name?, target_ids?|target_names?, options, ...)read(item_id?|name?)

The API behind the Edit page's Paste Attributes — the lever that makes a per-camera look repeatable: grade one clip, push the same attributes onto every other clip from that camera.

36 options in 6 groups (clip, video, zoom_crop_flip, retime, grade_fusion, audio). Shorthands: copy_all_video, copy_all_audio.

json
{"colorCorrection": true, "allZoomAttributes": true, "allCropAttributes": true, "videoPlugins": true}

export_frame

item(item_id?|name?, frame_offset, output_type?, file_path?, format?, max_dimension?)media(clip_id, frame_offset, output_type?, file_path?, format?, max_dimension?)timeline(frame_offset, ...)     # broken on 21.1.2 — see below

item and media are verified working. The offset is 0-based and must be below the item's duration. output_type: file (needs file_path) or encodedString (default); for the latter the base64 is decoded and written to out/ next to the server, with only a short prefix returned inline.

folder_ops

parent_of_clip(clip_id)              which bin holds this clipparent_of_folder(path?|folder_id?)   a folder's parent (root has none)path(clip_id?|folder_id?)            "Master/Sub/Bin"find_clip(clip_id)                   locate a clip anywhere in the tree

photo_albums

list() / current() / set_current(album_id?|name?)create(name) / create_from_photos(name, clip_ids) / delete(album_ids?) / rename(...)quick_export_presets() / render_settings(settings?)photos(album_id?|name?) / add_photos(clip_ids) / remove_photos(photo_ids) / current_item()stills(album_id?|name?, all_photos?)photo(photo_id) / rate(photo_id, stars) / flag(photo_id, color?|clear?)clip_color(photo_id, color?|clear?) / versions(photo_id)add_version / load_version / delete_versioncopy_grade / effects_list / effect_apply / effect_remove / fusion_comps / fusion_add

Verified working on 21.1.2.10: 9/9 PhotoAlbum methods, 20/20 PhotoAlbumItem methods, CreatePhotoAlbumFromPhotos, persistent ratings / flags / versions, AddFusionComp on a photo.

add_photos is broken upstream (AddToPhotoAlbum adds nothing) — the action verifies by reading the album back and tells you so. Use create_from_photos, which is the verified path.

Note the split: the album listing methods live on Project, the creating/adding ones on MediaPool, and Resolve answers none of them. The tool resolves the right object per call, because a Resolve proxy makes hasattr report every method on every object.

node_graph

info(item_id?|name?|photo_id?)        node list with labels and colourslabel(node_index, label)              "" clears the labelcolor(node_index, color)              "" clears the colourenable(node_index, enabled)tools(node_index)                     which Fusion/OFX tools sit in the nodelut(node_index, lut_path?)            read, or setcache(node_index, mode?)              read, or setreset_colors()                        photo graphs onlyreset_grades(confirm=true)            destructive — clears the whole grade

Valid node colours: Orange, Apricot, Yellow, Lime, Olive, Green, Teal, Navy, Blue, Purple, Violet, Pink, Tan, Beige, Brown, Chocolate.

Target a timeline clip by item_id/name, or a photo by photo_id. Labels and colours verified persistent across calls.

project_extras

capabilities()                             what this build answers at allrender_presets()                           GetRenderPresetListupdate_render_preset(preset_name)          GUI-dependent, see the broken tablequick_export_enable(preset_name, enabled)  GUI-dependentaudio_formats()                            {display name -> extension}audio_codecs(format_extension)             {description -> codec name}transcription(clip_id, use_nested?)        a clip's transcriptset_transcription(clip_id, transcription)  verified by reading back

audio_formats / audio_codecs VERIFIED: 7 real formats (FLAC, MP3, MP4, MXF OP-Atom, MXF OP1A (IMF), QuickTime, Wave) and their codecs. render_presets VERIFIED: 37 real presets.

camera_comparison

detect()                 which camera each clip is (from its name)grid_2x2()               four cameras in quadrants, scale 0.5split_h() / split_v()    two-up, side by side or stackedlayout(assignments)      explicit {clip_id: {x, y, scale}} — fractions of rasterfullframe(clip_ids)      back to 1.0 zoom, centredmarkers()                timeline markers naming each camerasort_to_bins()           file clips into per-camera bins by namebuild_timeline()         one video track per camera, scenes syncedread()                   current transform of every clip

Camera detection, longest prefix first:

prefixcameramarker
ace*Insta360 AceProOrange
go*Insta360 Go UltraGreen
luna*Insta360 Luna UltraCyan
x*Insta360 X5Blue
vid_*Handy (Android file)Gray

Why this tool exists: the loose scripts this replaces positioned clips with SetProperty("PositionX", …) / "PositionY". MEASURED on 21.1.2.10 those keys return False and are silently ignored — GetProperty gives back False too. Zoom worked, the positioning never did. The real keys are Pan (x, +right) and Tilt (y, +up), in pixels. Every write here is read back, and a transform that does not stick is reported as a failure.

Verified: on a 3840x2160 timeline grid_2x2 puts AcePro at Pan -960, Tilt 540 (top-left) and Go Ultra at Pan 960, Tilt 540 (top-right), read back.

clip_position

get(item_id?|name?)      position + left/right handle offsets   (safe, read-only)enabled()                timeline enabled state

set / move / set_offset / delete_gaps exist in the code but are disabled and transparent about why — they wrap Resolve calls that are broken or destructive on 21.1.2. See the next section.

Measured behaviour on Resolve 21.1.2.10

Everything below was measured against a live Studio build, not read from docs. tests/ reproduces all of it — 132 assertions across four suites, 0 failures.

Working

CallResult
Resolve.GetEffectsList36 fusion + 98 ofx (video), Fairlight (audio)
TimelineItem.AddEffect / GetEffects / DeleteEffectsverified end to end
Effect.GetInfo / GetIsEnabled / SetIsEnabled / GetIndexverified
TimelineItem.CopyAttributesverified with changed source values
TimelineItem.ExportFrameoffsets 0..duration-1 succeed, beyond is refused
MediaPoolItem.ExportFrameverified, file written
MediaPoolItem / Folder.GetParentFolderverified
Timeline.GetIsEnabled / SetIsEnabledverified

Broken or destructive — do not use

CallMeasured behaviour
TimelineItem.SetPositionReturns False for every input — real video clips and stills, int and float startFrame, a no-op equal to the current frame, both moveLinkedItems values. Timeline.MoveItems behaves identically, while SetCurrentTimecode succeeds in the same session.
Timeline.ExportFrameWorks — frameOffset is relative to the timeline start, valid 0..duration-1. Verified on a 480-frame timeline: 0..479 succeed, 480 is refused. An absolute frame is always refused, which reads like a failure. An earlier release listed this as broken; that was a bad measurement on a timeline whose metadata contradicted its contents.
Timeline.DeleteGapsWorks — verified [86400, 86600, 86800] → [86400, 86520, 86640], gaps closed. It does nothing on a timeline that reports StartFrame == EndFrame while holding clips; see the AppendToTimeline entry below.
TimelineItem.SetLeftOffsetDestructive. On a clip at frame 400 with duration 120, SetLeftOffset(5) moved it to -85995 and inflated the duration to 86515 frames: it extends the clip from source media, it does not nudge the edit point. Setting the offset back to 0 did not restore the original position (the clip stayed at -86000). There is no API-level undo.
MediaPool.AddToPhotoAlbumAdds nothing and returns an empty list. Tested four ways: immediately after CreateEmptyPhotoAlbum, with a 2 s pause, after an explicit SetCurrentPhotoAlbum that GetCurrentPhotoAlbum confirmed, and with a fresh album each time — zero photos every run. MediaPool.CreatePhotoAlbumFromPhotos VERIFIED working (photos land and read back), so use that.
Graph.ResetAllNodeColorsExists on a photo album item's graph but not on a timeline clip's graph (NoneType is not callable). Clearing a colour with SetNodeColor(i, "") works on both.
MediaPoolItem.GetNodeGraphNot callable on 21.1.2.10 (while TimelineItem.GetNodeGraph and PhotoAlbumItem.GetNodeGraph both work). Put the clip on a timeline and address it by item_id.
Project.UpdateRenderPresetReturns False for all 37 factory presets that GetRenderPresetList reports ('H.264 Master' included). Project.SaveRenderPreset does not exist in the API, so a user preset cannot be created from scripting to test against. GUI-dependent at best.
Project.SetQuickExportEnabledForRenderPresetSame shape: False for a factory preset.
MediaPoolItem.SetTranscriptionReturns False for a PNG still and for a real video clip with no transcript, with both '01:00:00:00' and '00:00:00:00' start timecodes. It replaces a transcript, so it appears unable to create one where none exists.
MediaPoolItem.SetClipColor (photo items)Returned False for 'Sky' on a photo album item while the colour list is documented; ClearClipColor works. The action reports the rejection rather than assuming success.
Folder.AddSubFolder / Folder.MoveClipsDo not exist. Both live on MediaPool (mp.AddSubFolder(parent, name), mp.MoveClips(clips, folder)) — verified that MoveClips really relocates the clip and returns True, not a false success. Same object-split as the photo-album API.
TimelineItem.SetProperty("PositionX"/"PositionY")Silently ignored — both the setter and the getter return False. Use Pan / Tilt (pixels, +x right, +y up). This is what broke the project's own grid scripts: zoom applied, positions never did.
TimelineItem.AddMarker(0) on the clip at timeline position 0Returns True and writes nothing — tl.GetMarkers() shows the count unchanged and no marker by that name. Timeline.AddMarker(0) works. Markers are therefore placed through the timeline, never through the item. An earlier release blamed Timeline.AddMarker; that was the same bad setup as above.
AppendToTimeline with recordFrame below StartFrameSilently accepted. Passing 0/200/400 on a timeline that starts at 86400 places the clips at 0/200/400 — outside the timeline's own range — and the timeline's metadata is not reconciled: it reports StartFrame == EndFrame (duration 0) while holding three clips. It survives SetProperty, closing and reopening. On such a timeline DeleteGaps and SetLeftOffset do nothing and Timeline.ExportFrame refuses every offset, so it looks like three broken APIs. Assert recordFrame >= GetStartFrame().
AppendToTimeline with startFrame == endFrameReturns None and places nothing. With single-frame media (GetClipProperty("Frames") == "1") the natural endFrame is 0, so a "correct" 0..0 range silently fails. Omitting endFrame lets Resolve use the whole clip and works.

Gotchas

  • TimelineItem.GetProperty("Position") returns a bool on 21.1.2, not coordinates. The position lives in Pan / Tilt (x/y in pixels). RotationAngle is degrees, Opacity 0–100, crop values 0–1, ZoomX/Y a multiplier. All are writable — verify with a read-back.
  • Setting a timeline's SetIsEnabled(False) makes GetCurrentTimeline() return None, so every later call reports "No current timeline" until it is switched back on in the GUI.
  • MediaPoolItem.GetParentFolder is only useful with a recursive walk of the media pool: ImportMedia drops clips into the currently selected bin, so a root-only lookup reports "not found" while the clip exists one level down.

Testing

Two layers, because DaVinci Resolve cannot run in CI.

Offline — no Resolve needed, this is what CI runs

bash
python tests/test_offline.py

Checks that server.py imports without Resolve present (so pip install followed by resolve-ext --help cannot fail), that all ten tools register, that the CLI returns the right exit codes, and that the platform path resolution produces the correct paths for the OS it finds itself on. Runs on Windows, macOS and Linux — see .github/workflows/test.yml.

Live — needs a running Resolve Studio

bash
python tests/test_e2e.py        # core toolspython tests/test_phase1.py     # photo albums + node graphpython tests/test_extras.py     # render presets, audio formats, transcriptionpython tests/test_camera.py     # camera layouts, labels, markers, sorting
# point at your own media if ~/Pictures has fewer than 3 PNGsRESOLVE_EXT_TEST_MEDIA="D:/stills/*.png" python tests/test_camera.py

162 assertions, 0 failures against Resolve Studio 21.1.2.10 (30 offline + 132 live).

Each suite creates its own scratch project, exercises the tools and deletes it again — they never touch your other projects. Two habits are deliberate:

  • Assertions check that values changed and read back, not merely that no error was returned. A write test that passes because nothing moved proves nothing; that is exactly how DeleteGaps and AddToPhotoAlbum were caught reporting success while doing nothing.
  • Known-broken calls are asserted to fail honestly. If a future Resolve build fixes AddToPhotoAlbum, its test will start failing — which is the signal to re-measure and update this README, not a broken test.

Design notes

  • Extension, not fork. Nothing here duplicates a mainstream server's surface, so both can run side by side without the model having to choose.
  • Broken APIs are reported, not hidden. Where Resolve's own call lies (DeleteGaps returning True), the tool says so with the measurement attached, rather than emitting a success the caller cannot trust.
  • Destructive APIs are not exposed. SetLeftOffset cannot be undone through the API, so it stays out of the surface and get remains read-only.

Requirements

  • DaVinci Resolve Studio 21.1.2+ (earlier builds lack these symbols)
  • Windows / macOS / Linux wherever the Resolve scripting API is available
  • Python 3.10+ and mcp[cli]>=1.30,<2

License

MIT — see LICENSE.

来源:README.md,提交 351bb7a

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

2
  1. v1.0.2最新Nov 7, 2026
  2. v1.0.1Nov 3, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

其他 Resolve 集成