Use cases
Seven things you can build that you couldn’t with a single-LLM, single-Blender setup. Each pattern shows who does what and which tools carry the load. Direct dispatch tools (blender_get_scene_info, blender_execute_code, blender_download_polyhaven_asset, etc.) handle the common cases; blender_send_message + job_dispatch is the escape hatch when a pattern needs script flexibility or custom subscription.
1. Multi-LLM specialization
Section titled “1. Multi-LLM specialization”Different LLM clients with different specialties on the same Blender scene. A modeling-focused LLM builds geometry; a shading-focused LLM writes node graphs; a lighting LLM places HDRIs.
Who:
llm-modeler(LLM session, capabilities["modeling", "geometry"])llm-shader(LLM session, capabilities["shading", "materials"])llm-lighter(LLM session, capabilities["lighting", "hdri"])blender-main(Blender peer, capabilities["python_execution", "modeling", "rendering"])
Flow:
- Modeler calls
blender_get_scene_info()to read the current scene, thenblender_execute_code(code="import bpy; bpy.ops.mesh.primitive_cube_add(...)")to add geometry. - Shader calls
blender_get_object_info(name="Cube")to discover existing materials, then dispatches its node-graph script viablender_execute_code. - Lighter calls
blender_search_polyhaven_assets(asset_type="hdris", categories="outdoor")thenblender_download_polyhaven_asset(...)— the addon handles the import.
Why MCP bus: previously this meant three separate Claude sessions each holding a full Blender context. With the bus they all see the same scene; with direct dispatch tools, each LLM just makes normal tool calls and gets JSON back.
2. Render farm
Section titled “2. Render farm”Many Blender peers in one logical group, dispatched in parallel for a batch render.
Who:
llm-coordinator(LLM session)blender-farm-01,blender-farm-02, …,blender-farm-N(Blender peers, allgroup_id="render-cluster", capabilities include"rendering"and"gpu")
Flow:
- Coordinator calls
blender_list_available_clients, filters togroup_id=="render-cluster"peers withgpucapability. - For each peer, dispatches
blender_execute_code(target_uuid="blender-farm-N", code="bpy.context.scene.frame_set(42); bpy.ops.render.render(write_still=True)"). Thetarget_uuidkwarg overrides auto-pick. - Each tool call returns when that peer reports completion. Run them concurrently with
asyncio.gather.
Payload (under the hood):
{"message_type":"command_dispatch","job_id":"j-...","command":"execute_code", "params":{"code":"import bpy\nbpy.context.scene.frame_set(42)\nbpy.ops.render.render(write_still=True)"}}3. Long-running jobs with progress
Section titled “3. Long-running jobs with progress”A simulation bake takes minutes. The dispatching client wants progress updates, not a single completion event.
Who:
llm-supervisor(LLM session)blender-sim(Blender peer)
Flow:
- Supervisor dispatches via
blender_send_messagewith ajob_dispatchpayload — the script needs to emit progress events back, which the flat dispatch tools don’t model. - The script calls a helper that wraps
blender_send_messagewith prioritynoticeand the samejob_id. - Supervisor’s
on_messagehandles bothjob_update(terminal) and progress notifications (intermediate).
Payload (dispatch):
{"message_type":"job_dispatch","job_id":"job-bake-001", "script":"# bake with periodic executor.send_progress(...) calls"}Payload (progress, addon-side):
{"kind":"progress","job_id":"job-bake-001","percent":47,"frame":120}Why script-dispatch here: the dispatch-tool path returns one JSON result per call. Progress streaming needs the LLM to subscribe to _message_bus and decode events as they arrive — that’s the custom-client pattern in Style B.
4. Cross-instance state mirroring
Section titled “4. Cross-instance state mirroring”Two Blender peers are supposed to stay in sync — a sculpting workstation and a preview render station. Changes on one propagate to the other.
Who:
blender-sculpt(Blender peer,group_id="studio-1")blender-preview(Blender peer,group_id="studio-1")- An external
llm-mirrordriving change detection.
Flow:
- Mirror periodically calls
blender_get_scene_info(target_uuid="blender-sculpt")andblender_browse_data(target_uuid="blender-sculpt", collection="objects"). - On detected delta, mirror calls
blender_execute_code(target_uuid="blender-preview", code="bpy.data.objects['Suzanne'].location = (1.2, 0, 0)").
Why MCP bus: nothing in the bus is tied to single-Blender state. Two peers on the same user’s bus is the same primitive as one peer; the dispatch tools take target_uuid so addressing either is one kwarg.
5. Approval workflows
Section titled “5. Approval workflows”An LLM proposes a change; a human (or another LLM) approves before it lands.
Who:
llm-proposer(LLM session)llm-approver(LLM session — could be a UI sitting on a notebook)blender-target(Blender peer)
Flow:
- Proposer sends a
proposalpayload directly to approver viablender_send_message. Not ajob_dispatch— just data. - Approver’s UI surfaces the proposal. On approval, approver calls
blender_execute_code(target_uuid="blender-target", code="...")to apply the change. - Proposer doesn’t see the dispatch directly; the approver returns the result of
blender_execute_codeover its own LLM channel.
Payload (proposal):
{"kind":"proposal","proposal_id":"prop-001","script":"...","rationale":"..."}Why MCP bus: an LLM-to-LLM message uses the same blender_send_message primitive as an LLM-to-Blender message. The approver doesn’t need a separate channel for “approval requests.”
6. Event broadcasting
Section titled “6. Event broadcasting”Server maintenance notice, scene-reset announcement, “anyone available?” pings.
Who: any sender; every client on the user’s bus.
Flow:
- Call
blender_send_messagewith notarget_uuid/group_id/client_type— defaults to broadcast. Sender is automatically excluded.
Payload:
{"kind":"announcement","text":"Server restarting in 5 min","at":1706203789}Use sparingly. Broadcasts go to everyone — blender-* peers will ignore announcement payloads (no message_type == "job_dispatch" and no message_type == "command_dispatch"), but they still get the notification and queue it briefly before discarding.
7. Status probe before dispatch
Section titled “7. Status probe before dispatch”Tier-3 dispatch tools (PolyHaven, Hyper3D, Sketchfab) are gated by addon preferences. Calling a gated-off tool returns status: "failed" with the addon-side error. Check first.
Who:
llm-asset-finder(LLM session)blender-main(Blender peer)
Flow:
status = json.loads(await client.call_tool("blender_get_polyhaven_status", {}))if status["result"]["enabled"]: await client.call_tool("blender_download_polyhaven_asset", { "asset_id": "kloofendal_43d_clear_puresky", "asset_type": "hdris", "resolution": "2k", })else: # surface the hint, or fall back to a different asset source print("PolyHaven disabled; try Sketchfab or Rodin instead")The same pattern applies to blender_get_hyper3d_status and blender_get_sketchfab_status. Each status tool has a tight default timeout (TIMEOUT_FAST = 15s) so the probe doesn’t add real latency.
Why this pattern: the dispatch tools mirror the addon’s command registry one-to-one, including the gating. Status probes are the cheap way to keep the LLM from dispatching a tool that’s structurally disabled.
Combining patterns
Section titled “Combining patterns”These compose. A render farm (pattern 2) with progress events (pattern 3) and an approval gate (pattern 5) is just three layers of routing on the same bus. Nothing in the design treats them as different kinds of traffic. The dispatch tools cover most calls; script-dispatch is reserved for the parts that genuinely need it.
Related
Section titled “Related”- Command dispatch vs script dispatch — when each path is the right answer
- Dispatch tools reference — all 24 tool signatures
- Routing modes — direct vs group vs broadcast vs type_filter
- Use capabilities — how the render-farm and specialization patterns pick targets
- Write your own LLM client — Style A (direct tool calls) vs Style B (custom subscription)