houdini-bridge-mcp
About
Drive SideFX Houdini from an AI chat — a security-first, data-only control surface where the AI authors validated wrangles, never arbitrary code.
Details
- Author
- eviscerations
- Categories
- Other
Jump to
Step 2 — Install the auto-arm Houdini package
This drops a small Houdini](https://rustup.rs)packagethat arms the executor automatically when Houdini's GUI starts — so the bridge comes up ready, with no "start the server" step.
Via the GUI (recommended):launch the binary, thenSettings → Install Houdini package.
Or manually,copy the two static package files into your Houdini user preference directory (defaults to%USERPROFILE%\Documents\houdini21.0):
houdini_package/houdini-bridge-mcp.json → <houdini-user-pref-dir>/packages/houdini-bridge-mcp.json houdini_package/houdini-bridge-mcp/scripts/456.py → <houdini-user-pref-dir>/houdini-bridge-mcp/scripts/456.py
The package files are shippable — no absolute paths, usernames, or machine values; everything dynamic is read at runtime from the shared config file.
Launch the binary withHMCP_GW_HEADLESSunset so the window appears, then:
- Settings— confirm theexecutor portandsession token(defaults are fine; the token is the shared secret between the two halves).
- Working dir— type yourproject root. Every subdirectory under it is reachable; nothing outside it is. ClickApply.
- Back inSettings, turn onAuto-arm Houdini.
Apply + Auto-arm write the shared config file (arm.json, under your user profile) that the GUI, the executor, and the headless gateway all read live. Changing the working directory later is justApply— no restart.
Wherearm.jsonlives / enabling safe-VEX.arm.jsonis the trust root — working dir, session token, port, and feature flags — at:
%USERPROFILE%\.houdini-bridge-mcp\arm.json (Windows) ~/.houdini-bridge-mcp/arm.json (macOS / Linux)
The one opt-in code lane,set_attrib_expr, isoff by default. To turn it on, openSettings → Safe-VEX (advanced)and flipEnable safe-VEX (allow_attrib_expr)— it takes effect immediately (the executor re-reads the flag per call; no restart). That panel also hasOpen arm.jsonandOpen config folderbuttons if you'd rather hand-edit; to enable by hand, set"allow_attrib_expr": truein the file. This is anoperator-onlyswitch — a driving agent can never reacharm.json(it is held off-limits even when the working dir is misconfigured to an ancestor), so the AI cannot enable its own code lane. Turn it back off the same way when you're done.
The executor armsfail-closed— it refuses to arm unless a firewall rule blocks inbound connections to its loopback port. Run the bundled script once, from an elevated shell:
scripts/harden-firewall.ps1 # -Mode loopback (default): loopback-only, single machine scripts/harden-firewall.ps1 -Mode lan # allow a trusted studio LAN to reach the executor
Useloopback(the default) for a single trusted machine; uselanonly on a trusted studio network.
Launch Houdini. The installed package auto-arms the executor from the shared config — the console prints:
The GUI's status pill showsArmedwith the connected Houdini version — for most people that pill is all the confirmation you need. No Python-shell snippet required. If you want to double-check from a terminal (optional, for the curious — use your configured port and token):
curl.exe http://127.0.0.1:8765/health -H "X-HMCP-Token: <your-token>"
→{"ok": true, "service": "houdini-bridge-mcp", ...}
Point your client (e.g. Claude Desktop — edit the file at%APPDATA%\Claude\claude_desktop_config.json; paste that path into the File Explorer address bar to find it) at the gateway binary inheadlessmode (no window — the AI drives it directly). The gateway reads the working directory, port, and token from the shared config file, so the env block only needs the headless flag. Setcommandto the full path of the.exefrom Step 1:
{ "mcpServers": { "houdini-bridge-mcp": { "command": "<path-to-repo>\\gateway\\target\\release\\houdini-bridge-mcp.exe", "env": { "HMCP_GW_HEADLESS": "1" } } } }
Usedouble backslashesin all Windows paths.
Fully quit and reopen the client. In a new chat thehoudini-bridge-mcptools appear.
-
Confirm the GUI status pill readsArmedwith your Houdini version.
In a new client chat, ask for a scene report:
A successful reply (hip file, frame, Houdini version,/objcontents) confirms the client → gateway → executor link end to end.
Then turn a prepped DEM tile into a real heightfield:
"import_heightfieldfromterrain.npy, name itterrain, and display it."
If both return, you are wired. Seedocs/SETUP.mdfor the full first-run walkthrough anddocs/GUIDE.mdfor day-to-day operation.
Around1,467 typed operations, grouped into the families below (the generated tables show the exact current catalog). Every tool is a validated handler — no free-form code path exists.Full parameter reference: seedocs/GUIDE.md, or ask thenode_referencetool live in-session.
Four discoverability surfaces back the tool catalog.capabilitiesis the start-here index — it prints pointers to all of the others (including the live help-server URL), so when in doubt call it first.
- Tool catalog— the enumerated list of every typed operation (reference/catalog.json, the authoritative count), surfaced as the tables above; per-parameter detail comes from thenode_referenceMCP tool andreference/NODE_REFERENCE.md. Thisisthe security boundary: if it isn't in the catalog, the server can't do it.
- Node reference— thenode_referenceMCP tool answers "what params does node X take?" from live-probed ground truth; the human-readable archive isreference/NODE_REFERENCE.md(SOP / OBJ / LOP / Driver / COP), annotated with which tool exposes each node.
- VEX reference— thevex_referenceMCP tool looks up validated safe-VEX functions; the curated guide isreference/VEX_REFERENCE.md.
- Offline Houdini help server— SideFX's full node/VEX/HOM documentation, served locally and launched alongside the bridge. It has no MCP tool; thecapabilitiesoutput prints its URL.
This is the differentiator.acquire_terrainis the one network operation — give it a lat/lon (+ radius) or an explicit bounding box, and it auto-selects a source, fetches, reprojects, and preps Houdini-ready tiles into your working directory. Coverage is global (seeDOWNLOADER_SCOPE.mdfor the full matrix):
- US— USGS 3DEP (1 m lidar / 10 m / 30 m) + several state lidar portals.
- Global 30 m— Copernicus GLO-30, SRTM, or JAXA ALOS AW3D30 (all anonymous, no key), so any point on Earth returns terrain.
- National hi-res— Netherlands 0.5 m, UK 1 m, France 1 m / 0.5 m, Spain 5 m, Australia 5 m (auto-selected when a "large"/hi-res request falls wholly inside a covered country).
- Keyed opt-in— OpenTopography's global API, using the user's own free key (HMCP_OPENTOPO_KEY), never bundled.
- flat— local metric heightfields for a single site, imported at true elevation withimport_heightfield.
- globe— ECEF tiles pinned onto a WGS84 globe (build_globe+import_ecef_tile) so a scan sits in a correct Earth frame and adjacent tiles register by construction.
Because one project origin is held across calls, successive tiles share a frame and align automatically. The fetch is confined to a small set of trusted DEM hosts; no arbitrary URL crosses the boundary.
1 Houdini unit = 1 meter Working CRS = a local UTM zone chosen per project (metric, minimal distortion) X = east-west, Y = elevation (up), Z = north-south, NEGATED (north = -Z)
TheZ negationis the classic mirror trap — it cost a full debugging session. One origin is held per project so successive tiles share a frame and align automatically. A prepared<tile>.npyneeds its<tile>.npy.jsonsidecar (cols,rows,res_m,houdini_center_x/z,nodata) beside it.
Real-world LIDAR/DEM in Houdini breaks in non-obvious ways. These are confirmed on 21.0.671 and are the hard-won original value of this project:
- GeoTIFF is unreadable by Houdini's COP2 /heightfield_file.All GeoTIFF I/O happens in system Python (rasterio) →.npy; only arrays cross into Houdini.
- convertheightfieldproduces 0 prims from old-stylecreateVolumevolumes— but converts cleanly from a properheightfieldSOP volume (verified: 249k polys from a default heightfield).
- heightfield_mosaic/heightfield_wrangledon't exist in H21— useheightfield_patch/volumewrangleinstead.
- The "12 GB freeze" is viewport GL tessellation, not RAM.A heavy heightfield tessellates hundreds of millions of voxels on the GPU. Fix: build display-OFF, stream packed tiles with a box proxy, and lower volume quality (viewport_optimize). Data RAM is a non-issue.
- Never flipbook or OpenGL-render a heavy heightfield scene— it can hang Houdini. Usecapture_ui(an OS-level screen grab) instead.
- AheightfieldSOP volume needs a primitive attributename='height', and LIDAR arrays are north-row-first, so rows are flipped beforesetAllVoxels.
- The GL viewport does not show Principled Shader bump(Karma-render only); real relief needs geometry displacement.
Houdini's Karma XPU GPU path is NVIDIA/OptiX-only. If you have anAMD Radeoncard (RDNA2 / gfx1030+) and want GPU rendering, this repo includes afrom-source build of AMD Radeon ProRender'shdRprdelegate ported to Houdini 21 / USD 25— AMD ships no prebuilt H21 plugin. It installs as a native Hydra renderer ("RPR") in Solaris and is entirely optional and independent of the core MCP.
Status: working(rebuilt with the MSVCv143toolset; "RPR" is a selectable Hydra renderer and the RPR material VOPs / LOP render-settings / Material Library all load). One known convenience gap: the RPR menu'sRender Devicesdialog still needs a USD-25 Python-binding port — not required to render. SeeAMDProRender/README.mdfor the prebuilt release, build-from-source steps, and the port patch.
Most configuration happens in the GUI and is written to a shared config file both halves read live. The only environment variable the MCP client needs is the headless flag.
The security model isthe boundary itself, not a sandbox:
- Data-only by construction.No arbitrary code, no generic node driver, no raw VEX or Python ever reaches Houdini. The catalog is the attack surface, and the catalog is data-shaped operations. A regression test asserts the RCE primitives (exec/node_op/wrangle) can never appear in the catalog.
- realpath-confined working directory.Every file operation resolves and re-checks against one root, with symlink/junction escapes closed. Reads must exist under the root; writes may create a new leaf but never escape.
- Fail-closed arming.The executor refuses to arm unless a firewall rule blocks inbound connections to its loopback port (see Step 4).
- Renders are wire-only.setup_karmaandbake_texturebuild graphs but never execute — you fire them in Houdini.
- batchgrants no privilege.Thebatchmeta-tool runs up to 64 ops in one call to cut latency, but each op is dispatched through theexact samepath as a direct call — schema-validated, numerics clamped, filesystem pathsrealpath-confined, and audited in order. A batch can only invoke real catalog tools (no arbitrary code, no non-catalog names) and cannot nest (an op namedbatchis rejected). It is a latency envelope, not a way around the boundary.
- Optional action throttle.HMCP_MIN_ACTION_INTERVAL_MS(default off) paces destructive tools (delete_node,save_scene,delete_keyframes) with a short sleep so a runaway/injection can't rapid-fire scene destruction. It slows, never blocks; ordinary tools are unaffected (see Configuration).
- Houdini's embedded Python is unsandboxed, so the guarantee iswhat the AI can ask for, validated at the gateway — not process isolation. Treat the AI as semi-trusted input.
- Intended posture: loopback, single trusted user, trusted machine.This is a local tool. The transport is meant to stay on the local host.
A code-level audit confirms the data-only boundary holds as built. For the full threat model, the current hardening status, and the known residual items, seeSECURITY.md— read it before running this anywhere other than a single trusted machine.
Drive SideFX Houdini from an AI chat — a security-first, data-only control surface where the AI authorsvalidatedwrangles, never arbitrary code.
A Windows-native MCP (Model Context Protocol) server that lets an AI chat client driveSideFX Houdiniacross a broad swath of its creative surface — through a fixed catalog oftyped, validated tools with no arbitrary-code path. The AI builds and inspects node networks and can author avalidated, boundedwrangle;youfire the heavy cooks and renders. It also doubles as a safe way tolearnHoudini — every step is a guided, explainable, sandboxed operation, not a black box. The catalog is broad: geometry & cleanup · instancing · simulation (FLIP/Pyro/RBD/Vellum) ·character rigging & animation(KineFX, Crowd, Muscle) · COP/image compositing · look & materials · ML/ONNX · SideFX-Labs (tree/biome/world-building) · render & export — plus a uniquereal-world geodata lane(DEM / USGS 3DEP / LIDAR) that reprojects and places elevation at true scale. One binary runs alongside Houdini and your AI client; that's the whole install.
Status:v0.1.0 released— security-hardened, feature-complete. The in-Houdini executor (the typed tool surface), the terrain downloader (global + national coverage), and the Rust driver binary + Houdini package are all shipped — grab the gateway from theReleasespage.Target: Houdini 21.0.671(Apprentice works; Houdini 22 exists but is not yet adopted here). Windows-first; other platforms later.
New to this / not a coder? Start here.Plenty of Houdini users already live in code and a terminal — but you donotneed to. Getting running is: get one program, click a couple of buttons in its window, launch Houdini, and paste one small block of settings into your AI client. That's the whole job. The three steps below are the map; the numberedSteps 1–7further down walk each one in detail, and you only ever touch a command line if you choose to build the program from source instead of downloading it.
What you'll need on hand:Houdini 21.0.671(the freeApprenticeedition is fine), aWindowsPC, and an AI client that speaks MCP (Claude Desktop, Cursor, etc.). One folder on your disk becomes the project the AI is allowed to touch — pick it in Step 3.
Three steps to a working setup (full detail in Steps 1–7 below):
- Get the gateway(the one program that connects your AI to Houdini) — eitherdownloadthe prebuilthoudini-bridge-mcp.exefrom Releases (no coding), orbuildit from source (cd gateway && cargo build --release, needs the Rust toolchain). It's a single file with no runtime dependencies.
- Install & arm— run the gateway, which opens a small GUI window. In it: clickInstall Houdini package(wires Houdini to auto-connect), set yourworking directoryand clickApply(the one folder the AI may read and write), and toggleAuto-armon. Then launch Houdini — the status pill should readArmed. Before letting anything but this one machine reach it, run the firewall script (Step 4).
- Connect your AI client— tell your AI client (Claude Desktop, Cursor, …) where the gateway is by pasting one small JSON block into its config (copy-paste ready in Step 6), fully restart the client, then run the Step 7 check to confirm the AI can see your Houdini scene.
Other Houdini/Blender MCP servers exposearbitrary Python executionto the model — powerful, but it is remote-code-execution by design (across the surveyed field every comparable bridge ships anexecute_code-style tool, and one widely-used Blender bridge has a documented remote-code-execution issue). This one is the inverse:
-
Data-only by construction.The AI can only call a fixed registry of1,467typed, validated operations. There is deliberatelynoarbitrary-code tool,nogeneric node-parameter setter, andnoraw VEX/Python path — those simply do not exist in the catalog, so the boundary cannot be talked past. The set of things the server can doisthe enumerated tool list.
Validated authoring — the differentiator, not an escape hatch.The one code-carrying tool,set_attrib_expr(opt-in,default-off), takes a VEX attribute snippet andvalidates it against an allowlist before Houdini ever sees it: no file/host/network reach, allowlisted functions only, and provablytotal — it always halts.Control flow is conditionals,statically-bounded counted loops(for— a literal ormin()-clamped iteration ceiling), and aleaf-only, snapshot-finite array loop(foreach, whose iteration count VEX fixes at entry, and which may not nest inside or contain another loop);while/do/gatherstay banned, so no infinite-loop construct exists. Three capabilities layer on behind theirownindependent default-off consents: bounded loops (allow_attrib_loops),deletion topology edits(removepoint/removeprim,allow_attrib_geoedit), andconstruction/growth(addpoint/addprim/addvertex/removevertex,allow_attrib_geogrow) — all pinned to the input-0 working geometry, and each consent independent (enabling one never grants another). Most wrangle work is covered bytypedoperators anyway (field calculus, per-voxel math, CSG/advection viavdb_);vex_referencealso serves the offline function reference for hand-paste.
This is the line no other Houdini MCP holds: the AI can author a real, capable wrangle without ever handing you a remote shell.Every third-party bridge ships unvalidatedexecute_code/raw-VEX — RCE by design. SideFX's own upcoming official MCP validatesgeneratedcode for correctness after the fact, and only for rigging. This validates abounded subset of the input, before it runs, across the whole toolset— a stricter model, not a smaller door.
Learn Houdini with an AI — safely, not just drive it.Every action is a typed, sandboxed,explainableoperation, and the AI hands you the exact validated wrangle it proposes — so it doubles as a guided tutor: ask it to build something, watch how it wires the network, read thewhy. Nothing it does can run arbitrary code on your machine or touch work outside the project folder, which makes it as safe for a beginner's first scene as for a locked-down pipeline. The same rails that keep it secure make it a low-stakes place to learn how Houdini actually works.
One working directory.Every file read and write isrealpath-confined to a single project folder you choose. Nothing outside it is reachable, even through a symlink or junction.
Renders are wire-only.The AI builds render graphs (Karma, texture bake);youfire them. It never triggers a render on its own.
Built for real-world geodata.It is the only one of its kind aimed at DEM / 3DEP / LIDAR: it reprojects and places elevation at true scale, reconstructs point clouds into clean meshes (plane-fit and remesh, not organic blobs), and can pin tiles onto a correct Earth frame.
Broad, not just terrain.The geospatial pipeline is the specialty, but the same typed, data-only surface spans most of Houdini: modeling and cleanup, the major solvers,character rigging and animation(KineFX skeletons/capture/deform, Crowd, Muscle), COP image compositing, ML/ONNX, and the SideFX-Labs tree/biome/world-building toolset — all under the same no-RCE boundary.
Houdini is famously deep, and the blank-network moment is where most people bounce off. This bridge is a guided, low-stakes way to sit down and actuallylearnit — you describe what you want, the AI builds it in your live session, and you watch the network take shape.
-
It's not a toy.The tool surface reaches a broad, capable slice of real Houdini — modeling and cleanup, geometry sim setup (FLIP / Pyro / RBD / Vellum), character rig & animation (KineFX, Crowd, Muscle), COP image compositing, look & materials, and the SideFX-Labs tree/biome/world toolset. You can learn a genuine workflow, not a sandbox imitation of one. (See the honest coverage numbers below for exactly what's in and out of scope.)
The typed endpoints are the learning scaffold.Every capability is a fixed, typed, validated operation, so the AI can only reachreal Houdini operations— it cannot wander outside what the software actually does or invent a step that isn't there. The tool list itself mirrors how Houdini is organized (the SOP/COP/DOP/KineFX families, the Labs toolset), so the surface that bounds the AI also teaches you how the application is structured.
You watch it, you don't run it blind.Every operation streams live into the gateway GUI's audit log, so youseethe AI work step by step in a running Houdini session — the network gets built in front of you, node by node, rather than executed in a headless batch you never observe. That live, watched mode is the learning advantage. (Headless operation is still supported for power users who want it.)
Mistakes become teaching moments, not disasters.AI can be wrong — it may pick the wrong node or misjudge a parameter. The point isn't that it never errs; it's that the typed, sandboxed,inspectablesurface makes any mistake visible, easy to undo, and harmless. Nothing it does runs arbitrary code or touches files outside your project folder, so a bad step is something youcatch and correct while learning why, not something that can damage your machine or your work.
- This is why it wasn't built on an existingexecute_codebridge.The design assumes the model can be wrong, steered (prompt injection), or malfunction — and that giving an agent arbitrary code plus a goal is the documented high-severity failure mode (agents that escape their sandbox, act autonomously and undetected, and reach credentials/network/files). So rather than iterate from a Blender/Houdini MCP that hands the model a shell, this one cuts the code path entirely and rebuilds data-only: the fixed typed catalogisthe boundary. The limitation is the security property. SeeSECURITY.mdfor the full rationale.
Honest coverage — what's in scope and what isn't.By raw count the catalog reaches a deliberateminorityof Houdini's non-deprecated node types — exposed as the1,467typed tools in the catalog (one node type is often reached by several tools, and whole families — VOP / SHOP / COP-internal / PDG — are excluded by design, not omission). But that raw numberunderstatesthe creative coverage, because it's weighted hard toward the workflows most people actually use and leaves some whole domains out on purpose:
- Well covered (the creative core):COP compositing~84%, SOP modeling/geometry~49%, SideFX-Labs~65%, KineFX rig/animation~53%.
- Deliberately out of scope (scoping decisions, not bugs):USD / Solaris (LOP)~10%, PDG / TOP0%(the batch / dependency-graph domain), legacy Cop2 and Shop contexts, and VOP internals (1.3%— by design: a VOP is a graph-internal building block, not a data surface the bridge exposes).
In short: roughly a quarter of Houdini's node surface by raw count, but weighted toward the creative workflows most people actually use, with a few whole domains (USD/Solaris, PDG) intentionally left out. A newcomer knows up front what they can learn here and what they can't.
Once installed and armed, you can say things like this directly in your AI chat client (paths are relative to the one working directory you configure):
- "Build the terrain around 46.5°N, 114.0°W at 10 m resolution and put a camera on it."
- "Fetch elevation for this bounding box and import it at true scale."
- "Loadscans/site.ply, clean out the speckle, and mesh it."
- "Erode this heightfield, then mask the gullies and the shadowed slopes."
- "Scatter rocks across the terrain with packed instancing so the viewport stays light."
- "Give me a sun light for late afternoon and frame the ridge."
- "Wire a Karma render aimed at that camera — I'll press the button."
- "Export the terrain mesh as USD into my project folder."
- "Build a KineFX skeleton for this mesh, capture it, and deform-test the bind."
- "Set up a crowd of agents walking a path across the terrain."
- "Splash a FLIP sim into that basin and cache it wire-only."
- "What's in the scene right now, and how much memory is Houdini using?"
AI / MCP client ──stdio──▶ houdini-bridge-mcp (one binary: config + GUI + gateway) │ loopback HTTP ▼ a data-only executor running inside your live Houdini session
- Thebinaryis both a small GUI (front-of-house: locate Houdini, set the working directory, generate a session token, show a live audit log of every call) and the headless MCP gateway your AI client talks to over stdio.
- Thegatewayis the typed front door: everytools/callis validated against the catalog — unknown keys rejected, numerics clamped to range, enums checked, paths confined — before anything is forwarded.
- Theexecutoris a data-only Python package that arms itself automatically inside your Houdini session and performs the requested operation on real nodes.
The gateway and executor share onetoken,port, andworking directory, single-sourced from a small config file the GUI writes — so there are no manual shell snippets and no port-collision dance.
- Houdini 21.0.671— Apprentice works (the free edition; no license purchase needed to try this).
- A Rust toolchain(stable) — only if youbuildthe gateway yourself; skip it if you download the prebuilt.exefrom Releases.rustup.rs
- Python— only for the optional terrain downloader (rasteriofor the DEM data-prep step); any recent CPython works. Not needed for a first run.
- Windows— Windows-first; other platforms later.
Prefer no coding?Download the prebuilthoudini-bridge-mcp.exefrom Releases and skip straight to Step 2 — it is the same single binary the build produces.Want to build from source instead(or there's no prebuilt binary for your setup yet)? Run:
Either way you end up with one file — the gateway is both the GUI and the headless MCP server. Which mode it runs in is selected at launch by one environment variable,HMCP_GW_HEADLESS— unset opens the GUI window,1runs the headless stdio server. (You won't normally set this by hand: double-clicking the file opens the GUI, and the config block in Step 6 sets the headless flag for your AI client.)
Step 2 — Install the auto-arm Houdini package
This drops a small Houdinipackagethat arms the executor automatically when Houdini's GUI starts — so the bridge comes up ready, with no "start the server" step.
Via the GUI (recommended):launch the binary, thenSettings → Install Houdini package.
Or manually,copy the two static package files into your Houdini user preference directory (defaults to%USERPROFILE%\Documents\houdini21.0):
houdini_package/houdini-bridge-mcp.json → <houdini-user-pref-dir>/packages/houdini-bridge-mcp.json houdini_package/houdini-bridge-mcp/scripts/456.py → <houdini-user-pref-dir>/houdini-bridge-mcp/scripts/456.py
The package files are shippable — no absolute paths, usernames, or machine values; everything dynamic is read at runtime from the shared config file.
Launch the binary withHMCP_GW_HEADLESSunset so the window appears, then:
- Settings— confirm theexecutor portandsession token(defaults are fine; the token is the shared secret between the two halves).
- Working dir— type yourproject root. Every subdirectory under it is reachable; nothing outside it is. ClickApply.
- Back inSettings, turn onAuto-arm Houdini.
Apply + Auto-arm write the shared config file (arm.json, under your user profile) that the GUI, the executor, and the headless gateway all read live. Changing the working directory later is justApply— no restart.
Wherearm.jsonlives / enabling safe-VEX.arm.jsonis the trust root — working dir, session token, port, and feature flags — at:
%USERPROFILE%\.houdini-bridge-mcp\arm.json (Windows) ~/.houdini-bridge-mcp/arm.json (macOS / Linux)
The one opt-in code lane,set_attrib_expr, isoff by default. To turn it on, openSettings → Safe-VEX (advanced)and flipEnable safe-VEX (allow_attrib_expr)— it takes effect immediately (the executor re-reads the flag per call; no restart). That panel also hasOpen arm.jsonandOpen config folderbuttons if you'd rather hand-edit; to enable by hand, set"allow_attrib_expr": truein the file. This is anoperator-onlyswitch — a driving agent can never reacharm.json(it is held off-limits even when the working dir is misconfigured to an ancestor), so the AI cannot enable its own code lane. Turn it back off the same way when you're done.
The executor armsfail-closed— it refuses to arm unless a firewall rule blocks inbound connections to its loopback port. Run the bundled script once, from an elevated shell:
scripts/harden-firewall.ps1 # -Mode loopback (default): loopback-only, single machine scripts/harden-firewall.ps1 -Mode lan # allow a trusted studio LAN to reach the executor
Useloopback(the default) for a single trusted machine; uselanonly on a trusted studio network.
Launch Houdini. The installed package auto-arms the executor from the shared config — the console prints:
The GUI's status pill showsArmedwith the connected Houdini version — for most people that pill is all the confirmation you need. No Python-shell snippet required. If you want to double-check from a terminal (optional, for the curious — use your configured port and token):
curl.exe http://127.0.0.1:8765/health -H "X-HMCP-Token: <your-token>"
→{"ok": true, "service": "houdini-bridge-mcp", ...}
Point your client (e.g. Claude Desktop — edit the file at%APPDATA%\Claude\claude_desktop_config.json; paste that path into the File Explorer address bar to find it) at the gateway binary inheadlessmode (no window — the AI drives it directly). The gateway reads the working directory, port, and token from the shared config file, so the env block only needs the headless flag. Setcommandto the full path of the.exefrom Step 1:
{ "mcpServers": { "houdini-bridge-mcp": { "command": "<path-to-repo>\\gateway\\target\\release\\houdini-bridge-mcp.exe", "env": { "HMCP_GW_HEADLESS": "1" } } } }
Usedouble backslashesin all Windows paths.
Fully quit and reopen the client. In a new chat thehoudini-bridge-mcptools appear.
-
Confirm the GUI status pill readsArmedwith your Houdini version.
In a new client chat, ask for a scene report:
A successful reply (hip file, frame, Houdini version,/objcontents) confirms the client → gateway → executor link end to end.
Then turn a prepped DEM tile into a real heightfield:
"import_heightfieldfromterrain.npy, name itterrain, and display it."
If both return, you are wired. Seedocs/SETUP.mdfor the full first-run walkthrough anddocs/GUIDE.mdfor day-to-day operation.
Around1,467 typed operations, grouped into the families below (the generated tables show the exact current catalog). Every tool is a validated handler — no free-form code path exists.Full parameter reference: seedocs/GUIDE.md, or ask thenode_referencetool live in-session.
Four discoverability surfaces back the tool catalog.capabilitiesis the start-here index — it prints pointers to all of the others (including the live help-server URL), so when in doubt call it first.
- Tool catalog— the enumerated list of every typed operation (reference/catalog.json, the authoritative count), surfaced as the tables above; per-parameter detail comes from thenode_referenceMCP tool andreference/NODE_REFERENCE.md. Thisisthe security boundary: if it isn't in the catalog, the server can't do it.
- Node reference— thenode_referenceMCP tool answers "what params does node X take?" from live-probed ground truth; the human-readable archive isreference/NODE_REFERENCE.md(SOP / OBJ / LOP / Driver / COP), annotated with which tool exposes each node.
- VEX reference— thevex_referenceMCP tool looks up validated safe-VEX functions; the curated guide isreference/VEX_REFERENCE.md.
- Offline Houdini help server— SideFX's full node/VEX/HOM documentation, served locally and launched alongside the bridge. It has no MCP tool; thecapabilitiesoutput prints its URL.
This is the differentiator.acquire_terrainis the one network operation — give it a lat/lon (+ radius) or an explicit bounding box, and it auto-selects a source, fetches, reprojects, and preps Houdini-ready tiles into your working directory. Coverage is global (seeDOWNLOADER_SCOPE.mdfor the full matrix):
- US— USGS 3DEP (1 m lidar / 10 m / 30 m) + several state lidar portals.
- Global 30 m— Copernicus GLO-30, SRTM, or JAXA ALOS AW3D30 (all anonymous, no key), so any point on Earth returns terrain.
- National hi-res— Netherlands 0.5 m, UK 1 m, France 1 m / 0.5 m, Spain 5 m, Australia 5 m (auto-selected when a "large"/hi-res request falls wholly inside a covered country).
- Keyed opt-in— OpenTopography's global API, using the user's own free key (HMCP_OPENTOPO_KEY), never bundled.
- flat— local metric heightfields for a single site, imported at true elevation withimport_heightfield.
- globe— ECEF tiles pinned onto a WGS84 globe (build_globe+import_ecef_tile) so a scan sits in a correct Earth frame and adjacent tiles register by construction.
Because one project origin is held across calls, successive tiles share a frame and align automatically. The fetch is confined to a small set of trusted DEM hosts; no arbitrary URL crosses the boundary.
1 Houdini unit = 1 meter Working CRS = a local UTM zone chosen per project (metric, minimal distortion) X = east-west, Y = elevation (up), Z = north-south, NEGATED (north = -Z)
TheZ negationis the classic mirror trap — it cost a full debugging session. One origin is held per project so successive tiles share a frame and align automatically. A prepared<tile>.npyneeds its<tile>.npy.jsonsidecar (cols,rows,res_m,houdini_center_x/z,nodata) beside it.
Real-world LIDAR/DEM in Houdini breaks in non-obvious ways. These are confirmed on 21.0.671 and are the hard-won original value of this project:
- GeoTIFF is unreadable by Houdini's COP2 /heightfield_file.All GeoTIFF I/O happens in system Python (rasterio) →.npy; only arrays cross into Houdini.
- convertheightfieldproduces 0 prims from old-stylecreateVolumevolumes— but converts cleanly from a properheightfieldSOP volume (verified: 249k polys from a default heightfield).
- heightfield_mosaic/heightfield_wrangledon't exist in H21— useheightfield_patch/volumewrangleinstead.
- The "12 GB freeze" is viewport GL tessellation, not RAM.A heavy heightfield tessellates hundreds of millions of voxels on the GPU. Fix: build display-OFF, stream packed tiles with a box proxy, and lower volume quality (viewport_optimize). Data RAM is a non-issue.
- Never flipbook or OpenGL-render a heavy heightfield scene— it can hang Houdini. Usecapture_ui(an OS-level screen grab) instead.
- AheightfieldSOP volume needs a primitive attributename='height', and LIDAR arrays are north-row-first, so rows are flipped beforesetAllVoxels.
- The GL viewport does not show Principled Shader bump(Karma-render only); real relief needs geometry displacement.
Houdini's Karma XPU GPU path is NVIDIA/OptiX-only. If you have anAMD Radeoncard (RDNA2 / gfx1030+) and want GPU rendering, this repo includes afrom-source build of AMD Radeon ProRender'shdRprdelegate ported to Houdini 21 / USD 25— AMD ships no prebuilt H21 plugin. It installs as a native Hydra renderer ("RPR") in Solaris and is entirely optional and independent of the core MCP.
Status: working(rebuilt with the MSVCv143toolset; "RPR" is a selectable Hydra renderer and the RPR material VOPs / LOP render-settings / Material Library all load). One known convenience gap: the RPR menu'sRender Devicesdialog still needs a USD-25 Python-binding port — not required to render. SeeAMDProRender/README.mdfor the prebuilt release, build-from-source steps, and the port patch.
Most configuration happens in the GUI and is written to a shared config file both halves read live. The only environment variable the MCP client needs is the headless flag.
The security model isthe boundary itself, not a sandbox:
- Data-only by construction.No arbitrary code, no generic node driver, no raw VEX or Python ever reaches Houdini. The catalog is the attack surface, and the catalog is data-shaped operations. A regression test asserts the RCE primitives (exec/node_op/wrangle) can never appear in the catalog.
- realpath-confined working directory.Every file operation resolves and re-checks against one root, with symlink/junction escapes closed. Reads must exist under the root; writes may create a new leaf but never escape.
- Fail-closed arming.The executor refuses to arm unless a firewall rule blocks inbound connections to its loopback port (see Step 4).
- Renders are wire-only.setup_karmaandbake_texturebuild graphs but never execute — you fire them in Houdini.
- batchgrants no privilege.Thebatchmeta-tool runs up to 64 ops in one call to cut latency, but each op is dispatched through theexact samepath as a direct call — schema-validated, numerics clamped, filesystem pathsrealpath-confined, and audited in order. A batch can only invoke real catalog tools (no arbitrary code, no non-catalog names) and cannot nest (an op namedbatchis rejected). It is a latency envelope, not a way around the boundary.
- Optional action throttle.HMCP_MIN_ACTION_INTERVAL_MS(default off) paces destructive tools (delete_node,save_scene,delete_keyframes) with a short sleep so a runaway/injection can't rapid-fire scene destruction. It slows, never blocks; ordinary tools are unaffected (see Configuration).
- Houdini's embedded Python is unsandboxed, so the guarantee iswhat the AI can ask for*, validated at the gateway — not process isolation. Treat the AI as semi-trusted input.
- Intended posture: loopback, single trusted user, trusted machine.This is a local tool. The transport is meant to stay on the local host.
A code-level audit confirms the data-only boundary holds as built. For the full threat model, the current hardening status, and the known residual items, seeSECURITY.md— read it before running this anywhere other than a single trusted machine.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



