Configuration¶
Environment Variables¶
| Variable | Default | Read by | Description |
|---|---|---|---|
FXHOUDINIMCP_PORT |
8100 |
Houdini | Port the plugin listens on; a second Houdini takes the next free one |
FXHOUDINIMCP_BIND |
127.0.0.1 |
Houdini | Address the plugin binds. See Security before widening it |
FXHOUDINIMCP_AUTOSTART |
1 |
Houdini | 0 disables auto-start |
FXHOUDINIMCP_AUTO_LAYOUT |
0 |
both | 1 lets tools re-lay-out a network after changing it. Off, only new nodes are placed |
FXHOUDINIMCP_PROJECT_ROOT |
unset | Houdini | Confine hip, import, export and HDA files to this directory |
FXHOUDINIMCP_TIMEOUT |
120 |
Houdini | Seconds a command may run; write_cache, start_render, cook_frame_range and press_button have no deadline |
FXHOUDINIMCP_TIMEOUT_<COMMAND> |
unset | Houdini | Per-command override: FXHOUDINIMCP_TIMEOUT_TOPS_COOK_TOP_NODE=900 |
FXHOUDINIMCP_OUTPUT_GRACE |
2 |
Houdini | Seconds a render or cache may take to show its file before it counts as not written |
HOUDINI_HOST |
localhost |
client | Houdini host |
HOUDINI_PORT |
scan 8100-8115 | client | Pin one Houdini port; switches off the scan |
HOUDINI_TIMEOUT |
plugin timeout + 15 | client | Seconds the client waits for a command |
MCP_TRANSPORT |
stdio |
client | stdio or streamable-http |
LOG_LEVEL |
INFO |
client | Logging level |
Houdini-side variables live in the package file install wrote, where every one sits at its default. They win over the same variables in your shell; install keeps your edits when it runs again. Client-side variables go in your MCP client's config.
Auto-Start¶
The plugin starts when Houdini's UI is ready (through uiready.py, which stacks with other packages) and reports ready once mcp.health answers from that Houdini process. FXHOUDINIMCP_AUTOSTART=0 turns this off; the MCP menu still starts and stops the server.
Node Placement and Auto-Layout¶
New nodes are always placed: under their inputs, or in a free column when they have none. Nothing that already exists moves, and an explicit position=[x, y] always wins.
FXHOUDINIMCP_AUTO_LAYOUT=1 also re-lays-out the whole network after each change, moving nodes you placed by hand, which is why it is off by default. Both processes read it, so set it in the MCP client's environment and in the package file. In a running Houdini, hou.putenv("FXHOUDINIMCP_AUTO_LAYOUT", "1") toggles it without a restart.
Timeouts¶
A command gets 120 seconds (FXHOUDINIMCP_TIMEOUT). Override one command with FXHOUDINIMCP_TIMEOUT_<COMMAND>, the dotted name uppercased with dots as underscores:
write_cache, start_render, cook_frame_range and press_button have no deadline: they show Houdini's progress dialog and are cancelled from there. FXHOUDINIMCP_TIMEOUT does not reach them; their own variable puts one back.
Houdini reads these, so they go in the package file. A command that times out names the variable to raise. The client waits for the plugin's deadline plus 15 seconds, unless HOUDINI_TIMEOUT says otherwise. Raise it to match a longer per-command override.
Ports and Several Sessions¶
The plugin takes port 8100, or the next free one when another Houdini holds it. The client scans 8100-8115 and connects to the lowest that answers. get_houdini_connection_status lists every session and connect_houdini(port) switches. Setting HOUDINI_PORT pins one port and switches the scan off. If you change FXHOUDINIMCP_PORT, set HOUDINI_PORT to match.
Transport¶
stdio (the default): the AI client starts the server as a child process. MCP_TRANSPORT=streamable-http runs it as an HTTP endpoint instead, for remote or shared setups.
With MCP SDK 2 (mcp>=2), Streamable HTTP runs without protocol sessions: no client keeps an Mcp-Session-Id, and clients of MCP 2026-07-28 are served too. Every client of that process shares one current Houdini, so connect_houdini from one moves them all; run one process per client, each with its own HOUDINI_PORT, when they need different sessions. With SDK 1 HTTP keeps its sessions, and each client its own Houdini. Either way it listens on loopback by default and has no authentication.
Security¶
A connection to this server is a shell inside your Houdini session: execute_python runs arbitrary code, and there is no authentication or per-tool permission. It is built for one artist's workstation and an MCP client they trust.
- The plugin binds to loopback unless
FXHOUDINIMCP_BINDsays otherwise. - Requests with an
Originheader (a web page) or a non-loopbackHost(DNS rebinding) are refused. FXHOUDINIMCP_PROJECT_ROOTconfines the files the tools open, save, import, export or install. It does not check paths written into parameters (a File SOP, a ROP output), andexecute_python/execute_hscriptare not sandboxed.- Recovery from a bad change is undo, one step per tool call.