MifBlender
MifBlender is MifBridge's Blender backend: a Blender add-on that serves typed operations on a local socket, driven by the same MCP server as the Unreal side. Blender is a first-class backend here, not an exporter bolted onto an Unreal tool.
What it covers
Operations for modeling, materials, UV, rigging, constraints, lights, cameras, animation and drivers, geometry nodes, physics, particles, rendering, world, compositing, collections and view layers, scenes, import/export, and undo. Browse them in the API reference.
1.2 added, among others:
- Sculpting.
bl_sculpt_strokepaints brush strokes headless (Draw, Clay, Grab, Boundary, Cloth and more), with face sets (bl_set_face_sets) and Multires levels (bl_subdivide_multires). - Grease Pencil. Drawing, layers and layer groups, keyframes, effects and modifiers on both API generations (
bl_create_grease_pencil,bl_draw_grease_pencil_strokes,bl_set_grease_pencil_frames), strokes exported as SVG or PDF, and an SVG brought in as Grease Pencil. - Garments. A garment lofted round a body through rings at its bones (
bl_loft_garment), sleeves, hoods, collars and bands grown from it, its ease measured against measured tables, pushed clear of the body across poses, and previewed alone the way an asset viewer lights it (bl_preview_garment). - Game pieces. Modular kit pieces on a grid (
bl_build_kit_piece), rocks, plants and hedges (bl_build_rock,bl_build_plant), LOD chains Unreal reads (bl_build_lod_chain), andbl_recipe_game_ready: the pivot, lightmap UVs, name and collision hulls a piece needs before it leaves for Unreal, checked bybl_mesh_quality. - Motion and rigs. Rigify rigs generated and regenerated, control rigs over a deform skeleton, motion paths, poses spread over frames, and keys cleaned and blended.
- Tracking and editing. Camera tracking in a movie clip (
bl_track_clip,bl_solve_clip), and strips in the Sequencer.
Everything above is procedural or driven by values you give: no trained model is involved. See Blender and Unreal for sending the results to Unreal.
Through the MCP server they are the bl_* tools. You can also speak the add-on's protocol directly.
Install
See Installation. In short: download MifBlender-1.2.0.zip (free, MIT license, not inside the Fab package), install it from Edit ▸ Preferences ▸ Add-ons, set the Token preference to match the MCP server, and the server starts by itself. Its status, Start and Stop are in the 3D viewport's N-panel ▸ MifBridge tab.
Verified on Blender 3.6.23, 4.2.17 LTS, 4.4.0, 5.0.1 and 5.2.1 LTS.
The protocol
- Loopback only:
127.0.0.1:8792. There is no bind-address setting. - One JSON object per frame: a 4-byte big-endian length, then UTF-8 JSON, with a 64 MiB cap. The connection is persistent, and requests are answered in order.
// request
{ "endpoint": "object_info", "token": "dev", "params": { "object": "Cube" } }
// success: the operation's fields are flat, not nested under a "result" key
{ "ok": true, "endpoint": "object_info", "object": { "...": "..." }, "elapsedMs": 3.1 }
// failure
{ "ok": false, "endpoint": "object_info", "error": "no object named '...'. Present: ..." }
endpoint also accepts the aliases op and type. An unknown parameter is an error, not a silent ignore, so a misspelled key tells you so instead of quietly doing nothing. An unknown operation name answers with the operations you most likely meant.
One Blender per port, any port
A second Blender cannot silently take the port. On Windows the socket is bound exclusively, so the second Blender refuses to start its server and says why, rather than both claiming to be listening.
From 1.2, a Blender on another port is found anyway. Each MifBlender records where it listens (port, process id, versions and the open file) in a per-user file, and removes the record when it stops. bl_status lists the other live ones, and bl_status with port or pid switches the session to one of them, with no restart. When the session's port refuses and exactly one other MifBlender is running, every Blender refusal names it and the call that switches to it. With several, it lists them and picks none. This needs the 1.2 add-on.
The add-on shows its process id in the N-panel, in its preferences, in the console and in bl_status. If the id bl_status reports is not the Blender in front of you, your edits are landing somewhere else.
Headless Blender
The add-on does not auto-start under blender -b. A background Blender has no event loop, so the server has to own the main thread, and starting from registration would block startup forever. Start it explicitly:
blender -b --python-expr "import MifBlender; MifBlender.serve_forever()"
Timeouts
The add-on answers a job with an error if Blender's main thread has not picked it up within its job timeout (150 seconds by default). Long bakes and modal operators block that thread. Keep this below the MCP server's MIF_BLENDER_TIMEOUT (180 seconds by default), so Blender gives up first and the caller gets a real error. See Configuration.
Security
- It binds
127.0.0.1only, by design. - Every request must carry a
tokenmatching the add-on preference, compared in constant time. An empty token turns authentication off, and the add-on says so loudly in the console, the preferences and the N-panel. run_pythonexecutes arbitrary Python with your user's privileges, and it is allowed by default as the documented escape hatch. If you do not need it, turn off Allow run_python in the add-on preferences. The N-panel shows whether it is allowed or blocked. The same preference gatescall_operator(any registered Blender operator by id),list_recent_operatorsandenable_addon, which can install an add-on from a file, because each runs code with the same privileges. The typed operations cover the common cases that used to need it.- Web pages cannot reach it. The socket speaks length-prefixed JSON, which no browser can send, and anything a browser does send is dropped before it is read.
- The change cap applies here too. From 1.2,
bl_batchandbl_transform_objectsover 25 objects answer a list to commit, and bulk deletes over it are refused. See Safety and Write Modes.
Undo
Blender has no equivalent of Unreal's transactions, so the add-on makes its own undo steps: one after every call that can change the scene, whether it succeeded or was refused, and none after a read.
undoandredotakesteps(1 to 64, default 1). Each names the steps it moved, reports what the scene gained and lost (objectsAdded,objectsRemoved,datablockCountsChanged), and says how many steps are left each way (undoAvailable,redoAvailable). A call that changes the scene after an undo ends the redo history, as it does in Blender.undo_historylists the steps the bridge recorded, whether it is recording (recording, withwhyNotRecordingwhen it is not), and Blender's step limit, 32 by default.- Files and renders are not taken back. When undo or redo passes over an export, a render, a texture bake or a generator operation,
notRevertednames it. Only the scene moves. - Object mode only. Undo refuses in edit mode, and a call made in edit mode records no step.
- Not while a fluid simulates. While the file holds a Mantaflow fluid domain no steps are recorded, because a step pushed after a flow object changes stops the domain simulating.
undo_historysays so. - Turning it off:
MIF_BLENDER_UNDO=0in Blender's environment, or Blender's own Global Undo preference.
In an interactive Blender, your own edits in the UI are undo steps too, and undo walks back through them in the order they happened. A failed geometry operation still leaves the broken object in the scene as the thing to inspect, and undo takes it back.
Which copy is running
Blender runs the add-on from its own add-ons folder, the installed copy, not the files in your project. After updating, reinstall the zip, then restart Blender. In a copy from GitHub, python tools/sync_blender_addon.py copies the add-on into every installed Blender instead (--check reports drift and changes nothing); the store download does not carry it. If behavior does not match what you expect, check which copy Blender loaded before debugging anything else.
Updating from a checkout: link instead of copying
If you work from a checkout of the repository, link Blender's add-on folder to it instead of copying. There is then no zip and nothing to sync: updating is git pull and a Blender restart.
- Close Blender.
- Move the
MifBlenderfolder out of%APPDATA%\Blender Foundation\Blender\<version>\scripts\addons\- somewhere outside that folder, because Blender loads every folder inside it as an add-on. - From a Command Prompt, link your checkout in its place:
mklink /J "%APPDATA%\Blender Foundation\Blender\<version>\scripts\addons\MifBlender" "<checkout>\tools\blender-addon\MifBlender"
Or from PowerShell:
New-Item -ItemType Junction -Path "$env:APPDATA\Blender Foundation\Blender\<version>\scripts\addons\MifBlender" -Target "<checkout>\tools\blender-addon\MifBlender"
A junction needs no administrator rights. A symbolic link works too, but needs an administrator prompt or Windows Developer Mode. On macOS and Linux, ln -s <checkout>/tools/blender-addon/MifBlender <Blender scripts>/addons/MifBlender.
Make the link from your own terminal, not through an AI app: a link created inside an app's sandbox can come out pointing at nothing, and Blender then shows no MifBlender at all. dir /AL in the add-ons folder shows such a link's target as [..]; delete it in Explorer and make it again. A linked Blender runs whatever the checkout holds when it starts, half-finished edits included, and bl_status reports sourceChangedSinceStart when the checkout changed after Blender started.