Skip to content

nodes

nodes

MCP tool wrappers for Houdini node operations.

Each tool delegates to the corresponding handler running inside Houdini via the HTTP bridge.

Functions:

Name Description
change_node_type

Change a node's type in place, keeping wires, name, position, flags,

connect_nodes

Connect two nodes together.

connect_nodes_batch

Connect multiple node pairs in a single call.

copy_node

Copy a node, optionally into a different parent network.

create_network_box

Draw a titled network box around nodes, to document a graph you built.

create_node

Create a node inside a parent network.

create_sticky_note

Leave a sticky note in a network.

delete_node

Delete a node, or several in one call.

disconnect_node

Disconnect one or all inputs of a node.

find_nodes

Search for nodes by name pattern, type, or context.

get_node_info

Get type, connections, flags, errors, cook time, and non-default parameters for a node.

layout_children

Auto-layout children of a network node.

list_children

List children of a network node.

list_node_types

List available node types for a context category.

move_node

Move a node to a different parent network.

press_button

Press a button parameter — "Stash Input", "Reload Geometry", an

rename_node

Rename a node.

reorder_inputs

Reorder the input connections of a node.

set_node_color

Set a node's color in the network editor.

set_node_flags

Set flags on a node.

set_node_position

Set a node's position in the network editor.

set_object_transform

Set an object's translate, rotate, scale and/or parent in one call.

Classes

Functions:

change_node_type async

change_node_type(
    ctx: Context,
    node_path: str,
    new_type: str,
    keep_name: bool = True,
    keep_parms: bool = True,
    keep_network_contents: bool = True,
) -> dict

Change a node's type in place, keeping wires, name, position, flags, parameter values and (for subnets/assets) network contents.

This is how an HDA instance is moved to an installed newer version (building::2.0) without losing its edits, and how a placeholder is swapped for the real node. Every value set before the swap and not after it is named in parms_dropped (no such parameter on the new type) or parms_reset (back at its default). Unversioned names map to the preferred version, as create_node does.

Parameters:

Name Type Description Default
node_path
str

Node to change.

required
new_type
str

Type name in the node's own category.

required
keep_name
bool

Keep the node's name.

True
keep_parms
bool

Carry parameter values over by name.

True
keep_network_contents
bool

Keep a subnet's/asset's children (False resets an asset to its definition's contents, also on a node that is already of new_type).

True

connect_nodes async

connect_nodes(
    ctx: Context,
    source_path: str,
    dest_path: str,
    output_index: int = 0,
    input_index: int = 0,
    input_name: str | None = None,
    indirect_input: int | None = None,
) -> dict

Connect two nodes together.

To feed a node INSIDE a subnet from one of the subnet's own input connectors (a SubnetIndirectInput — not a node, it has no path), pass the subnet as source_path and the connector index as indirect_input.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
source_path
str

Upstream node path; with indirect_input, the subnet whose input connector is the source.

required
dest_path
str

Downstream node path.

required
output_index
int

Source output index.

0
input_index
int

Destination input index.

0
input_name
str | None

Destination connector name or label (e.g. "base_color" on a VOP shader); wins over input_index.

None
indirect_input
int | None

Index of the subnet input connector at source_path to wire from (dest_path must live inside that subnet).

None

connect_nodes_batch async

connect_nodes_batch(ctx: Context, connections: list[dict[str, Any]]) -> dict

Connect multiple node pairs in a single call.

Parameters:

Name Type Description Default
connections
list[dict[str, Any]]

List of connections. Each dict has keys: source_path (str), dest_path (str), output_index (int, default 0), input_index (int, default 0), input_name (str, optional: connector name or label, wins over input_index), indirect_input (int, optional: source_path is then a subnet and this is the index of its input connector to wire from — for the first node of a chain built inside that subnet).

required

copy_node async

copy_node(
    ctx: Context,
    node_path: str,
    dest_parent: str | None = None,
    new_name: str | None = None,
    offset: list[float] | None = None,
) -> dict

Copy a node, optionally into a different parent network.

In the same network the copy lands one node width to the right of its original instead of on top of it; in another network it keeps the original's position. offset overrides both, and position in the reply says where the copy is. inputs lists the wires the copy kept ({index, from}, or {index, indirect_input} for a subnet's own input connector); inputs_not_copied the original's wires it could not keep, as in a copy into another network.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Source node path.

required
dest_parent
str | None

Destination parent path.

None
new_name
str | None

Name for the copy.

None
offset
list[float] | None

[dx, dy] from the original's position.

None

create_network_box async

create_network_box(
    ctx: Context,
    parent_path: str,
    node_paths: list[str] | None = None,
    comment: str | None = None,
    color: list[float] | None = None,
) -> dict

Draw a titled network box around nodes, to document a graph you built.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
parent_path
str

Network the box lives in.

required
node_paths
list[str] | None

Sibling nodes to enclose; the box fits around them.

None
comment
str | None

Title shown on the box.

None
color
list[float] | None

RGB in 0..1.

None

create_node async

create_node(
    ctx: Context,
    parent_path: str,
    node_type: str,
    name: str | None = None,
    position: list[float] | None = None,
) -> dict

Create a node inside a parent network.

Before using this, call list_node_types(context='', filter='') to verify a dedicated node exists for the operation. Houdini has thousands of nodes — many common operations (boolean, scatter, copy to points, fracture, ocean, hair, vellum, pyro, etc.) have dedicated nodes that are better than writing VEX or Python.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
parent_path
str

Parent network path.

required
node_type
str

Node type (e.g. 'geo', 'box', 'grid').

required
name
str | None

Node name.

None
position
list[float] | None

[x, y] network editor position.

None

create_sticky_note async

create_sticky_note(
    ctx: Context,
    parent_path: str,
    text: str,
    position: list[float] | None = None,
    size: list[float] | None = None,
    color: list[float] | None = None,
) -> dict

Leave a sticky note in a network.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
parent_path
str

Network the note lives in.

required
text
str

Note text.

required
position
list[float] | None

[x, y] in network editor units.

None
size
list[float] | None

[width, height] in network editor units.

None
color
list[float] | None

RGB in 0..1.

None

delete_node async

delete_node(
    ctx: Context,
    node_path: str | None = None,
    node_paths: list[str] | None = None,
) -> dict

Delete a node, or several in one call.

Pass node_path or node_paths, not both.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str | None

Node path.

None
node_paths
list[str] | None

Several nodes at once, one undo step. Every path is checked first: a missing one deletes nothing. A node inside another listed one goes with it (deleted_with_parent).

None

disconnect_node async

disconnect_node(
    ctx: Context,
    node_path: str,
    input_index: int | None = None,
    disconnect_all: bool = False,
) -> dict

Disconnect one or all inputs of a node.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
input_index
int | None

Input index to disconnect.

None
disconnect_all
bool

Disconnect all inputs.

False

find_nodes async

find_nodes(
    ctx: Context,
    pattern: str | None = None,
    node_type: str | None = None,
    context: str | None = None,
    inside: str = "/",
) -> dict

Search for nodes by name pattern, type, or context.

Narrow the search: use inside to limit to a specific sub-network and supply at least one of pattern, node_type, or context. Searching from inside="/" with no filters scans the entire scene and can return hundreds of nodes.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
pattern
str | None

Glob pattern for node names (e.g. 'box*').

None
node_type
str | None

Node type filter (e.g. 'box', 'null').

None
context
str | None

Category filter (e.g. 'Sop', 'Object').

None
inside
str

Root path to search within (default '/').

'/'

get_node_info async

get_node_info(ctx: Context, node_path: str) -> dict

Get type, connections, flags, errors, cook time, and non-default parameters for a node.

A parameter whose expression uses a SOP local variable ($CEX, $BBX, $PT, @N.x) is not evaluated outside a cook: it comes with value: null, its expression and local_variable: true.

Returns only parameters that differ from their defaults (non_default_parameters) plus a total_param_count. Use get_parameter_schema to inspect the full parameter list. A VOP node also gets connector_types: the data type each input and output carries now (a variadic input is "undef" on the type until it is wired).

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required

layout_children async

layout_children(
    ctx: Context, parent_path: str, spacing: float | None = None
) -> dict

Auto-layout children of a network node.

Does nothing when auto-layout is disabled via FXHOUDINIMCP_AUTO_LAYOUT=0.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
parent_path
str

Parent network path.

required
spacing
float | None

Spacing multiplier between nodes.

None

list_children async

list_children(
    ctx: Context,
    parent_path: str,
    recursive: bool = False,
    filter_type: str | None = None,
    include_locked_assets: bool = False,
) -> dict

List children of a network node.

Avoid recursive=True on large networks — it can return hundreds or thousands of nodes. Prefer find_nodes with a specific pattern instead. A recursive listing does not enter locked assets (a POP or FLIP solver's insides): the asset itself is listed, flagged locked_asset.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
parent_path
str

Parent network path.

required
recursive
bool

Include all descendants (use sparingly on large scenes).

False
filter_type
str | None

Node type filter (e.g. 'box', 'merge').

None
include_locked_assets
bool

With recursive, also list what locked assets contain.

False

list_node_types async

list_node_types(
    ctx: Context, context: str, filter: str | None = None, limit: int = 200
) -> dict

List available node types for a context category.

IMPORTANT: Any context can have hundreds of node types (SOPs alone can exceed 800 in a production install). Always pass a filter keyword (e.g. 'mountain', 'scatter', 'boolean') instead of dumping the full list — the unfiltered response is capped at limit and may still be large.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
context
str

Category name (e.g. 'Sop', 'Lop', 'Dop', 'Top', 'Cop2').

required
filter
str | None

Substring to filter type name or label (case-insensitive).

None
limit
int

Max entries to return (default 200, max recommended 200).

200

move_node async

move_node(ctx: Context, node_path: str, dest_parent: str) -> dict

Move a node to a different parent network.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
dest_parent
str

Destination parent path.

required

press_button async

press_button(
    ctx: Context,
    node_path: str,
    parm_name: str,
    arguments: dict[str, Any] | None = None,
    cook: bool = False,
    action: bool = False,
) -> dict

Press a button parameter — "Stash Input", "Reload Geometry", an asset's own Build button — and read the node's errors and warnings afterwards.

The call holds until the callback returns, with no deadline. A callback that opens a dialog blocks Houdini's main thread and this bridge with it; read the button's script first if in doubt. A Python callback that RAISES does not hang anything: the bridge runs it rather than pressButton(), and its error comes back as this call's error. callback_route says how the press ran: python, hscript or native (a built-in action). For a Save to Disk or a render use write_cache / start_render, which report a verdict.

A press usually only dirties the node, so errors/warnings are from its last cook unless cook=True; without it needs_cook says whether they are stale (a cook that failed leaves it True too). has_script_callback is False for built-in buttons that still do work (File's Reload, Stash's Stash Input).

A parm that is not a button and has no callback is refused: pressing it does nothing. The small action button beside a field ("Create spare parameters" on a VEXpression) runs with action=True; an action that opens a picker holds the bridge like a dialog does.

Parameters:

Name Type Description Default
node_path
str

Node that owns the button.

required
parm_name
str

The button parameter's name.

required
arguments
dict[str, Any] | None

Optional kwargs handed to the callback script; values must be int, bool, float or str.

None
cook
bool

Cook the node after the press so errors describe the result.

False
action
bool

Run the parm's action button (script_action) instead of its callback.

False

rename_node async

rename_node(ctx: Context, node_path: str, new_name: str) -> dict

Rename a node.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
new_name
str

New node name.

required

reorder_inputs async

reorder_inputs(ctx: Context, node_path: str, new_order: list[int]) -> dict

Reorder the input connections of a node.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
new_order
list[int]

New input ordering (e.g. [1, 0] swaps first two).

required

set_node_color async

set_node_color(
    ctx: Context, node_path: str, r: float, g: float, b: float
) -> dict

Set a node's color in the network editor.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
r
float

Red (0.0-1.0).

required
g
float

Green (0.0-1.0).

required
b
float

Blue (0.0-1.0).

required

set_node_flags async

set_node_flags(
    ctx: Context,
    node_path: str,
    display: bool | None = None,
    render: bool | None = None,
    bypass: bool | None = None,
    template: bool | None = None,
    lock: bool | None = None,
) -> dict

Set flags on a node.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
display
bool | None

Display flag.

None
render
bool | None

Render flag.

None
bypass
bool | None

Bypass flag.

None
template
bool | None

Template flag.

None
lock
bool | None

Lock flag.

None

set_node_position async

set_node_position(ctx: Context, node_path: str, x: float, y: float) -> dict

Set a node's position in the network editor.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Node path.

required
x
float

Horizontal position.

required
y
float

Vertical position.

required

set_object_transform async

set_object_transform(
    ctx: Context,
    node_path: str,
    translate: list[float] | None = None,
    rotate: list[float] | None = None,
    scale: list[float] | None = None,
    parent: str | None = None,
) -> dict

Set an object's translate, rotate, scale and/or parent in one call.

Only the arguments you pass change. Object-level nodes under /obj only; SOP transforms are a Transform SOP, not this.

Parameters:

Name Type Description Default
ctx
Context

MCP context.

required
node_path
str

Object node, e.g. "/obj/geo1".

required
translate
list[float] | None

[tx, ty, tz].

None
rotate
list[float] | None

[rx, ry, rz] in degrees.

None
scale
list[float] | None

[sx, sy, sz].

None
parent
str | None

Object to parent under, or "" to unparent.

None