You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: v0.4.1 — Installation by Rhino command `_McpInstall`
inside Rhino: install the YAK package once, type
`_McpInstall` on the command line, and the C# plugin bootstraps the
PyPI distribution and writes the Claude Desktop config without ever
opening a terminal.
Implementation
--------------
`rhino_plugin/csharp/Commands/McpInstallCommand.cs` adds a
`Rhino.Commands.Command` subclass with `EnglishName = "McpInstall"`.
Rhino's plugin loader picks it up automatically through assembly
scanning, so no extra registration in `Plugin.cs` is required.
The command:
* Resolves a launcher in priority order — `uvx` first (ephemeral
install of `rhino3dm-mcp`, no permanent footprint), an installed
`rhino-mcp` console script next, then a system `python` /
`python3` fallback that runs `python -m rhino_mcp.server install`.
* On macOS extends the search beyond the inherited GUI-app `PATH`
with `~/.local/bin`, `~/.cargo/bin`, `/opt/homebrew/bin`, and
`/usr/local/bin`, since Rhino is launched from Finder/Dock and
rarely sees the user's shell `PATH`.
* On Windows tries common `.exe` / `.cmd` / `.bat` extensions on top
of bare names so `where`-style probing works.
* Runs non-interactively. The MCP server is always registered with
`--mode auto`, so Claude Desktop attaches to the bridge when Rhino
is running and falls back to standalone (rhino3dm) when Rhino is
closed. Rhino-design users are never asked about
"standalone" / "bridge" terminology — both terms are MCP-internal
vocabulary that does not belong on a Rhino command line.
* Spawns the launcher through `Process.Start` with redirected stdout
/ stderr and streams every line into Rhino's command window via
`RhinoApp.WriteLine`, prefixed with `[rhino-mcp]`.
* Falls back gracefully when no launcher is found: prints the canonical
`pip install rhino3dm-mcp && rhino-mcp install` recipe plus the
`uv` install URL, then returns `Result.Failure` so the user sees the
red command-line outcome.
Internal helpers (`Launcher`, `LauncherKind`, `LauncherResolver`,
`ProcessRunner`, `McpInstallConstants`) are kept `internal` so they do
not leak into the plugin's public surface.
Version sync
------------
Every version-bearing file is moved from `0.4.0` to `0.4.1` in lock
step:
* `pyproject.toml`
* `src/rhino_mcp/__init__.py`
* `rhino_plugin/csharp/manifest.yml`
* `rhino_plugin/csharp/RhinoMCPPlugin.csproj` — note: this `<Version>`
was lagging at `0.3.1` and is brought into the matrix here.
* `rhino_plugin/csharp/yak-stage/{win,mac}/manifest.yml`
* `uv.lock`
Docs
----
`README.md`, `README.ko.md`, and `CHANGELOG.md` gain a `[0.4.1]`
section describing the new Rhino command and the version sync, in
both English and Korean.
Verification
------------
* `dotnet build rhino_plugin/csharp -c Release` — 0 errors / 0
warnings.
* `uv run pytest tests/ -q` — 237 passed (the new command is C#
only; existing Python install-flow tests remain green).
* `uv build` — `dist/rhino3dm_mcp-0.4.1-py3-none-any.whl`.
Operational notes
-----------------
Tagging `v0.4.1` triggers the existing release workflow:
1. `build-python` publishes the wheel + sdist to PyPI through Trusted
Publishing.
2. `build-rhp` produces the new `rhino-mcp.rhp` (now containing the
`_McpInstall` command) and attaches it to the GitHub Release.
3. `build-yak` packages the per-platform `.yak` files when the
Windows runner has the Yak CLI available.