Skip to content

v0.2.2 — bridge fixes found by dogfooding the tool surface

Latest

Choose a tag to compare

@Qervas Qervas released this 15 Aug 18:47

Every fix in this release came from building a real asset end-to-end through the shipped tools with execute_python off — so each one is a gap the loop actually hit, not a speculative improvement.

Headline fixes

Fix Why it mattered
execute_python was write-only exec() ran and returned {"ok": true}, discarding stdout and any value. It now returns captured stdout, a JSON-coerced result variable if the snippet sets one, and partial stdout on failure. An escape hatch that can mutate but never answer a question is half a tool.
Two python gates disagreed The server required NIUA_BLENDER_MCP_ALLOW_PYTHON=1 while the add-on preference defaulted on, so system.health reported python_enabled: true while every call was refused at the server. Both now default on, the env var can still close the server side, and health reports the effective AND of the two.
object.transform_set returned stale derived fields location showed the new value while matrix_world/dimensions showed the old one, so an agent verifying its own edit concluded it failed and re-applied it. Fixed in the readers (_object_state / _bounds_state) so no future mutator can forget the refresh.
feedback.capture ignored MATERIAL/RENDERED On the view="current" path, render.opengl draws through scene.display.shading and never consults render.engine, so both EEVEE modes silently degraded to flat Workbench solid.

Quality of life

  • The bridge autostarts with Blender — no N-panel click. Configurable port, with NIUA_BLENDER_MCP_AUTOSTART=0 / NIUA_BLENDER_MCP_PORT=<port> overrides.
  • execute_python moved from a Scene property to AddonPreferences, so a security toggle no longer rides inside a shared .blend, and it is re-read per request instead of captured once at Start.
  • Shading socket lookup prefers the enabled data-type variant. Map Range, Math and Mix expose several sockets sharing one display name; a plain name lookup could write to the inactive twin and silently do nothing.
  • geometry.set_bezier_spline takes a real number array plus comma-separated handle types, instead of a JSON-encoded string that violated the repo's own parameter convention (rule 2 in tests/test_spec_conventions.py).
  • RENDER_ENGINES lists both EEVEE ids, so EEVEE is selectable on Blender 5.x.
  • client/generate.py gained write_all() and a __main__ — a drift test enforced the generated modules with no writer to satisfy it.

Tests

Suite is green. Two pre-existing failures fixed along the way:

  • test_describe_tools asserted the pre-ca22ebf dotted tool name
  • test_benchmark compared a native absolute path against a /-joined suffix, so it only ever passed on POSIX

New coverage for stdout/result/partial-output capture, both python gates plus effective health reporting, socket data-type variants, and the bezier array contract.

Artifacts

File What it is
niua_blender_finisher-0.2.2.zip Blender extension (GPL). Drag onto Blender, or blender --command extension install-file.
niua_blender_mcp-0.2.2-py3-none-any.whl MCP server (Apache). pip install, then run python -m niua_blender_mcp.

Note on this release's extension zip: it is the pure MCP — 63 entries, zero domains/policy / finishing files, as ARCHITECTURE.md requires. The v0.2.1 asset shipped with the held-back policy layer included; CI only asserts purity on the zip from scripts/build_addon_zip.py and never checked the Blender-built extension zip.