Skip to content

v0.4.1

Choose a tag to compare

@github-actions github-actions released this 04 May 17:24
· 3 commits to main since this release
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.