Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
LOG_LEVELNoLogging levelINFO
HOUDINI_HOSTNoHoudini host addresslocalhost
HOUDINI_PORTNoHoudini hwebserver port8100
MCP_TRANSPORTNoMCP transport (stdio or streamable-http)stdio
FXHOUDINIMCP_PORTNoPort for the Houdini plugin to listen on8100
FXHOUDINIMCP_AUTOSTARTNoSet to 0 to disable auto-start1

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
set_keyframeC

Set a single keyframe on a parameter.

Args: node_path: Node path. parm_name: Parameter name. frame: Frame number. value: Value at this keyframe. slope: Tangent slope. accel: Acceleration.

set_keyframesA

Batch-set multiple keyframes on a parameter.

Args: node_path: Node path. parm_name: Parameter name. keyframes: List of dicts with "frame", "value", and optionally "slope"/"accel".

delete_keyframeC

Delete a keyframe at a specific frame.

Args: node_path: Node path. parm_name: Parameter name. frame: Frame number to delete.

get_keyframesC

Get all keyframes on a parameter.

Args: node_path: Node path. parm_name: Parameter name.

set_frameC

Set the current frame in the timeline.

Args: frame: Frame number.

get_frameA

Get the current frame and FPS.

set_frame_rangeC

Set the global frame range.

Args: start: Start frame. end: End frame.

set_playback_rangeC

Set the playback range (green bar in the timeline).

Args: start: Start frame. end: End frame.

playbar_controlC

Control playback: play, stop, or reverse.

Args: action: One of "play", "stop", or "reverse". real_time: Enable or disable real-time playback. fps: Frames per second.

list_cachesC

List all cache-type nodes under a root path.

Args: ctx: MCP context. root_path: Root path to search from.

get_cache_statusA

Frames on disk for a cache node, against the range it is set to write.

This is what to poll after a background write_cache: complete is true when every frame of expected_range is on disk, missing_frames lists the rest, writing is true while files are still arriving, and hint tells you when the finished cache is not yet loaded from disk. Never wait for a cache with a shell loop; call this between other work.

Args: ctx: MCP context. node_path: Path to the cache node.

clear_cacheC

Delete cached files on disk for a cache node.

Args: ctx: MCP context. node_path: Path to the cache node. frame_range: [start, end] frame range to limit deletion.

write_cacheA

Execute a cache node, and report whether a cache actually appeared.

Foreground by default: Houdini shows its own progress dialog and the user can cancel. The call holds until the write finishes, however long that is; a client that hands a long call to a background task notifies you with the verdict when it lands. Do nothing else in Houdini meanwhile (every other call queues behind the write) and never poll the disk.

success and wrote_files reflect the files on disk and the errors of the node that did the writing -- a filecache delegates to an internal ROP and stays silent itself, so a failed write used to be reported as success. Errors are named with the node they came from.

Args: ctx: MCP context. node_path: Path to the cache node. frame_range: [start, end] frame range to render. Overrides the node's $FSTART/$FEND expressions for this and later writes. background: Save from a separate Houdini process (File Cache's own "Save to Disk in Background") so Houdini stays usable, at the cost of the user seeing no progress there. Saves the hip first, returns at once with status "launched"; follow it with get_cache_status. Use it only when asked to keep working while a cache writes. A verified foreground write turns the node's Load from Disk on.

get_chop_dataC

Get CHOP node track data.

Args: node_path: CHOP node path. channel_name: Specific channel to retrieve. start: Start sample index. end: End sample index.

create_chop_nodeB

Create a new CHOP node.

Before using this, call list_node_types(context='Chop', filter='') to verify the correct node type. CHOPs has many dedicated nodes for motion and timing — noise, wave, spring, jiggle, lag, limit, filter, math, function, blend, shift, stretch, trim, cycle, speed, constraintlookatat, constraintpath — that may already do what you need.

Args: parent_path: Parent network path. chop_type: CHOP node type to create. name: Node name override.

list_chop_channelsC

List all channels on a CHOP node.

Args: node_path: CHOP node path.

export_chop_to_parmC

Export a CHOP channel to a parameter via a chop() expression.

Args: chop_path: CHOP node path. channel_name: Channel to export. target_node_path: Target node path. target_parm_name: Parameter to receive the export.

execute_pythonA

Execute arbitrary Python code inside Houdini. LAST RESORT only.

DO NOT use this to:

  • Create nodes or networks → use build_network or create_node

  • Set parameters → use set_parameter or set_parameters

  • Create wrangles or write Python SOPs → use create_wrangle

  • Connect nodes → use connect_nodes or connect_nodes_batch

  • Read geometry → use get_geometry_info, get_points, sample_geometry

ONLY use this when no dedicated tool exists for the operation — i.e. hou.* API calls or Python-level state that no other tool exposes. The justification parameter is mandatory: name the dedicated tools you considered and why none covers this operation.

Args: code: Python source code to execute. justification: Which dedicated tools you considered and why none covers this operation. return_expression: Python expression to evaluate after execution.

reload_pluginA

Re-import the plugin's Houdini-side code without restarting Houdini.

For developing this server: after editing its handlers, this picks the edit up in the running session. The MCP server's own tool definitions are not reloaded; the client has to reconnect for those.

execute_hscriptC

Execute an HScript command in Houdini.

Args: command: HScript command string to execute.

evaluate_expressionC

Evaluate an expression in Houdini and return its result.

Args: expression: Expression string to evaluate. language: Expression language, "hscript" or "python".

get_env_variableC

Get a Houdini environment variable value.

Args: var_name: Name of the environment variable.

get_file_referencesB

Every file path the scene references, with the parameter holding it and whether it exists.

Args: ctx: MCP context. include_missing_only: Only report paths that are missing on disk.

set_update_modeA

Set Houdini's cook update mode, or read it when called with no mode.

"manual" before a long build stops every parameter change from re-cooking; set "auto" back afterwards.

Args: ctx: MCP context. mode: "auto", "on_mouse_up" or "manual". Omit to read.

get_network_overviewA

Get a compact overview of a network.

Keep depth low (1–2). Larger values on complex scenes return thousands of nodes and can overflow the context window.

Args: path: Network path. depth: Recursion depth (default 2, keep ≤ 3).

get_cook_chainC

Trace the cook dependency chain for a node.

Args: node_path: Node path.

explain_nodeC

Explain a node in human-readable form.

Args: node_path: Node path.

get_selectionB

Get the current node selection.

set_selectionC

Set the node selection.

Args: node_paths: Node paths to select.

get_scene_summaryC

Get a high-level summary of the scene.

compare_snapshotsC

Take or compare scene state snapshots.

Args: action: "take" or "compare". snapshot_name: Snapshot name.

get_node_errors_detailedB

Get detailed error analysis for nodes.

Args: node_path: Node to analyze, or scan from root_path if omitted. root_path: Root path to scan.

get_cop_infoC

Get information about a COP node.

Args: node_path: Path to the COP node.

get_cop_geometryC

Get geometry representation from a COP node.

Args: node_path: Path to the COP node. output_index: Output connector index.

get_cop_layerC

Get image layer data from a COP node.

Args: node_path: Path to the COP node. output_index: Output connector index.

create_cop_nodeA

Create a COP node in the specified network.

Before using this, call list_node_types(context='Cop', filter='') for Copernicus nodes (Houdini 20+), or context='Cop2' for legacy COPs. Copernicus is the modern image processing system and is preferred over COP2 (deprecated as of Houdini 20.5). COPs has many dedicated image-processing nodes — blur, sharpen, levels, contrast, over, multiply, luminance, premultiply, channelcopy, noise, ramp, fractalnoise, worleynoise, rasterizegeo, heighttonormal, sdfshape — that may cover the operation without needing a VEX COP or Python.

Args: parent_path: Path to the parent COP network. cop_type: COP node type to create. name: Override node name.

set_cop_flagsC

Set flags on a COP node.

Args: node_path: Path to the COP node. display: Display flag state. export_flag: Render/export flag state. compress: Compress flag state.

list_cop_node_typesB

List available COP node types.

Args: filter: Substring filter for node type names.

get_cop_vdbC

Get VDB volumetric data from a COP node.

Args: node_path: Path to the COP node. output_index: Output connector index.

get_simulation_infoC

Get DOP network simulation state.

Args: node_path: DOP network node path.

list_dop_objectsC

List all DOP objects in a simulation.

Args: node_path: DOP network node path.

get_dop_objectC

Get detailed data for a specific DOP object.

Args: node_path: DOP network node path. object_name: DOP object name.

get_dop_fieldB

Read a specific field value from a DOP record.

Args: node_path: DOP network node path. object_name: DOP object name. data_path: Dot-separated subdata path (e.g. "Geometry", "Forces/Gravity"). field_name: Field name to read.

get_dop_relationshipsC

List all relationships between DOP objects.

Args: node_path: DOP network node path.

step_simulationC

Advance the simulation by a number of frames.

Args: node_path: DOP network node path. steps: Number of frames to advance.

reset_simulationC

Reset the simulation to its initial state.

Args: node_path: DOP network node path.

get_sim_memory_usageC

Get detailed memory breakdown for the simulation.

Args: node_path: DOP network node path.

get_geometry_infoC

Get geometry summary for a SOP node.

Args: node_path: Node path. output_index: Which output to read, for nodes with several (FLIP compress, Vellum solver, whitewater source): 0 is the first.

get_pointsA

Read point positions and attributes with pagination.

Args: node_path: Node path. attributes: Attribute names to read. start: Start index. count: Max points per page (200 by default, about 14 KB; page on with start while has_more is true). group: Point group filter.

get_primsC

Read primitive data and attributes with pagination.

Args: node_path: Node path. attributes: Attribute names to read. start: Start index. count: Max prims per page (200 by default; page on with start while has_more is true). group: Prim group filter.

get_attrib_valuesA

Read attribute values as a flat array with pagination.

For spot-checking a few values prefer sample_geometry — it returns a representative spread of points with all their attributes in one call. Use get_attrib_values when you need a specific slice of one attribute.

Values are element-major: for a float3 attribute every 3 consecutive values belong to one element. Check has_more and increment start to read subsequent pages.

Args: node_path: Node path. attrib_name: Attribute name. attrib_class: "point", "prim", "vertex", or "detail". start: First element index to return. count: Max elements per page (default 200).

set_detail_attribB

Set a detail attribute on a SOP node.

Appends an Attribute Create SOP after the node and moves the display flag to it; the result includes the new node's path.

Args: node_path: Node path. attrib_name: Attribute name. value: Value to set.

get_groupsC

List all geometry groups on a SOP node.

Args: node_path: Node path.

get_group_membersA

Get element indices in a geometry group, with pagination.

Check has_more and increment start to read subsequent pages.

Args: node_path: Node path. group_name: Group name. group_type: "point", "prim", or "edge". start: First element index to return. count: Max elements per page (default 5 000).

get_bounding_boxC

Get the bounding box of a SOP node's geometry.

Args: node_path: Node path.

get_attribute_infoC

Get metadata for a geometry attribute.

Args: node_path: Node path. attrib_name: Attribute name. attrib_class: "point", "prim", "vertex", or "detail".

sample_geometryC

Sample evenly distributed points from a SOP node's geometry.

Args: node_path: Node path. sample_count: Number of points to sample. seed: Random seed.

get_prim_intrinsicsA

Get intrinsic values for primitives: one, many, or all of them.

Read many prims in one call rather than one call per prim. intrinsics alone sweeps every prim for those intrinsics and answers with a prims table plus stats (min/max/avg and the prim index each extreme belongs to, per component for a vector such as bounds); prim_indices or prim_range narrow it to the prims you care about. Up to 2000 rows per call; beyond that the reply says truncated and requested_count, and stats cover only the rows returned: page with prim_range.

Args: node_path: Node path. prim_index: One primitive index, or None for a summary. prim_indices: Several primitive indices, read in one call. prim_range: [start, end] (end inclusive) instead of a list. intrinsics: Only these intrinsics, e.g. ["bounds", "packedfulltransform"]. With none of the index arguments, they are read for every prim.

find_nearest_pointC

Find the nearest point(s) to a given position.

Args: node_path: Node path. position: Query position as [x, y, z]. max_results: Max nearest points to return.

get_attrib_statsA

Aggregate statistics for numeric attributes: min, max, mean, sum.

Use this to prove something is happening, rather than reading values. get_geometry_info names the attributes; get_attrib_values returns every value, which on a 60k-point cache tells you nothing you can read. Vector attributes also report per-component ranges, so a velocity field's per-axis extremes come back in the same call.

Args: node_path: SOP node path. attribs: Attribute names. Omit for every attribute of the class. A name written "age/life" is the ratio of two attributes, per element (elements dividing by zero are counted, not used). attrib_class: "point", "prim", "vertex" (uv and N usually live there) or "detail". frames: Measure at each of these frames: a row per node per frame, frames cooked in increasing order, the current frame put back. element_count is the point count and P's per-component min/max the bounds, so a sim's count and spread over time is ONE call. node_paths: Several nodes (variants) in the same call, instead of node_path. percentiles: e.g. [5, 50, 95] for the distribution (50 = median). group: Only the elements in this group pattern, as a SOP group field takes it: "grp", "@id>=0", "0-99"; space-separated parts add up. Point and prim classes. unique: Count distinct values of integer and string attributes (unique_count, most_common); for the prim class also vertices_per_prim, a trail's length and its distribution. distance_to: A SOP whose surface each point's distance is measured to (distance_to in the reply: min / max / mean, percentiles): particles crawling on or hovering over a mesh. Point class; the scene is not changed. Both are taken in their own SOP space: object transforms are not applied, so use it within one object.

get_volume_infoA

Per-volume name, resolution, active voxels, value range, mean and sum.

A primitive count cannot tell a correctly named non-empty density field from an empty one, which is the question worth asking before wiring a solver's sourcing. This is the SOP counterpart of get_cop_vdb.

threshold or bins read the voxels (VDB: active ones) for percentiles, a histogram, the count over threshold and box_above_threshold, the world box of the voxels over it: where the smoke is, not where the grid is.

Args: node_path: SOP node path holding volume or VDB primitives. max_volumes: Cap on volumes reported. threshold: Split the voxels at this value and box the ones above it. bins: Histogram bin count, or a list of bin edges.

sample_volumeA

Read named volume fields at world positions, or at another SOP's points.

"What does the collision SDF read where the particles are" is one call with from_node, and adds no node to the scene. A VDB SDF reads its background (the band width) outside its narrow band, not the distance.

Args: node_path: SOP holding the volumes. fields: Volume names (the name attribute), e.g. ["density"]. positions: [[x, y, z], ...] in world space. from_node: SOP whose points are the positions, instead of positions. limit: Values are returned up to this many positions; the summary always is. bins: Histogram bin count, or a list of bin edges, for the summary. threshold: Count the samples above this value.

compare_volumesA

How much of one field sits in each band of another field.

"How much density is inside the collider" is field="density", against="surface" (an SDF), bands=[-1000, 0, 1000]: the first band's field_total is what is inside. Both are sampled on a grid over field's box.

Args: node_path: SOP holding field. field: Volume to total, e.g. "density". against: Volume whose value picks the band, e.g. a collider SDF. against_node: SOP holding against, when not node_path. bands: Band count, or a list of band edges.

build_networkA

Build a whole node network in ONE atomic call — the PREFERRED way to construct anything of 3+ nodes (massively faster than node-by-node calls, and either the whole network builds or nothing does).

Every node type, parameter name, and input reference is validated against the running Houdini BEFORE anything is created; errors come back with did-you-mean suggestions. Use dry_run=True to prove a plan when using unfamiliar node types. The result includes cooked evidence: per-node errors and the display node's geometry counts — read them instead of assuming success.

Each node spec dict supports exactly these keys; an unknown one (in a spec or in an input entry) is a validation error with a did-you-mean, never a silently dropped request: type (required), name, parms (lists set whole parm tuples; a value written {"expr": "ch('../x')"} is set as an expression, with an optional "language": "hscript" | "python", also as one component of a list: "t": [{"expr": "$F"}, 0, 0]; a ramp takes the whole ramp as {"keys", "values", "basis"}), expressions (or its alias exprs: a block of parm name -> expression), inputs (list of source names — earlier spec names, existing children, or absolute paths; or dicts with index or input_name / source / source_output, where input_name is a connector name or label as get_node_card lists them and source_output an output index or name ("v", "P"); or {"indirect_input": n} to wire from connector n of the parent subnet itself), flags (display/render/bypass/template), color [r,g,b], comment, override_expression, run_callbacks. Parms are written in the order given.

A string aimed at a numeric parameter is caught during validation and answered with the {"expr": ...} spelling, instead of failing mid-build and rolling the whole graph back.

A literal in parms does not replace an expression the parm already holds (a Ray SOP ships dir = @N.x): the dry run lists such parms in expressions_in_the_way, the build reports expressions_kept and a warning. "override_expression": true on the spec clears them first.

Display: in a network that was empty, the last node gets the display flag unless a spec sets one. A display flag asked of a node that has none (a usdrender_rop) goes to its nearest input that has one, listed in display_set_upstream.

A LOCKED parm (karmarendersettings resolutiony while res_mode is autoheight) takes nothing; such a spec is refused at validation, nothing built, with locked_parms naming the menu whose callback sets the lock. Houdini runs callbacks only from the UI: "run_callbacks": true on the spec runs each parm's callback after its write, so {"res_mode": "manual", "resolution": [1920, 1080]} builds. Validation replays a spec on a probe, its callbacks included, only when it writes a parm a fresh node locks.

There is no "children" key: build the subnet, then call build_network again with the subnet as parent_path.

Nodes built inside a DOP network come with simulation_cache: the network to pass to reset_simulation before reading a frame it cooked.

Args: parent_path: Network to build inside (e.g. "/obj/geo1"). A missing parent directly under /obj is created, as the container the specs' context needs (geo for SOPs, lopnet for LOPs), and removed again if the build fails; a dry run reports it as would_create_parent. nodes: Ordered node specs (see above). dry_run: Validate the whole spec without creating anything. layout: Also lay out the parent network afterwards (default True; honoured only when auto-layout is enabled). The nodes this call creates are always positioned, each relative to its inputs, regardless of this flag; nodes that already existed keep their exact positions, so building into a hand-arranged network is safe.

verify_networkA

Inspect every node in a network at once — errors, warnings, flags, and the display node's cooked geometry counts.

Call this after building or modifying a network, the way an artist middle-clicks nodes: if healthy is false or error_nodes is non-empty, fix those nodes before telling the user anything is done. Each node lists errors, warnings, bypassed and display only when it has them; absent means none. For a LOP network the evidence is the stage (prims, cameras, lights, gprims without a material), for a COP network the image layer (resolution, channel ranges).

A node's errors are its LAST cook's verdict. A node that nothing has cooked since its cause was fixed is reported stale and listed in stale_error_nodes; pass force_cook=True to recook before judging. The default cooks only the display node, so a heavy scene is left alone.

Args: parent_path: Network to verify (e.g. "/obj/geo1"). force_cook: Cook the display node with force and recook every node that has errors, so the verdict is about the network as it is now.

get_node_cardA

Get the authoritative documentation card for a node type, straight from the running Houdini: connectors in order (inputs / outputs with index, name and label — the index of texcoord on mtlximage lives here), real parameter names/defaults/menus, and the node's own shipped help text. Connectors are read off a probe node the first time a type is asked for in a session (no undo entry, creation scripts not run); connectors_probed: false with connectors_note means they could not be read, not that the type has none. A menu whose items a script computes (loadtype on filemerge::2.0) is read off the same probe and marked menu_source: "generator", with the script in menu_generator. A radio folder set (switcher1 on an Add SOP: By Pattern / By Group) is listed as a FolderSet parm whose menu is its folders; a default that is an expression ($F on timeshift's frame) is in default_expression; a VOP's outputs carry their data_type.

Use this BEFORE setting parameters on a node type you have not used in this session — never guess parameter names. Unversioned names resolve to the newest version.

A menu carries menu_labels (same order as menu) whenever its labels differ from its tokens: "0"/"1"/"2" = Surface Scatter/Keep Input/Volume Scatter.

Args: node_type: Type name (e.g. "scatter", "rbdbulletsolver"). context: Category — "Sop", "Lop", "Vop" (MaterialX and other shader nodes inside a material network), "Dop", "Cop", "Chop", "Top", "Object", "Driver"; also "Cop2", "Shop", "VopNet". parm_filter: Substring filter for the parameter list. include_help: The node's help text (about 4 KB). Default: included for a whole card, left out when parm_filter asks for specific parameters. Pass True or False to decide.

find_expensive_nodesA

Profile cooking and rank the most expensive nodes — how a senior artist finds the slow node instead of guessing.

Records a performance-monitor profile while force-cooking the display outputs under root_path. cook_ms is cumulative (parents include their children), so compare siblings to locate the hotspot.

Args: root_path: Network to profile (a geo container, or "/" broadly). frame: Optionally jump to this frame before cooking. limit: Max nodes to return.

cook_frame_rangeA

Cook a node frame by frame and report what changed on each frame.

This is how you advance a sequential solver and how you prove a simulation is doing something. Frames are cooked in order, so a SOP solver, a DOP network or an animated chain all accumulate correctly, and per-frame cook time, errors, counts, bounding box and attribute aggregates come back in ONE round trip instead of one per frame. static: true means counts and bounds never changed over the range: the node cooks but does nothing. Past 25 frames the rows are 25 evenly spaced frames plus every frame with an error or warning (frames_shown); totals, static and slowest_frame still cover every frame.

Prefer this over set_frame in a loop, and over stepping by hand: a 100-frame check is one call rather than 100. The frame is left where the cook ended, ready to screenshot.

No deadline: a heavy sim runs under Houdini's progress bar for as long as it takes; wait for the verdict and call nothing else meanwhile. Stopped from that bar, it answers interrupted: true with the frames cooked so far. A node that keeps a cache across frames (Trail, SOP Solver) starts from what it holds: press_button its reset (Trail: clear) or reset_simulation first.

Args: node_path: Node to cook; its output is what gets measured. start: First frame. Defaults to the playbar start. end: Last frame, inclusive. Defaults to the playbar end. step: Frame increment. Keep at 1.0 for any solver, since skipping frames gives it a discontinuous time step and invalid results. attribs: Point attributes to aggregate per frame (min/max/mean/sum). volumes: Also report per-volume name, resolution and value range.

get_cook_statusA

Whether a node has cooked, how often, and whether it is time dependent.

Note the shape of the limitation: every command runs on Houdini's main thread, so a long cook blocks the bridge and cannot be polled while it runs. This answers the after-the-fact question instead -- did it really recook, is it time dependent, did it end in error -- plus whether the hip has unsaved changes. For asynchronous work use a ROP's background execution and get_render_progress.

Args: node_path: Node to report on.

list_installed_hdasA

List installed HDA definitions, grouped by library file.

A stock install loads thousands; pass a filter (namespace, name or path fragment). truncated says when limit cut the list.

Args: ctx: MCP context. filter: Substring filter for type names or file paths. limit: Maximum definitions returned.

get_hda_infoC

Get detailed information about an HDA definition.

Args: ctx: MCP context. node_path: Node path. hda_file: HDA file path. type_name: HDA type name.

install_hdaB

Install an HDA file into the current session.

Args: ctx: MCP context. file_path: HDA file path. force: Force reinstall even if already loaded.

uninstall_hdaC

Uninstall an HDA file from the current session.

Args: ctx: MCP context. file_path: HDA file path.

reload_hdaC

Reload an HDA file from disk.

Args: ctx: MCP context. file_path: HDA file path.

create_hdaC

Create a new HDA from an existing subnet node.

Args: ctx: MCP context. node_path: Subnet node path. hda_file: Destination HDA file path. type_name: Operator type name. label: Human-readable label. version: Version string.

update_hdaA

Save the current node contents back to its HDA definition.

The definition's library file is written by this call: saved_to_disk and library_file_mtime say so, so no separate save is needed. An embedded definition lives in the hip file and is kept when the scene is saved.

Args: ctx: MCP context. node_path: Node path.

get_hda_sectionsC

List all sections in an HDA definition.

Args: ctx: MCP context. node_path: Node path.

get_hda_section_contentC

Read the content of a specific section in an HDA definition.

Args: ctx: MCP context. node_path: Node path. section_name: Section name.

set_hda_section_contentC

Write content to a specific section in an HDA definition.

Args: ctx: MCP context. node_path: Node path. section_name: Section name. content: Section content.

list_hda_versionsC

Every installed definition of an HDA node's type: version, file, which is current.

Args: ctx: MCP context. node_path: An HDA instance.

set_hda_interfaceA

Author an HDA's Type Properties interface in one call.

Use this for the asset's TYPE interface — tab folders, strict ranges, ordered menus, Hide/Disable When. create_spare_parameter is a different thing: it adds parameters to one node instance and never reaches the type.

Each entry of parameters is a dict: name, label, type (int|float|string|toggle|menu|folder), default, min, max, min_strict, max_strict, components, menu_items ([value, label] pairs or plain strings), folder_type (tabs|simple|collapsible|radio) + children for folders, hide_when / disable_when (Houdini conditionals), help.

Example — a Controls tab whose Bevel disappears for a single stud: [{"name": "controls", "label": "Controls", "type": "folder", "children": [ {"name": "stud_count", "type": "int", "default": 4, "min": 1, "max": 8, "min_strict": True, "max_strict": True}, {"name": "bevel", "type": "float", "default": 0.02, "min": 0.0, "max": 0.1, "hide_when": "{ stud_count == 1 }"}, {"name": "material", "type": "menu", "menu_items": [["plastic", "Plastic"], ["metal", "Metal"]]}]}]

It is edit_hda_interface with one insert per entry: names already in the interface are refused before anything is written, and the reply is read back off the definition — ops[].stored, renamed_by_houdini (a tab folder joins the existing tab set's naming series), not_found_after_write, instance_parms_missing and instance_expression_errors.

Args: ctx: MCP context. node_path: An instance of the HDA whose definition is edited. parameters: Interface spec (see above). create_spare_parameters' spelling (parm_name, parm_type, default_value) is accepted too. replace: Start from an empty interface. Built-in parameters of the node type cannot be removed: Houdini puts them back (reinstated_by_houdini). dry_run: Validate and report the plan without writing.

edit_hda_interfaceA

Edit an HDA's EXISTING Type Properties interface in one atomic call: insert at a position, remove, hide/show, replace, modify, move.

set_hda_interface only appends. Every op here works on the definition's parameter group; all ops are applied to a copy, the result is checked for component-name collisions, and it is written once — a failing op changes nothing. Read the interface first with get_parm_template_tree.

Ops (dicts, applied in order): {"op": "insert", "spec": {...}, "after": name | "before": name | "in_folder": label or [labels]} — omit the position to append. spec is a set_hda_interface spec, plus types button (with "callback", Python by default), separator, label, vector, color, file, oppath; and fields naming_scheme (base1|xyzw|rgba|minmax| startend|uvw), default_expression (+ default_expression_language), hidden, join_with_next, callback, tags; folder_type "multiparm" for a multiparm block (children named "item#"). {"op": "remove", "name": name_or_folder_label} {"op": "hide" | "show", "name": ...} {"op": "replace", "name": ..., "spec": {...}} {"op": "modify", "name": ..., <label | help | default | default_expression | default_expression_language | min | max | min_strict | max_strict | hide_when | disable_when ("" clears) | hidden | join_with_next | menu_items | callback | naming_scheme | new_name | tags>} ("rename", "set_conditional", "set_default" are aliases) {"op": "move", "name": ..., "after" | "before" | "in_folder": ...}

Names are template names (t, not tx; stud_count); folders are addressed by label ("Controls"). Built-in parameters of the node type (an Object's Transform) cannot be removed — Houdini re-adds them at the top level and the reply says so in reinstated_by_houdini; hide them.

default_expression_language is "hscript" (Houdini's default) or "python"; given alone in a modify, it changes the language of the expression already there. stored reads both back, and instance_expression_errors names a default expression that does not evaluate on the instance.

Args: ctx: MCP context. node_path: An instance of the HDA whose definition is edited. ops: Operations, in order. dry_run: Validate and report the plan without writing.

search_helpA

Search the running Houdini's own documentation — concepts, workflows, VEX functions, expression functions, HOM API, and every effects manual SideFX ships. Version-exact, straight from the install.

Use this BEFORE improvising: when unsure how a workflow is meant to be done ("pyro shaping", "vellum constraints"), what a VEX or expression function does, or what a Solaris/TOPs concept means. Follow up with get_help_page on a result path.

Args: query: Search words (all must match a page). scope: Optional corpus, named after the archive. Every help archive in the install is searchable, which on a full 22.0 is 47 of them. The ones worth knowing by name: "nodes", "vex", "expressions", "hom", "solaris", "tops", plus the workflow manuals "pyro", "fluid", "vellum", "destruction", "grains", "crowds", "model", "copy", "assets", "render", "shade", "anim", "character", "ref", "shelf". Omit to search all. limit: Max results.

get_help_pageA

Fetch one page of Houdini's shipped documentation by path.

Read the real reference instead of writing from memory — especially the VEX function pages (vex/functions/...) before any justified wrangle, and expression pages (expressions/...) before channel expressions.

Args: path: As returned by search_help — e.g. "nodes/sop/scatter", "vex/functions/noise", "expressions/ch".

get_workflow_guideA

The server's written guide for a subject: what to build, in what order, which mistakes it exists to prevent, and the shipped help pages to read.

Call this BEFORE designing a setup you have not built this session, and again the moment two attempts at the same symptom have failed. Each guide is distilled from that subject's SideFX manual.

Args: topic: Help scope name or common alias: pyro, fluid (flip, water, whitewater), vellum (cloth), destruction (rbd), mpm (sand, snow), ocean, solaris, tops, model, copy, render, shade, character, crowds, heightfields, copernicus, assets, troubleshooting, dyno. description: What you are trying to build, for the guide's framing.

get_stage_infoA

Get USD stage info from a LOP node, or from a LOP network.

Given a network such as "/stage", the answer is about what that network displays: display_node (and render_node) name it, resolved_from is "display_node", viewport_delegate names the Hydra delegate the Scene Viewer draws with, and frame is the current frame.

Args: node_path: LOP node or LOP network path (default "/stage").

get_usd_primA

Get detailed info about a USD prim.

Array attributes longer than 16 elements (points, faceVertexIndices, primvars:st, ...) come back as a summary: size, element_type, the first 8 as head, and min/max for numeric data. That is what a mesh question needs; the full arrays of a building ran to 6.6 million characters. Pass full=True for every element, or read one array in windows with get_usd_attribute(offset=, limit=).

Values are read at time, or at the current frame when it is not given -- what a render of that frame sees; the reply names both as time and time_source. An attribute with time samples carries time_samples: its value differs at other frames. Relationships (a RenderSettings' camera) are listed with their targets. For the same attributes across many prims, get_usd_attributes reads them in one call.

Args: node_path: LOP node path. prim_path: USD prim path. full: Return array attributes in full instead of summarised. traverse_instance_proxies: List the children that live on an instanceable prim's prototype. Without it such a prim answers children: [] and is flagged is_instanceable with a hidden_descendants count, so the empty list is not read as "nothing inside". time: Time code (frame) to read at; default the current frame. attr_patterns: Glob patterns on attribute and relationship names (e.g. ["resolution", "karma:global:*"]); default all.

list_usd_primsA

List USD prims on a stage with filtering.

Instanced geometry is invisible to the default walk: an instanceable prim has no children of its own, they belong to its prototype. Set traverse_instance_proxies to list the prims under it.

Args: node_path: LOP node path. root_path: Root prim path to list from. prim_type: USD type filter (e.g. "Mesh", "Xform"). kind: Kind filter (e.g. "component", "group"). depth: Max traversal depth. traverse_instance_proxies: Descend into instanceable prims and list the prims under their prototypes.

get_usd_attributeA

Read a USD attribute value from a prim.

A long array (over 16 elements) answers with value as a summary (size, element_type, head, min/max) plus slice: the elements from offset, at most limit of them (default the first 64), with has_more. Walk a big array by raising offset; pass full=True to get every element in value at once.

A time-sampled attribute (a PointInstancer's positions, protoIndices) has nothing in its default slot: read with no time it answers null. With no time given, the current frame is read instead, and the reply carries time, time_source, time_samples and time_range, so value: null never stands unexplained next to is_authored: true.

Args: node_path: LOP node path. prim_path: USD prim path. attr_name: Attribute name. time: Time code (frame number). Omitted on a time-sampled attribute, the current frame is used (the first sample outside the range). full: Return the whole array as value. offset: First element of the window for a long array. limit: Window size for a long array.

get_usd_attributesA

Read the same attributes across many prims as one table.

One row per prim and attribute: {prim, prim_type, name, type, value, time_samples?} or, for a relationship, {prim, prim_type, name, relationship: true, targets}. The call for "sourceName of every RenderVar", "lpetag of every light", "the camera of the render settings" -- instead of one get_usd_prim per prim. matched counts every row found; truncated says the limit cut some off.

Args: node_path: LOP node path. prims: Prim paths or globs: * stays within one path element, ** crosses them (["/Render/Vars/*"], ["/lights/**"]). attr_patterns: Glob patterns on attribute and relationship names (["sourceName"], ["*lpetag"]); default all. prim_type: Keep only prims of this type (glob, e.g. "*Light"). relationships: Include relationships as rows. time: Time code (frame) to read at; default the current frame. full: Return array values in full instead of summarised. traverse_instance_proxies: Let globs match prims inside instances. limit: Row cap.

get_usd_world_transformA

World transform of USD prims at one or more frames.

get_usd_prim gives local xformOps; this composes every parent, so an animated parent shows. Per prim and frame: translate, rotate (XYZ degrees), scale and the row-major matrix. Each frame recooks the stage there, so LOP-parm animation reads right, and the playbar is restored.

Args: node_path: LOP node whose stage to read. prim_paths: Prim paths, e.g. ["/world/cam"]. frames: Frames to read at, at most 500. Default: the current frame.

get_usd_layersC

List all layers in a USD stage.

Args: node_path: LOP node path.

get_usd_prim_statsA

Get prim counts by USD type under a root path.

Instanced geometry counts once per prototype, not per instance: instanceable_prims says how many prims were counted without their contents, and traverse_instance_proxies counts what is under them.

Args: node_path: LOP node path. prim_path: Root prim path to gather stats from. traverse_instance_proxies: Count prims under instanceable prototypes.

get_last_modified_primsB

Get prims modified by the last LOP node cook.

Args: node_path: LOP node path.

create_lop_nodeA

Create a new LOP node.

Before using this, call list_node_types(context='Lop', filter='') to verify the correct node type. Solaris ships many specialized LOPs — sublayer, reference, materiallibrary, assignmaterial, karmarendersettings, editproperties, xform, prune, configurelayer, collection, addvariant — that may not be obvious from their names.

Args: parent_path: Parent node path. lop_type: LOP node type (e.g. "sphere", "sublayer", "merge"). name: Node name. prim_path: USD prim path to set on the node.

set_usd_attributeB

Set a USD attribute value via an inline Python LOP.

Args: node_path: LOP node path to connect after. prim_path: USD prim path. attr_name: Attribute name. value: Value to set.

get_usd_bound_materialA

The material each prim renders with, resolved the way the renderer resolves it (ComputeBoundMaterials), and where the binding comes from: direct on the prim, inherited from which ancestor, or which collection. A binding to a material prim that does not exist is reported in missing_material, not as unbound.

Batched: pass every prim of interest in one call.

Args: node_path: LOP node whose stage to read. prim_paths: Prim paths to resolve. purpose: "full" (default; what Karma renders, falling back to an all-purpose binding), "preview", or "all" (all-purpose bindings only).

get_usd_materialsA

List all USD materials on a stage.

Each material reports surface_shaders keyed by render context: "surface" is the universal output, a UsdPreviewSurface for viewports and Storm, and "mtlx" is the MaterialX shader Karma renders. surface_shader is the mtlx one when present, so it agrees with get_material_info on the same material.

bound_to lists the prims a binding is authored on. rendered_on (up to 50 paths) and rendered_on_count are the geometry that resolves to the material for rendering, including geometry bound through a parent or a collection; get_usd_bound_material says why for a given prim.

Args: node_path: LOP node path.

find_usd_primsB

Search USD prims by path pattern.

Args: node_path: LOP node path. pattern: Glob pattern (supports *, **) or substring. traverse_instance_proxies: Search prims under instanceable prototypes too; the default walk never visits them.

get_usd_compositionB

Get composition arcs for a USD prim.

Args: node_path: LOP node path. prim_path: USD prim path.

get_usd_variantsB

Get variant sets and selections for a USD prim.

Args: node_path: LOP node path. prim_path: USD prim path.

inspect_usd_layerC

Inspect a USD layer by index.

Args: node_path: LOP node path. layer_index: Layer index (0 = root layer).

create_lightB

Create a USD light in a LOP network.

Args: parent_path: Parent LOP network path. light_type: "dome", "distant", "rect", "sphere", "disk", or "cylinder". name: Light node name. intensity: Light intensity. color: [r, g, b] color values. position: [x, y, z] world position.

list_lightsC

List all USD lights on a LOP stage.

Args: node_path: LOP node path.

set_light_propertiesC

Set properties on a USD light prim via an inline Python LOP.

Args: node_path: LOP node path to connect after. prim_path: USD light prim path. properties: Property name-value pairs to set.

create_light_rigB

Create a preset lighting rig in a LOP network.

Args: parent_path: Parent LOP network path. preset: "three_point", "studio", "outdoor", or "hdri". intensity_mult: Multiplier for all light intensities.

list_materialsC

List all material nodes under a root path.

Args: ctx: MCP context. root_path: Root path to search for materials.

get_material_infoA

Get detailed information about a material node.

assignments lists the nodes under /obj and /stage whose material-path parameters name this material; only those parameters are read, so the call costs the same on a 4,000-node scene as on an empty one (assignment_scan reports how many nodes were visited).

Args: ctx: MCP context. node_path: Absolute path to the material node.

create_material_networkA

Create a new material network in /mat.

The keys base_color ([r, g, b]), roughness, metalness and opacity are accepted on both shader types and mapped to the shader's own parameter names (base_colorr/g/b and specular_roughness on MaterialX, basecolor, rough, metallic and opac on Principled). Any other key must be the shader's real parameter name; a list sets the whole parm tuple. The reply lists what was applied and, under "skipped", every key that matched no parameter, with the reason.

Args: ctx: MCP context. name: Name for the new material node. shader_type: "principled" (principledshader::2.0), "materialx" (mtlxstandard_surface), or any material node type name. params: Parameter name-value pairs to set on the shader.

list_material_typesB

List available VOP/material node types.

Args: ctx: MCP context. filter: Substring to filter type names and labels by.

create_nodeB

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.

Args: ctx: MCP context. parent_path: Parent network path. node_type: Node type (e.g. 'geo', 'box', 'grid'). name: Node name. position: [x, y] network editor position.

delete_nodeC

Delete a node.

Args: ctx: MCP context. node_path: Node path.

rename_nodeC

Rename a node.

Args: ctx: MCP context. node_path: Node path. new_name: New node name.

copy_nodeA

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.

Args: ctx: MCP context. node_path: Source node path. dest_parent: Destination parent path. new_name: Name for the copy. offset: [dx, dy] from the original's position.

move_nodeC

Move a node to a different parent network.

Args: ctx: MCP context. node_path: Node path. dest_parent: Destination parent path.

get_node_infoA

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).

Args: ctx: MCP context. node_path: Node path.

list_childrenA

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.

Args: ctx: MCP context. parent_path: Parent network path. recursive: Include all descendants (use sparingly on large scenes). filter_type: Node type filter (e.g. 'box', 'merge'). include_locked_assets: With recursive, also list what locked assets contain.

find_nodesA

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.

Args: ctx: MCP context. pattern: Glob pattern for node names (e.g. 'box*'). node_type: Node type filter (e.g. 'box', 'null'). context: Category filter (e.g. 'Sop', 'Object'). inside: Root path to search within (default '/').

list_node_typesA

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.

Args: ctx: MCP context. context: Category name (e.g. 'Sop', 'Lop', 'Dop', 'Top', 'Cop2'). filter: Substring to filter type name or label (case-insensitive). limit: Max entries to return (default 200, max recommended 200).

change_node_typeA

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.

Args: node_path: Node to change. new_type: Type name in the node's own category. keep_name: Keep the node's name. keep_parms: Carry parameter values over by name. keep_network_contents: 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).

press_buttonA

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.

Args: node_path: Node that owns the button. parm_name: The button parameter's name. arguments: Optional kwargs handed to the callback script; values must be int, bool, float or str. cook: Cook the node after the press so errors describe the result. action: Run the parm's action button (script_action) instead of its callback.

connect_nodesA

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.

Args: ctx: MCP context. source_path: Upstream node path; with indirect_input, the subnet whose input connector is the source. dest_path: Downstream node path. output_index: Source output index. input_index: Destination input index. input_name: Destination connector name or label (e.g. "base_color" on a VOP shader); wins over input_index. indirect_input: Index of the subnet input connector at source_path to wire from (dest_path must live inside that subnet).

connect_nodes_batchA

Connect multiple node pairs in a single call.

Args: connections: 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).

disconnect_nodeC

Disconnect one or all inputs of a node.

Args: ctx: MCP context. node_path: Node path. input_index: Input index to disconnect. disconnect_all: Disconnect all inputs.

reorder_inputsC

Reorder the input connections of a node.

Args: ctx: MCP context. node_path: Node path. new_order: New input ordering (e.g. [1, 0] swaps first two).

set_node_flagsC

Set flags on a node.

Args: ctx: MCP context. node_path: Node path. display: Display flag. render: Render flag. bypass: Bypass flag. template: Template flag. lock: Lock flag.

layout_childrenB

Auto-layout children of a network node.

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

Args: ctx: MCP context. parent_path: Parent network path. spacing: Spacing multiplier between nodes.

set_node_positionC

Set a node's position in the network editor.

Args: ctx: MCP context. node_path: Node path. x: Horizontal position. y: Vertical position.

set_node_colorB

Set a node's color in the network editor.

Args: ctx: MCP context. node_path: Node path. r: Red (0.0-1.0). g: Green (0.0-1.0). b: Blue (0.0-1.0).

create_network_boxC

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

Args: ctx: MCP context. parent_path: Network the box lives in. node_paths: Sibling nodes to enclose; the box fits around them. comment: Title shown on the box. color: RGB in 0..1.

create_sticky_noteB

Leave a sticky note in a network.

Args: ctx: MCP context. parent_path: Network the note lives in. text: Note text. position: [x, y] in network editor units. size: [width, height] in network editor units. color: RGB in 0..1.

set_object_transformA

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.

Args: ctx: MCP context. node_path: Object node, e.g. "/obj/geo1". translate: [tx, ty, tz]. rotate: [rx, ry, rz] in degrees. scale: [sx, sy, sz]. parent: Object to parent under, or "" to unparent.

get_parameterB

Get the value and metadata of a parameter.

A ramp reads as {"type": "Ramp", "basis", "keys", "values", "is_color"}, which set_parameters and build_network take back as it is.

Args: node_path: Node path. parm_name: Parameter name.

set_parameterA

Set a parameter value.

A parameter that holds an expression does NOT take a literal: Houdini writes the value into a slot the expression keeps overriding. The reply then carries expression_kept: true with the surviving expression and what you requested (plus same_as_evaluated when the expression happens to evaluate to that value right now) — read those before calling the write done. Pass override_expression=True to clear the expression first.

A parameter holding a BARE ch() reference is the opposite trap: Houdini writes THROUGH it into the parameter it reads, so the value lands on another node. The reply names that parameter in written_through.

Inside a DOP network a write does not reset frames already simulated: simulation_cache names the network to pass to reset_simulation.

A String parameter echoes raw_value (the unexpanded text, $JOB/...) next to the expanded new_value.

A list with {"expr": ...} components ("t": [{"expr": "$F"}, 0, 0]) and a whole ramp ({"keys", "values", "basis"}) go through set_parameters: this tool's value takes plain values only.

A LOCKED parameter (karmarendersettings resolutiony under res_mode autoheight) takes nothing at all; the error names the menu whose callback sets the lock. Houdini runs such callbacks only from the UI: set that menu with run_callbacks=True first, then the locked parameter.

Args: node_path: Node path. parm_name: Parameter name. value: New value (int, float, string, bool, or list). override_expression: Remove an expression standing in the way, instead of reporting that the write did not take. run_callbacks: Run the parameter's callback script after the write, as editing it in the UI does (callback_run in the reply, and callback_error when the callback raised).

set_parametersA

Batch-set multiple parameters on a node, in the order given.

Inside a DOP network a write does not reset frames already simulated: simulation_cache names the network to pass to reset_simulation.

Parameters that held an expression and therefore ignored the literal are listed in expressions_kept, with a top-level warning: a batch whose errors is empty can still contain a write that did not take. Values that landed on ANOTHER node, because the parameter is a bare ch() reference Houdini writes through, are in written_through. Each entry in set carries the same keys as set_parameter's reply. Pass override_expression=True to clear those expressions and links instead.

Locked parameters are in errors with locked: true and listed in locked_parms; the error names the menu whose callback sets the lock. With run_callbacks=True each parameter's callback runs after its write, so {"res_mode": "manual", "resolutiony": 1080} unlocks and then writes; a callback that raised is listed in callbacks_not_run.

Args: node_path: Node path. params: Mapping of parameter names to values, written in this order. A value written {"expr": "...", "language": "hscript" | "python"} is set as an expression, as in build_network, also as one component of a list ("t": [{"expr": "$F"}, 0, 0]). A ramp takes the whole ramp at once: {"keys": [0, 1], "values": [[1, 0, 0], [0, 0, 1]], "basis": "linear"} (one basis or one per key; a float ramp takes numbers), the shape get_parameter reads it in. A ramp's new_value is what it holds once the whole call is through, so a key added by count and then set reads as set. override_expression: Remove expressions standing in the way. run_callbacks: Run each parameter's callback script after its write, as the UI does.

get_parameter_schemaA

Get the template schema for parameter(s) on a node.

Most nodes have dozens of parameters; many have 100+. Always use parm_name or filter unless you genuinely need the full list.

Args: node_path: Node path. parm_name: Exact parameter name for a single-parameter lookup. filter: Substring to match against parameter name or label (case-insensitive). Use instead of dumping all params.

get_parm_referencesA

Who references a parameter, and what it references — in one call.

incoming: for each parameter of the node (or just parm_name), the parameters elsewhere whose expressions read it — what breaks if this control is renamed. outgoing: what this node's expressions and backtick strings read, resolved to parameter paths (pure ch() links and richer expressions alike; unresolved names a written target that no longer exists). node_dependents / node_references give the node-level view for this node only; include_node_level in the reply says whether they were included.

Args: node_path: Node to inspect. parm_name: One parameter instead of all of them. direction: "both", "incoming" or "outgoing". limit: Cap on reported entries. include_node_level: Include node_dependents / node_references. Default: on for a whole-node query, off when parm_name names one parameter; on an asset with hundreds of children those lists run to about 100 KB and answer a question about the node, not the parameter.

get_parm_template_treeA

The whole parameter interface as a tree, the way Type Properties shows it: folders (with folder_type — tabs, collapsible, multiparm), every parameter in order with defaults, default expressions, ranges, menu items, Hide/Disable When conditionals, callbacks, naming scheme; a multiparm's default_instances. Each entry uses get_parameter_schema's keys (default_value, is_hidden, menu_items...).

get_hda_info shows only the top folders and get_parameter_schema flattens the structure away; read this before editing an interface. Give node_path for a node (its instance interface, spares included) or type_name + context for a type.

Args: node_path: Node whose interface to read. type_name: Node type instead (with context). context: Category of type_name — "Sop", "Object", "Lop", ... folder: Narrow to one folder by label, or a list of nested labels. max_entries: Cap on entries (depth-first); the reply says when it cut. include_tags: Also return each template's tags (needed to preserve them when editing an interface; about a quarter of the size).

set_expressionC

Set an expression on a parameter.

Args: node_path: Node path. parm_name: Parameter name. expression: Expression string. language: "hscript" (default) or "python".

get_expressionC

Get the expression on a parameter.

Args: node_path: Node path. parm_name: Parameter name.

revert_parameterB

Revert a parameter to its default value.

A default that is itself an expression comes back, named in default_expression with its default_expression_language; expression_error says when it does not evaluate.

A locked parameter cannot be reverted; the error names what sets the lock.

Args: node_path: Node path. parm_name: Parameter name.

link_parametersA

Create a channel reference from one parameter to another.

The destination gets an HScript expression that reads the source as its own type: chs() for a String parameter, ch() for numbers, toggles and menus. The path is relative to the destination node (chs("../CTRL/mat")), so the link survives moving the pair, collapsing into a subnet or instancing an HDA. The reply carries the expression, the function used and the destination's evaluated value.

Args: source_path: Source node path. source_parm: Source parameter name. dest_path: Destination node path. dest_parm: Destination parameter name. replace_existing: Overwrite a destination that already has keyframes or an expression. Refused otherwise, so animation is never lost by accident. A link whose source already reads the destination through ch() is refused as a cycle in every case.

lock_parameterC

Lock or unlock a parameter.

Args: node_path: Node path. parm_name: Parameter name. locked: True to lock, False to unlock.

create_spare_parameterB

Add a spare parameter to a node.

Args: node_path: Node path. parm_name: Internal parameter name. parm_type: "float", "int", "string", "toggle", or "menu". label: UI label. default_value: Default value. min_val: Minimum value (float/int only). max_val: Maximum value (float/int only).

create_spare_parametersA

Batch-create multiple spare parameters in one call, optionally in a folder tab.

A name that already exists as a spare parameter is updated in place (label, default, range); its current value and keyframes are kept. A type change on an existing parameter is refused.

Args: node_path: Node path. parameters: List of parameter specs. Each dict has keys: parm_name (str), parm_type (str: "float"/"int"/"string"/"toggle"/"menu"), label (str), default_value (optional), min_val (optional), max_val (optional). folder_name: If provided, wraps all parameters in a named folder tab. folder_type: Folder style: "Tabs", "Collapsible", or "Simple".

get_parametersA

Read many parameter values at once, matched by name or label substring.

The batch counterpart of set_parameters. Several unrelated groups of settings ("flame", "wind", "buoy") come back in one call instead of one call each, and unlike get_node_card these are the live values on this node rather than the defaults for its type.

Pass inside instead of node_path to read the same patterns across a whole network in one call: "every file parm of this material library, unexpanded" comes back as rows of {node, parm, value, raw_value}, up to 2000 rows. raw_value is the unexpanded text ($JOB/...), shown when it differs from the value, exactly as for a single node.

Args: node_path: Node to read. patterns: Substrings matched against parameter name and label. Omit for everything, up to the cap. Required with inside, unless non_default_only. include_defaults: Also report whether each value is still the default, and, where it differs, the default (default, default_expression). inside: Network to read instead of a single node. recursive: With inside, include every descendant, not only children. Nodes inside locked HDAs (a solver's own internals) are skipped and counted in skipped_inside_locked_assets. node_type: With inside, only nodes of this type (e.g. "mtlximage"). include_locked_assets: With recursive, read inside locked HDAs too. non_default_only: Only parameters changed from their defaults, each with its default: "what was changed on every node of this network" in one call (with inside, no patterns needed).

list_panesA

List all visible pane tabs in the Houdini UI.

get_viewport_infoC

Get viewport settings for a pane tab.

Args: pane_name: Pane tab name.

set_viewport_cameraA

Set the viewport to look through a specific camera.

Args: camera_path: Camera node path, or a USD camera prim path for a Solaris viewport. The result reports the camera the viewport is actually looking through, and fails if it did not take. pane_name: Pane tab name.

set_viewport_displayA

Set how the viewport draws: shading, environment background, grid, particle point size, colour scheme. Any of them in one call; each is read back in the reply.

Args: display_mode: One of 'wireframe', 'shaded', 'smooth', 'smooth_wire', 'hidden_line', 'flat', 'flat_wire', 'matcap', 'matcap_wire'. pane_name: Pane tab name. environment_background: False hides an environment (dome) light's map behind the scene, True shows it. Set on every view of the viewer; the reply reads it back per view. reference_plane: False hides the reference plane (the grid), True shows it. point_size: Diameter in pixels of particles drawn as points, on every view of the viewer. color_scheme: 'dark', 'darkgrey', 'grey' or 'light', on every view.

set_viewport_rendererA

Set the viewport's Hydra rendering delegate for live preview.

Use this during lookdev to preview materials and lighting directly in the viewport instead of writing full renders to disk.

Args: renderer: Renderer name. The result reports the delegate that is actually active afterwards, read back from Houdini rather than inferred from a setter not raising. renderer: Renderer name — "GL", "Storm", "Karma CPU", "Karma XPU", etc. Case-insensitive partial match. pane_name: Pane tab name.

frame_selectionC

Frame the current selection in the viewport.

Args: pane_name: Pane tab name.

frame_allA

Frame all geometry in the viewport, or only some nodes or a box.

Args: pane_name: Pane tab name. node_paths: Frame just these objects or SOPs (their world bounds), not the spread of everything in the scene. An object frames what it draws: a null its marker, a camera or a light its icon. bounds: Frame [xmin, ymin, zmin, xmax, ymax, zmax], world space. A point is framed as a 1-unit cube around it (padded in the reply).

set_viewport_directionA

Set the viewport to a standard viewing direction, or place the free view.

rotation/pivot/distance orbit the viewport's own (non-camera) view: rotation [rx, ry, rz] in degrees about the pivot, distance from it. The reply reads the view back. Looking through a camera, move the camera.

Args: direction: "front", "back", "top", "bottom", "left", "right", or "perspective". pane_name: Pane tab name. rotation: [rx, ry, rz] degrees for the free view. pivot: [x, y, z] the free view orbits. distance: Distance of the free view from its pivot along its view axis (the dolly); a sideways pan is not counted in it.

capture_screenshotA

Capture a screenshot of the viewport or a specific pane tab.

The image is written to disk only; open output_path with your file reader to look at it. Prefer get_geometry_info, get_node_info or get_scene_summary unless visual confirmation is genuinely needed. A Scene Viewer capture names the network it shows (viewer_network); viewer_note says when that is a DOP network, drawn as the simulation's objects rather than the SOP display.

Args: output_path: Image file path. Default: a new PNG in the temp dir. pane_name: Pane tab name. settle_seconds: Wait this long before capturing, without blocking Houdini, so a Karma viewport can converge after a change. Use this instead of a shell sleep between calls. Capped at 120.

capture_network_editorA

Capture a screenshot of the network editor.

With node_path the view is put on that node at once (no animated flight), and the reply says what the frame shows: visible_bounds, node_bounds and node_in_view, all in network space.

The image is written to disk only; open output_path with your file reader to look at it. Prefer get_node_info or list_children for inspecting node connections unless visual confirmation of wiring is genuinely needed.

Args: output_path: Image file path. Default: a new PNG in the temp dir. node_path: Node path to frame before capture.

set_current_networkA

Navigate the network editor to a network; the viewer follows it in.

Call it on the network you build in. By default the viewer then hides every other object (the viewport's Y hotkey, no display flag touched), so the work is seen on its own and the rest of the scene does not cook.

Args: network_path: Network path to navigate to. other_objects: "hide" (default), "ghost", "show", or null to leave the viewer as it is.

find_error_nodesC

Find all nodes with errors or warnings in the scene.

Args: root_path: Root node path to search from.

log_statusA

Display a status message in Houdini's status bar.

Call this at the START of every major step so the user can follow along in real time without having to inspect tool call logs. Examples: "Creating base geometry...", "Wiring SOP chain...", "Setting up pyro simulation...", "Assigning materials...".

Args: message: Status message to display (keep it short and human-readable). severity: "message" (default), "important", "warning", or "error".

set_viewer_contextA

Point the Scene Viewer at a network, and optionally a node inside it.

set_current_network moves the network EDITOR; this moves the VIEWER. That is what decides whether a scene graph view exists, so it is the prerequisite for previewing a USD stage or setting a Hydra delegate: call this with "/stage" before set_viewport_renderer or before binding a USD camera prim.

The result reports is_scene_graph_view, which is the question you are usually really asking.

Args: network_path: Network for the viewer to display, e.g. "/stage". current_node: Node inside it to make current, which selects the stage a Solaris viewport shows. pane_name: Pane tab name.

render_viewportB

Capture the current 3D viewport to an image file.

Args: output_path: Image file path. Default: a new PNG in the temp dir. resolution: [width, height] in pixels. camera: Camera node path. settle_seconds: Wait this long before capturing, without blocking Houdini, so a Karma viewport can converge after a change. Use this instead of a shell sleep between calls. Capped at 120.

render_quad_viewB

Capture all four viewport panes to separate images.

Args: output_path: Base image path; viewport names are appended. Default: a new PNG in the temp dir. resolution: [width, height] in pixels.

list_render_nodesA

List all render (ROP/Driver) nodes in the scene.

get_render_settingsC

Get render settings from a ROP node.

Args: node_path: ROP node path.

set_render_settingsC

Set render parameters on a ROP node.

Args: node_path: ROP node path. settings: Parameter name-value pairs.

create_render_nodeC

Create a new render (ROP) node in /out.

Args: renderer: Renderer type ('karma', 'opengl', 'mantra', 'rop_geometry', 'rop_alembic', 'usdrender', 'fetch', 'merge', 'rop_fbx', 'rop_gltf'). name: Node name. camera: Camera node path. output_path: Output file path.

start_renderA

Execute any node that renders or writes files.

Foreground by default: Houdini shows its own progress dialog and the user can cancel. The call holds until the render finishes, however long that is; a client that hands a long call to a background task notifies you with the verdict. Do nothing else in Houdini meanwhile and never poll the disk.

Not just /out ROPs: a LOP usdrender_rop (which is how Solaris renders), a SOP ROP Geometry, or a File Cache's Save to Disk all work, because what matters is whether the node can be executed rather than its category.

The result reports the output path it wrote to and whether anything is actually on disk there, so a render that succeeds and writes nowhere is visible instead of silent.

Args: node_path: Any node with a render() or an 'execute' button. frame_range: [start, end] or [start, end, increment]. background: Render in a separate hython on the saved hip and return at once with status "launched"; get_render_progress reports the process, its log tail and the files. The user sees no progress in Houdini, so use it only when asked to keep working while a render runs. overrides: {parm_name: value} for this render only, e.g. a draft {"resolutionx": 640, "resolutiony": 360}; a parm tuple takes a list. Put back afterwards, expressions and keyframes included, even if the render fails (overrides_applied, overrides_restored). Foreground only. A Karma LOP's "Wait for Render to Complete" is switched on for the call when it is off (foreground_forced).

render_node_networkB

Capture a screenshot of a node's network editor view.

Args: node_path: Node path to focus on. output_path: Image file path. Default: a new PNG in the temp dir.

get_render_progressA

Progress of a render or write started with start_render.

Accepts every node start_render accepts (a LOP usdrender_rop or Karma LOP, a SOP ROP, a File Cache), not only /out ROPs. Reports the node's errors with license_error singled out, the output files on disk, and for a background render the process state and the tail of its log. done is true when there is nothing left to wait for.

Args: node_path: The node given to start_render.

render_sheetA

Render frames start..end with the OpenGL ROP and tile them into one image.

One image shows motion a single frame cannot: a sim's spread, a camera move. Needs no viewport, so it works in a headless session too. A snapshot of the scene as it is now (unsaved edits included, the session untouched) renders in a separate hython, since a second OpenGL render in one hython crashes on Houdini 22; that hython takes a license seat while it runs. Frames are labelled. Objects (/obj) only, not a LOP stage.

Args: start: First frame. end: Last frame. step: Frame step; at most 64 frames in all. camera: Camera object path. Default: the scene's only camera. resolution: [width, height] of each tile. Default [320, 240]. columns: Tiles per row. Default: about square. output_path: Sheet image path. Default: a new PNG in the temp dir.

get_houdini_connection_statusA

Check the MCP-to-Houdini bridge without raising on disconnect.

Returns structured connection diagnostics, including the configured bridge URL and Houdini health payload when reachable, and sessions: every Houdini serving the plugin (port, pid, version), the one in use marked current. connect_houdini switches; start_houdini starts one. Use this before live viewport workflows when Houdini may have restarted.

get_scene_infoC

Get information about the current Houdini scene.

new_sceneA

Create a new empty Houdini scene.

Args: save_current: Save the current scene before clearing.

save_sceneB

Save the current Houdini scene to disk.

Args: file_path: Destination path; defaults to the current hip file.

load_sceneA

Open a Houdini hip file, or merge it — or named nodes from it — into the current scene.

Load warnings (missing assets and the like) come back in warnings. A merge reports what arrived: merged_nodes, conflicts (a node that already exists is merged under a new name, or overwritten in place with overwrite_on_conflict=True) and not_found_in_file. node_paths are absolute (/obj/building_v3) and bring their contents.

Args: file_path: Path to the hip file to open. merge: Merge into the current scene instead of replacing it. node_paths: With merge, the absolute node paths to merge; default everything. overwrite_on_conflict: With merge, overwrite same-named nodes instead of renaming the merged copy.

import_fileC

Import a geometry, USD, or Alembic file into the scene.

Args: file_path: Path to the file to import. parent_path: Network path for the import node. node_name: Name for the created node.

export_fileA

Export a node's output to a file on disk, and report whether it landed.

SOPs are saved directly, LOPs export their USD stage, and a /out ROP is pointed at file_path and executed (its own output path is restored afterwards). Reports wrote_files, so success: True means a file appeared or changed -- not merely that the call returned. A frame_range writes name.0001.ext per frame and leaves the playbar where it was.

Args: node_path: Path to the node to export. file_path: Destination file path. For a ROP this overrides its output parameter for the duration of the export. frame_range: Frame range as [start, end] or [start, end, step].

get_context_infoC

Get information about a Houdini network context.

Args: context: Context path, e.g. "/obj", "/stage", "/out".

undoA

Undo the last change(s) made in Houdini.

Every tool call is one undo step, however many nodes it touched, so one undo reverses one build_network or set_parameters call. Needs a graphical Houdini: hython keeps no undo history.

Args: ctx: MCP context. steps: How many steps to undo (default 1).

redoA

Redo the last undone change(s) in Houdini.

Args: ctx: MCP context. steps: How many steps to redo (default 1).

connect_houdiniB

Talk to the Houdini serving on port from now on.

get_houdini_connection_status lists the sessions and their ports.

Args: port: Port of a Houdini serving the plugin.

start_houdiniA

Start a Houdini of this server's own and connect to it.

Headless (hython) by default: no window, no viewport, so the capture tools refuse there. gui=True starts the full application, which serves only if the plugin's package is installed (fxhoudinimcp install). Either takes a license seat until stop_houdini. Set HYTHON to choose the build.

Args: gui: Start the Houdini application instead of headless hython. hip_file: Scene to open. wait_seconds: How long to wait for it to serve.

stop_houdiniA

Stop a Houdini that start_houdini started, and go back to the previous session.

Only sessions started by this server can be stopped: anything else may be someone's unsaved work.

Args: pid: Session to stop. Default: the current one, if this server started it.

list_shelf_toolsA

Find shelf tools by name, label or keyword.

Use this when a setup exists as a shelf tool rather than as a node: oceans, quick sims, rigging setups. A full install ships around 8,000 of them, so always filter.

Args: filter: Substring matched against name, label and keywords. limit: Maximum tools to return.

get_shelf_tool_scriptA

Read the script a shelf tool runs, plus its help and imports.

This is how you learn SideFX's own recipe instead of reinventing it. Most scripts are two or three lines calling a worker in a toolutils module, and the reported imports name exactly what to read next.

Args: tool_name: Internal tool name, from list_shelf_tools.

run_shelf_toolA

Run a shelf tool and report the nodes it created.

A tool that asks for objects takes selection, or the objects already selected, as in Houdini. A tool that asks for anything else is retried once as a Ctrl+click, Houdini's "place immediately" (ran_as_ctrl_click): the Crowds Simulate tool then builds its whole default crowd. A tool that still asks (the FLIP ocean layer, collide-with) is refused, since through the bridge it would block Houdini until someone clicks: read the recipe with get_shelf_tool_script and build the nodes with build_network.

Nodes the tool added inside networks that already existed (a FLIP tool into the current POP network) are listed in created_in_existing; current_dop_network says where DOP tools put theirs, before and after.

Args: tool_name: Internal tool name, from list_shelf_tools. kwargs: Overrides merged into the synthetic kwargs the script reads. parent_path: An extra network to watch for new nodes. /obj, /stage, /out, /mat and /img are always watched, because a shelf tool is free to build in more than one of them: largeOcean creates both a geo in /obj and a LOP in /stage. A SOP network given here is also where a SOP tool places its nodes (placed_in). selection: Object paths the tool takes as its object selection. The scene's selection is left as it was, whatever the tool selects.

list_takesB

List all takes in the scene with their hierarchy.

get_current_takeB

Get the current take and its overridden parameters.

set_current_takeC

Set the current take by name.

Args: name: Take name to make current.

create_takeB

Create a new take, optionally under a parent take.

Args: name: Name for the new take. parent_name: Parent take name (defaults to current take).

get_top_network_infoB

Get an overview of a TOP network.

Args: ctx: MCP context. node_path: TOPnet or TOP node path.

cook_top_nodeB

Cook a TOP node to execute its work items.

Args: ctx: MCP context. node_path: TOP node path. block: Wait for cooking to complete. generate_only: Only generate work items, do not cook.

cancel_top_cookC

Cancel active cooking on a TOP network.

Args: ctx: MCP context. node_path: TOP node or TOPnet path.

pause_top_cookC

Pause cooking on a TOP network.

Args: ctx: MCP context. node_path: TOP node or TOPnet path.

dirty_work_itemsB

Dirty work items on a TOP node so they can be regenerated.

Args: ctx: MCP context. node_path: TOP node path. remove_outputs: Also remove output files from disk.

get_work_item_statesC

Get work item state counts for a TOP node.

Args: ctx: MCP context. node_path: TOP node path.

get_work_item_infoC

Get detailed information about a specific work item.

Args: ctx: MCP context. node_path: TOP node path. work_item_index: Work item index within the node.

get_pdg_graphC

Get the PDG dependency graph structure for a TOP network.

Args: ctx: MCP context. node_path: TOPnet or TOP node path.

generate_static_itemsB

Generate static work items on a TOP node without cooking.

Args: ctx: MCP context. node_path: TOP node path.

get_top_scheduler_infoC

Get information about TOP scheduler nodes in a network.

Args: ctx: MCP context. node_path: TOP scheduler or TOPnet path.

get_failed_work_itemsC

List the work items that failed on a TOP node, with the tail of each log.

Args: ctx: MCP context. node_path: TOP node path. limit: Maximum items returned.

get_top_logsA

Cook logs for a TOP node, or the scheduler log of one work item.

Args: ctx: MCP context. node_path: TOP node path. work_item_index: Work item index; omit for the node's own errors and warnings. tail: Maximum characters of log text, taken from the end.

create_wrangleA

Create an Attribute Wrangle node with VEX code.

LAST RESORT. VEX is for attribute math that no node expresses — NEVER for modeling, scattering, copying, deforming, grouping, or randomizing, which all have dedicated nodes. Building geometry in a wrangle when a native node exists is a failure, not a shortcut.

The justification parameter is mandatory: state which list_node_types searches you ran and why none of the results can do this. If you cannot write that sentence honestly, you have not checked — check first.

Args: parent_path: Parent SOP network path. vex_code: VEX snippet to set. justification: Which native nodes you checked (the actual list_node_types filters used) and why none can express this logic. run_over: Element to run over ("Points", "Vertices", "Primitives", "Detail", "Numbers"). name: Node name.

set_wrangle_codeC

Set VEX code on an existing Attribute Wrangle node.

Args: node_path: Path to the wrangle node. vex_code: VEX snippet to set.

get_wrangle_codeC

Read the VEX code from an Attribute Wrangle node.

Args: node_path: Path to the wrangle node.

create_vex_expressionA

Set an HScript expression on a parameter, evaluated before it is kept.

Parameters cannot run VEX: attribute @ syntax is refused with a pointer to create_wrangle. An expression that does not evaluate is not kept.

Args: node_path: Path to the node. parm_name: Parameter name. vex_code: Expression code, in HScript syntax.

validate_vexC

Validate VEX code by cooking the node and checking for errors.

Args: node_path: Path to the wrangle node.

setup_pyro_simA

Build a Pyro smoke/fire simulation network from source geometry.

Preferred over manual DOP wiring — builds the entire pyro network in one call: Pyro Source (density, temperature, burn), Volume Rasterize Attributes, Pyro Solver and a File Cache. For custom setups beyond what this provides, use create_node with DOP nodes (pyrosolver, smokeobject, volumesource, etc.).

Args: source_geo: Source SOP path. container: Container type. res_scale: Resolution scale multiplier. substeps: DOP substeps. name: Top-level geo node name.

setup_rbd_simA

Build an RBD rigid-body simulation network with fracture and solver.

Preferred over manual DOP wiring — builds the entire RBD network in one call. For source geometry, build SOP chains with native nodes (voronoifracture, booleanfracture, rbdmaterialfracture) instead of VEX.

Args: geo_path: Source geometry object path. ground: Add a ground plane. pieces_type: Fracture method ("voronoi"). name: Top-level geo node name.

setup_flip_simA

Build a FLIP fluid simulation network from source geometry.

Preferred over manual wiring — builds SideFX's SOP FLIP chain in one call: FLIP Container sized around the source, FLIP Boundary emitting from it, FLIP Solver with a ground plane at y=0, and a File Cache on the particles.

Args: source_geo: Source SOP path. domain: Domain type. particle_sep: Particle separation distance. name: Top-level geo node name.

setup_vellum_simA

Build a Vellum simulation network with configure node and solver.

Preferred over manual DOP wiring — builds the entire Vellum network in one call: the shelf's Configure recipe for the type, the Vellum Solver, and a Vellum I/O cache that keeps constraints and collisions with the geometry. Use Vellum Drape SOP to let cloth settle before the main simulation.

Args: geo_path: Source geometry object path. sim_type: Simulation type ("cloth", "hair", "grain", "softbody"). substeps: Solver substeps. name: Top-level geo node name. ground: Turn on the solver's ground plane at y=0.

create_materialB

Create a material in /mat with configurable surface properties.

Args: name: Material node name; refused if taken. Default: material1, numbered up when that exists. mat_type: Material type ("principled", "materialx"). base_color: [R, G, B] base color, 0-1 per channel. roughness: Surface roughness, 0-1. metallic: Metallic factor, 0-1. opacity: Opacity, 0-1.

assign_materialC

Assign a material to a geometry node via a Material SOP.

Args: geo_path: Target geometry node path. material_path: Material to assign.

build_sop_chainA

Build a sequential chain of SOP nodes wired together in a single call.

PREFERRED over individual create_node calls for linear SOP chains — builds and wires the entire chain in one round-trip, which is significantly faster.

Each step dict: {"type": str, "name": str (optional), "params": dict (optional)}. Nodes are created in order and each is automatically connected to the previous.

Example: steps=[ {"type": "box"}, {"type": "polybevel", "params": {"offset": 0.05}}, {"type": "scatter", "params": {"npts": 200}}, {"type": "copy_to_points", "name": "copy1"}, ]

Args: parent_path: Parent SOP network path. steps: List of step dicts defining the chain.

setup_renderB

Set up a render configuration with camera and ROP node.

Args: renderer: Renderer type ("karma", "mantra"). camera: Camera node path; creates one if omitted. output_path: Output image path (supports Houdini variables). resolution: [width, height] resolution. samples: Render sample count. name: ROP node name in /out.

Prompts

Interactive templates invoked by user choice

NameDescription
procedural_modeling_workflowGuide for building a procedural modeling network in SOPs. Args: description: What geometry to create (e.g. "a rocky terrain with scattered trees") output_context: Where to create the geo container
usd_scene_assemblyGuide for building a USD scene in Houdini's LOPs/Solaris. Args: scene_description: Description of the USD scene to build
simulation_setupGuide for setting up a dynamics simulation. Dispatches to the solver-specific guide when one exists, because a single generic file had to cover pyro, FLIP, Vellum, RBD and MPM at once and so could not say more than a table row about any of them. Houdini ships a separate manual per solver, and these files mirror that split. Anything without its own guide falls back to dyno.md, the general dynamics one. Args: sim_type: Type of simulation (pyro, flip, rbd, vellum, mpm, pop) description: Additional context about the simulation
pdg_pipelineGuide for building a PDG/TOPs pipeline. Args: task_description: What the pipeline should accomplish
hda_developmentGuide for creating a Houdini Digital Asset. Args: asset_description: What the HDA should do context: Node context for the HDA (Sop, Lop, Object, etc.)
copernicus_workflowGuide for image work in Copernicus (COPs). Args: description: What to build (e.g. "a tileable rust texture")
heightfield_terrainGuide for building terrain with heightfields. Args: description: The terrain to build (e.g. "an eroded desert mesa")
houdini_workflowGuide for any Houdini subject the shipped manual documents. One entry point rather than a function per subject, so a new corpus needs a markdown file and nothing else. `topic` is the SideFX help scope name, which is also the markdown filename: character, render, shade, crowds, copy, props, dopparticles, io, anim, ocean, grains, muscles, finiteelements, feathers, fur, ml, composite, heightfields_cop, plus every subject that has its own named prompt (pyro, fluid, vellum, destruction, mpm, solaris, tops, model, assets, copernicus, heightfields, dyno, troubleshooting). Args: topic: Help scope name for the subject, e.g. "character" or "render" description: What you are trying to build
debug_sceneSystematic approach to debugging a Houdini scene. Args: problem_description: What problem the user is experiencing

Resources

Contextual data attached and managed by the client

NameDescription
scene_infoCurrent Houdini scene information including hip file, version, frame range, and node counts.
scene_treeTop-level node tree of the current scene.
scene_errorsAll nodes with errors or warnings in the scene.
installed_hdasList of installed Houdini Digital Assets.

TDQS

B3.1/5.0

Scored across 215 tools

Disambiguation3/5

Several clusters overlap in purpose: get_parameter/get_parameters/get_parameter_schema/get_node_card/get_parm_template_tree all read parameter data, while capture_screenshot/render_viewport/render_quad_view/render_node_network/capture_network_editor all capture images, and execute_hscript/execute_python/evaluate_expression/set_expression/create_vex_expression all involve expressions. The very detailed descriptions explicitly steer between many of these, but with 215 tools an agent still faces real misselection risk.

Naming Consistency4/5

Almost all names follow a predictable snake_case verb_noun pattern (get_parameter, set_parameters, create_node, list_usd_prims, build_network), which is highly consistent across contexts. Minor deviations exist, such as playbar_control, undo/redo, and a few noun-first or verb-only names, but these are rare and readable.

Tool Count2/5

At 215 tools this is far beyond the typical well-scoped range and places a heavy selection and context burden on the agent, even for a domain as broad as Houdini. The breadth justifies some expansion, but the surface is clearly over-large and would benefit from consolidation or progressive disclosure.

Completeness4/5

Coverage is unusually broad: node creation/deletion/wiring, parameter read/write/expressions, geometry inspection, DOP/TOP/CHOP/COP/LOP workflows, USD, HDAs, caches, rendering, viewport, takes, undo and session management are all present. There are minor gaps (e.g. no dedicated spare-parameter removal or parameter renaming), but agents can generally work around them with the provided escape hatches.

Maintenance

ActivityActive
ResponsivenessSlow