使用说明
Houdini MCP服务器
用于通过以下方式控制SideFX Houdini的MCP(模型上下文协议)服务器 hrpyc,使Claude、Cursor和Letta代理等AI助手能够与Houdini会话进行交互。
建筑学
+-----------------+ MCP (HTTP) +------------------+ hrpyc:18811 +-------------+
| Claude/Cursor | <------------------> | MCP Server | <------------------> | Houdini |
| Letta Agents | | (Python/FastMCP)| | Session |
+-----------------+ +------------------+ +-------------+
架构决策
架构决策记录(ADR) docs/adr/:
- ADR 0001:语言和过程边界
--为什么服务器仍然使用Python
hou语义和FastMCP网关 模块边界和允许的依赖方向以及测量的阈值 这将证明未来非Python sidecar的合理性。
特性
- 43个MCP工具 横跨15个模块化类别
- 完全后模块访问 -远程执行任何Houdini Python代码
- 场景管理 -创建、加载、保存场景
- 节点操作 -创建、删除、修改节点和参数
- 渲染 -视口渲染、四视图、Karma GPU/CPU支持
- 窗格截图 -捕获网络编辑器、场景查看器和其他窗格
- 场景序列化 -操作前后不同的场景状态
- 连接管理 -指数回退+抖动自动重新连接
- 错误处理 -具有恢复提示的一致错误响应
- 响应优化 -大小限制、截断、AI摘要
- 内存缓存 -具有TTL的节点类型缓存以提高性能
先决条件
-
启用RPC的Houdini -启动Houdini的RPC服务器:
- 在胡迪尼:
Windows > Python Shell,然后运行:import hrpyc hrpyc.start_server(port=18811) - 或添加到您的
123.py自动启动的启动脚本
- 在胡迪尼:
-
网络接入 -MCP服务器必须能够访问Houdini的RPC端口(默认值:18811)
安装
有关Windows上的Codex桌面,请参阅中的专用设置说明
docs/codex-windows-setup.md.
选项1:Houdini插件(stdio模式)
Houdini插件使用stdio传输直接在Houdini内部运行MCP服务器。这是最简单的设置,不需要网络配置。
安装:
-
复制
houdini_plugin文件夹到您的Houdini包目录:# Windows copy houdini_plugin %USERPROFILE%\Documents\houdini20.5\packages\houdini_mcp # Linux/Mac cp -r houdini_plugin ~/houdini20.5/packages/houdini_mcp -
复制包JSON:
# Windows copy houdini_plugin\houdini_mcp.json %USERPROFILE%\Documents\houdini20.5\packages\ # Linux/Mac cp houdini_plugin/houdini_mcp.json ~/houdini20.5/packages/ -
在Houdini的Python中安装FastMCP:
# Windows (from Houdini's Python) hython -m pip install fastmcp # Or from Houdini's Python Shell import subprocess subprocess.run(["pip", "install", "fastmcp"]) -
重新启动Houdini并找到“Houdini MCP”机框
用途:
- 点击机框上的“启动MCP”以启动服务器
- 配置您的MCP客户端(Claude Desktop、Cursor等)以使用stdio传输
- 点击“停止MCP”停止服务器
MCP客户端配置(stdio模式):
{
"mcpServers": {
"houdini": {
"command": "hython",
"args": ["-c", "from houdini_mcp_plugin import start_server; start_server(use_thread=False)"]
}
}
}
选项2:Docker(远程模式)
对于生产使用或当Houdini在不同的机器上运行时,请使用基于Docker的远程模式。这通过hrpyc/RPyC连接到Houdini。
第一步:在Houdini中启动hrpyc
如果您安装了Houdini MCP插件:
- 点击 “远程启动” 在Houdini MCP货架上
- 使用 “远程状态” / “远程自检” 确认实际界限 端点、可达性和防火墙指导
- 默认情况下,侦听器绑定到
127.0.0.1(仅限环回)。让a 远程客户端(例如另一台主机上的Docker网关)连接,设置HOUDINI_RPC_BIND_HOST和 选择加入HOUDINI_RPC_TRUSTED_NETWORK=1或HOUDINI_RPC_TOKEN。参见 docs/remote-listener.md.
或者在Houdini的Python Shell中手动操作(未更改,仍受支持):
import hrpyc
hrpyc.start_server(port=18811)
步骤2:运行Docker MCP服务器
# Clone the repository
git clone https://github.com/oculairmedia/houdini-mcp.git
cd houdini-mcp
# Copy and configure environment
cp .env.example .env
# Edit .env with your Houdini host IP (from Step 1)
# Run with Docker Compose
docker compose up -d
步骤3:配置MCP客户端
{
"mcpServers": {
"houdini": {
"url": "http://localhost:3055"
}
}
}
远程模式的优点:
- Houdini可以在不同的机器上运行(例如,渲染农场)
- MCP服务器在Docker中运行,便于部署
- 具有高级功能的全套工具
- 服务器端处理能力
本地开发
# Clone and install
git clone https://github.com/oculairmedia/houdini-mcp.git
cd houdini-mcp
pip install -r requirements.txt
# Run
HOUDINI_HOST=192.168.50.90 python -m houdini_mcp
配置
环境变量:
| 变量 | 默认值 | 描述 |
|---|---|---|
HOUDINI_HOST |
localhost |
Houdini机器IP/主机名 |
HOUDINI_PORT |
18811 |
hrpyc服务器端口 |
MCP_PORT |
3055 |
MCP服务器HTTP端口 |
MCP_TRANSPORT |
http |
传输类型(http、stdio、sse) |
LOG_LEVEL |
INFO |
日志记录级别 |
工具类别(43种工具)
服务器分为15个模块化工具类别 houdini_mcp/tools/:
场景和节点(scene.py, nodes.py)
| 工具 | 说明 |
|---|---|
get_scene_info |
获取当前场景信息(文件、版本、节点) |
serialize_scene |
序列化差异的场景结构 |
new_scene |
创建空场景 |
save_scene |
保存当前场景 |
load_scene |
加载.hip文件 |
create_node |
创建新节点 |
delete_node |
按路径删除节点 |
get_node_info |
获取节点详细信息、参数、连接、错误 |
list_children |
列出具有连接详细信息的子节点 |
find_nodes |
按名称模式或类型查找节点 |
list_node_types |
按类别列出可用节点类型 |
接线和布局(wiring.py, layout.py)
| 工具 | 说明 |
|---|---|
connect_nodes |
将节点连接在一起 |
disconnect_node_input |
断开连接 |
reorder_inputs |
重新排序节点输入 |
set_node_flags |
设置显示/渲染/绕过标志 |
layout_children |
自动布局子节点 |
set_node_position |
设置网络中的节点位置 |
set_node_color |
设置节点颜色 |
create_network_box |
在节点周围创建网络框 |
参数(parameters.py)
| 工具 | 说明 |
|---|---|
set_parameter |
设置参数值 |
get_parameter_schema |
获取参数元数据(类型、范围、菜单) |
几何形状和材料(geometry.py, materials.py)
| 工具 | 说明 |
|---|---|
get_geo_summary |
获取几何统计数据和元数据 |
create_material |
创建新材质 |
assign_material |
为几何体指定材质 |
get_material_info |
获取材质参数和着色器 |
渲染图(rendering.py)
| 工具 | 说明 |
|---|---|
render_viewport |
使用摄影机控制渲染视口 |
render_quad_view |
渲染前/左/上/透视图 |
list_render_nodes |
列出所有进出ROP |
get_render_settings |
获取ROP配置 |
set_render_settings |
修改ROP设置 |
create_render_node |
使用设置创建新的ROP |
窗格截图(pane_screenshot.py)
| 工具 | 说明 |
|---|---|
capture_pane_screenshot |
将任何Houdini窗格捕获为PNG |
list_visible_panes |
列出可捕获窗格 |
capture_multiple_panes |
批量捕获多个窗格 |
render_node_network |
导航到节点并捕获网络 |
代码执行(code.py, hscript.py)
| 工具 | 说明 |
|---|---|
execute_code |
使用以下命令执行Python hou 可用 |
execute_hscript |
执行HScript命令 |
错误处理(errors.py)
| 工具 | 说明 |
|---|---|
find_error_nodes |
查找所有存在cook错误的节点 |
帮助和摘要(help.py, summarization.py)
| 工具 | 说明 |
|---|---|
get_houdini_help |
获取节点类型的帮助 |
summarize_response |
AI总结大量响应 |
estimate_tokens |
估计令牌计数 |
get_summarization_status |
获取摘要配置 |
基础设施(_common.py, cache.py)
- 错误处理:
@handle_connection_errors装饰器 - 连接重试:具有抖动的指数回退
- 响应大小:阈值、截断、元数据
- 缓存:带TTL的节点类型缓存
- 并行执行:
semaphore_gather,batch_items
常见模式
创建SOP链
从头开始构建一个完整的SOP网络:
# 1. Create geo container
geo = create_node("geo", "/obj", "my_geo")
# 2. Create SOP nodes
sphere = create_node("sphere", geo["node_path"], "sphere1")
xform = create_node("xform", geo["node_path"], "xform1")
color = create_node("color", geo["node_path"], "color1")
out = create_node("null", geo["node_path"], "OUT")
# 3. Wire nodes together
connect_nodes(sphere["node_path"], xform["node_path"])
connect_nodes(xform["node_path"], color["node_path"])
connect_nodes(color["node_path"], out["node_path"])
# 4. Set display flag
set_node_flags(out["node_path"], display=True, render=True)
将节点插入到现有链中
在现有连接之间插入新节点:
# 1. Discover existing network
children = list_children("/obj/geo1")
# Find grid and noise nodes from children
# 2. Get current connections
noise_info = get_node_info("/obj/geo1/noise1", include_input_details=True)
# See that noise is connected to grid
# 3. Create new node
mountain = create_node("mountain", "/obj/geo1", "mountain1")
# 4. Rewire: grid → mountain → noise
disconnect_node_input("/obj/geo1/noise1", 0) # Break noise ← grid
connect_nodes("/obj/geo1/grid1", "/obj/geo1/mountain1") # grid → mountain
connect_nodes("/obj/geo1/mountain1", "/obj/geo1/noise1") # mountain → noise
智能设置参数
使用参数架构正确设置值:
# 1. Discover parameter metadata
schema = get_parameter_schema("/obj/geo1/sphere1", parm_name="rad")
param = schema["parameters"][0]
# 2. Check parameter type
if param["type"] == "vector":
# Set vector parameter correctly
set_parameter("/obj/geo1/sphere1", "rad", [3.0, 3.0, 3.0])
elif param["type"] == "menu":
# Use menu items
first_option = param["menu_items"][0]["value"]
set_parameter("/obj/geo1/sphere1", "type", first_option)
验证结果
操作后始终验证几何图形:
# Get comprehensive geometry summary
summary = get_geo_summary(
"/obj/geo1/OUT",
max_sample_points=10,
include_attributes=True
)
# Check cook state
if summary["cook_state"] != "cooked":
# Handle errors
node_info = get_node_info("/obj/geo1/OUT", include_errors=True)
errors = node_info["cook_info"]["errors"]
# Fix errors...
# Verify geometry metrics
assert summary["point_count"] > 0
assert summary["primitive_count"] > 0
# Check bounding box
bbox = summary["bounding_box"]
# Verify expected size/position
错误处理最佳实践
读取几何图形前检查烹饪状态
# 1. Check cook state first
node_info = get_node_info(
node_path,
include_errors=True,
force_cook=True
)
cook_state = node_info["cook_info"]["cook_state"]
# 2. Handle different states
if cook_state == "error":
# Examine errors
errors = node_info["cook_info"]["errors"]
for err in errors:
print(f"Error: {err['message']}")
# Fix errors...
elif cook_state == "cooked":
# Safe to access geometry
geo = get_geo_summary(node_path)
验证参数类型
# Always check parameter schema before setting
schema = get_parameter_schema(node_path, parm_name="rad")
param = schema["parameters"][0]
if param["type"] == "vector":
# Use list/tuple for vector parameters
set_parameter(node_path, "rad", [5.0, 5.0, 5.0])
else:
# Use scalar for single parameters
set_parameter(node_path, "rad", 5.0)
处理连接错误
# Connection validation
result = connect_nodes(src_path, dst_path)
if result["status"] == "error":
if "incompatible" in result["message"].lower():
# Different node categories (e.g., SOP vs OBJ)
print("Can't connect nodes of different types")
elif "not found" in result["message"].lower():
# Node doesn't exist
print("Source or destination node not found")
使用错误自检进行调试
# Use include_errors=True to diagnose issues
node_info = get_node_info(
node_path,
include_errors=True,
force_cook=True
)
cook_info = node_info["cook_info"]
# Check for errors
if cook_info["errors"]:
print(f"Node has {len(cook_info['errors'])} errors:")
for error in cook_info["errors"]:
print(f" - {error['message']}")
# Check for warnings
if cook_info["warnings"]:
print(f"Node has {len(cook_info['warnings'])} warnings:")
for warning in cook_info["warnings"]:
print(f" - {warning['message']}")
示例工作流
完整的工作示例可在 examples/ 目录:
build_from_scratch.py-构建球体→ 变换→ 颜色→ 从头开始augment_existing_scene.py-在网格之间插入山→ noiseparameter_workflow.py-发现→ set → 验证参数error_handling.py-检测→ fix → 验证错误
运行示例:
cd examples
python build_from_scratch.py
python augment_existing_scene.py
python parameter_workflow.py
python error_handling.py
使用示例
与克劳德/光标
添加到MCP客户端配置中:
{
"mcpServers": {
"houdini": {
"url": "http://localhost:3055"
}
}
}
与莱塔
在Letta的配置中添加为MCP服务器,以赋予代理Houdini控制权。
示例提示
- “创建球体→ 转化→ 颜色→ OUT网络”
- “在网格和噪波之间插入一个山节点”
- “发现球体节点上可用的参数”
- “检查噪声节点是否有任何烹饪错误”
- “使用参数模式将球体半径设置为3.0”
发展
# Install dev dependencies
pip install -r requirements.txt pytest
# Run tests
pytest tests/
# Run server locally
python -m houdini_mcp
故障排除
连接被拒绝
- 验证Houdini是否在hrpyc服务器启动的情况下运行
- 检查防火墙是否允许端口18811
- 验证HOUDINI_HOST是否正确
身份验证错误
- hrpyc默认不使用身份验证
- 确保您在受信任的网络上
- 插件拒绝绑定非环回地址,除非您明确选择
in(
HOUDINI_RPC_TRUSTED_NETWORK=1)或设置共享密钥 (HOUDINI_RPC_TOKEN).看 docs/remote-listener.md 对于完整的安全模型及其局限性。
项目结构
houdini_mcp/
├── server.py # FastMCP server with 43 tool wrappers
├── connection.py # RPyC connection with retry/backoff
└── tools/ # Modular tool implementations
├── _common.py # Shared utilities, error handling
├── cache.py # Node type caching with TTL
├── code.py # Python/HScript execution
├── errors.py # Error node detection
├── geometry.py # Geometry introspection
├── help.py # Houdini help access
├── hscript.py # HScript command execution
├── layout.py # Node layout tools
├── materials.py # Material creation/assignment
├── nodes.py # Node CRUD operations
├── pane_screenshot.py # Pane capture tools
├── parameters.py # Parameter get/set
├── rendering.py # Viewport/Karma rendering
├── scene.py # Scene management
├── summarization.py # AI response summarization
└── wiring.py # Node connection tools
houdini_plugin/ # Houdini plugin for stdio mode
├── python/houdini_mcp_plugin/
├── toolbar/ # Shelf tools
└── houdini_mcp.json # Package descriptor
tests/ # 418 tests (406 passing)
docs/ # Implementation documentation
examples/ # Working example scripts
鸣谢
- 基于hrpyc集成模式 OpenWebUI Houdini管道
- 受...启发 卡波姆吉特/胡迪尼
许可证
麻省理工学院
