Skip to content

bridge

bridge

HTTP bridge connecting the MCP server to Houdini's hwebserver.

Houdini's hwebserver uses an RPC-style calling convention:

POST /api
Content-Type: application/x-www-form-urlencoded
Body: json=["namespace.function", [positional_args], {keyword_args}]

The server returns the function's return value JSON-encoded.

Classes:

Name Description
HoudiniBridge

Manages HTTP communication between the MCP server and Houdini's hwebserver.

Functions:

Name Description
find_servers

Probe base..base+max_tries for live plugins, lowest port first.

Classes

HoudiniBridge

HoudiniBridge(host: str = 'localhost', port: int = 8100, timeout: float = 60.0)

Manages HTTP communication between the MCP server and Houdini's hwebserver.

Houdini's hwebserver exposes @apiFunction endpoints via a single /api URL. Calls are dispatched by function name inside the JSON-encoded body.

Methods:

Name Description
close

Close the HTTP client connection.

execute

Execute a command on Houdini and return the result data.

health_check

Check if Houdini is responsive.

list_commands

Return the command names the connected plugin has registered.

Methods:
close async
close() -> None

Close the HTTP client connection.

execute async
execute(
    command: str,
    params: dict[str, Any] | None = None,
    timeout: float | None = None,
) -> Any

Execute a command on Houdini and return the result data.

Parameters:

Name Type Description Default
command str

The command name (e.g. "scene.get_scene_info")

required
params dict[str, Any] | None

Command parameters

None
timeout float | None

Override timeout for this request (seconds)

None

Returns:

Type Description
Any

The response data dict on success.

Raises:

Type Description
ConnectionError

Cannot reach Houdini

HoudiniCommandError

Houdini returned an error

health_check async
health_check() -> dict[str, Any]

Check if Houdini is responsive.

Deliberately cheap: the plugin answers this without touching HOM, so it works while Houdini's main thread is busy. That is also why it reports no scene details -- use scene.get_scene_info for hip_file.

Returns:

Type Description
dict[str, Any]

Dict with status, pid and houdini_version.

list_commands async
list_commands() -> list[str]

Return the command names the connected plugin has registered.

Used to detect a plugin older than this server. Calls mcp.list_commands rather than going through mcp.execute, so it works even when the dispatcher is missing commands.

Functions:

find_servers async

find_servers(
    host: str,
    base: int,
    max_tries: int = PORT_SEARCH_RANGE,
    timeout: float = 1.0,
) -> list[dict[str, Any]]

Probe base..base+max_tries for live plugins, lowest port first.

Each entry is the mcp.health payload plus the port it answered on. Returns every server found rather than just the first, so a caller can say how many Houdini sessions are running instead of silently picking one.

Probing is cheap because mcp.health touches no HOM: a closed port refuses immediately, and a live one answers without waiting on Houdini's main thread.