houdini-mcp-server 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- houdini_mcp_server-0.4.0/.gitignore +30 -0
- houdini_mcp_server-0.4.0/AGENTS.md +31 -0
- houdini_mcp_server-0.4.0/LICENSE +23 -0
- houdini_mcp_server-0.4.0/PKG-INFO +193 -0
- houdini_mcp_server-0.4.0/README.md +172 -0
- houdini_mcp_server-0.4.0/agents/architecture.md +43 -0
- houdini_mcp_server-0.4.0/agents/code.md +30 -0
- houdini_mcp_server-0.4.0/agents/deployment.md +21 -0
- houdini_mcp_server-0.4.0/agents/houdini-api.md +29 -0
- houdini_mcp_server-0.4.0/agents/issues.md +18 -0
- houdini_mcp_server-0.4.0/agents/testing.md +16 -0
- houdini_mcp_server-0.4.0/bootstrap.bat +42 -0
- houdini_mcp_server-0.4.0/bootstrap.sh +41 -0
- houdini_mcp_server-0.4.0/houdini_mcp_server.py +27 -0
- houdini_mcp_server-0.4.0/pyproject.toml +46 -0
- houdini_mcp_server-0.4.0/src/bridge/__init__.py +1 -0
- houdini_mcp_server-0.4.0/src/bridge/cli.py +38 -0
- houdini_mcp_server-0.4.0/src/bridge/connection.py +314 -0
- houdini_mcp_server-0.4.0/src/bridge/onboarding/__init__.py +1 -0
- houdini_mcp_server-0.4.0/src/bridge/onboarding/harnesses.py +284 -0
- houdini_mcp_server-0.4.0/src/bridge/onboarding/houdini.py +185 -0
- houdini_mcp_server-0.4.0/src/bridge/onboarding/install.py +264 -0
- houdini_mcp_server-0.4.0/src/bridge/onboarding/plugin.py +95 -0
- houdini_mcp_server-0.4.0/src/bridge/onboarding/tui.py +192 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/__init__.py +18 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/batch.py +30 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/capture.py +69 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/connect.py +35 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/console.py +28 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/cook.py +32 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/docs.py +282 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/execute.py +35 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/geometry_inspect.py +49 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/hda.py +43 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/node_edit.py +63 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/node_inspect.py +51 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/parm_set.py +59 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/pdg.py +27 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/playbar.py +23 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/render.py +82 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/scene_file.py +24 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/scene_overview.py +40 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/select.py +18 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/session.py +52 -0
- houdini_mcp_server-0.4.0/src/bridge/tools/stage_inspect.py +41 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/HoudiniMCPRender.py +361 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/__init__.py +34 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/__init__.py +1 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/animation.py +99 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/cache.py +68 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/chops.py +65 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/code.py +50 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/context.py +129 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/cops.py +111 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/dops.py +124 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/geometry.py +252 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/hda.py +160 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/lop.py +292 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/materials.py +81 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/nodes.py +522 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/parameters.py +214 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/pdg.py +85 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/rendering.py +202 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/scene.py +77 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/takes.py +46 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/vex.py +77 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/handlers/viewport.py +171 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/headless.py +33 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/houdinimcp.shelf +21 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/protocol.py +55 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/server.py +120 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/__init__.py +38 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/batch.py +21 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/capture.py +65 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/connect.py +23 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/console.py +38 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/cook.py +38 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/docs.py +8 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/execute.py +21 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/geometry_inspect.py +45 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/hda.py +33 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/node_edit.py +85 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/node_inspect.py +78 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/parm_set.py +59 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/pdg.py +21 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/playbar.py +21 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/render.py +20 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/scene_file.py +22 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/scene_overview.py +42 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/select.py +12 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/session.py +18 -0
- houdini_mcp_server-0.4.0/src/houdinimcp/tools/stage_inspect.py +51 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv
|
|
11
|
+
|
|
12
|
+
# Test artifacts
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
|
|
15
|
+
# Hip ingest output (generated via scripts/ingest/)
|
|
16
|
+
hip_parsed.json
|
|
17
|
+
hda_parsed.json
|
|
18
|
+
hip_patterns/
|
|
19
|
+
hip_patterns_index.json
|
|
20
|
+
|
|
21
|
+
# env files
|
|
22
|
+
.env
|
|
23
|
+
.env.*
|
|
24
|
+
|
|
25
|
+
# agent environment-specific
|
|
26
|
+
.claude
|
|
27
|
+
|
|
28
|
+
# generally ignore hidden files and directories except for .gitignore
|
|
29
|
+
.*
|
|
30
|
+
!.gitignore
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Project information: @README.md
|
|
4
|
+
|
|
5
|
+
## Guides
|
|
6
|
+
|
|
7
|
+
- [Architecture](agents/architecture.md) — the three layers, and which file owns what.
|
|
8
|
+
- [Deployment](agents/deployment.md) — this repo is canonical; Houdini reads copies.
|
|
9
|
+
- [Code](agents/code.md) — one source of truth, small modules, no legacy paths.
|
|
10
|
+
- [Testing](agents/testing.md) — test the change, do not commit the test.
|
|
11
|
+
- [Houdini API](agents/houdini-api.md) — the API is the authority, not your memory.
|
|
12
|
+
- [Issues](agents/issues.md) — where specs live.
|
|
13
|
+
|
|
14
|
+
## Rules
|
|
15
|
+
|
|
16
|
+
- Use ASD-STE100 Simplified Technical English in all writing: replies, comments,
|
|
17
|
+
commits, pull requests.
|
|
18
|
+
- Do not keep backward compatibility. Delete the old path. Do not add fallbacks,
|
|
19
|
+
shims, or migrations.
|
|
20
|
+
- Do not write documentation that a person can get from the code. Write a short
|
|
21
|
+
comment in the code instead.
|
|
22
|
+
- Do not record a fact that goes stale: tool counts, version numbers, file
|
|
23
|
+
inventories, status tables, audit results. Point to the code that holds it.
|
|
24
|
+
- Do not add a file to this repo unless the product needs it. Scratch work goes
|
|
25
|
+
in a temporary directory.
|
|
26
|
+
- Do not commit or publish SideFX content or any other copyrighted material.
|
|
27
|
+
This includes help pages, images from the Houdini install, and test fixtures
|
|
28
|
+
made from them. Make a fixture on the machine that runs the test.
|
|
29
|
+
- Look at the change in a live Houdini before you report it done. Code that
|
|
30
|
+
imports is not a plugin that answers. See [Deployment](agents/deployment.md):
|
|
31
|
+
Houdini runs a copy, so run the installer and restart Houdini first.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2025 Capoom
|
|
5
|
+
Copyright (c) 2026 John Chedeville
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in all
|
|
15
|
+
copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
23
|
+
SOFTWARE.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: houdini-mcp-server
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: MCP server for SideFX Houdini: 20 tools, honest failures, version-exact documentation
|
|
5
|
+
Project-URL: Repository, https://github.com/JTCHE/houdini-mcp
|
|
6
|
+
Project-URL: Issues, https://github.com/JTCHE/houdini-mcp/issues
|
|
7
|
+
Author: John Chedeville
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: 3d,houdini,mcp,model-context-protocol,sidefx,vfx
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Requires-Dist: houdinimd-docs>=0.1
|
|
19
|
+
Requires-Dist: mcp[cli]>=2.2
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
|
|
22
|
+
# Houdini MCP
|
|
23
|
+
|
|
24
|
+
<img src="public/cover.png" alt="An illustration titled "Houdini MCP", showing multiple agentic platforms connected to Houdini, symbolizing a link" />
|
|
25
|
+
|
|
26
|
+
<p align="center" alt="HoudiniMCP Server Glama Badge">
|
|
27
|
+
<a href="https://glama.ai/mcp/servers/JTCHE/houdini-mcp"><img src="https://glama.ai/mcp/servers/JTCHE/houdini-mcp/badges/card.svg">
|
|
28
|
+
</a>
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
<p align="center">
|
|
32
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/JTCHE/houdini-mcp?color=blue" alt="License: MIT"/></a>
|
|
33
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10%2B-blue?logo=python&logoColor=white" alt="Python 3.10+"/></a>
|
|
34
|
+
<a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-compatible-green" alt="MCP Compatible"/></a>
|
|
35
|
+
<a href="https://www.sidefx.com/"><img src="https://img.shields.io/badge/Houdini-22.0-orange" alt="Houdini 22.0"/></a>
|
|
36
|
+
</p>
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
Control **SideFX Houdini** from an AI client (Claude, ChatGPT Codex, Gemini) through the **Model Context Protocol**.
|
|
40
|
+
|
|
41
|
+
The bridge talks to Houdini's Python API over a local TCP socket.
|
|
42
|
+
|
|
43
|
+
If no Houdini GUI is running, the bridge starts a
|
|
44
|
+
headless `hython` session, so you can work without the UI.
|
|
45
|
+
|
|
46
|
+
- **20 tools** — one for each noun: `scene_overview`, `node_inspect`,
|
|
47
|
+
`geometry_inspect`, `stage_inspect`, `node_edit`, `parm_set`, `connect`,
|
|
48
|
+
`cook`, `execute`, `render`, `capture`, `console`, `docs`, `playbar`,
|
|
49
|
+
`scene_file`, `select`, `hda`, `pdg`, `session`, `batch`. A `mode` argument
|
|
50
|
+
chooses the action, and every tool takes one item or a list. The modules are
|
|
51
|
+
in [`src/bridge/tools/`](src/bridge/tools/).
|
|
52
|
+
- **Honest failures** — a write that Houdini silently ignored is reported as
|
|
53
|
+
such, and every error names the next action.
|
|
54
|
+
- **Documentation** — the official Houdini docs for the exact build on this
|
|
55
|
+
machine, read out of the install by the [HoudiniMD](https://houdinimd.com)
|
|
56
|
+
engine. No network.
|
|
57
|
+
|
|
58
|
+
## Install
|
|
59
|
+
|
|
60
|
+
**Prerequisites:** Python 3.10+. Houdini is optional at setup time.
|
|
61
|
+
|
|
62
|
+
The script installs [uv](https://docs.astral.sh/uv/) and the `houdinimcp`
|
|
63
|
+
package from PyPI, installs the Houdini plugin, and registers the bridge with
|
|
64
|
+
the agent harnesses you pick.
|
|
65
|
+
|
|
66
|
+
**Windows**
|
|
67
|
+
|
|
68
|
+
```powershell
|
|
69
|
+
powershell -c "irm https://raw.githubusercontent.com/JTCHE/houdini-mcp/main/bootstrap.bat -OutFile bootstrap.bat; .\bootstrap.bat"
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Linux / macOS**
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
curl -sSL https://raw.githubusercontent.com/JTCHE/houdini-mcp/main/bootstrap.sh | bash
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
At a terminal you get menus: which Houdini release to install for, which
|
|
79
|
+
harnesses to configure — Claude Code, Claude Desktop, Codex, Gemini CLI, Cursor,
|
|
80
|
+
opencode, pi. pi reads MCP servers through its
|
|
81
|
+
[pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter) extension.
|
|
82
|
+
|
|
83
|
+
Have uv already? `uv tool install houdini-mcp-server && houdinimcp-install` does the
|
|
84
|
+
same thing.
|
|
85
|
+
|
|
86
|
+
Working from a clone? Run the installer from the repository root:
|
|
87
|
+
`uv run python -m bridge.onboarding.install`. It installs the plugin from that
|
|
88
|
+
clone, and points every harness at it.
|
|
89
|
+
|
|
90
|
+
<details>
|
|
91
|
+
<summary><strong>Unattended install (agents, CI, scripted setup)</strong></summary>
|
|
92
|
+
|
|
93
|
+
The installer never blocks without a terminal: it takes the default for every
|
|
94
|
+
question and says so. Flags make each choice explicit, and `--json` reports what
|
|
95
|
+
it did.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# What is on this machine, as JSON: Houdini releases, harnesses, uv
|
|
99
|
+
houdinimcp-install --list
|
|
100
|
+
|
|
101
|
+
# Every default: newest Houdini, every detected harness
|
|
102
|
+
houdinimcp-install --yes
|
|
103
|
+
|
|
104
|
+
# Explicit, and report what changed
|
|
105
|
+
houdinimcp-install --houdini-version 22.0 --harness claude-code --harness codex --yes --json
|
|
106
|
+
|
|
107
|
+
# Report only, change nothing
|
|
108
|
+
houdinimcp-install --dry-run --yes
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
From a clone, `uv run python -m bridge.onboarding.install` takes the same flags.
|
|
112
|
+
|
|
113
|
+
`bootstrap.sh` and `bootstrap.bat` pass every flag through, so the one-line
|
|
114
|
+
install above works unattended too — `bash bootstrap.sh --yes` on Linux and
|
|
115
|
+
macOS, `.\bootstrap.bat --yes` on Windows.
|
|
116
|
+
|
|
117
|
+
Useful flags: `--houdini-version none` skips the plugin, `--prefs-dir` names the
|
|
118
|
+
Houdini preferences directory outright, `--harness none` leaves every client
|
|
119
|
+
alone, `--skip-deps` skips `uv sync` in a clone, `--quiet-start` stops the
|
|
120
|
+
usage statistics dialog and the Start Here window that cover the viewport on
|
|
121
|
+
a first launch (it adds `HOUDINI_NO_START_PAGE_SPLASH = 1` to `houdini.env`).
|
|
122
|
+
|
|
123
|
+
With `--json`, stdout carries the JSON report and nothing else — the progress
|
|
124
|
+
log goes to stderr. The report names every file written and every client
|
|
125
|
+
configured, so it is also the verification: read `plugin.wrote` and
|
|
126
|
+
`harnesses[].target` back, and check `errors` is empty. `claude mcp list` is the
|
|
127
|
+
independent check for Claude Code.
|
|
128
|
+
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details>
|
|
132
|
+
<summary><strong>Manual setup</strong></summary>
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
uv tool install houdini-mcp-server
|
|
136
|
+
houdinimcp-install --harness none # plugin only
|
|
137
|
+
claude mcp add --transport stdio houdini -- houdinimcp-bridge
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
For a client that reads a JSON config, point `command` at `houdinimcp-bridge`
|
|
141
|
+
with no arguments. From a clone, point it at `uv` with
|
|
142
|
+
`args: ["--directory", "/path/to/houdini-mcp", "run", "python", "houdini_mcp_server.py"]`.
|
|
143
|
+
|
|
144
|
+
ChatGPT accepts remote MCP servers only. The bridge speaks stdio, so put a
|
|
145
|
+
stdio-to-HTTP proxy in front of it and expose that with a tunnel.
|
|
146
|
+
|
|
147
|
+
</details>
|
|
148
|
+
|
|
149
|
+
## How it works
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
MCP client ──stdio──> src/bridge/ ──TCP──> src/houdinimcp/ ──> hou API
|
|
153
|
+
└──────> houdinimd_docs ──> $HFS/houdini/help
|
|
154
|
+
|
|
155
|
+
No Houdini running? The bridge starts hython -> houdinimcp/headless.py
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`src/bridge/` is the MCP side and holds the installer. `src/houdinimcp/` is the
|
|
159
|
+
plugin, which Houdini loads from a copy in its preferences directory.
|
|
160
|
+
|
|
161
|
+
The installer also adds a **HoudiniMCP** shelf with a button that starts and
|
|
162
|
+
stops the TCP server.
|
|
163
|
+
|
|
164
|
+
Headless mode gives you every tool except the ones that need a UI: viewport,
|
|
165
|
+
screenshots and flipbooks. Set `HOUDINIMCP_NO_HEADLESS=1` to turn auto-launch off.
|
|
166
|
+
For those, `session` with `action="start_gui"` starts Houdini with its window
|
|
167
|
+
(and `hip=` opens a file), then waits for the plugin.
|
|
168
|
+
|
|
169
|
+
On Windows, a Houdini that the bridge starts reads the same preferences as one
|
|
170
|
+
started from the Start menu: the bridge sets `HOUDINI_USER_PREF_DIR` when it is
|
|
171
|
+
not set. A shell that sets `HOME` (Git Bash does) otherwise sends Houdini to
|
|
172
|
+
`$HOME\houdiniX.Y`.
|
|
173
|
+
|
|
174
|
+
## Contributing
|
|
175
|
+
|
|
176
|
+
Read [AGENTS.md](AGENTS.md) before you change anything. It carries the working
|
|
177
|
+
rules and links to the short guides in [`agents/`](agents/).
|
|
178
|
+
|
|
179
|
+
## Acknowledgements
|
|
180
|
+
|
|
181
|
+
Built on the work of [blender-mcp](https://github.com/ahujasid/blender-mcp),
|
|
182
|
+
[capoomgit/houdini-mcp](https://github.com/capoomgit/houdini-mcp),
|
|
183
|
+
[eetumartola/houdini-mcp](https://github.com/eetumartola/houdini-mcp),
|
|
184
|
+
[Houdini21MCP](https://github.com/orrzxz/Houdini21MCP) and
|
|
185
|
+
[fxhoudinimcp](https://github.com/healkeiser/fxhoudinimcp).
|
|
186
|
+
|
|
187
|
+
MIT licensed.
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
<sub>HoudiniMCP is an independent community project. It is not affiliated with,
|
|
192
|
+
endorsed by, or sponsored by SideFX Software. Houdini and SideFX are trademarks
|
|
193
|
+
of SideFX Software Inc.</sub>
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Houdini MCP
|
|
2
|
+
|
|
3
|
+
<img src="public/cover.png" alt="An illustration titled "Houdini MCP", showing multiple agentic platforms connected to Houdini, symbolizing a link" />
|
|
4
|
+
|
|
5
|
+
<p align="center" alt="HoudiniMCP Server Glama Badge">
|
|
6
|
+
<a href="https://glama.ai/mcp/servers/JTCHE/houdini-mcp"><img src="https://glama.ai/mcp/servers/JTCHE/houdini-mcp/badges/card.svg">
|
|
7
|
+
</a>
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/JTCHE/houdini-mcp?color=blue" alt="License: MIT"/></a>
|
|
12
|
+
<a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10%2B-blue?logo=python&logoColor=white" alt="Python 3.10+"/></a>
|
|
13
|
+
<a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-compatible-green" alt="MCP Compatible"/></a>
|
|
14
|
+
<a href="https://www.sidefx.com/"><img src="https://img.shields.io/badge/Houdini-22.0-orange" alt="Houdini 22.0"/></a>
|
|
15
|
+
</p>
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
Control **SideFX Houdini** from an AI client (Claude, ChatGPT Codex, Gemini) through the **Model Context Protocol**.
|
|
19
|
+
|
|
20
|
+
The bridge talks to Houdini's Python API over a local TCP socket.
|
|
21
|
+
|
|
22
|
+
If no Houdini GUI is running, the bridge starts a
|
|
23
|
+
headless `hython` session, so you can work without the UI.
|
|
24
|
+
|
|
25
|
+
- **20 tools** — one for each noun: `scene_overview`, `node_inspect`,
|
|
26
|
+
`geometry_inspect`, `stage_inspect`, `node_edit`, `parm_set`, `connect`,
|
|
27
|
+
`cook`, `execute`, `render`, `capture`, `console`, `docs`, `playbar`,
|
|
28
|
+
`scene_file`, `select`, `hda`, `pdg`, `session`, `batch`. A `mode` argument
|
|
29
|
+
chooses the action, and every tool takes one item or a list. The modules are
|
|
30
|
+
in [`src/bridge/tools/`](src/bridge/tools/).
|
|
31
|
+
- **Honest failures** — a write that Houdini silently ignored is reported as
|
|
32
|
+
such, and every error names the next action.
|
|
33
|
+
- **Documentation** — the official Houdini docs for the exact build on this
|
|
34
|
+
machine, read out of the install by the [HoudiniMD](https://houdinimd.com)
|
|
35
|
+
engine. No network.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
**Prerequisites:** Python 3.10+. Houdini is optional at setup time.
|
|
40
|
+
|
|
41
|
+
The script installs [uv](https://docs.astral.sh/uv/) and the `houdinimcp`
|
|
42
|
+
package from PyPI, installs the Houdini plugin, and registers the bridge with
|
|
43
|
+
the agent harnesses you pick.
|
|
44
|
+
|
|
45
|
+
**Windows**
|
|
46
|
+
|
|
47
|
+
```powershell
|
|
48
|
+
powershell -c "irm https://raw.githubusercontent.com/JTCHE/houdini-mcp/main/bootstrap.bat -OutFile bootstrap.bat; .\bootstrap.bat"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Linux / macOS**
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
curl -sSL https://raw.githubusercontent.com/JTCHE/houdini-mcp/main/bootstrap.sh | bash
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
At a terminal you get menus: which Houdini release to install for, which
|
|
58
|
+
harnesses to configure — Claude Code, Claude Desktop, Codex, Gemini CLI, Cursor,
|
|
59
|
+
opencode, pi. pi reads MCP servers through its
|
|
60
|
+
[pi-mcp-adapter](https://github.com/nicobailon/pi-mcp-adapter) extension.
|
|
61
|
+
|
|
62
|
+
Have uv already? `uv tool install houdini-mcp-server && houdinimcp-install` does the
|
|
63
|
+
same thing.
|
|
64
|
+
|
|
65
|
+
Working from a clone? Run the installer from the repository root:
|
|
66
|
+
`uv run python -m bridge.onboarding.install`. It installs the plugin from that
|
|
67
|
+
clone, and points every harness at it.
|
|
68
|
+
|
|
69
|
+
<details>
|
|
70
|
+
<summary><strong>Unattended install (agents, CI, scripted setup)</strong></summary>
|
|
71
|
+
|
|
72
|
+
The installer never blocks without a terminal: it takes the default for every
|
|
73
|
+
question and says so. Flags make each choice explicit, and `--json` reports what
|
|
74
|
+
it did.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# What is on this machine, as JSON: Houdini releases, harnesses, uv
|
|
78
|
+
houdinimcp-install --list
|
|
79
|
+
|
|
80
|
+
# Every default: newest Houdini, every detected harness
|
|
81
|
+
houdinimcp-install --yes
|
|
82
|
+
|
|
83
|
+
# Explicit, and report what changed
|
|
84
|
+
houdinimcp-install --houdini-version 22.0 --harness claude-code --harness codex --yes --json
|
|
85
|
+
|
|
86
|
+
# Report only, change nothing
|
|
87
|
+
houdinimcp-install --dry-run --yes
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
From a clone, `uv run python -m bridge.onboarding.install` takes the same flags.
|
|
91
|
+
|
|
92
|
+
`bootstrap.sh` and `bootstrap.bat` pass every flag through, so the one-line
|
|
93
|
+
install above works unattended too — `bash bootstrap.sh --yes` on Linux and
|
|
94
|
+
macOS, `.\bootstrap.bat --yes` on Windows.
|
|
95
|
+
|
|
96
|
+
Useful flags: `--houdini-version none` skips the plugin, `--prefs-dir` names the
|
|
97
|
+
Houdini preferences directory outright, `--harness none` leaves every client
|
|
98
|
+
alone, `--skip-deps` skips `uv sync` in a clone, `--quiet-start` stops the
|
|
99
|
+
usage statistics dialog and the Start Here window that cover the viewport on
|
|
100
|
+
a first launch (it adds `HOUDINI_NO_START_PAGE_SPLASH = 1` to `houdini.env`).
|
|
101
|
+
|
|
102
|
+
With `--json`, stdout carries the JSON report and nothing else — the progress
|
|
103
|
+
log goes to stderr. The report names every file written and every client
|
|
104
|
+
configured, so it is also the verification: read `plugin.wrote` and
|
|
105
|
+
`harnesses[].target` back, and check `errors` is empty. `claude mcp list` is the
|
|
106
|
+
independent check for Claude Code.
|
|
107
|
+
|
|
108
|
+
</details>
|
|
109
|
+
|
|
110
|
+
<details>
|
|
111
|
+
<summary><strong>Manual setup</strong></summary>
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
uv tool install houdini-mcp-server
|
|
115
|
+
houdinimcp-install --harness none # plugin only
|
|
116
|
+
claude mcp add --transport stdio houdini -- houdinimcp-bridge
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
For a client that reads a JSON config, point `command` at `houdinimcp-bridge`
|
|
120
|
+
with no arguments. From a clone, point it at `uv` with
|
|
121
|
+
`args: ["--directory", "/path/to/houdini-mcp", "run", "python", "houdini_mcp_server.py"]`.
|
|
122
|
+
|
|
123
|
+
ChatGPT accepts remote MCP servers only. The bridge speaks stdio, so put a
|
|
124
|
+
stdio-to-HTTP proxy in front of it and expose that with a tunnel.
|
|
125
|
+
|
|
126
|
+
</details>
|
|
127
|
+
|
|
128
|
+
## How it works
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
MCP client ──stdio──> src/bridge/ ──TCP──> src/houdinimcp/ ──> hou API
|
|
132
|
+
└──────> houdinimd_docs ──> $HFS/houdini/help
|
|
133
|
+
|
|
134
|
+
No Houdini running? The bridge starts hython -> houdinimcp/headless.py
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`src/bridge/` is the MCP side and holds the installer. `src/houdinimcp/` is the
|
|
138
|
+
plugin, which Houdini loads from a copy in its preferences directory.
|
|
139
|
+
|
|
140
|
+
The installer also adds a **HoudiniMCP** shelf with a button that starts and
|
|
141
|
+
stops the TCP server.
|
|
142
|
+
|
|
143
|
+
Headless mode gives you every tool except the ones that need a UI: viewport,
|
|
144
|
+
screenshots and flipbooks. Set `HOUDINIMCP_NO_HEADLESS=1` to turn auto-launch off.
|
|
145
|
+
For those, `session` with `action="start_gui"` starts Houdini with its window
|
|
146
|
+
(and `hip=` opens a file), then waits for the plugin.
|
|
147
|
+
|
|
148
|
+
On Windows, a Houdini that the bridge starts reads the same preferences as one
|
|
149
|
+
started from the Start menu: the bridge sets `HOUDINI_USER_PREF_DIR` when it is
|
|
150
|
+
not set. A shell that sets `HOME` (Git Bash does) otherwise sends Houdini to
|
|
151
|
+
`$HOME\houdiniX.Y`.
|
|
152
|
+
|
|
153
|
+
## Contributing
|
|
154
|
+
|
|
155
|
+
Read [AGENTS.md](AGENTS.md) before you change anything. It carries the working
|
|
156
|
+
rules and links to the short guides in [`agents/`](agents/).
|
|
157
|
+
|
|
158
|
+
## Acknowledgements
|
|
159
|
+
|
|
160
|
+
Built on the work of [blender-mcp](https://github.com/ahujasid/blender-mcp),
|
|
161
|
+
[capoomgit/houdini-mcp](https://github.com/capoomgit/houdini-mcp),
|
|
162
|
+
[eetumartola/houdini-mcp](https://github.com/eetumartola/houdini-mcp),
|
|
163
|
+
[Houdini21MCP](https://github.com/orrzxz/Houdini21MCP) and
|
|
164
|
+
[fxhoudinimcp](https://github.com/healkeiser/fxhoudinimcp).
|
|
165
|
+
|
|
166
|
+
MIT licensed.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
<sub>HoudiniMCP is an independent community project. It is not affiliated with,
|
|
171
|
+
endorsed by, or sponsored by SideFX Software. Houdini and SideFX are trademarks
|
|
172
|
+
of SideFX Software Inc.</sub>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Three layers. Each runs in a different process.
|
|
4
|
+
|
|
5
|
+
1. **Bridge** — `src/bridge/`, started by `houdini_mcp_server.py` in a clone or
|
|
6
|
+
by the `houdinimcp-bridge` console script from the package. Speaks MCP over
|
|
7
|
+
stdio to the client, and JSON over a TCP socket to the plugin.
|
|
8
|
+
`connection.py` is the only place that touches the socket, and it starts a
|
|
9
|
+
headless Houdini when nothing listens. `tools/` holds one module for each
|
|
10
|
+
tool, and `onboarding/` holds the installer.
|
|
11
|
+
2. **Plugin** — `src/houdinimcp/`. Runs inside Houdini. `server.py` accepts the
|
|
12
|
+
socket, `tools/` holds one module for each tool, and the tools call
|
|
13
|
+
`handlers/`. `headless.py` runs the plugin in hython. Only this layer imports
|
|
14
|
+
`hou`.
|
|
15
|
+
3. **Documentation** — the `houdinimd-docs` wheel, the HoudiniMD engine built
|
|
16
|
+
for Python. No Houdini running and no network needed: it reads the help out
|
|
17
|
+
of the Houdini install on this machine and keeps an FTS5 index beside the
|
|
18
|
+
HoudiniMD app's own. `bridge/tools/docs.py` is the only caller.
|
|
19
|
+
|
|
20
|
+
`src/houdinimcp/protocol.py` holds the port and the wire format. Both sides
|
|
21
|
+
import it, so neither side can define its own port. A message is a 4-byte
|
|
22
|
+
big-endian length, then the UTF-8 JSON body.
|
|
23
|
+
|
|
24
|
+
## The tool surface
|
|
25
|
+
|
|
26
|
+
One tool covers one noun. A `mode` argument chooses the action, and every tool
|
|
27
|
+
takes one item or a list of items, so no tool has a batch twin.
|
|
28
|
+
|
|
29
|
+
A tool is a pair of modules with the same name: `src/bridge/tools/<name>.py`
|
|
30
|
+
holds `tool(...)`, whose docstring is what the model reads, and
|
|
31
|
+
`src/houdinimcp/tools/<name>.py` holds `run(...)`, which does the work inside
|
|
32
|
+
Houdini. Both sides find their modules by the file name, so a new tool needs no
|
|
33
|
+
registration and no dispatch table. `MUTATES = True` on the plugin module puts
|
|
34
|
+
the call in an undo group.
|
|
35
|
+
|
|
36
|
+
## Boundaries
|
|
37
|
+
|
|
38
|
+
- The plugin must not know about MCP. The bridge must not import `hou`.
|
|
39
|
+
- Each handler module owns one Houdini context (nodes, geometry, LOPs, COPs...).
|
|
40
|
+
A new context gets a new module, not a longer existing one.
|
|
41
|
+
- Handlers take plain JSON and return plain JSON. Keep Houdini types inside.
|
|
42
|
+
- A failure names the next action. "Not connected" is not an answer; "start
|
|
43
|
+
Houdini, or call session with action='start'" is.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Code
|
|
2
|
+
|
|
3
|
+
## One source of truth
|
|
4
|
+
|
|
5
|
+
Each value, shape, and rule lives in one place. Ports, paths, defaults, and
|
|
6
|
+
patterns get one definition that every caller imports. A value written twice
|
|
7
|
+
will drift.
|
|
8
|
+
|
|
9
|
+
If you find the same value in two files, that is a bug. Fix the duplication
|
|
10
|
+
before you fix the symptom.
|
|
11
|
+
|
|
12
|
+
## Small modules
|
|
13
|
+
|
|
14
|
+
Split by purpose, not by size. A module does one thing and says so in its name.
|
|
15
|
+
Shared logic goes in a module both callers import — never copied, never
|
|
16
|
+
re-implemented.
|
|
17
|
+
|
|
18
|
+
Orchestration goes in the entry points. One-purpose logic goes in focused
|
|
19
|
+
modules that the entry points call.
|
|
20
|
+
|
|
21
|
+
## Change discipline
|
|
22
|
+
|
|
23
|
+
- Fix the cause, not the symptom. Before you edit a function, find every caller.
|
|
24
|
+
One guard in the shared function beats a guard in each caller.
|
|
25
|
+
- Choose the simplest code that meets the current requirement. Do not add
|
|
26
|
+
configuration, indirection, or abstraction for a need that does not exist yet.
|
|
27
|
+
- Delete more than you add when you can.
|
|
28
|
+
- Use names that explain themselves. `positionX`, not `pX`.
|
|
29
|
+
- Write a comment only when the code cannot show the reason. Keep it to one or
|
|
30
|
+
two lines, next to the code it explains.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Deployment
|
|
2
|
+
|
|
3
|
+
This repo is the source. Houdini does not read it.
|
|
4
|
+
|
|
5
|
+
Houdini loads a **copy** of the plugin from its own preferences directory.
|
|
6
|
+
`src/bridge/onboarding/` makes that copy, as one Houdini package that holds the
|
|
7
|
+
module, the startup script and the shelf. An edit in `src/houdinimcp/` has no
|
|
8
|
+
effect on a running Houdini until you run the installer again and restart the
|
|
9
|
+
plugin.
|
|
10
|
+
|
|
11
|
+
The installer copies the `houdinimcp` package that it imports itself, so a clone
|
|
12
|
+
installs the working tree and a PyPI install installs the package. Run it from a
|
|
13
|
+
clone with `uv run python -m bridge.onboarding.install`.
|
|
14
|
+
|
|
15
|
+
The repository ships `.mcp.json`, a project-scope MCP server, for work inside
|
|
16
|
+
the repo. The installer writes a user-scope server as well, so a client that
|
|
17
|
+
reads both reports a scope conflict on the name `houdini`. Expected when you
|
|
18
|
+
install this repo onto itself; pick one scope to keep enabled.
|
|
19
|
+
|
|
20
|
+
Two copies that drift apart is the most costly failure in this project. If a fix
|
|
21
|
+
does not appear, confirm which copy Houdini loaded before you debug the code.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Houdini API
|
|
2
|
+
|
|
3
|
+
The `hou` module is the authority. Your memory of it is not.
|
|
4
|
+
|
|
5
|
+
Houdini changes method names, enum members, and node categories between
|
|
6
|
+
releases. Confirm a symbol exists before you call it: read the object with
|
|
7
|
+
`dir()`, or query the live session.
|
|
8
|
+
|
|
9
|
+
The product supports Houdini 21.0 and 22.0. Add a version conditional only
|
|
10
|
+
where the behaviour is genuinely different. Keep it in one place inside the
|
|
11
|
+
tool that needs it, and name the releases it covers in a comment. A version
|
|
12
|
+
check that guards a symbol you did not confirm is a guess, not a fix.
|
|
13
|
+
|
|
14
|
+
Do not record API facts in this repo. Facts about one release go stale. Use the
|
|
15
|
+
`docs` tool for reference, and the live session for truth.
|
|
16
|
+
|
|
17
|
+
## Failure behaviour
|
|
18
|
+
|
|
19
|
+
Houdini often fails without an error. A name that does not match, a parameter
|
|
20
|
+
with an expression, a node outside its frame range: each produces a wrong result
|
|
21
|
+
and no message.
|
|
22
|
+
|
|
23
|
+
So a handler must:
|
|
24
|
+
|
|
25
|
+
- Report what Houdini reported. Pass `node.errors()` and `node.warnings()` to
|
|
26
|
+
the caller instead of a generic message.
|
|
27
|
+
- Name what it could not do. A parameter that does not exist, a node that did
|
|
28
|
+
not cook, an input that it skipped — return it, do not drop it.
|
|
29
|
+
- Fail loudly on a partial result. Silence reads as success to the caller.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Issues
|
|
2
|
+
|
|
3
|
+
Issues and features live as specs in an Obsidian base, not in this repo.
|
|
4
|
+
|
|
5
|
+
**Vault path:** `<value of OBSIDIAN_VAULT_PATH in @.env.obsidian>/side projects/Houdini/HoudiniMCP — Fork/HoudiniMCP — Fork.base`
|
|
6
|
+
|
|
7
|
+
## Spec format
|
|
8
|
+
|
|
9
|
+
Frontmatter: `Type` (Issue | Feature), `Area`, `Status` (Open | Closed),
|
|
10
|
+
`Priority` (P1 | P2 | P3).
|
|
11
|
+
|
|
12
|
+
Body: one short paragraph. Name the file and the behaviour. State the decision
|
|
13
|
+
to make. No code blocks, no steps, no history.
|
|
14
|
+
|
|
15
|
+
## Status
|
|
16
|
+
|
|
17
|
+
When you commit work that closes a spec, and the user confirms it is complete,
|
|
18
|
+
set `Status: Closed` in that spec.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
Test your change. Do not commit the test.
|
|
4
|
+
|
|
5
|
+
Write the smallest check that fails if the logic breaks, run it, read the
|
|
6
|
+
result, then delete it. A test written for one change is waste in the tree: it
|
|
7
|
+
adds files to read, it goes stale, and nobody runs it again.
|
|
8
|
+
|
|
9
|
+
Keep a test only if the user asks for it, or if it protects logic that a person
|
|
10
|
+
cannot check by hand and that will change again.
|
|
11
|
+
|
|
12
|
+
Scratch scripts, smoke tests, and one-off harnesses go in a temporary directory,
|
|
13
|
+
never in the repo.
|
|
14
|
+
|
|
15
|
+
Prefer a real check over a mock. A Houdini behaviour is only confirmed against
|
|
16
|
+
a running Houdini or `hython`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
setlocal enabledelayedexpansion
|
|
3
|
+
REM bootstrap.bat — One-command setup for HoudiniMCP (Windows).
|
|
4
|
+
REM
|
|
5
|
+
REM Puts uv on the machine, installs the houdinimcp package from PyPI, then
|
|
6
|
+
REM hands over to the installer, which does the Houdini plugin and the MCP
|
|
7
|
+
REM client configuration.
|
|
8
|
+
REM
|
|
9
|
+
REM Fresh install: powershell -c "irm https://raw.githubusercontent.com/JTCHE/houdini-mcp/main/bootstrap.bat -OutFile bootstrap.bat; .\bootstrap.bat"
|
|
10
|
+
REM From inside a clone: bootstrap.bat (uses the code in the clone)
|
|
11
|
+
REM No questions: bootstrap.bat --yes
|
|
12
|
+
REM Every installer flag is passed through: bootstrap.bat --houdini-version 22.0 --harness codex
|
|
13
|
+
|
|
14
|
+
echo.
|
|
15
|
+
echo === HoudiniMCP bootstrap ===
|
|
16
|
+
echo.
|
|
17
|
+
|
|
18
|
+
where uv >nul 2>&1
|
|
19
|
+
if errorlevel 1 (
|
|
20
|
+
echo [..] Installing uv...
|
|
21
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
22
|
+
set "PATH=%USERPROFILE%\.local\bin;!PATH!"
|
|
23
|
+
)
|
|
24
|
+
where uv >nul 2>&1
|
|
25
|
+
if errorlevel 1 (
|
|
26
|
+
echo [FAIL] uv install failed. https://docs.astral.sh/uv/
|
|
27
|
+
exit /b 1
|
|
28
|
+
)
|
|
29
|
+
for /f "tokens=*" %%v in ('uv --version') do echo [OK] %%v
|
|
30
|
+
|
|
31
|
+
if exist "pyproject.toml" if exist "houdini_mcp_server.py" set "IN_REPO=1"
|
|
32
|
+
if defined IN_REPO (
|
|
33
|
+
echo [OK] Inside the repository — installing from this clone
|
|
34
|
+
uv run python -m bridge.onboarding.install %*
|
|
35
|
+
exit /b !errorlevel!
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
echo [..] Installing houdinimcp from PyPI...
|
|
39
|
+
uv tool install --force houdini-mcp-server || exit /b 1
|
|
40
|
+
echo [OK] Installed
|
|
41
|
+
houdinimcp-install %*
|
|
42
|
+
exit /b !errorlevel!
|