{
  "markdown": "![MCP for Cinema 4D](https://raw.githubusercontent.com/kumoproductions/mcp-cinema4d/main/assets/ogp.png)\n\n# mcp-cinema4d\n\n[![CI](https://github.com/kumoproductions/mcp-cinema4d/actions/workflows/ci.yml/badge.svg)](https://github.com/kumoproductions/mcp-cinema4d/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)\n[![Node](https://img.shields.io/badge/node-%3E%3D24-informational)](package.json)\n[![Cinema 4D](https://img.shields.io/badge/Cinema%204D-%3E%3D2026.0.0-informational)](https://www.maxon.net/en/cinema-4d)\n\nLet an LLM drive Cinema 4D. **mcp-cinema4d** bridges MCP-compatible clients (Claude Desktop, Claude Code, or any other stdio-capable MCP client) to a running Cinema 4D 2026 session so the model can inspect scene hierarchy, author shots, build node materials, and rig animation through a typed, undo-safe tool layer — not arbitrary Python pasted into a Script Manager.\n\n> [日本語](README.ja.md)\n> [简体中文](README.zh-CN.md)\n\n**Good for:**\n\n- **Scene audits** — \"List every object on the `hero` layer; flag any with non-uniform scale or missing Texture tags.\"\n- **Shot setup** — \"Create a 1920×1080 RenderData, a camera at (0, 150, -400), and a Take that uses both.\"\n- **Material work** — \"Build a Redshift node material with a noise texture driving roughness at 0.4 gain.\"\n- **Procedural edits** — \"On every Subdivision Surface in the scene, reduce editor/render levels by 1.\"\n- **Xpresso rigs** — \"Build a 3-gear meshing rig where the master gear's pitch radius dynamically drives the others' size and counter-rotation via an Xpresso graph.\"\n\n> [!CAUTION]\n> **Do not proceed unless you understand what this does.** An LLM with a live connection to Cinema 4D can read your scene, write to it, and (if you opt in) execute arbitrary code on your machine. In concrete terms:\n>\n> 1. **Your scene data leaves your machine.** Object names, hierarchy paths, material/parameter values, imported file paths — whatever the LLM reads via `list_entities` / `describe` / `get_container` / `dump_shader` / `get_mesh` — is forwarded to your chosen LLM provider and may be logged by your MCP client. **Under NDA or on unreleased IP? Confirm with your studio/legal team first** that the provider's retention policy and your client's logs are acceptable.\n> 2. **The LLM gets write access.** It can create, mutate, and delete objects, tags, materials, takes, render data, and layers; import / merge / open / save files; and render. Ctrl/Cmd-Z covers most edits — `save_document`, `open_document`, `render`, and some `call_command` invocations do not.\n> 3. **Arbitrary Python is off by default.** `exec_python` runs unrestricted code with the full authority of the Cinema 4D process (file I/O, subprocess, network). Enabled only when `C4D_MCP_ENABLE_EXEC_PYTHON=1` is set on **both** sides; turn it back off when you no longer need it. The same applies to plugin types that store Python source in their container — Python tag, Python generator, MoGraph Python effector, Python field, and the Xpresso Python operator. Creating or editing them is gated behind a separate `C4D_MCP_ENABLE_PYTHON_OPS=1` opt-in, since their code parameter is RCE-equivalent to `exec_python`.\n>\n> Before first use: back up (or commit) your scene, start on a throwaway project, and leave your MCP client's per-call approval prompts enabled. See [Security](#security) before exposing the bridge beyond loopback.\n\n---\n\n## Architecture\n\n```\nMCP client\n   ↓ stdio\nMCP server  (this repo, Node.js)\n   ↓ TCP, JSON Lines (default 127.0.0.1:18710)\ncinema4d_mcp_bridge  (Python plugin inside C4D)\n   ↓\nCinema 4D\n```\n\nTwo pieces to install: the **MCP server** (this npm package, runs as an MCP stdio process) and the **bridge plugin** (Python, lives inside Cinema 4D). C4D must be running for the bridge to respond.\n\n## Quickstart\n\nAssuming you already have Cinema 4D 2026.0.0+ and Node.js 24+.\n\n1. **Install the bridge plugin into Cinema 4D (one-off).** Download the latest\n   `cinema4d_mcp_bridge-<version>.zip` from the\n   [Releases page](https://github.com/kumoproductions/mcp-cinema4d/releases/latest)\n   and extract the `cinema4d_mcp_bridge/` folder into your Cinema 4D plugins\n   directory (see [Installing the bridge plugin](#installing-the-bridge-plugin)\n   for platform-specific paths).\n2. **Launch (or restart) Cinema 4D.** The C4D console should print\n   `[cinema4d_mcp_bridge] listening on 127.0.0.1:18710`.\n3. **Smoke-test the MCP server from the CLI:**\n\n   ```bash\n   echo '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"ping\",\"arguments\":{}}}' \\\n     | npx -y @kumoproductions/mcp-cinema4d\n   #   → {\"jsonrpc\":\"2.0\",\"id\":1,\"result\":{\"content\":[{\"type\":\"text\",\"text\":\"{\\\"pong\\\": true, ...}\"}]}}\n   ```\n\nThen wire it into your MCP client (see [Client configuration](#client-configuration)) and try:\n\n> _\"List every object in the scene, then add a cube named `hero` 200 units above the origin.\"_\n\nThe LLM will call `list_entities` → `create_entity` in sequence; you should see a new cube appear in the viewport.\n\nPrefer running from a local checkout? See [CONTRIBUTING.md](./CONTRIBUTING.md) for the source-install flow.\n\n## Client configuration\n\nGenerate a random token and set it on **both** the MCP server process (via the client's `env` map, below) and the Cinema 4D launch environment. The bridge rejects mismatched requests (constant-time compare); the Node client forwards the value automatically. Strongly recommended — localhost is not a trust boundary on a shared workstation.\n\n```bash\nopenssl rand -hex 16\n```\n\nRegister the MCP server in your client with the token in the `env` map:\n\n```json\n{\n  \"mcpServers\": {\n    \"cinema4d\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@kumoproductions/mcp-cinema4d\"],\n      \"env\": {\n        \"C4D_MCP_TOKEN\": \"paste-your-random-hex-here\"\n      }\n    }\n  }\n}\n```\n\n| Client                       | Config file                                                                                                                         |\n| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| Claude Desktop / Claude Code | `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows) · `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) |\n| Other MCP clients            | see the client's docs for registering a stdio server                                                                                |\n\n**The same `C4D_MCP_*` variables must also be set in the Cinema 4D launch environment** — the bridge plugin reads them at C4D startup. macOS: `open -a \"Cinema 4D\" --env C4D_MCP_TOKEN=...` (or export in your shell profile before launch). Windows: set as User environment variables and restart C4D.\n\nTo change the bridge socket, set `C4D_MCP_PORT` (and optionally `C4D_MCP_HOST` — see [Security](#security)) alongside `C4D_MCP_TOKEN` in the same `env` map, plus the C4D launch env.\n\n## Tools\n\n68 tools across 16 groups. The LLM picks tools itself based on the prompt — you rarely invoke them directly. See [docs/TOOLS.md](./docs/TOOLS.md) for the full table with per-tool descriptions.\n\n| Group                            | Count | What's in it                                                                                                                                                                                                                       |\n| -------------------------------- | :---: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Basics                           |   4   | `ping`, `render`, `preview_render` (Viewport renderer + Constant Lines, returns inline PNG), `reset_scene`.                                                                                                                        |\n| Script-style                     |   5   | `exec_python` (opt-in), `call_command`, `list_plugins`, `undo`, `batch` — escape hatches + undo-grouped multi-op.                                                                                                                  |\n| Generic CRUD                     |   9   | `list_entities`, `describe`, `get_params`/`set_params`, `get_container`, `dump_shader`, `create_entity`, `remove_entity`, `set_keyframe`.                                                                                          |\n| Shot setup                       |  11   | Document state, fps / frame range / camera, `import_scene` (merge), RenderData + Take, `take_override`, timeline markers (`create_marker` / `list_markers` / `set_marker` / `remove_marker`), `sample_transform`.                  |\n| Selection · Hierarchy            |   4   | Active selection read / write; reparent, reorder, clone.                                                                                                                                                                           |\n| Modeling · Mesh                  |   4   | `modeling_command` (CSO / Make Editable / Connect / Subdivide / …), `get_mesh`, `set_mesh`, `set_mesh_selection`.                                                                                                                  |\n| Document I/O                     |   6   | `save_document`, `open_document`, `new_document`, `list_documents`, `set_active_document` (switch between already-open docs), `close_document` (force-gated for unsaved changes).                                                  |\n| Node graphs                      |  10   | Node-material graphs (walk / asset enum / `apply_graph_description` / per-port edits / removal) **and** Xpresso (GvNodeMaster) graphs (`list_xpresso_nodes` / `apply_xpresso_graph` / `set_xpresso_port` / `remove_xpresso_node`). |\n| Tag helpers · Animation          |   5   | `assign_material`; `list_tracks`, `get_keyframes`, `delete_keyframe`, `delete_track`.                                                                                                                                              |\n| Transforms · User data · MoGraph |   5   | `set_transform`; `add_user_data` / `list_user_data` / `remove_user_data`; `list_mograph_clones`.                                                                                                                                   |\n| Layers                           |   5   | Enumerate, create, assign, query, flag toggles (solo / view / render / locked / …).                                                                                                                                                |\n\n## Entity handles\n\nEvery CRUD tool identifies entities by a typed `handle` object. The resolver raises on ambiguous names — prefer `path` when a scene contains duplicates.\n\n| Kind             | Shape                                                                                                                     |\n| ---------------- | ------------------------------------------------------------------------------------------------------------------------- |\n| `object`         | `{kind:\"object\", name:\"Cube\"}` **or** `{kind:\"object\", path:\"/Root/Character/Hip\"}`                                       |\n| `render_data`    | `{kind:\"render_data\", name:\"VFX_Shot002\"}`                                                                                |\n| `take`           | `{kind:\"take\", name:\"VFX_Shot002\"}`                                                                                       |\n| `material`       | `{kind:\"material\", name:\"Concrete\"}`                                                                                      |\n| `tag`            | `{kind:\"tag\", object:\"Cube\", type_id:1029524, tag_name?:\"...\"}` (or `object_path` instead of `object`)                    |\n| `video_post`     | `{kind:\"video_post\", render_data:\"VFX_Shot002\", type_id:1029525}`                                                         |\n| `shader`         | `{kind:\"shader\", owner:<handle>, name?:\"Layer 0\"}` **or** `{..., index:0}`                                                |\n| `plugin_options` | `{kind:\"plugin_options\", plugin_id:\"abc\"\\|1028082, plugin_type?:\"scene_saver\"}` — exporter / importer private settings BC |\n\n`name` lookups are strict: if several entities share the name, the bridge returns an error listing up to five candidate paths so you can switch to a path-based handle. `create_entity` always returns the freshly-resolved handle (objects include `path`; shaders include both `name` and `index`) so chained edits stay stable.\n\n## Installing the bridge plugin\n\nGrab the latest `cinema4d_mcp_bridge-<version>.zip` from\n[Releases](https://github.com/kumoproductions/mcp-cinema4d/releases/latest)\nand extract the inner `cinema4d_mcp_bridge/` folder into your Cinema 4D plugins\ndirectory:\n\n| OS      | Typical plugins directory                                        |\n| ------- | ---------------------------------------------------------------- |\n| Windows | `%APPDATA%\\Maxon\\Maxon Cinema 4D <VERSION>\\plugins\\`             |\n| macOS   | `~/Library/Preferences/Maxon/Maxon Cinema 4D <VERSION>/plugins/` |\n\nYou can also register a custom search path via Cinema 4D's `Preferences → Plugins → Add` and extract the zip there instead.\n\nLaunch (or restart) Cinema 4D after extracting. **The plugin only reloads when C4D restarts.**\n\nKeep the plugin version pinned to the npm package version you run — a version mismatch surfaces as `unknown command: <tool>` in the bridge log. See [CONTRIBUTING.md](./CONTRIBUTING.md) if you want to run a development checkout instead.\n\n> [!NOTE]\n> **Official releases only come from two places:** the npm package [`@kumoproductions/mcp-cinema4d`](https://www.npmjs.com/package/@kumoproductions/mcp-cinema4d) and the GitHub Releases page under [kumoproductions/mcp-cinema4d](https://github.com/kumoproductions/mcp-cinema4d/releases). If you obtained a zip or a scoped npm package from anywhere else claiming to be this plugin, treat it as untrusted.\n\n## Configuration\n\n| Var                          | Side       | Default     | Notes                                                                                                                                                                                                                                                                         |\n| ---------------------------- | ---------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `C4D_MCP_HOST`               | both       | `127.0.0.1` | Host for the TCP bridge. Legacy aliases: `C4D_BRIDGE_HOST` (Node), `C4D_MCP_BRIDGE_HOST` (plugin).                                                                                                                                                                            |\n| `C4D_MCP_PORT`               | both       | `18710`     | Port for the TCP bridge. Legacy aliases: `C4D_BRIDGE_PORT`, `C4D_MCP_BRIDGE_PORT`.                                                                                                                                                                                            |\n| `C4D_MCP_ENABLE_EXEC_PYTHON` | both       | unset       | **Opt-in.** Set to `1` (or `true`/`yes`/`on`) on both sides to expose the `exec_python` tool. See [Security](#security).                                                                                                                                                      |\n| `C4D_MCP_ENABLE_PYTHON_OPS`  | C4D plugin | unset       | **Opt-in.** Set to `1` to allow creating / editing Python-bearing plugin types (Python tag, Python generator, MoGraph Python effector, Python field (Fpython, 440000277), Xpresso Python operator). Off by default — their code parameter is RCE-equivalent to `exec_python`. |\n| `C4D_MCP_TOKEN`              | both       | unset       | Shared secret. When set on the C4D side, the Node client must send the same value. Strongly recommended.                                                                                                                                                                      |\n| `C4D_MCP_ALLOW_REMOTE`       | C4D plugin | unset       | Required to bind `C4D_MCP_HOST` to a non-loopback interface. The bridge refuses to start otherwise.                                                                                                                                                                           |\n\n## Security\n\nEven without `exec_python`, many tools mutate state: `call_command`, `set_params`, `import_scene`, `render`, `remove_entity`, `save_document`, `open_document`, `new_document`. Treat the bridge like a local shell, not a sandbox.\n\n- **`exec_python` is opt-in.** It runs unrestricted Python on Cinema 4D's main thread (file I/O, subprocess, network). Hidden and rejected by the bridge unless `C4D_MCP_ENABLE_EXEC_PYTHON=1` is set on **both** the MCP server process and the Cinema 4D process. Turn it back off when you no longer need it — set-and-forget is how accidents happen.\n- **Python-bearing plugin types are opt-in too.** Python tag (`Tpython`), Python generator (`Opython`), MoGraph Python effector, Python field (`Fpython`), and the Xpresso Python operator all store caller-supplied source code in their container and run it on scene evaluation — i.e. they are RCE-equivalent to `exec_python`. The bridge refuses `create_entity`, `set_params`, `apply_xpresso_graph`, and `take_override` operations targeting these types unless `C4D_MCP_ENABLE_PYTHON_OPS=1` is set on the Cinema 4D side. Listing / reading / removing existing instances is unaffected.\n- **Set a shared-secret token (`C4D_MCP_TOKEN`).** Localhost is not a trust boundary — any local process running as your user can otherwise connect. See [Client configuration](#client-configuration) for the JSON snippet.\n- **Loopback default + remote opt-in.** The bridge binds to `127.0.0.1` by default. Binding `C4D_MCP_HOST` to a non-loopback interface **refuses to start** unless `C4D_MCP_ALLOW_REMOTE=1` is also set — guarding against a one-character typo (`0.0.0.0`) exposing C4D to the LAN.\n- **Only connect MCP clients you trust.** Review their tool-use permissions so mutating tools (especially `exec_python` if opted in) are not auto-approved.\n- **Indirect prompt injection via scene content.** Scene data (object names, parameter strings, imported file paths) flows back to the LLM through `list_entities` / `describe` / `get_container` / `dump_shader` / `get_mesh`. When `exec_python` is enabled, a malicious string in a scene can steer the model into running arbitrary Python. Don't run `import_scene` against untrusted `.c4d` / `.fbx` / `.abc` files while `exec_python` is on, and rely on your MCP client's per-call approval for `exec_python` / `call_command` / `save_document` / `import_scene` rather than blanket-approving them.\n- **Audit log.** Every `exec_python` call records the code body to the local bridge log (`%TEMP%/cinema4d_mcp_bridge.log` on Windows, `$TMPDIR/cinema4d_mcp_bridge.log` on macOS) for after-the-fact review. The log is append-only with no rotation — prune it manually if it grows.\n\n```bash\nexport C4D_MCP_TOKEN=\"$(openssl rand -hex 16)\"   # set in C4D launch env too\nnpx -y @kumoproductions/mcp-cinema4d\n```\n\n## Troubleshooting\n\n| Symptom                                                                     | Likely cause / fix                                                                                                                                                                                                                                     |\n| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `Cannot connect to Cinema 4D bridge at 127.0.0.1:18710`                     | C4D isn't running, plugin didn't load, or a firewall is blocking localhost. Check the C4D console for the `listening on …` line and look at `%TEMP%/cinema4d_mcp_bridge.log` (Windows) / `$TMPDIR/cinema4d_mcp_bridge.log` (macOS).                    |\n| Plugin loads but the `listening` line never prints                          | Usually a Python import error in `cinema4d_mcp_bridge.pyp`. Inspect the C4D console; common cause is leftover stale files from an older install — delete the destination folder and re-extract the latest release zip, then restart C4D.               |\n| `listening on 127.0.0.1:18710` fails with `OSError: address already in use` | Another process already owns that port. Either quit it, or set both `C4D_MCP_PORT` (C4D side) **and** the same value on the MCP server launch command.                                                                                                 |\n| `unknown command: <tool>`                                                   | Bridge plugin is older than the npm package. Download the matching release zip, re-extract it into your plugins folder, and restart C4D.                                                                                                               |\n| `object name '…' is ambiguous`                                              | Two or more scene objects share the name. Use a path-based handle: `{kind:\"object\", path:\"/A/B/C\"}`. Candidate paths are included in the error.                                                                                                        |\n| `exec_python is disabled on this C4D instance`                              | `exec_python` is off by default. Set `C4D_MCP_ENABLE_EXEC_PYTHON=1` in **both** the Cinema 4D launch environment **and** the MCP server `env` map, then restart C4D. See [Security](#security).                                                        |\n| `requires C4D_MCP_ENABLE_PYTHON_OPS=1 …`                                    | You tried to create or edit a Python-bearing entity (Python tag, Python generator, MoGraph Python effector, Python field, Xpresso Python operator). Off by default. Set `C4D_MCP_ENABLE_PYTHON_OPS=1` in the Cinema 4D launch environment and restart. |\n\nStill stuck? Open an [issue](https://github.com/kumoproductions/mcp-cinema4d/issues/new/choose) with the bridge log, your OS, Cinema 4D version, and the tool call that failed.\n\n## Known limitations\n\n- **`modeling_command make_editable` is unreliable on Cinema 4D 2026.** The SDK's `SendModelingCommand` handling of `MCOMMAND_MAKEEDITABLE` shifts across builds — sometimes it returns the new polygon object, sometimes it removes the source without inserting a replacement. **Use `current_state_to_object` instead** when you need a guaranteed polygon copy (the bridge inserts the result for you and returns its handle).\n- **`list_graph_node_assets` can return an empty list** on builds where the Maxon asset repository doesn't expose node-template assets through the usual query path. The tool still returns `supported: true` with shape-correct output; treat an empty `assets` array as \"discovery unavailable on this C4D build\" and pass `$type` asset ids you already know (e.g. from `list_graph_nodes` on an existing material).\n- **Node material friendly names vary.** `apply_graph_description` accepts the declarative `$type` strings documented by Maxon (e.g. `\"Standard Material\"`), but the resolver varies between 2024 / 2025 / 2026 builds — when in doubt, pass the fully-qualified asset id returned by `list_graph_node_assets` / `list_graph_nodes` instead.\n- **`exec_python` is the only way to seed classical-shader fixtures.** A handful of E2E tests (for `dump_shader`) need to build a shader tree before asserting on it, so they skip cleanly when `C4D_MCP_ENABLE_EXEC_PYTHON` isn't set on both sides. The tools themselves don't require `exec_python`.\n- **Older Cinema 4D versions are not tested.** The CI + E2E suite targets C4D 2026. The bridge guards optional SDK constants with `getattr` fallbacks, so most tools likely work on 2024 / 2025 as well — but we don't verify that and won't accept bug reports that don't reproduce on 2026.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for setup, the development loop, how to add a new tool, coding style, and the PR flow.\n\n## License\n\n[MIT](./LICENSE) © 2026 kumo.productions, Inc.\n\n## Trademarks\n\nCinema 4D® and Maxon® are trademarks of Maxon Computer GmbH. This project is an independent, unofficial tool, **not affiliated with or endorsed by Maxon**.\n",
  "bytes": 24965,
  "sha": "6ae5f1bd76ba59f0ece0f16c00b6f9a46db78e6e5cfeddd94adba527961048c2",
  "repo_slug": "kumoproductions/mcp-cinema4d",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_kumoproductions_mcp_cinema4d_b923beff/readme"
}