nuke-mcp
Provides tools for interacting with Foundry Nuke scripts and sessions, enabling agents to read and edit Nuke scripts, create/connect/delete nodes, inspect and set knobs, render Write nodes, preview frames from any node, execute Python, and manage live or headless Nuke workflows.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@nuke-mcp Open the script comp_v003.nk and render all Write nodes"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
nuke-mcp
An MCP server for Foundry Nuke. It lets any MCP-capable agent (Claude, ChatGPT / Codex, Gemini and others) read and edit Nuke scripts, render Write nodes and look at the output of any node. It works two ways, chosen per call:
live: the Nuke you have open. The agent sees and edits the same script as you, and every change is one undo step.
headless: a fresh
nuke -tprocess on a.nkfile. Nothing has to be open; it uses one Nuke licence while it runs.
Agent (Claude / Codex / Gemini)
│ MCP (stdio)
▼
nuke-mcp (this package, Python ≥ 3.11, outside Nuke)
│ │
│ live: JSON over TCP │ headless: Nuke -t headless_runner.py
│ 127.0.0.1:7393 + shared token │ (job and result as JSON files)
▼ ▼
nuke_mcp_bridge plugin (inside Nuke, nuke_mcp_bridge.commands
on Nuke's main thread) (the same code, the same commands)Both backends run the same commands, so every tool behaves the same live and headless.
Requirements
Nuke 16 or 17 (tested on Nuke 17.1v2, macOS).
uv (
curl -LsSf https://astral.sh/uv/install.sh | sh).
Related MCP server: nuke-mcp
Installation
1. Nuke plugin (once per machine)
Only needed for the live mode. Headless works without it.
uvx --from git+https://github.com/hramirezedc/nuke-mcp nuke-mcp install-pluginThis copies the nuke_mcp_bridge package into ~/.nuke/, adds a marked block to ~/.nuke/init.py (your own lines are kept) and creates the shared token in ~/.nuke_mcp/token. Restart Nuke, then check both backends:
uvx --from git+https://github.com/hramirezedc/nuke-mcp nuke-mcp statusThe listener starts in GUI sessions only; nuke -t never opens a socket. To skip it for one session, launch Nuke with NUKE_MCP_DISABLE=1. To remove it: nuke-mcp uninstall-plugin.
2. Register the server with your agent
In every case the command is uvx --from git+https://github.com/hramirezedc/nuke-mcp nuke-mcp. Desktop apps don't always inherit your shell PATH: if they can't find uvx, use its full path (which uvx).
Claude Desktop: in ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"nuke": {
"command": "/Users/YOU/.local/bin/uvx",
"args": ["--from", "git+https://github.com/hramirezedc/nuke-mcp", "nuke-mcp"]
}
}
}Claude Code
claude mcp add nuke -- uvx --from git+https://github.com/hramirezedc/nuke-mcp nuke-mcpOpenAI Codex CLI: in ~/.codex/config.toml
[mcp_servers.nuke]
command = "uvx"
args = ["--from", "git+https://github.com/hramirezedc/nuke-mcp", "nuke-mcp"]Gemini CLI: in ~/.gemini/settings.json
{
"mcpServers": {
"nuke": {
"command": "uvx",
"args": ["--from", "git+https://github.com/hramirezedc/nuke-mcp", "nuke-mcp"]
}
}
}Restart the app after editing its configuration.
Live or headless?
Every tool that works on a script takes script (a .nk path) and mode:
| What happens |
| Live if Nuke is open and has |
| Live only. Error if Nuke is not open, or has another script open. |
| Always a new |
Headless edits are saved back to the file, and the previous version is kept as
<name>.nk.bak.renderruns headless by default, so the Nuke window never freezes. With noscriptit renders a snapshot of the live script, including unsaved changes, and deletes the snapshot afterwards.mode="live"renders inside the open Nuke instead. Either way it checks that every expected frame exists on disk.open_script,save_script,undo,redo,get_selectionandset_selectiononly exist in a live session.Apart from
render, a headless run does not see the unsaved changes of your open session.
Headless uses the newest Nuke it finds in /Applications. Choose a version with NUKE_MCP_NUKE_VERSION=17.0, or an executable with NUKE_MCP_EXE.
Tools
Area | Tools |
Application and script |
|
Nodes |
|
Output |
|
Live changes are one undo step each, cancelled again if the command fails half way. delete_nodes deletes nothing if one name is wrong. Tools that delete or overwrite carry destructiveHint, so agents ask before using them.
Knob values: numbers, strings and booleans; lists for multi-value knobs ([r, g, b, a]); "=expr" or {"expression": "…"} for expressions; {"keyframes": {"1": 0, "24": 1}} for animation; {"script": "…"} for Nuke's own text form. A Read's file accepts "name.####.exr 1001-1100".
Configuration
Variable | Used by | Default |
| Nuke and server |
|
| Nuke and server | contents of |
| Nuke and server |
|
| Nuke | unset |
| server (headless) | newest installed Nuke |
The default port differs from hiero-mcp (7392), so both can run at once. Only one Nuke GUI can hold the port: a second one prints a message and runs without the listener.
Development
uv sync
uv run pytest # offline tests, no Nuke needed
uv run python scripts/live_check.py # with Nuke open: runs every tool in a throw-away scriptThe offline tests run the real listener, client, MCP server and headless runner against tests/fake_nuke.py, a small stand-in for the nuke module (and a fake Nuke -t executable). The live check needs Nuke open with no unsaved changes: it opens a script in a temporary folder and works only there.
src/nuke_mcp/server.py defines the MCP tools. src/nuke_mcp/nuke_plugin/nuke_mcp_bridge/commands.py implements them with the Nuke API. Each tool has a command with the same name and parameters, and the tests check that they stay in sync. After changing the plugin, run nuke-mcp install-plugin and restart Nuke.
License
Freeware by Toolbox Design, all rights reserved: free to use, including commercially, but not to modify, redistribute or sell. See LICENSE. Foundry and Nuke are trademarks of their respective owners; this project is not affiliated with Foundry.
Available Tools
17 toolsconnect_nodeA
Connect source to input number input of node (0 is the main input). Leave source empty to disconnect.
Inputs: node (required), mode, input, script, +1 more. Returns: object
create_nodeA
Create a node (e.g. "Blur", "Grade", "Read", "Write") with optional name, knob values and input node names.
Without `position` the node is placed under its first input. Headless runs save the script afterwards.
Inputs: node_class (required), mode, name, knobs, +3 more. Returns: object
delete_nodesADestructive
Delete nodes by name. Nothing is deleted if one of the names does not exist.
Inputs: nodes (required), mode, script. Returns: object
execute_pythonADestructive
Run Python in Nuke for anything the other tools do not cover.
`nuke` is pre-imported. Assign to a variable named `result` to return a JSON-serialisable value;
stdout, stderr and any traceback are returned too. Headless runs only keep changes to the script when `save` is true.
Inputs: code (required), mode, save, script. Returns: object
get_app_infoARead-only
Which Nuke backends are available: the live GUI session (version, open script) and the installed executables used for headless runs.
Inputs: no named parameters. Returns: object
get_nodeCRead-only
One node's inputs, dependents and knobs. By default only knobs that differ from their default are listed.
Inputs: node (required), mode, script, all_knobs. Returns: object
get_script_infoCRead-only
Frame range, fps, format, colour management, node counts by class, and the names of Read and Write nodes.
Inputs: mode, script. Returns: object
get_selectionBRead-only
Names of the nodes selected in the live Nuke session.
Inputs: no named parameters. Returns: object
list_nodesBRead-only
Nodes with class, position, inputs and disabled flag. Filter by class ("Blur"), selection, text in the name, or look inside a Group node by name.
Inputs: mode, group, limit, script, +3 more. Returns: object
open_scriptADestructive
Open a .nk script in the live Nuke session. Refuses if the open script has unsaved changes unless discard_changes is true.
Inputs: path (required), discard_changes. Returns: object
preview_frameBRead-only
Look at the output of any node: renders one frame to an image and returns it.
Uses a temporary Write node (removed afterwards). `max_size` is the longest-side width in pixels the image is scaled down to.
Inputs: node (required), mode, frame, format, +2 more.
redoA
Redo the last undone action in the live Nuke session.
Inputs: no named parameters. Returns: object
renderA
Render a Write node and check that the expected frames exist on disk.
Runs headless so the Nuke interface stays usable: with no `script` it renders a snapshot of the live
script (including unsaved changes). With mode="live" it renders inside the open Nuke and blocks its interface.
Frame range defaults to the script's.
Inputs: write_node (required), last, mode, step, +3 more. Returns: object
save_scriptA
Save the live script, or save it to a new .nk path ("save as") when path is given.
Inputs: path. Returns: object
set_knobsC
Set one or more knobs on a node. Returns the values they have afterwards.
Inputs: node (required), knobs (required), mode, script. Returns: object
set_selectionA
Select nodes in the live Nuke session (replaces the selection unless add is true).
Inputs: nodes (required), add. Returns: object
undoA
Undo the last action in the live Nuke session.
Inputs: no named parameters. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 17 tools
Each tool maps to a distinct resource+action: node listing/inspection (list_nodes vs get_node) is differentiated by the knobs/dependents detail, and app vs script info are clearly scoped. The only real overlap is execute_python acting as a superset of every other tool, plus mild adjacency between set_knobs and create_node's knob arguments, but these are conventional escape hatches rather than true ambiguity.
The dominant pattern is verb_noun (get_app_info, list_nodes, create_node, set_knobs, delete_nodes, set_selection), applied consistently with correct singular/plural semantics. Deviations are the bare verbs undo/redo and the noun-ish render/preview_frame, which are idiomatic for a DCC app and remain readable.
17 tools is slightly above the comfortable band but each earns its place across session control, node graph editing, selection, and rendering. Nothing looks like a redundant wrapper, though consolidation (e.g. selection get/set) could trim it a little.
Coverage is strong: script lifecycle (open/save), undo/redo, node CRUD, knob edits, graph wiring, selection, render verification, and a Python escape hatch for anything missing. Minor gaps remain around creating a new script from scratch, cloning/grouping nodes, and closing/reverting the session, all of which execute_python can work around.
Related MCP Connectors
OCR, transcription, file extraction, and image generation for AI agents via MCP.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceConnects AI assistants to Nuke for compositing tasks via natural language.15MIT
- AlicenseBqualityDmaintenanceA production-grade MCP server for Foundry Nuke that enables AI assistants to understand and manipulate compositing environments, including AOVs, deep workflows, distortion, tracking, OCIO/ACEScct, and CopyCat ML.45MIT
- AlicenseNot gradedqualityCmaintenanceEnables language models to inspect the current Houdini scene, create and modify nodes, and run VEX/Python code in the running Houdini session via MCP.1MIT
- AlicenseAqualityBmaintenanceEnables AI agents to read, edit, and render Compositor .comp projects, including layer inspection, image manipulation, and preview.1562 npm8MIT