# ResolveMCP-ext (pypi · resolve-ext)

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

- Trust score: 58/100 (low)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-04

## Components

- pypi · `resolve-ext`: 58/100 (this document), [markdown](https://verifymcp.io/servers/captrauti-resolve-ext/resolve-ext.md), [page](https://verifymcp.io/servers/captrauti-resolve-ext/resolve-ext)

## Channel facts

- Registry: `pypi`
- Package: `resolve-ext`
- Version: `1.0.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-04.

- **Supply Chain Security**: 44/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Declares code that runs automatically (build-time code we could not rule out (a Hatch, PDM or setuptools build hook, a dynamic version we could not read statically, shipped VCS metadata or a stray root module)) and that we could not recognise. It may be perfectly ordinary, but we have not established what it does.
  - 0 of 28 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to CaptRauti/ResolveMCP-ext).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 1 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 54/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 4934 tokens (~493/item across 10 items; 10 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 71/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 10 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 10 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the ResolveMCP-ext MCP server?

ResolveMCP-ext runs locally as a PyPI package, launched with uvx resolve-ext. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add captrauti-resolve-ext -- uvx resolve-ext
```

### Cursor

```json
{
  "mcpServers": {
    "captrauti-resolve-ext": {
      "command": "uvx",
      "args": [
        "resolve-ext"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "captrauti-resolve-ext": {
      "command": "uvx",
      "args": [
        "resolve-ext"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add captrauti-resolve-ext -- uvx resolve-ext
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "captrauti-resolve-ext": {
      "type": "local",
      "command": [
        "uvx",
        "resolve-ext"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add captrauti-resolve-ext --command uvx --arg resolve-ext
```

### Hermes

```yaml
mcp_servers:
  captrauti-resolve-ext:
    command: "uvx"
    args: ["resolve-ext"]
```

### Netclaw

```json
{
  "McpServers": {
    "captrauti-resolve-ext": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "resolve-ext"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add captrauti-resolve-ext -t stdio -c uvx -a resolve-ext
```

### Other

```json
{
  "mcpServers": {
    "captrauti-resolve-ext": {
      "command": "uvx",
      "args": [
        "resolve-ext"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 58, −15)

- [security regression] Malware scan: pass → unverified

### 2026-11-03 (score 73, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-11-02 (score 58)

First indexed and scored.

## MCP tools (10)

### `effects` (~432 tokens)

Clip effects and effect properties on TimelineItems (Resolve 21.1.2+).

The upstream server has no coverage for the 21.1.2 "Clip Effect Actions"
and "Effect Properties" APIs. This tool exposes them.

Actions:
  list_available(media_type?) -> {effects, count}
    — every effect Resolve can apply. media_type: 'video' (default),
      'photo' or 'audio'. Each entry: {category, id, name}.
      This is the lookup you need before apply().
      Example: find the id for a Fusion text+ via
      list_available(media_type="video").
  list_applied(item_id?|name?, track_type?, track_index?, category?)
    -> {effects, count}
    — effects currently ON a timeline item. category filters to
      'fusion' | 'ofx' | 'audio'; omit for all three.
  apply(item_id?|name?, category, id, track_type?, track_index?)
    -> {effect: {category,id,name,index,enabled}}
    — applies an effect to a timeline item. Get category+id from
      list_available().
  remove(item_id?|name?, indices?|category?, track_type?, track_index?)
    -> {removed: [...]}
    — removes effects from a timeline item. Either give explicit 1-based
      `indices` (with `category`), or `category` alone to remove every
      effect of that category.
  set_enabled(item_id?|name?, index, enabled, category?, track_type?,
              track_index?) -> {success, effect}
    — toggle one effect on/off by its index.
  reorder(item_id?|name?, index, new_index, category?, track_type?,
          track_index?) -> {success, effects}
    — move an effect to another position in its category's stack.

Addressing a timeline item: give `item_id` (GetUniqueId) — or `name`
plus the track it sits on. Track defaults are video/1.

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `clip_attrs` (~346 tokens)

Copy clip attributes between timeline items (Resolve 21.1.2+).

\`TimelineItem.CopyAttributes` is the API behind Edit-page Paste Attributes.
It is what makes a per-camera look repeatable: grade one clip, then push
the same attributes onto every other clip of that camera.

Actions:
  options() -> {groups}
    — the full option vocabulary, grouped, from Resolve's own type stubs.
  copy(source_id?, source_name?, target_ids?, target_names?, options,
       copy_all_video?, copy_all_audio?, track_type?, track_index?)
    -> {success, copied_to, options_used}
    — copy attributes from one source item onto one or more targets.
      `options` is a dict of the flags from options(); a true value means
      copy that attribute. Shorthands:
        copy_all_video=true -> allVideoAttributes
        copy_all_audio=true -> allAudioAttributes
      Common per-camera case:
        {"colorCorrection": true, "allZoomAttributes": true,
         "allCropAttributes": true, "videoPlugins": true}
  read(item_id?|name?, track_type?, track_index?) -> {attributes}
    — the readable video attributes of an item (position, zoom, crop,
      opacity, rotation, composition mode), so you can see what a copy
      would carry.

Notes:
  \- Targets are addressed by `target_ids` (GetUniqueId list) or
    `target_names` (exact names on one track). Pick one form.
  \- CopyAttributes needs the source and targets on the SAME timeline.

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `resolve_ext_status` (~53 tokens)

Health check for the resolve-ext server and its Resolve connection.

Reports whether Resolve is reachable, which product/version is live,
whether a project is open, and which of this server's surfaces are
usable on that build.

Output parameters:

- `result` (object)

### `clip_position` (~511 tokens)

Inspect clip placement, handle offsets, gaps and timeline enable state.

\**SetPosition / MoveItems are BROKEN on Resolve 21.1.2.10** — measured to
return False for every input (real clips and stills, int and float
startFrame, even a no-op), while other write APIs work in the same
session. `set` and `move` therefore report an honest error rather than
pretending to have moved anything. Use `get` to plan, and reposition in
the Edit page by hand.

Actions that DO work:
  get(item_id?|name?, track_type?, track_index?) -> {position, left_offset,
                                                     right_offset, start, end}
    — where an item sits and how many frames of handle it offers. This is
      the read you need before deciding a trim. READ-ONLY, safe.
  enabled() -> {enabled}
    — read the timeline's enabled state. Setting it (enabled=true/false)
      works but turns the timeline non-current, so later calls report
      'No current timeline' until it is switched back in the GUI.

Actions DISABLED or exposing a broken API on this build:
  set(start_frame?|new_track_index?) — SetPosition returns False for every
    input, including no-ops.
  move(items=[…]) — same broken call per item.
  set_offset(left?|right?) — SetLeftOffset does NOT nudge the edit point:
    it EXTENDS the clip from source media. Measured: a clip at frame 400
    with duration 120 became start=-85995, duration=86515 after
    SetLeftOffset(5), and could not be restored by setting 0.
  delete_gaps() — closes the gaps between clips so they sit back to back.
    **Verified working** on a timeline whose StartFrame/EndFrame agree with
    its contents. It appeared to be a silent no-op in an earlier release;
    that measurement ran on a timeline whose metadata contradicted its
    contents (StartFrame == EndFrame while holding three clips). The action
    compares the clip starts before and after and reports the real outcome
    either way.

Addressing: `item_id` (GetUniqueId) or `name` on a track…

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `export_frame` (~490 tokens)

Export a frame as a still — from a timeline, a clip, or the media pool.

Resolve 21.1.2 added ExportFrame on Timeline, TimelineItem and
MediaPoolItem. The upstream server's frame capture goes through a render
or a Gallery still; this is the direct call.

Actions:
  item(item_id?|name?, frame_offset?, output_type?, file_path?, format?,
       max_dimension?, track_type?, track_index?)
    — TimelineItem.ExportFrame. **This is the one that works.** Offset is
      0-based from the ITEM start and must be < the item's duration
      (verified: 0..119 succeed on a 120-frame item, 120+ is refused).
  media(clip_id, frame_offset?, output_type?, file_path?, format?,
        max_dimension?)
    — MediaPoolItem.ExportFrame. Also verified working; offset is 0-based
      from the SOURCE start, ignoring the timeline.
  timeline(frame_offset, …)
    — Timeline.ExportFrame. Offset is **0-based from the TIMELINE start**
      (`StartFrame`), valid `0 .. (EndFrame - StartFrame - 1)`.
      Verified on 21.1.2.10 against a 480-frame timeline: offsets 0..479
      succeed, 480 is refused with 'frameOffset is out of range'.
      An absolute frame (e.g. the value from `GetStartFrame()`) is ALWAYS
      refused, which reads like a failure but is correct behaviour. An
      earlier release documented that rejection as a defect; that was a
      wrong measurement on an empty timeline, corrected here.

Parameters:
  output_type  'file' (needs file_path) or 'encodedString' (default).
  file_path    Output path; format is inferred from the extension.
  format       'jpg' (default) or 'png' — only for output_type
               'encodedString'.
  max_dimension  Cap the longer edge in pixels (default 0 = full size).

Returns for output_type='file': {success, path, bytes}.
Returns for 'encodedString': {saved_to} — the base64 is decoded and
written to <server dir>/out/, with only a short prefix returned inline.

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `folder_ops` (~166 tokens)

Folder hierarchy lookups the upstream server does not expose.

Actions:
  parent_of_clip(clip_id) -> {name, id, path}
    — which bin a media pool clip lives in (MediaPoolItem.GetParentFolder).
  parent_of_folder(path?|folder_id?) -> {name, id, path} | {root: true}
    — a folder's parent (Folder.GetParentFolder). The root folder has none.
  path(clip_id?|folder_id?) -> {path, segments}
    — the full "Master/Sub/Bin" path of a clip or folder.
  find_clip(clip_id) -> {name, folder_path}
    — locate a clip by id anywhere in the tree.

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `photo_albums` (~878 tokens)

Photo albums and their items (Resolve 21.1.2+).

A photo album is the stills/photo counterpart of a timeline: an ordered set
of photo items, each with its own grade, flags, rating and versions.
Measured on 21.1.2.10 this whole area works — 9/9 PhotoAlbum methods and
20/20 PhotoAlbumItem methods answered.

The API is split across objects and the split is NOT documented: the album
\*listing* methods live on Project, while creating/adding lives on MediaPool,
and Resolve itself answers none of them. This tool resolves the right object
at call time, so it keeps working if a build moves them.

Albums:
  list() -> {albums, count}
  current() -> {album|None}
  set_current(album_id?|name?) -> {success, album}
  create(name) -> {album}
  create_from_photos(name, clip_ids) -> {album}
    — THE RELIABLE WAY to get photos into an album: VERIFIED working
      (added 2 photos, read back). Prefer this over add_photos.
  delete(album_ids?) -> {success, deleted}
  rename(album_id?|name?, new_name) -> {success, album}
  quick_export_presets() -> {presets}
  render_settings(settings?) -> {settings}

Photos inside an album:
  photos(album_id?|name?) -> {photos, count}
  add_photos(clip_ids, album_id?|name?) -> {added, count}
    — BROKEN on 21.1.2.10: AddToPhotoAlbum adds nothing and returns an
      empty list. This action verifies by reading the album back and
      reports the failure with the measurement instead of a false success.
      Use create_from_photos instead (verified working).
  remove_photos(photo_ids, album_id?|name?) -> {success, remaining}
  current_item(album_id?|name?) -> {photo|None}

Per-photo properties (address a photo by photo_id, or by name inside an
album):
  photo(photo_id|photo_name?, album_id?|name?) -> {photo}
  rate(photo_id|photo_name?, stars) -> {success, rating}
  flag(photo_id|photo_name?, color?|clear?) -> {success, flags}
  clip_color(photo_id|photo_name?, color?|clear?) -> {success, clip_color}
  versions(photo_id|photo_name?) -> {versions, curre…

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `node_graph` (~431 tokens)

Node graph inspection and labelling, on a clip or a photo (21.1.2+).

Verified working on 21.1.2.10: GetNodeLabel, SetNodeLabel, GetNodeColor,
SetNodeColor, SetNodeEnabled, GetNumNodes, ResetAllGrades, ResetAllNodeColors.
SetLUT/GetLUT returned False/None in testing (a LUT path is required and
must exist) — the tool reports what it gets rather than assuming.

Target: pass `item_id`/`name` for a timeline clip, or `photo_id` for a photo
album item. `clip_id` is accepted but NOT usable on 21.1.2.10:
MediaPoolItem.GetNodeGraph is not callable there, while the timeline and
photo variants both work.

Actions:
  info(item_id?|name?|photo_id?|clip_id?, track_type?, track_index?)
    -> {num_nodes, nodes: [{index, label, color, enabled}]}
  label(node_index, label, ...) -> {success, nodes}
    — SetNodeLabel. Pass an empty string to clear.
  color(node_index, color, ...) -> {success, nodes}
    — SetNodeColor. Valid names: Orange, Apricot, Yellow, Lime, Olive,
      Green, Teal, Navy, Blue, Purple, Violet, Pink, Tan, Beige, Brown,
      Chocolate. An empty string clears the color.
  enable(node_index, enabled, ...) -> {success, nodes}
  tools(node_index, ...) -> {tools}
    — which Fusion/OFX tools sit in that node.
  lut(node_index, lut_path?, ...) -> {success, lut}
    — read, or set when lut_path is given (Resolve's relative LUT path).
  cache(node_index, mode?, ...) -> {success, cache_mode}
  reset_colors(...) -> {success}
  reset_grades(...) -> {success}   — destructive: clears the whole grade.

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `project_extras` (~614 tokens)

Project-level gaps: render presets, audio render formats, transcription.

Three surfaces the mainstream servers do not implement, all verified
present on Resolve 21.1.2.10 by calling them (the type stubs list them, but
a stub only says a name exists — see CONTRIBUTING.md).

Render presets:
  render_presets() -> {presets}
    — GetRenderPresetList. Verified: returns the real list.
  update_render_preset(preset_name) -> {success, preset}
    — UpdateRenderPreset: overwrite a saved preset with the CURRENT render
      settings. MEASURED on 21.1.2.10: returns False for the 37 factory
      presets GetRenderPresetList reports (e.g. 'H.264 Master'), so this
      only has a chance against a preset saved from the Render page in the
      GUI. Project.SaveRenderPreset does NOT exist in the API, so a preset
      cannot be created from here to test with. Treat as GUI-dependent.
  quick_export_enable(preset_name, enabled) -> {success}
    — SetQuickExportEnabledForRenderPreset. Same limitation: False for
      factory presets on this build.

Audio render formats:
  audio_formats() -> {formats}
    — GetAudioRenderFormats: {display name -> file extension}.
  audio_codecs(format_extension) -> {codecs}
    — GetAudioRenderCodecs: {codec description -> codec name} for a format
      extension such as 'wav', 'mov', 'mxf'.

Transcription (a clip's speech-to-text content):
  transcription(clip_id, use_nested?) -> {transcription}
    — GetTranscription. `use_nested` reads a nested timeline's transcript.
  set_transcription(clip_id, transcription) -> {success, verified}
    — SetTranscription. REPLACES an existing transcript. MEASURED on
      21.1.2.10: returns False for a PNG still AND for a real video clip
      that had no transcript, with both '01:00:00:00' and '00:00:00:00'
      start timecodes — it appears unable to create a transcript where none
      exists. Produce one in the Edit page (AI Transcription) first, then
      this can replace it. The shape is:
        {languag…

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

### `camera_comparison` (~1013 tokens)

Lay out a multi-camera comparison timeline (Insta360 grid / split views).

Reproduces the camera-comparison workflow this project has been running as
loose scripts, with the position bug fixed.

\**The bug worth knowing:** those scripts set the image position with
\`SetProperty("PositionX", …)` / `"PositionY"`. MEASURED on 21.1.2.10 those
keys return **False and are silently ignored** — `GetProperty` gives back
\`False` too. The real keys are **`Pan`** (x, +right) and **`Tilt`** (y,
\+up), in pixels. Zoom worked in those scripts; positioning never did. This
tool uses Pan/Tilt and verifies each write by reading it back.

Camera detection from the clip name, longest prefix first:

  ace*   -> Insta360 AcePro       (marker Orange)
  go*    -> Insta360 Go Ultra     (marker Green)
  luna*  -> Insta360 Luna Ultra   (marker Cyan)
  x*     -> Insta360 X5           (marker Blue)
  vid_*  -> Handy                 (marker Gray)
             (an Android file, e.g. VID_20260614_170228.mp4)

Actions:
  detect(track_type?, track_index?) -> {clips: [{name, id, camera}], unknown}
    — what this timeline holds and which camera each clip is. Run this
      first: it tells you whether the names match the convention.
  grid_2x2(track_type?, track_index?, scale?, verify?)
    -> {applied, skipped, layout}
    — place the four cameras in a 2x2 quadrant grid. Quadrant centres are
      at ±25 % of each axis; default scale 0.5.
  split_h / split_v(track_type?, track_index?, scale?)
    -> {applied, layout}
    — two-up side by side (left/right) or stacked (top/bottom).
  layout(assignments, track_type?, track_index?, scale?)
    -> {applied, results}
    — explicit control. assignments maps a clip_id (or camera name) to
      {x?, y?, scale?}, where x/y are fractions of the timeline raster
      (+x right, +y up) and scale multiplies the 1.0 zoom.
  fullframe(clip_ids?|cameras?, track_type?, track_index?)
    -> {reset}
    — back to 1.0 zoom and centred, for the "phone as full picture" clip.…

Input parameters:

- `action` (string, required)
- `params`

Output parameters:

- `result` (object)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/captrauti-resolve-ext/resolve-ext#diagnostics

## Score history

- 2026-11-04: 58
- 2026-11-03: 73
- 2026-11-02: 58

## Common questions

### What is the ResolveMCP-ext MCP server?

ResolveMCP-ext is an MCP server listed in the public MCP registry as io.github.CaptRauti/resolve-ext. Resolve MCP gaps: clip effects, Paste Attributes, frame export, photo albums, camera layouts. This page covers its PyPI package (resolve-ext).

### Is the ResolveMCP-ext MCP server safe to use?

ResolveMCP-ext scores 58 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 4 November 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the ResolveMCP-ext MCP server expose?

ResolveMCP-ext exposes 10 tools: effects, clip_attrs, resolve_ext_status, clip_position, export_frame, and 5 more. Their descriptions and schemas cost roughly 4,934 tokens of context every time the server is loaded.

### Is the ResolveMCP-ext MCP server still maintained?

ResolveMCP-ext is still listed as active in the MCP registry. We last reached this channel on 4 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the ResolveMCP-ext MCP server under?

ResolveMCP-ext declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/resolve-ext/
- Socket report: https://socket.dev/pypi/package/resolve-ext
- Repository: https://github.com/CaptRauti/ResolveMCP-ext
- Changelog RSS feed: https://verifymcp.io/servers/captrauti-resolve-ext/resolve-ext.xml
- Changelog JSON feed: https://verifymcp.io/servers/captrauti-resolve-ext/resolve-ext.json
- HTML version of this page: https://verifymcp.io/servers/captrauti-resolve-ext/resolve-ext
