# io.github.kumoproductions/mcp-cinema4d (npm · @kumoproductions/mcp-cinema4d)

MCP server for Cinema 4D — entity CRUD, parameter-level access, batched undo, security controls.

- Trust score: 75/100 (medium)
- Change this week: +51
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- npm · `@kumoproductions/mcp-cinema4d`: 75/100 (this document), [markdown](https://verifymcp.io/servers/kumoproductions-mcp-cinema4d/kumoproductions-mcp-cinema4d.md), [page](https://verifymcp.io/servers/kumoproductions-mcp-cinema4d/kumoproductions-mcp-cinema4d)

## Channel facts

- Registry: `npm`
- Package: `@kumoproductions/mcp-cinema4d`
- Version: `0.3.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-08-03.

- **Supply Chain Security**: 86/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (94 of 98), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (94 of 98), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to kumoproductions/mcp-cinema4d).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 47 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 59/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 10466 tokens (~166/item across 63 items; 63 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 23/100
  - Stability observed for 7 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 99/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 96% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add kumoproductions-mcp-cinema4d -- npx -y @kumoproductions/mcp-cinema4d
```

### Codex

```bash
codex mcp add kumoproductions-mcp-cinema4d -- npx -y @kumoproductions/mcp-cinema4d
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "kumoproductions-mcp-cinema4d": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@kumoproductions/mcp-cinema4d"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add kumoproductions-mcp-cinema4d --command npx --arg -y --arg @kumoproductions/mcp-cinema4d
```

### Hermes

```yaml
mcp_servers:
  kumoproductions-mcp-cinema4d:
    command: "npx"
    args: ["-y", "@kumoproductions/mcp-cinema4d"]
```

### Other

```json
{
  "mcpServers": {
    "kumoproductions-mcp-cinema4d": {
      "command": "npx",
      "args": [
        "-y",
        "@kumoproductions/mcp-cinema4d"
      ]
    }
  }
}
```

## 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-08-03 (score 75, +3)

- [functional improvement] Stability: unverified → 0.23

### 2026-08-02 (score 72, +63)

- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security improvement] Provenance: unverified → pass
- [security improvement] Malware scan: unverified → pass
- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [security] The attested source repository moved: kumoproductions/mcp-cinema4d
- [functional regression] Dependency health: partial → unverified
- [functional regression] Security disclosure: fail → unverified
- [functional improvement] Schema quality: unverified → good
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] License: unverified → pass
- [functional improvement] Tool coverage: unverified → 100
- [functional] Licence: MIT

### 2026-08-01 (score 9, −10)

- [functional regression] Tool coverage: 100 → unverified
- [functional improvement] Dependency health: unverified → partial

### 2026-07-31 (score 19, −6)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 25, −18)

- [security regression] Malware scan: pass → unverified

### 2026-07-28 (score 43, +19)

- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Schema quality: unverified
- [functional] First check of Schema quality: fail
- [functional] First check of Tool coverage: 96
- [functional] First check of Schema quality: fail

### 2026-07-27 (score 24)

First indexed and scored.

## MCP tools (63)

### `ping` (~18 tokens)

Ping C4D

Check connectivity to the Cinema 4D bridge plugin.

### `render` (~94 tokens)

Render Active Document

Render the active Cinema 4D document at its currently-active render data settings. To change resolution / renderer / frame range / etc., adjust the active RenderData first via `create_render_data` (with `update_if_exists:true` on the active RD) or `set_params`. May take up to 60 seconds.

Input parameters:

- `output_path` (string): Optional absolute path to write the rendered image. Defaults to a temp file.

### `preview_render` (~316 tokens)

Preview Render (Viewport, Constant Lines)

Quick agent-friendly verification render. Uses the Viewport renderer with the active editor view temporarily switched to Constant Shading (Lines) — sketch-style and fast. Independent of the active RenderData (built freestanding, never inserted) and restores BaseDraw / camera / time / take in finally. Returns a base64 PNG inline so the agent can directly view it. Use `view: top|bottom|left|right|front|back` for an auto-framed temp camera, or `camera` to render through a named scene camera. Pass `save_path` to also write the PNG to disk.

Input parameters:

- `camera` (string): Optional scene camera object name. Mutually exclusive with a non-'current' view.
- `frame` (integer): Optional frame number; defaults to the current document time.
- `height` (integer): Output height in pixels (default 1024, max 4096).
- `save_path` (string): Optional absolute PNG path. When set, the rendered image is also written to disk (parent directory must already exist). The base64 PNG is still returned inline.
- `take` (string): Optional take name to switch to before rendering. Restored afterward.
- `view` (string): Preset view. 'current' (default) uses the active BaseDraw camera. The other presets place a temp camera looking at the scene bounds from that side; the temp camera is removed in finally.
- `width` (integer): Output width in pixels (default 1024, max 4096).

### `reset_scene` (~139 tokens)

Reset Active Scene

Clear scene state in one RPC. With `prefix` (e.g. 'e2e_') removes only objects / materials / non-active render data / non-main takes whose name starts with the prefix, then flushes the undo buffer — cheap cleanup for test suites. Without prefix, swaps the active document for a fresh empty BaseDocument (everything goes). Much faster than chained remove_entity calls when cleanup involves animated objects.

Input parameters:

- `keep_active_rd` (boolean): Prefix-mode only: protect the currently-active RenderData from deletion. Default true.
- `prefix` (string): Only remove entities whose name starts with this prefix. Omit for full reset.

### `call_command` (~150 tokens)

Call C4D Command

Invoke a Cinema 4D command by plugin id via c4d.CallCommand(). Works for built-in commands (render, save, make editable, ...) and any registered command plugin.

Input parameters:

- `command_id` (integer, required): Cinema 4D command id. Examples: 12099 = Render to Picture Viewer, 12161 = Save Document, 12236 = Make Editable, 12168 = New Document. Use list_plugins (plugin_type="command") to discover.
- `subid` (integer): Optional sub-id (rarely needed).
- `timeout_ms` (integer): Request timeout in ms (default 60000). CallCommand often runs synchronously; increase for long-running ones like Render.

### `list_plugins` (~197 tokens)

List C4D Plugins (Any Type)

Generalized plugin enumerator. Pass plugin_type (e.g. "material", "shader", "video_post", "command") or a raw int to FilterPluginList. Each entry includes "plugin" (parent folder of the binary, e.g. "OctaneRender 1.7.1") and "plugin_file" (binary basename) for host-plugin attribution. Filter results by name_pattern and/or plugin_pattern regex.

Input parameters:

- `name_pattern` (string): Optional regex applied to plugin display name (e.g. "octane|convert").
- `plugin_pattern` (string): Optional regex matched against the host plugin folder or binary filename (e.g. "octane" → "OctaneRender 1.7.1"). Useful for commands whose display name does not include the plugin brand.
- `plugin_type`: Plugin category: string alias or raw c4d.PLUGINTYPE_* integer. Defaults to 'command'.

### `undo` (~75 tokens)

Pop Undo Stack

Pop up to `steps` entries off the active document's undo stack via doc.DoUndo. Stops early if the stack empties. Returns `steps_performed` so callers can tell when fewer steps were available than requested. Default: 1 step.

Input parameters:

- `steps` (integer): Number of undo steps to perform (default 1).

### `batch` (~102 tokens)

Batch Execute

Run many generic ops in one RPC. Each op is applied in order; by default failures are recorded per op and the batch continues. The whole batch is wrapped in a single undo group. Useful for 'apply X to all matching entities' workflows (pair with list_entities + name_pattern to get handles).

Input parameters:

- `ops` (array, required): Operations to execute in order.
- `stop_on_error` (boolean): Abort on first error (default false — errors are collected per op).

### `list_entities` (~424 tokens)

List C4D Entities

Enumerate scene entities of a given kind. Returns compact summaries (name, type_id, type_name, plus kind-specific fields — `is_active` for take / material / render_data). For kind=object also supports type_ids / tag_types / max_depth filters and include_tags / include_params to read data inline — so you can find 'all cubes with a Ttexture tag and their position in one call' without falling back to exec_python. Use this first to find what exists before `describe`/`set_params`. **Note:** kind=shader walks classical shader chains; for node-material graphs use `list_graph_nodes`.

Input parameters:

- `include_params` (array): (kind=object) Parameter ids to read per match. Returned under `params: {param_id: value}`.
- `include_tags` (boolean): (kind=object) Attach `tags: [{type_id, type_name, name}, ...]` to each match.
- `kind` (string, required): Entity kind to list.
- `max_depth` (integer): (kind=object) Skip objects deeper than this (root=0). Default: unlimited.
- `name_pattern` (string): Optional regex to filter results by name (e.g. "^VFX_Shot00[2-9]$").
- `object` (string): Filter tags to this object name (only for kind=tag). Omit to list tags on all objects.
- `object_path` (string): Filter tags to this object path (only for kind=tag). Use when the name is not unique.
- `owner`: Owner handle (required for kind=shader).
- `render_data` (string): Render data name (required for kind=video_post).
- `tag_types` (array): (kind=object) Keep only objects carrying a tag whose type id is in this set (e.g. [5616] for Ttexture).
- `type_ids` (array): (kind=object) Keep only objects whose GetType() is in this set (e.g. [5159] for cubes).

### `describe` (~268 tokens)

Describe C4D Entity

Dump all description parameters (id, name, cycle enum, current value) of a C4D entity resolved by handle. Use this to discover parameter IDs before reading/writing.

Input parameters:

- `handle` (required): C4D entity handle. Shapes: {kind:"object",name?|path?}, {kind:"render_data",name}, {kind:"take",name}, {kind:"material",name}, {kind:"tag",object?|object_path?,type_id?,tag_name?}, {kind:"video_post"…

### `get_params` (~363 tokens)

Get Parameter Values

Read parameter values on a C4D entity by id or DescID path. Each id may be: an int (top-level), a list [a, b, …] (chained DescID; dtypes inferred from the description), or contain 'x'/'y'/'z' for vector sub-components (e.g. [903, 'x'] = position.x). For explicit dtypes use [[id, 'real|long|bool|vector'], …]. Returns `{values: [{path, value}]}` in request order. Discover ids via `describe`.

Input parameters:

- `handle` (required): C4D entity handle. Shapes: {kind:"object",name?|path?}, {kind:"render_data",name}, {kind:"take",name}, {kind:"material",name}, {kind:"tag",object?|object_path?,type_id?,tag_name?}, {kind:"video_post"…
- `ids` (array, required): List of parameter paths to read.

### `set_params` (~334 tokens)

Set Parameter Values

Atomically write parameter values (wrapped in one undo). Each entry is `{path, value}` where `path` is either an int id or a DescID path (e.g. [903, 'x'] = position.x). Lists of 3 numbers auto-coerce into c4d.Vector for vector-typed destinations. Returns `{applied: [{path, value}], errors: [{path, error}]}`.

Input parameters:

- `handle` (required): C4D entity handle. Shapes: {kind:"object",name?|path?}, {kind:"render_data",name}, {kind:"take",name}, {kind:"material",name}, {kind:"tag",object?|object_path?,type_id?,tag_name?}, {kind:"video_post"…
- `values` (array, required): Writes to apply. Wrapped in an undo group.

### `get_container` (~309 tokens)

Dump Raw BaseContainer

Dump the raw BaseContainer of a C4D entity (including hidden keys that don't show up in `describe`, e.g. Octane AOV shader slots at 3740/3741). Filter by key range to narrow output.

Input parameters:

- `handle` (required): C4D entity handle. Shapes: {kind:"object",name?|path?}, {kind:"render_data",name}, {kind:"take",name}, {kind:"material",name}, {kind:"tag",object?|object_path?,type_id?,tag_name?}, {kind:"video_post"…
- `id_from` (integer): Inclusive lower bound for container keys.
- `id_to` (integer): Inclusive upper bound for container keys.

### `dump_shader` (~426 tokens)

Dump Shader Tree

Recursively dump a shader (resolved from a handle) into JSON. **Classical materials only** — node materials (Standard node space / Redshift / etc.) expose their shading as a maxon node graph; use `list_graph_nodes` / `apply_graph_description` for those instead. Captures type_id / type_name / name per node; promotes c4d.Xbitmap paths to a "file" field; heuristically surfaces image-like strings hiding in other shader BaseContainers as "file_candidates"; and expands shader links stored inside the container as "linked_shaders" (the shape used by Fusion / Colorizer whose internals don't appear via GetDown). Pair with list_entities kind=shader to discover shader handles.

Input parameters:

- `handle` (required): C4D entity handle. Shapes: {kind:"object",name?|path?}, {kind:"render_data",name}, {kind:"take",name}, {kind:"material",name}, {kind:"tag",object?|object_path?,type_id?,tag_name?}, {kind:"video_post"…
- `max_depth` (integer): Maximum recursion depth (default 5). 0 returns only the root node.

### `create_entity` (~381 tokens)

Create C4D Entity

Unified constructor for object / tag / material / shader / video_post. Handles parent linking, optional params, positions, and container slot assignment in one call. Returns the handle of the created entity (object handles include `path` for stable re-resolution) so you can chain set_params / set_keyframe. Note: `kind:"shader"` targets classical shader chains (Fusion, Colorizer, Xbitmap, …). For node-material edits (Standard node space / Redshift), use `apply_graph_description` instead. `kind:"video_post"` attaches a renderer effect (Octane 1029525, Redshift 1036219, Magic Bullet Looks 1054755, …) to a RenderData parent.

Input parameters:

- `kind` (string, required): Entity kind to create.
- `name` (string): Optional display name.
- `params` (object): {param_id: value} to set after allocation. Lists of 3 numbers become Vectors.
- `parent`: Parent handle. Required for tag (owner object), shader (owner VideoPost / tag / material) and video_post (owner render_data). Optional for object (creates at scene root if omitted).
- `position` (array): Relative position [x,y,z] (objects only).
- `slots` (array): Owner BaseContainer slot ids to link the new shader into (e.g. [3740, 3741] for Octane AOV).
- `type_id` (required): Plugin id. Accepts a numeric id (c4d.Ocube=5159, c4d.Ttexture=5616, Octane renderer=1029525, …) or, for kind='object', an alias string: 'cube', 'sphere', 'cylinder', 'cone', 'torus', 'plane', 'disc',…

### `remove_entity` (~27 tokens)

Remove C4D Entity

Delete the resolved entity (wrapped in an undo step).

Input parameters:

- `handle` (required): Entity to delete.

### `set_keyframe` (~228 tokens)

Set Keyframe

Create or update a single keyframe on a resolved entity's parameter. Supports scalar (real/long/bool) and vector (x/y/z component) parameters; the bridge infers the dtype from the entity's description, or you can override it explicitly. Creates the CTrack automatically on first use.

Input parameters:

- `component` (string): Sub-component for Vector params. For C4D rotation (HPB) use "x" for H, "y" for P, "z" for B.
- `dtype` (string): Override the dtype when description lookup fails (rare).
- `fps` (integer): Time base override (default: doc fps).
- `frame` (integer, required): Frame number.
- `handle` (required): Entity whose parameter gets the keyframe.
- `interp` (string): Key interpolation (default "spline").
- `param_id` (integer, required): Top-level description id (e.g. c4d.ID_BASEOBJECT_REL_ROTATION = 904).
- `value` (required): Value at this frame (rotations in radians; bools coerce to 0/1).

### `set_document` (~140 tokens)

Set Document Settings

Update document-level settings: fps, frame range, current frame, active camera, active take. FPS and frame range are also mirrored onto the active render data.

Input parameters:

- `active_camera` (string): Name of the camera object to set as scene camera.
- `active_take` (string): Name of the take to make current (Main is always valid).
- `current_frame` (integer): Move playhead to this frame.
- `fps` (integer): Document FPS (also mirrored to active render data).
- `frame_end` (integer): Document max time / loop-max in frames.
- `frame_start` (integer): Document min time / loop-min in frames.

### `import_scene` (~145 tokens)

Import / Merge Scene File

Merge an external file (abc/fbx/obj/c4d/etc.) into the active document via MergeDocument. Returns the newly-imported top-level objects so they can be chained with set_params / create_entity / create_take. Optionally re-parents them under an existing object and renames the first root.

Input parameters:

- `filter` (string): Scene filter (default "all").
- `parent`: Optional parent handle — newly-imported top-level objects are moved under this object.
- `path` (string, required): Absolute path to the file to merge (abc/fbx/obj/c4d/...).
- `rename` (string): Optional new name for the first imported top-level object.

### `create_render_data` (~252 tokens)

Create Render Data

Create (or update-if-exists) a RenderData with resolution / renderer / fps / frame range in one call. Returns the render_data handle for subsequent create_take / set_params chaining.

Input parameters:

- `fps` (integer): Frame rate (also disables Use Project Frame Rate).
- `frame_end` (integer): Frame range end.
- `frame_sequence` (string): Frame range mode (default "manual" when frame_start/end given).
- `frame_start` (integer): Frame range start.
- `height` (integer): Output height (pixels).
- `make_active` (boolean): Make this the active render data.
- `name` (string, required): Render data name (used as handle).
- `params` (object): Extra {param_id: value} to apply (any RDATA_* id).
- `parent` (string): Parent render_data name to nest under (default: top level).
- `renderer`: Renderer plugin id, or alias: "octane"/"standard"/"physical"/"redshift"/"cycles"/"viewport".
- `update_if_exists` (boolean): If a render data with this name already exists, update it instead of creating.
- `width` (integer): Output width (pixels).

### `create_take` (~215 tokens)

Create / Update Take

Create or update a Take (AddTake + SetCamera + SetRenderData + SetChecked) in one call. New takes are checked by default so they participate in batch renders; pass `checked:false` to override. Returns the take handle — ideal for building per-shot take stacks programmatically.

Input parameters:

- `camera` (string): Object name to link as the take's camera override.
- `checked` (boolean): Checked state for batch rendering (default true on create).
- `clear_camera` (boolean): Explicitly clear the camera override.
- `clear_render_data` (boolean): Explicitly clear the render data override.
- `make_active` (boolean): Make this take the current take.
- `name` (string, required): Take name (used as handle).
- `parent` (string): Parent take name (default: Main).
- `render_data` (string): Render data name to link as the take's render settings override.
- `update_if_exists` (boolean): If a take with this name already exists, update it instead of creating.

### `take_override` (~193 tokens)

Write Take Parameter Overrides

Write per-Take parameter overrides onto a target node (object / tag / material / render_data / video_post / shader). Wraps `take.OverrideNode + UpdateSceneNode + override[descid] = value`. Use this for shot-by-shot variations that share a single scene (e.g. override Focal Length per Take while one Camera is reused). Paths use the same syntax as `set_params`.

Input parameters:

- `clear` (array): Paths to drop from the override (parameter reverts to scene value).
- `params` (object): Shorthand {pid: value} for flat writes (applied after `values`).
- `remove_all` (boolean): Drop the entire override for this target on this Take.
- `take` (string, required): Take name (must not be Main).
- `target` (required): Handle of the node to override.
- `values` (array): Override writes — same path syntax as set_params.

### `sample_transform` (~161 tokens)

Sample Object Transform at Frames

Evaluate the scene at each requested frame and return the object's transform. Useful to verify alembic / constraint / xpresso-driven animation without writing a bespoke exec_python sampler.

Input parameters:

- `format` (string): Output format: "off_rot" returns pos+rot(HPB radians); "matrix" returns 4x3 rows.
- `fps` (integer): Time base override (default: doc fps).
- `frames` (array, required): Frames to sample (1..500). The scene is evaluated at each frame via ExecutePasses.
- `handle` (required): Target object handle (must resolve to a BaseObject).
- `restore_time` (boolean): Restore the original playhead after sampling (default true).
- `space` (string): Transform space (default "global").

### `get_selection` (~68 tokens)

Get Active Selection

Read the active document's current selection: the active object (primary), all selected objects, and the active tag / material. Useful for reacting to the user's current focus without asking them to re-pick entities. Returns canonical handles so results can be piped directly into describe / set_params / etc.

### `set_selection` (~154 tokens)

Set Active Selection

Replace or extend the active document's selection. Pass `objects` (first becomes the active object), `tag`, or `material`. With `mode:'add'` the listed objects are added to the existing selection; with `mode:'replace'` (default) the prior selection is cleared first. `clear:true` deselects everything and ignores other fields.

Input parameters:

- `clear` (boolean): If true, deselect everything and ignore other fields.
- `material`: Material handle to set as active.
- `mode` (string): Applies to `objects`. Default 'replace'.
- `objects` (array): Object handles to select. The first becomes the active object.
- `tag`: Tag handle to set as active.

### `move_entity` (~190 tokens)

Move / Reparent / Reorder Node

Reparent a node under a new parent, promote it to the top of its hierarchy, or reorder it relative to a sibling. Works on objects, takes, and render_data — siblings/parents must share the moved node's kind. Exactly one destination field must be provided (`parent`, `before`, `after`, or `to_root:true`). For takes, `to_root:true` reparents under Main; the Main take itself cannot be moved. Returns the node's new canonical handle so follow-up edits remain stable.

Input parameters:

- `after`: Insert immediately after this sibling.
- `before`: Insert immediately before this sibling.
- `handle` (required): Node to move (object / take / render_data).
- `parent`: Insert as last child of this parent.
- `to_root` (boolean): Promote to the top of the hierarchy (objects → doc root, takes → under Main, render_data → top level).

### `clone_entity` (~166 tokens)

Clone Entity

Duplicate an entity. Supports object / tag / material / shader (via GetClone + parent insert), render_data (doc.InsertRenderData — copies VideoPosts too), video_post (rd.InsertVideoPost), and take (TakeData.AddTake, copying existing overrides). Objects default to dropping next to the source; pass `parent` to place the clone elsewhere. Returns a handle to the new entity.

Input parameters:

- `handle` (required): Source entity to clone.
- `name` (string): Optional name for the clone.
- `parent`: For objects: destination parent (defaults to source's sibling). For tags: required owner object. For shaders: required owner. For video_post: target render_data (defaults to source's host). For take:…

### `modeling_command` (~202 tokens)

Modeling Command

Run a Cinema 4D modeling operation via c4d.utils.SendModelingCommand on one or more target objects. Commands that produce new geometry (Current State to Object, Connect / Join, Split, Explode Segments) return handles to the inserted results; in-place commands (Make Editable, Subdivide, Triangulate, …) return the mutated targets. Aliases: current_state_to_object / cso, make_editable, connect / join, connect_delete, subdivide, triangulate, untriangulate, reverse_normals, align_normals, optimize, center_axis, split, explode_segments, melt, collapse, dissolve.

Input parameters:

- `command` (required): Alias (see description) or raw MCOMMAND_* integer.
- `mode` (string): MODELINGCOMMANDMODE_* selector. Default 'all'.
- `params` (object): Optional BaseContainer params for the command (e.g. subdivision level).
- `targets` (array, required): Target object handles.

### `get_mesh` (~188 tokens)

Get Mesh

Read points and polygons (or spline segments) from an editable PointObject / PolygonObject / SplineObject. Primitives (Cube, Sphere, …) must be converted first via `modeling_command` make_editable. Triangles are returned as [a,b,c] (c==d in C4D storage), quads as [a,b,c,d]. Point and polygon counts are capped to 50,000 by default to protect JSON payload size — override via max_points / max_polys.

Input parameters:

- `handle` (required): Target object (must be editable).
- `include` (array): Optional extras. 'normals' adds phong-shaded vertex normals. 'selections' adds `point_selection` / `poly_selection` / `edge_selection` index lists.
- `max_points` (integer): Default 50000.
- `max_polys` (integer): Default 50000.

### `set_mesh` (~120 tokens)

Set Mesh

Overwrite the points (and optionally polygons) of an editable object. Triangles may be passed as [a,b,c]; the bridge expands them to C4D's quad storage (a,b,c,c). If polygons is omitted, only points are rewritten and the count must match the existing topology. Wrapped in a single undo entry.

Input parameters:

- `handle` (required): Target editable object.
- `points` (array, required): New point positions.
- `polygons` (array): New polygon indices. [a,b,c] = triangle, [a,b,c,d] = quad.

### `set_mesh_selection` (~91 tokens)

Set Mesh Selection

Replace the point / polygon / edge BaseSelect on an editable mesh. Existing selection of the specified kind is cleared first. Pair with `get_mesh` using `include:['selections']` to read the same channels back.

Input parameters:

- `handle` (required): Editable target (PointObject / PolygonObject).
- `indices` (array, required): Indices to mark selected.
- `kind` (string, required): Which selection channel to replace.

### `save_document` (~127 tokens)

Save Document

Save the active document to disk. Path must be absolute; the parent directory must exist. Supported formats: c4d (default), abc / alembic, fbx, obj, stl, ply, usd / usda, gltf. With `copy:true` the document's internal name/path is left unchanged (Save-As-Copy behaviour).

Input parameters:

- `copy` (boolean): Save as copy — document's active path/name stays unchanged. Default false.
- `format` (string): Export format alias. Default 'c4d'.
- `path` (string, required): Absolute output path.

### `open_document` (~107 tokens)

Open Document

Load a Cinema 4D scene file as a new document. Unlike `import_scene` (which merges into the current doc), this opens the file as its own document. Pass `make_active:true` (default) to switch focus to the loaded document. Differs from `import_scene` which calls MergeDocument.

Input parameters:

- `make_active` (boolean): Switch the active document to the newly loaded one. Default true.
- `path` (string, required): Absolute path to a loadable scene file.

### `new_document` (~77 tokens)

New Document

Insert a fresh empty BaseDocument into C4D's document list and (by default) switch focus to it. Useful for starting a clean scene without overwriting the current one.

Input parameters:

- `make_active` (boolean): Switch the active document to the new one. Default true.
- `name` (string): Optional display name for the new document.

### `list_documents` (~71 tokens)

List Documents

Enumerate the documents currently open in Cinema 4D. Each entry has its list `index` (the handle accepted by `set_active_document`), name, path and whether it is the active document. `get_document_state` only reports the active document; this is how you discover the others before switching.

### `set_active_document` (~123 tokens)

Set Active Document

Switch focus to an already-open document, identified by its list `index` (from `list_documents`) or `name`. Pass exactly one of the two. `name` errors if it matches zero or several open documents — use `index` to disambiguate. This only switches between documents already open; use `open_document` to load a file from disk.

Input parameters:

- `index` (integer): 0-based position in the document list (see `list_documents`).
- `name` (string): Document name; errors if it matches zero or several open documents.

### `close_document` (~149 tokens)

Close Document

Close an open document, identified by its list `index` (from `list_documents`) or `name`. Pass exactly one of the two. A document with unsaved changes is refused unless `force:true` — closing discards unsaved work without a prompt (unlike the GUI close). C4D always keeps at least one document, so closing the last one leaves a fresh empty document active.

Input parameters:

- `force` (boolean): Close even with unsaved changes, discarding them. Default false.
- `index` (integer): 0-based position in the document list (see `list_documents`).
- `name` (string): Document name; errors if it matches zero or several open documents.

### `list_graph_nodes` (~160 tokens)

List Node Material Graph Nodes

Walk a node graph and return a flat list of nodes. Target either a node-based material (via `handle`) or the active document's scene-nodes graph (via `scope:'document'`). `supported:false` comes back when the maxon framework is unavailable or no graph exists in the requested space.

Input parameters:

- `handle`: Material handle. Required unless `scope:'document'`.
- `node_space` (string): Alias 'standard' | 'redshift' | 'scenenodes' / 'neutron' or a fully-qualified maxon.Id. Default 'standard' (materials) or 'scenenodes' (document).
- `scope` (string): Set to 'document' to target the scene-nodes (neutron) graph.

### `list_graph_node_assets` (~164 tokens)

List Node Graph Asset Types

Enumerate registered node-template asset ids for a node space — the ids you pass to `apply_graph_description` as `$type`. For the scene-nodes (neutron) space, results are filtered to the templates actually addable there (e.g. 'net.maxon.node.invert', 'net.maxon.node.access.composecolor64'); note these differ from the net.maxon.corenode:* ids that `list_graph_nodes` reports for existing nodes. `supported:false` comes back when the C4D build lacks the maxon framework.

Input parameters:

- `node_space` (string): Alias 'standard' | 'redshift' | 'scenenodes' (a.k.a. 'neutron') or a fully-qualified maxon.Id. Default 'standard'.

### `get_graph_info` (~66 tokens)

Get Node Material Graph Info

Report which node spaces a material exposes a graph in, which one is currently active, and the alias table the bridge understands. Use this before `apply_graph_description` to confirm the right `node_space` is addressable on this build / material.

Input parameters:

- `handle` (required): Material handle.

### `apply_graph_description` (~333 tokens)

Apply Node Graph Description

Build or mutate a node graph using maxon.GraphDescription's declarative dict syntax. Supports creating nodes (`$type`), assigning stable ids (`$id`), wiring connections via 'thisPort -> childPort' keys (the value is the nested upstream node), and setting port values inline. Example: {"$type":"Output","Surface -> outColor":{"$type":"Standard Material","$id":"mat","Base/Color":[1,0,0]}}. Works for material graphs (standard/redshift) and the scene-nodes (neutron) document graph via `scope:"document"`. For scene-nodes, `$type` must be a node-template asset id from `list_graph_node_assets` (node_space:"scenenodes"), e.g. "net.maxon.node.invert" — NOT the net.maxon.corenode:* ids; the scene-nodes path supports creation + connections + port values (graph queries/labels are material-only). Creates the graph on demand by default.

Input parameters:

- `create_graph` (boolean): Create the graph if missing. Default true.
- `description` (object, required): maxon.GraphDescription dict (nested; $type / $id / '->' keys).
- `handle`: Material handle. Required unless `scope:'document'`.
- `node_space` (string): Alias 'standard' | 'redshift' | 'scenenodes' or a maxon.Id. Default 'standard' for materials, 'scenenodes' for document scope.
- `scope` (string): Target the active document's scene-nodes graph instead of a material.

### `set_graph_port` (~196 tokens)

Set Node Graph Port Value

Update a single port on a node addressable by its stable $id within a node material graph. Thin convenience over apply_graph_description: internally builds a {$query:{$id:node_id}, port: value} payload. Lists of 3 numbers are coerced to maxon.Vector for vector-typed ports.

Input parameters:

- `handle`: Material handle. Required unless `scope:'document'`.
- `node_id` (string, required): The $id assigned to the target node.
- `node_space` (string): Alias 'standard' | 'redshift' | 'scenenodes' or maxon.Id. Default 'standard'.
- `port` (string, required): Port path, e.g. 'Base/Metalness' or 'Image/Custom Gamma'.
- `scope` (string): Target the scene-nodes graph on the active document.
- `value` (required): New port value. [x,y,z] is passed as maxon.Vector.

### `remove_graph_node` (~126 tokens)

Remove Node Graph Node

Delete a node by id from a node-material graph. The id must match the node's stable maxon.Id (as reported by list_graph_nodes or assigned via $id in apply_graph_description).

Input parameters:

- `handle`: Material handle. Required unless `scope:'document'`.
- `node_id` (string, required): The id of the node to remove.
- `node_space` (string): Alias 'standard' | 'redshift' | 'scenenodes' or maxon.Id. Default 'standard'.
- `scope` (string): Target the scene-nodes graph on the active document.

### `list_xpresso_nodes` (~150 tokens)

List Xpresso Graph Nodes

Walk an Xpresso (Texpresso / GvNodeMaster) tag and return a flat list of its GvNodes. Each entry carries a stable dotted-index path id ('0.2' = root's first child, its third child) plus port summaries. Use the id to address nodes from `apply_xpresso_graph`, `set_xpresso_port`, `remove_xpresso_node`, or any handle-taking tool via `{kind:'gv_node', tag, id}`. Accepts either a tag handle (Texpresso) or an object handle (uses that object's first Texpresso tag).

Input parameters:

- `handle` (required): Xpresso tag handle or host object handle.

### `apply_xpresso_graph` (~328 tokens)

Apply Xpresso Graph Description

Declarative builder for an Xpresso (classic GvNodeMaster) graph — mirror of `apply_graph_description` but for Xpresso rather than Maxon node materials. Creates nodes (CreateNode) and wires connections (GvPort.Connect) in one call. Accepts an operator_id as an int (e.g. c4d.ID_OPERATOR_CONST=1001150) or short alias ('object'|'const'|'result'|'math'|'range_mapper'|'condition'|'compare'|'memory'|'iterate'|'bool'|'freeze'|'formula'|'realtovect'|'vecttoreal'|'matrix2vect'|'vect2matrix'|'link'|'spy'|'python'). Optionally creates the Texpresso tag when given an object handle and `create_tag_if_missing:true`. Example: build a `Object.Global Position -> Result` graph in three calls (create Cube → apply_xpresso_graph → EventAdd).

Input parameters:

- `connect` (array): Connection list. `from` defaults to dir='out' and `to` defaults to dir='in'. Internally always calls outputPort.Connect(inputPort).
- `create_tag_if_missing` (boolean): When handle is an object and no Texpresso tag exists, create one. Default true.
- `handle` (required): Xpresso tag handle (Texpresso) or an object handle (pass create_tag_if_missing:true to auto-add a tag).
- `nodes` (object, required): Node specs keyed by caller-chosen stable id (used in `connect`).

### `set_xpresso_port` (~260 tokens)

Edit Xpresso Port

Low-level Xpresso port primitive — covers cases `apply_xpresso_graph` can't express. `action:'add'` adds a new input/output port via GvNode.AddPort(port_id). `connect` wires this node's `port` to `target` (on a peer node identified by `target.node_handle`); output-vs-input direction is auto-detected. `disconnect` removes incoming connections from `port`. `set_value` writes the port's default. `remove` deletes the port. Use `list_xpresso_nodes` first to discover node path ids and existing ports.

Input parameters:

- `action` (string, required): Operation to perform.
- `io` (string): Direction for `add`.
- `node` (required): gv_node handle for the operated-on GvNode.
- `port` (object): Target port selector. Required for remove / connect / disconnect / set_value.
- `port_id` (integer): Port main id passed to GvNode.AddPort (required for `add`).
- `target` (object): Peer port selector (with its node_handle). Required for connect.
- `value`: New default value for `set_value`. [x,y,z] is coerced to c4d.Vector.

### `remove_xpresso_node` (~76 tokens)

Remove Xpresso Graph Node

Delete a GvNode from an Xpresso graph. The handle must be a gv_node handle pointing at the target (use `list_xpresso_nodes` to discover its path id). All incoming / outgoing connections on the node are severed automatically.

Input parameters:

- `handle` (required): gv_node handle for the node to remove.

### `assign_material` (~209 tokens)

Assign Material (Texture Tag)

Link a material to an object by creating a Texture tag (or updating an existing one when `update_if_exists:true`). Avoids wrangling TEXTURETAG_* param ids by hand. Projection aliases: spherical, cylindrical, flat, cubic, frontal, spatial, uvw, shrinkwrap, camera.

Input parameters:

- `material` (required): Material to assign.
- `name` (string): Optional display name for the Texture tag.
- `object` (required): Target object.
- `projection` (string): Projection alias. Omit to preserve the existing projection.
- `restrict_to_selection` (string): Polygon-selection tag name to restrict this texture to.
- `update_if_exists` (boolean): If a Texture tag already exists on the object, update it in place instead of appending. Default false.
- `uv_offset` (array): [u, v] offset applied to TEXTURETAG_OFFSETX/Y.
- `uv_tiles` (array): [u, v] tile count applied to TEXTURETAG_TILESX/Y.

### `set_transform` (~207 tokens)

Set Object Transform

Write an object's transform in local or global space. Pass any combination of `pos`/`rot` (HPB radians)/`scale` to patch individual components — unspecified parts keep their current value. Or pass a full 4x3 `matrix` (rows: offset, v1, v2, v3) to replace the whole transform; matrix is mutually exclusive with the decomposed fields. Space defaults to 'local' (SetMl). Use 'global' (SetMg) to write world coordinates through a parent.

Input parameters:

- `handle` (required): Target object.
- `matrix` (array): 4x3 matrix as [offset, v1, v2, v3]. Exclusive with pos/rot/scale.
- `pos` (array): [x, y, z].
- `rot` (array): [heading, pitch, bank] in radians.
- `scale` (array): [sx, sy, sz].
- `space` (string): Default 'local'.

### `add_user_data` (~187 tokens)

Add User Data Slot

Add a new User Data slot to any BaseList2D (common rigging / control-exposure pattern). Returns the slot's DescID (as a nested list) which can be piped into `get_params` / `set_params` as a path. dtype aliases: real, long, bool, vector, string, color, filename, time, link.

Input parameters:

- `default`: Default stored on the descriptor.
- `dtype` (string, required): User-data dtype.
- `handle` (required): Target (object / tag / material / etc.).
- `max` (number): Numeric upper bound (real / long).
- `min` (number): Numeric lower bound (real / long).
- `name` (string, required): Display name for the new UD slot.
- `step` (number): Spinner step size.
- `value`: Initial value. For vector / color, pass [x,y,z].

### `list_user_data` (~69 tokens)

List User Data

Enumerate the User Data slots on a target. Each entry carries `{desc_id, name, dtype, value}`. Feed `desc_id` back into `remove_user_data` / `get_params` / `set_params` as a DescID path.

Input parameters:

- `handle` (required): Target to inspect.

### `remove_user_data` (~67 tokens)

Remove User Data Slot

Delete a User Data slot by its DescID path (as returned by `list_user_data` or `add_user_data`). Wrapped in undo.

Input parameters:

- `desc_id` (array, required): DescID path — list of [id, dtype, creator?] levels.
- `handle` (required): Target.

### `list_mograph_clones` (~144 tokens)

List MoGraph Clones

Read the per-clone transforms from a MoGraph generator (Cloner / Matrix / Tracer / …). The bridge forces a scene pass so the MoData array is populated before sampling. Returns `{count, returned, clones: [{index, pos, matrix?}]}`. `supported:false` when the build lacks c4d.modules.mograph or when the handle isn't a MoGraph generator.

Input parameters:

- `handle` (required): MoGraph generator (e.g. Omgcloner).
- `include_matrix` (boolean): Include the 4x3 matrix per clone. Default true.
- `max_count` (integer): Cap on clones returned. Default 2048.

### `list_tracks` (~76 tokens)

List Animation Tracks

Enumerate CTracks on the resolved entity. Returns `{name, param_id, component, dtype, key_count}` per track so callers can pipe the results straight into get_keyframes / set_keyframe. Vector tracks (Position, Rotation, Scale) surface as separate entries per component.

Input parameters:

- `handle` (required): Entity whose animation tracks to enumerate.

### `get_keyframes` (~135 tokens)

Get Keyframes

Read the keys on a specific animation track. Combine with list_tracks to discover which (param_id, component) pairs are animated. Returns `[{frame, value, interp}]`. Optional start_frame / end_frame clip the range inclusively.

Input parameters:

- `component`: Sub-component for vector parameters. Omit / null for scalar tracks.
- `end_frame` (integer): Inclusive upper frame bound.
- `fps` (integer): Override for BaseTime → frame conversion.
- `handle` (required): Animated entity.
- `param_id` (integer, required): Top-level description id of the parameter.
- `start_frame` (integer): Inclusive lower frame bound.

### `delete_keyframe` (~137 tokens)

Delete Keyframe

Remove keys from a CTrack. Pass `frame` for a single-frame delete, or `start_frame` / `end_frame` (inclusive) for a range. Returns `{removed, track}`. Symmetric with `set_keyframe`.

Input parameters:

- `component`: Vector sub-component. null / omitted for scalar tracks.
- `end_frame` (integer): Inclusive upper bound.
- `fps` (integer): Override for BaseTime conversion.
- `frame` (integer): Single frame to remove.
- `handle` (required): Animated target.
- `param_id` (integer, required): Top-level description id.
- `start_frame` (integer): Inclusive lower bound.

### `delete_track` (~70 tokens)

Delete Animation Track

Remove an entire CTrack (identified by `param_id` + optional `component`) from the target. Returns `{removed: bool}`.

Input parameters:

- `component`: Vector sub-component. null / omitted for scalar tracks.
- `handle` (required): Animated target.
- `param_id` (integer, required): Top-level description id.

### `list_layers` (~60 tokens)

List Layers

Enumerate every LayerObject in the active document. Each entry returns the layer's name, optional color [r,g,b], and its flag dict (solo / view / render / manager / locked / generators / deformers / expressions / animation / xref).

### `create_layer` (~134 tokens)

Create Layer

Create a LayerObject at the document's layer root. With `update_if_exists:true` the existing layer with the same name is updated in place (idempotent). Pass `color:[r,g,b]` (0..1) and/or `flags:{solo,view,render,manager,locked,...}` to configure it.

Input parameters:

- `color` (array): [r,g,b] in 0..1.
- `flags` (object): Initial flag values.
- `name` (string, required): Layer display name (also used for lookup).
- `update_if_exists` (boolean): Idempotent update. Default false.

### `assign_to_layer` (~68 tokens)

Assign To Layer

Place a target (object / tag / material) on a named layer. Pass `layer:null` to clear the assignment. The layer must exist — call `create_layer` first if needed.

Input parameters:

- `layer` (required): Layer name, or null to clear.
- `target` (required): Entity to assign.

### `get_object_layer` (~39 tokens)

Get Object's Layer

Return the layer currently assigned to a target entity (object / tag / material), or null if unassigned.

Input parameters:

- `target` (required): Entity to query.

### `set_layer_flags` (~154 tokens)

Set Layer Flags

Toggle a layer's visibility / render / lock flags in one call. Only fields explicitly passed are modified; omitted flags keep their current value. `flags` returned in the response reflects the post-update state.

Input parameters:

- `animation` (boolean)
- `color` (array): Optional color update as [r,g,b] in 0..1.
- `deformers` (boolean)
- `expressions` (boolean)
- `generators` (boolean)
- `layer` (string, required): Layer name (required).
- `locked` (boolean)
- `manager` (boolean)
- `render` (boolean)
- `solo` (boolean)
- `view` (boolean)
- `xref` (boolean)

### `get_document_state` (~61 tokens)

Get Document State

One-shot reader for the active document's key fields: fps, min/max and loop frame range, current frame, document name/path, and canonical handles for the active camera / take / render data. Pairs with `set_document` for the writer side.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/kumoproductions-mcp-cinema4d/kumoproductions-mcp-cinema4d#diagnostics

## Score history

- 2026-08-03: 75
- 2026-08-02: 72
- 2026-08-01: 9
- 2026-07-31: 19
- 2026-07-30: 25
- 2026-07-28: 43
- 2026-07-27: 24

## Links

- npm package: https://www.npmjs.com/package/@kumoproductions/mcp-cinema4d
- Socket report: https://socket.dev/npm/package/@kumoproductions/mcp-cinema4d
- Repository: https://github.com/kumoproductions/mcp-cinema4d
- Changelog RSS feed: https://verifymcp.io/servers/kumoproductions-mcp-cinema4d/kumoproductions-mcp-cinema4d/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/kumoproductions-mcp-cinema4d/kumoproductions-mcp-cinema4d/changelog.json
- HTML version of this page: https://verifymcp.io/servers/kumoproductions-mcp-cinema4d/kumoproductions-mcp-cinema4d
