
Nuke MCP
STDIOBridge between Nuke and AI systems for automating compositing tasks via MCP.
Bridge between Nuke and AI systems for automating compositing tasks via MCP.
A bridge between The Foundry's Nuke and AI systems using the Model Context Protocol (MCP).
Nuke-MCP allows AI assistants to interact with Nuke through a socket connection, enabling them to:
nuke_mcp_addon.py
): A Nuke script that creates a socket server within Nukenuke_mcp_server.py
): A Python server that connects to the Nuke addon and exposes tools to AI systemsmain.py
): A simple script to start the MCP serverpip install fastmcp
nuke_mcp_addon.py
to your Nuke scripts folder or a location in your Nuke Python pathCopy the Addon File:
nuke_mcp_addon.py
file and place it in a location where Nuke can find it:
~/.nuke
on Linux/Mac or in your home directory on Windows)Create a Startup Script (Recommended):
init.py
file in your .nuke
directoryimport nuke_mcp_addon
Manual Loading (Alternative):
import nuke_mcp_addon
By default, the NukeMCP panel opens as a floating window. If you prefer to have it docked in Nuke's interface, you can modify the NukeMCPPanel
class in nuke_mcp_addon.py
:
# Find the NukeMCPPanel class definition (around line 380) class NukeMCPPanel(nukescripts.PythonPanel): def __init__(self): nukescripts.PythonPanel.__init__(self, 'Nuke MCP', 'com.example.NukeMCP') # ... existing code ... # Add this method to enable docking def addToPane(self): pane = nuke.getPaneFor('Properties.1') if not pane: pane = nuke.getPaneFor('Viewer.1') self.setMinimumSize(300, 200) # Set a reasonable minimum size return pane.addPermanentAsQWidget(self) # Modify the show_panel function to use docking def show_panel(): """Show the NukeMCP panel""" global _panel if _panel is None: _panel = NukeMCPPanel() # Show as docked panel instead of floating window pane = _panel.addToPane() if pane: _panel.setParent(pane)
You can also modify how the panel appears in the menu. Based on your menu.py file, you have:
# MCP Tools nuke.toolbar("Nodes").addCommand('DUGCO/MCP/NukeMCP Panel', 'nuke_mcp_addon.show_panel()')
To ensure it's properly integrated with your existing toolbar structure, make sure this line is uncommented in your menu.py file.
To use Nuke-MCP with Claude Desktop, follow these steps:
Download and Install Claude Desktop:
Enable Developer Mode:
Edit the Configuration File:
claude_desktop_config.json
file){ "mcpServers": { "nuke": { "command": "python", "args": [ "/path/to/your/nuke-mcp/main.py" ], "trusted": true } } }
Replace the Path:
main.py
file"args": ["Z:/path/to/nuke_mcp/main.py"]
or
"args": ["Z:\\path\\to\\nuke_mcp\\main.py"]
"trusted": true
flag is required for full functionalityRestart Claude Desktop:
Now when you use Claude Desktop, you can instruct it to interact with Nuke through the MCP connection.
The system consists of three main components that work together:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ AI Client │◄───►│ MCP Server │◄───►│ Nuke Addon │
│ (Claude) │ │ │ │ (in Nuke) │
│ │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘
The MCP server exposes the following tools:
get_script_info()
: Get information about the current Nuke scriptget_node_info(node_name)
: Get details about a specific nodecreate_node(node_type, name, position, inputs, parameters)
: Create a new nodemodify_node(name, parameters, position, inputs)
: Change an existing nodedelete_node(name)
: Delete a nodeposition_node(name, x, y)
: Position a node in the node graphconnect_nodes(output_node, input_node, input_index)
: Connect nodesrender(frame_range, write_node, proxy_mode)
: Render framesviewer_playback(action, start_frame, end_frame)
: Control Viewer playbackexecute_nuke_code(code)
: Run Python code in Nukeauto_layout_nodes(selected_only)
: Automatically arrange nodesset_frames(first_frame, last_frame, current_frame)
: Set frame rangecreate_viewer(input_node)
: Create a Viewer nodecreate_node(node_type="Blur", parameters={"size": 10})
create_node(node_type="Read", name="input", parameters={"file": "/path/to/image.exr"})
create_node(node_type="Grade", name="grade1", position=[200, 0])
create_node(node_type="Grade", name="grade2", position=[400, 0])
create_node(node_type="Write", name="output", position=[600, 0], parameters={"file": "/path/to/output.exr"})
connect_nodes(output_node="input", input_node="grade1")
connect_nodes(output_node="grade1", input_node="grade2")
connect_nodes(output_node="grade2", input_node="output")
render(frame_range="1-10", write_node="output")
When working with Claude Desktop, you can give it natural language instructions to control Nuke. Here are some example commands:
"Can you tell me what's in my current Nuke script?"
"Create a compositing setup in Nuke with a Read node, Color Correct, Grade, and Write node, all properly connected."
"Create a professional green screen keying setup in Nuke with Keyer, Despill, Edge Blur, and compositing over a background."
"Build a particle system in Nuke using Noise, ParticleEmitter, and Merge nodes to create a fire effect."
"Analyze my current Nuke script, then enhance it by creating a color grading chain with separate adjustments for shadows, midtones, and highlights. Add a subtle film grain effect and a gentle vignette."
"Set up a 3D scene in Nuke with a Camera, 3D objects, and proper lighting."
You can extend the system by adding new tools to the nuke_mcp_server.py
file. The MCP tools are defined using the @mcp.tool()
decorator pattern.
Each tool follows this basic structure:
@mcp.tool() def tool_name(ctx: Context, param1: type, param2: type = default_value) -> str: """ Tool description for documentation. Parameters: - param1: Description of param1 - param2: Description of param2 with default value """ try: logger.info(f"Tool called: tool_name with params") nuke = get_nuke_connection() result = nuke.send_command("command_name", { "param1": param1, "param2": param2 }) # Process result and format response return "Human-readable response" except Exception as e: logger.error(f"Error in tool_name: {str(e)}") return f"Error message: {str(e)}"
To add a new tool:
Identify the functionality you want to add
Add a new method in the Nuke addon (in nuke_mcp_addon.py
):
NukeMCPServer
classhandlers
dictionary in the execute_command
methodCreate a corresponding tool in nuke_mcp_server.py
:
@mcp.tool()
decoratorTest the new tool thoroughly
Here's an example of how you might add a specialized tool for creating a Transform node:
@mcp.tool() def create_transform( ctx: Context, name: str = None, position: List[int] = None, rotation: float = 0.0, scale: float = 1.0, center: List[float] = None ) -> str: """ Create a Transform node with specified parameters. Parameters: - name: Optional name for the Transform node - position: Optional [x, y] position coordinates for the node - rotation: Rotation in degrees - scale: Uniform scale factor - center: Optional [x, y] center of transformation """ try: logger.info(f"Tool called: create_transform") nuke = get_nuke_connection() # Prepare parameters for the Transform node parameters = { "rotate": rotation, "scale": scale } if center: parameters["center"] = center # Call the generic create_node command result = nuke.send_command("create_node", { "node_type": "Transform", "name": name, "position": position, "parameters": parameters }) actual_name = result.get("name", "unknown") return f"Created Transform node named '{actual_name}' with rotation={rotation}° and scale={scale}" except Exception as e: logger.error(f"Error in create_transform: {str(e)}") return f"Error creating Transform node: {str(e)}"
This pattern allows you to build specialized tools that provide higher-level functionality while leveraging the existing command infrastructure.
If Claude cannot connect to Nuke, check the following:
This is an initial implementation. Future improvements could include: