blender
Blender MCP-compatible modeling surface for Zero. `execute_blender_code` runs Python/bpy as Zero world content; no external Blender is used. Tool names and argument names mirror Blender MCP.
blender
Blender MCP-compatible modeling surface for Zero. execute_blender_code runs Python/bpy as Zero world content; no external Blender is used. Tool names and argument names mirror Blender MCP.
The Python is interpreted in Luau (modeling/pythonParser, modeling/pythonRuntime) — a subset, not CPython. The bpy/bmesh/mathutils surface is modeling/blenderSession.
Tools
| Tool | Notes |
|---|---|
get_addon_status(user_prompt?) | Implementation and compatibility version. |
bpy_api_lookup(query, user_prompt?) | Returns the schema from api.json. Unknown names return NotImplementedError plus related supported names. |
execute_blender_code(code, user_prompt?, session?) | Runs Python, then evaluates modifiers and writes meshes/materials/entities under modeling/sessions/<session>. Sessions are isolated; default default. |
get_scene_info(session?) | Objects, locations, material count. |
get_object_info(object_name, session?) | Dimensions, mesh counts, evaluated triangles, modifier stack, topology audit. |
get_viewport_screenshot(max_size?, session?, view?, perspective?) | Renders the session's viewport state, which scripts drive through bpy (bpy.ops.view3d.view_axis/view_all/view_selected/view_orbit/view_persportho, or region_3d.view_rotation/view_location/view_distance/view_perspective). view (FRONT…BOTTOM, ISO) and perspective (PERSP/ORTHO) override it for one capture. Rendered by Zero, not a Blender viewport. |
Coordinates
Scripts use Blender coordinates (Z-up, right-handed). Zero entities receive (x, y, z) -> (x, z, -y).
Supported API
Authoritative list: api.json (or bpy_api_lookup). Summary:
- Primitives: cube, plane, cylinder, cone, uv_sphere, ico_sphere, torus, circle, grid — with
location,rotation,scale,enter_editmode. New primitives are fully selected, as in Blender. - Object ops:
mode_set(OBJECT/EDIT),select_all,delete,transform_apply,shade_smooth/flat,modifier_apply,modifier_move_up. - Edit ops:
select_mode,select_all,extrude_region_move,inset(region and individual,depth),subdivide(number_cuts1–100),loopcut_slide,bevel(edges and vertices, segments),bridge_edge_loops,spin,remove_doubles,object.material_slot_assign. - Transform:
translate,resize,rotate. In EDIT mode the pivot defaults to the selection median;center_overridesets it explicitly. - Data:
bpy.data.meshes/objects/materials.new,objects.remove,Mesh.from_pydata,mesh.vertices/edges/polygons/materials,collection.objects.link,view_layer.objects.active. - bmesh:
new,from_edit_mesh,update_edit_mesh,from_mesh,to_mesh,verts.new,faces.new,edges(verts,link_faces,is_boundary,is_manifold,calc_length,select),calc_volume,ops.recalc_face_normals. - Modifiers: BEVEL (ANGLE/NONE limit), BOOLEAN (DIFFERENCE/UNION/INTERSECT), ARRAY (with merge), SUBSURF, MIRROR (with merge), SOLIDIFY (offset −1/0/1), SCREW, WELD, DISPLACE (no texture).
- Curves and text:
bpy.data.curves.new(name, 'CURVE'|'FONT'), POLY, BEZIER and NURBS splines,bevel_depth,extrude, 2D fills with holes,object.text_add,curve.primitive_bezier_curve_add/circle_add,object.convert(target='MESH'). Text uses Zero fonts viacurve.zero_font(default Arimo). - UVs:
bpy.ops.uv.smart_project,mesh.uv_layers(one layer). UVs are carried into rendered meshes and bundles. - Images and shader nodes:
bpy.data.images.new/load/remove,Image.pixels(incl.[:]assignment),colorspace_settings.name; node tree with Principled BSDF, Image Texture and Normal Map nodes; texture links to Base Color, Roughness, Metallic, Emission Color and Normal become Zero PBR texture slots (roughness/metallic packed). - Zero shaders as nodes:
nt.nodes.new('ShaderNodeZeroShader'), setnode.shaderto any Zero shader; its properties become inputs. - Knife project, texture DISPLACE, Closest interpolation, float images, multiple UV layers are implemented (see api.json).
- Hierarchy:
Object.parent,parent_set,parent_clear,matrix_worldand friends,object.join,mathutils.Matrix. - Viewport:
bpy.ops.view3d.*above,RegionView3D,SpaceView3D.lens,context.screen.areas,temp_override. - Compare to reference:
blender.compare_to_reference(reference, session)scores the session's FRONT elevation against a reference sheet (silhouette IoU, per-band scores, overlay image). - Output (preferred):
bpy.ops.export_scene.zero_bundle(filepath='/zero/source/<folder>/<Name>.bundle')writes a native Zero bundle — meshes and materials inside it, one Model per material slot, spawnable with theAssetcomponent. A material bound withmat.zero_material = '<material identity>'keeps its custom Zero shader. Exports are frozen snapshots: an existing path is refused unlessoverwrite=True, and each bundle carriesprovenance.json. - Interchange (optional):
bpy.ops.export_scene.gltf(..., export_format='GLB')exists for leaving Zero; nothing inside Zero needs it. - Materials: Principled BSDF
Base Color,Metallic,Roughness,Alpha,IOR; multiple slots with per-facematerial_index;material_slots,active_material(_index);zero_materialbinds an existing Zero material asset.
Rigging and animation
Armatures (bpy.data.armatures, object.armature_add, edit_bones, pose.bones), bone parenting (parent_set(type='BONE')), keyframes (keyframe_insert on objects and pose bones), Blender 5 slotted actions and F-Curves, and scene.frame_set. Bone matrices and F-Curve evaluation match Blender 5.2.1.
Actions are written into the document's output.bundle as animation clips; a placed .zblend plays them (SkinnedModel + ClipPlayer). Vertex groups, the ARMATURE modifier and automatic weights deform meshes; constraints (incl. IK), drivers and NLA are implemented and baked into the clips.
Documents: .zblend (live)
session names a .zblend document, Zero's .blend: a bare name maps to modeling/models/<name>.zblend, or pass "<folder>/<Name>". The document holds scene.json (objects, meshes, curves, modifier stacks, node graphs, images, UV layers, view), history.json, images/, and output.bundle/.
Every execute_blender_code updates the document and its output.bundle in place (only changed objects are rebuilt). A .zblend is scene-instantiable: drag it into a scene or call asset.resolve(id, "zblend"):instantiate(...). Placed copies follow later edits. It has a preview and is indexed for search. export_scene.zero_bundle is only for a frozen snapshot; nothing needs an export step to use the model inside Zero.
Session previews live in the ModelingWorkspace additive scene layer (ZeroBlender.package/workspace/ModelingWorkspace.scene, loaded persistent on first use), so modeling never touches or saves into the scene open in the editor.
Old modeling/sessions/<name>/ folders migrate automatically on first open.
Known differences and limits
- Unsupported calls raise
NotImplementedError: …orAttributeError: …naming the missing API. Nothing is silently ignored exceptcalc_uvs. subdividerequires all faces selected;number_cuts > 1requires quads.insetexpects planar selections;extrude_region_moverequires FACE selection.- BOOLEAN operands must be closed manifold solids.
- ARRAY merge, bevel
limit_methodWEIGHT/VGROUP, and adding primitives in EDIT mode are not implemented. - SUBSURF:
get_object_inforeports the dimensions of the smoothed surface; Blender with GPU subdivision may report the cage size. - Python: one number type (so
24.0prints as24); no classes, generators, decorators or*args.
Parity suite
modeling/references/parity/cases.json holds scripts with numbers captured from native Blender 5.2.1. Run execute { file = "/zero/source/modeling/references/parity/run.luau" }; currently 76/76 pass (subsurf counted as a documented difference).
Not implemented yet
Scene arrangement is implemented: empties, duplicates and linked duplicates, collections, collection instances, Object.zero_instance (place another .zblend), origin_set, the 3D cursor and snapping.
Scoped to this part · feeds back into the world's score.