Skip to content

Releases: OhaoTech/niua-blender-mcp

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

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.

v0.2.1 — Blender extension + Niua Blender Finisher naming

Choose a tag to compare

@Qervas Qervas released this 30 Jul 16:49

Product-facing polish on top of the pure MCP (v0.2.0).

What's new

  • Blender extension packaging — install via Extensions, not legacy Add-ons:
    • blender_addon/niua_mcp_bridge/blender_manifest.toml
    • python scripts/install_extension.py (recommended)
    • Extension id: niua_blender_finisherbl_ext.user_default.niua_blender_finisher
  • Product name: Niua Blender Finisher (UI panel, server title, extension name)
  • Legacy scripts/install_addon.py still works but points you at the extension path

Internal import path stays niua_mcp_bridge for stability.

Install

pip install niua_blender_mcp-0.2.1-py3-none-any.whl
# or from repo:
pip install -e .
python scripts/install_extension.py --include-policy

Or install the extension zip from this release in Blender:
Preferences → Extensions → Install from Diskniua_blender_finisher-0.2.1.zip

Assets

File Role
niua_blender_mcp-0.2.1-py3-none-any.whl MCP host (stdio server)
niua_blender_finisher-0.2.1.zip Blender extension

Not in this release

Rebuild-from-photo track and demo reports remain WIP and are not tagged here.

v0.2.0 — the pure MCP

Choose a tag to compare

@Qervas Qervas released this 27 Jul 03:21

An agentic Blender MCP: 291 tools across 47 domains, plus eyes so an agent can look at
what it just did instead of driving blind.

This release deliberately does less than v0.1.0.

What changed

v0.1.0 shipped an opinionated finisher — triangle budgets per asset class, readiness
gates, a retopo recipe. That code still exists in the repo and still runs under
scripts/, but it is not in this release, because it is not good enough to stand
behind: the reducer hits budget on simple props and cannot take a dense character there
without wrecking it. A tool that fails on the hard case makes the whole MCP look broken
when the Blender surface underneath is fine.

So the MCP no longer decides anything for you. modifiers.add with a DECIMATE modifier
does exactly what it does in Blender; how far to take it is the agent's call.

Removed from the shipped surface (13 tools):

  • feedback.quality, feedback.readiness, feedback.critique, feedback.preservation,
    feedback.capture_intake, io.profile_validate, asset_class.list,
    asset_class.describe, object.retopo, object.lod_create,
    object.collision_hulls_create, object.collision_proxy_create — held back, still in
    the repo under benchmark.
  • lattice.convert_to_meshgone for good. Blender cannot do it: the operator
    returns FINISHED and leaves the object a LATTICE; to_mesh() raises "Object does
    not have geometry data"
    .

Kept: the eyes. feedback.capture, silhouette, topology, uv, wire_shaded,
turntable, lookdev, orientation — they look at the mesh and report, without judging.

Verified, not assumed

Every one of the 291 tools was exercised against a live Blender 5.1.2 — including the
destructive ones, tested against backups. Zero crashes, zero missing commands, zero broken
tools. Full evidence: docs/reports/tool-audit-2026-07-26.md.

Install

  • MCP server (Apache-2.0, never imports bpy): pip install niua_blender_mcp-0.2.0-py3-none-any.whl
  • Blender add-on (GPL-3.0-or-later): install niua_mcp_bridge-0.2.0.zip through
    Preferences → Add-ons → Install…

Two processes, two licences — the boundary is the socket between them. See LICENSING.md.

execute_python is off by default; enable it per session in the N-panel.