Skip to content

Adapt Blender

Adapt Blender — mvp.adapt_blender

Cluster: Creative & Media | Type: component | MCP Tools: 69

Overview

Blender 3D automation block that drives the Blender binary through a subprocess Python API, generating bpy scripts on the fly for primitive creation, modifiers, materials, animation keyframes, rendering, and export. When Blender is not installed it falls back to a pure-Python OBJ text generator for cube, sphere, plane, and cylinder primitives so the block remains useful in headless environments. Supports persistent sessions so multiple operations can accumulate state inside a single .blend file.

Production Review Outcome

adapt_blender has real utility for basic OBJ fallback generation and for users who have Blender installed and configured. It should not be treated as broadly production-ready in a launch workflow, because most 3D, rendering, session, animation, material, and export operations require a local Blender binary plus a working Blender runtime environment.

For first-user and launch-plan use, position this component as beta:

  • Works without Blender for simple OBJ primitive generation: cube, sphere, plane, and cylinder.
  • Requires Blender for rendering, materials, modifiers, animation, session persistence, file import, and non-OBJ exports.
  • Returns structured BLENDER_ERROR failures when Blender is unavailable for operations that cannot fall back.
  • Useful for technically capable users or controlled demos where Blender installation is verified first.
  • Avoid using this component as evidence that G6 provides production-grade 3D rendering out of the box.

When to use:

  • Programmatically constructing and rendering 3D scenes from agent-generated geometry descriptions
  • Exporting meshes to OBJ, STL, glTF, or FBX for downstream pipelines
  • Building animated sequences with keyframe data driven by solver or goal-engine output
  • Creating persistent sessions to accumulate scene objects across multiple agent steps
  • Pulling free CC0 HDRIs, textures, and models from Poly Haven (polyhaven_* ops) to dress agent-built scenes without manual asset hunting
  • Fast OpenGL viewport_preview for agent visual feedback (~1–2 s vs ~10–60 s for full Cycles/EEVEE render)

Network use is opt-out via allow_network=False; cached assets still serve in offline mode. Downloads are restricted to *.polyhaven.org / *.polyhaven.com hosts with a 200 MB per-asset cap.

Use without Blender only for:

  • create_primitive with cube, sphere, plane, or cylinder
  • Basic OBJ text output from the Python fallback backend

Example:

from mvp.adapt_blender import AdaptBlenderBlock, BlenderInput

block = AdaptBlenderBlock(name="blender")
result = block.infer(BlenderInput(
    op="create_primitive",
    primitive="sphere",
    name="MySphere",
    scale=[1.5, 1.5, 1.5],
    location=[0.0, 0.0, 0.0],
))
# result.value.objects → ["MySphere"]; result.value.vertices → sphere vertex count

Works well with: adapt_generative_art, adapt_image, adapt_comfyui

Public API

AdaptBlenderBlock(AIBlock[BlenderInput, BlenderOutput, None])

Blender 3D automation block.

Field Type Default
name str 'adapt_blender'
resource_bounds ResourceBounds \| None None
usage ResourceUsage field(default_factory=ResourceUsage)
sessions_dir str \| None None

Methods:

infer(data: BlenderInput) -> Result[BlenderOutput]

PolyhavenCache

Filesystem + manifest cache for Poly Haven downloads.

Constructor:

Parameter Type Default
cache_root Path \| None None
db_path str \| None None

Methods:

hdri_path(slug: str, resolution: str, ext: str) -> Path

texture_map_path(slug: str, map_type: str, resolution: str, ext: str) -> Path

model_path(slug: str, resolution: str, ext: str) -> Path

lookup(slug: str, asset_type: str, resolution: str) -> dict[str, Any] | None

Return manifest row if it exists AND the file is still on disk.

record(slug: str, asset_type: str, resolution: str, local_path: str, sha256: str, bytes_: int) -> None

list_all() -> list[dict[str, Any]]

BlenderInput(BaseModel)

Input to AdaptBlenderBlock.

Field Type Default
op str 'create_primitive'
primitive str ''
name str ''
location list[float] [0.0, 0.0, 0.0]
scale list[float] [1.0, 1.0, 1.0]
rotation list[float] [0.0, 0.0, 0.0]
material_color str ''
modifier_type str ''
modifier_params dict {}
keyframe_data dict {}
render_engine str 'EEVEE'
render_resolution list[int] [1920, 1080]
output_path str ''
export_format str 'obj'
script str ''
scene_name str ''
camera_location list[float] [0.0, 0.0, 10.0]
camera_target list[float] [0.0, 0.0, 0.0]
light_type str 'SUN'
light_energy float 1.0
preset_name str ''
timeout_seconds int 120
session_id str ''
clear_scene bool True
import_path str ''
import_format str ''
object_names list[str] []
material_roughness float -1.0
material_metallic float -1.0
material_emission str ''
material_emission_strength float 0.0
material_transmission float 0.0
material_ior float 1.45
material_alpha float 1.0
light_location list[float] [0.0, 0.0, 5.0]
light_rotation list[float] [0.0, 0.0, 0.0]
light_color str ''
light_radius float 0.0
light_params dict {}
frame_start int 1
frame_end int 250
fps int 24
frame_current int 1
render_output_format str 'PNG'
render_samples int 0
render_denoising bool False
render_transparent_bg bool False
boolean_operation str ''
boolean_target str ''
parent_name str ''
child_name str ''
collection_name str ''
select_pattern str ''
select_type str ''
bone_name str ''
bone_head list[float] [0.0, 0.0, 0.0]
bone_tail list[float] [0.0, 0.0, 1.0]
bone_parent_name str ''
armature_name str ''
bones list[dict] []
pose_rotation list[float] [0.0, 0.0, 0.0]
pose_location list[float] [0.0, 0.0, 0.0]
shape_key_name str ''
shape_key_value float 0.0
driver_target str ''
driver_property str ''
driver_expression str ''
constraint_type str ''
constraint_params dict {}
physics_type str ''
physics_params dict {}
bake_start int 1
bake_end int 250
polyhaven_slug str ''
polyhaven_resolution str '2k'
polyhaven_texture_maps list[str] ['Diffuse', 'nor_gl', 'Rough']
allow_network bool True
preview_resolution list[int] [512, 512]
native BackendNativeOpRequest \| None None
scene_graph SceneGraph \| None None
material_node_graph MaterialNodeGraph \| None None
geometry_node_graph GeometryNodeGraph \| None None
asset_operation AssetOperation \| None None
request_id str ''
task_id str ''
run_id str ''

BlenderOutput(BaseModel)

Output from AdaptBlenderBlock.

Field Type Default
op str required
output_path str ''
output_base64 str ''
objects list[str] []
format str ''
vertices int 0
faces int 0
metadata dict {}
backend str ''
script_used str ''
session_id str ''
degraded bool False
degradation_reason str \| None None
available_with str ''
warnings list[dict[str, Any]] []
completion_state str 'qualified-draft'
warning_card dict[str, Any] \| None None
evidence dict[str, Any] {}
request_id str ''
task_id str ''
run_id str ''
error_code str ''
error_message str ''

BlenderSession

Represents a single Blender session backed by a .blend file on disk.

Field Type Default
session_id str required
session_dir str required
blend_path str required

Methods:

exists() -> bool

True if the .blend file has been written (session has been initialised).

SessionManager

Manages session directories under a configurable root.

Constructor:

Parameter Type Default
sessions_dir str \| None None

Methods:

new_session(session_id: str | None = None) -> BlenderSession

Create a new session directory and return a BlenderSession for it.

get_session(session_id: str) -> BlenderSession | None

Return a BlenderSession if the session directory exists, else None.

delete_session(session_id: str) -> bool

Delete the session directory. Returns True if deleted, False if not found.

list_sessions() -> list[str]

Return sorted session IDs (directory names) under the sessions root.

AdaptBlenderMCPBlock(AIBlock[MCPBlenderInput, MCPBlenderOutput, dict])

Full-featured Blender 3D block with SQLite persistence.

Field Type Default
name str 'adapt_blender_mcp'
state dict \| None None
db_path str ':memory:'
sessions_dir str \| None None
resource_bounds ResourceBounds \| None None
usage ResourceUsage field(default_factory=ResourceUsage)

Methods:

infer(data: MCPBlenderInput) -> Result[MCPBlenderOutput]

MCPBlenderRecord(BaseModel)

Field Type Default
id str required
record_type str required
key str required
value str required
tags list[str] []
timestamp str required
metadata dict[str, Any] {}

MCPBlenderInput(BaseModel)

Field Type Default
op Literal['discover_capabilities', 'capabilities', 'create_primitive', 'apply_modifier', 'set_material', 'animate_keyframe', 'render', 'export_obj', 'export_stl', 'export_gltf', 'export_fbx', 'list_objects', 'get_metadata', 'run_script', 'set_camera', 'set_lighting', 'merge_scenes', 'duplicate', 'array_modifier', 'import_file', 'transform_object', 'delete_object', 'add_named_light', 'render_animation', 'set_scene_range', 'boolean_op', 'select_objects', 'parent_objects', 'join_objects', 'create_collection', 'move_to_collection', 'create_armature', 'add_bone', 'parent_to_armature', 'pose_bone', 'add_shape_key', 'set_shape_key_value', 'add_driver', 'add_constraint', 'set_physics', 'bake_animation', 'scene_save', 'scene_load', 'scene_list', 'scene_delete', 'preset_list', 'preset_apply', 'stats', 'get_info', 'session_new', 'session_get', 'session_delete', 'session_list', 'run_workflow', 'viewport_preview', 'polyhaven_hdri', 'polyhaven_texture', 'polyhaven_model', 'polyhaven_cache_list', 'recommend_technique', 'list_patterns', 'backend_native_op', 'native_op', 'build_scene_graph', 'build_material_nodes', 'build_geometry_nodes', 'asset_import', 'asset_export', 'render_export'] required
primitive str ''
name str ''
location list[float] [0.0, 0.0, 0.0]
scale list[float] [1.0, 1.0, 1.0]
rotation list[float] [0.0, 0.0, 0.0]
material_color str ''
modifier_type str ''
modifier_params dict {}
keyframe_data dict {}
render_engine str 'EEVEE'
render_resolution list[int] [1920, 1080]
output_path str ''
export_format str 'obj'
script str ''
scene_name str ''
camera_location list[float] [0.0, 0.0, 10.0]
camera_target list[float] [0.0, 0.0, 0.0]
light_type str 'SUN'
light_energy float 1.0
preset_name str ''
timeout_seconds int 120
import_path str ''
import_format str ''
object_names list[str] []
clear_scene bool True
material_roughness float -1.0
material_metallic float -1.0
material_emission str ''
material_emission_strength float 0.0
material_transmission float 0.0
material_ior float 1.45
material_alpha float 1.0
light_location list[float] [0.0, 0.0, 5.0]
light_rotation list[float] [0.0, 0.0, 0.0]
light_color str ''
light_radius float 0.0
light_params dict {}
frame_start int 1
frame_end int 250
fps int 24
frame_current int 1
render_output_format str 'PNG'
render_samples int 0
render_denoising bool False
render_transparent_bg bool False
boolean_operation str ''
boolean_target str ''
parent_name str ''
child_name str ''
collection_name str ''
select_pattern str ''
select_type str ''
bone_name str ''
bone_head list[float] [0.0, 0.0, 0.0]
bone_tail list[float] [0.0, 0.0, 1.0]
bone_parent_name str ''
armature_name str ''
bones list[dict] []
pose_rotation list[float] [0.0, 0.0, 0.0]
pose_location list[float] [0.0, 0.0, 0.0]
shape_key_name str ''
shape_key_value float 0.0
driver_target str ''
driver_property str ''
driver_expression str ''
constraint_type str ''
constraint_params dict {}
physics_type str ''
physics_params dict {}
bake_start int 1
bake_end int 250
scene_data_json str ''
description str ''
tags list[str] []
query str ''
limit int 50
top_k int 5
session_id str ''
workflow_ops_json str ''
polyhaven_slug str ''
polyhaven_resolution str '2k'
polyhaven_texture_maps list[str] ['Diffuse', 'nor_gl', 'Rough']
allow_network bool True
preview_resolution list[int] [512, 512]
native dict[str, Any] \| None None
scene_graph dict[str, Any] \| None None
material_node_graph dict[str, Any] \| None None
geometry_node_graph dict[str, Any] \| None None
asset_operation dict[str, Any] \| None None
request_id str ''
task_id str ''
run_id str ''
brief str ''
context str ''

MCPBlenderOutput(BaseModel)

Field Type Default
op str required
key str ''
value str ''
found bool False
count int 0
records list[MCPBlenderRecord] []
retrieved list[str] []
scores list[float] []
summary str ''
message str ''
output_path str ''
output_base64 str ''
objects list[str] []
format str ''
vertices int 0
faces int 0
backend str ''
script_used str ''
metadata dict[str, Any] {}
session_id str ''
sessions list[str] []
degraded bool False
degradation_reason str \| None None
available_with str ''
warnings list[dict[str, Any]] []
completion_state str 'qualified-draft'
warning_card dict[str, Any] \| None None
evidence dict[str, Any] {}
request_id str ''
task_id str ''
run_id str ''
error_code str ''
error_message str ''
recommendation dict[str, Any] {}
llm_used bool False

BlenderStore

Sync SQLite blender store with 2 tables: scenes and presets.

Constructor:

Parameter Type Default
db_path str ':memory:'

Methods:

save_scene(name: str, description: str, scene_data: str, tags: list[str], blend_path: str = '') -> str

Save or update a named scene.

load_scene(name: str) -> dict[str, Any] | None

Load a scene by name.

list_scenes(limit: int = 50) -> list[dict[str, Any]]

List all saved scenes.

delete_scene(name: str) -> bool

Delete a scene by name.

list_presets(limit: int = 50) -> list[dict[str, Any]]

List all presets (built-in + user).

get_preset(name: str) -> dict[str, Any] | None

Get a preset by name.

save_preset(name: str, description: str, script: str, tags: list[str]) -> str

Save or update a user preset.

polyhaven_lookup(slug: str, asset_type: str, resolution: str) -> dict[str, Any] | None

Return manifest row for a cached Poly Haven asset, or None.

polyhaven_insert(slug: str, asset_type: str, resolution: str, local_path: str, sha256: str, bytes_: int, downloaded_at: int) -> None

Upsert a Poly Haven download manifest row.

polyhaven_list(limit: int = 200) -> list[dict[str, Any]]

count_all() -> dict[str, int]

Functions

parse_stdout(stdout: str) -> dict[str, Any]

Parse structured tag lines written by bpy scripts to stdout.

validate_modifier_type(modifier_type: str) -> str | None

normalise_modifier_type(modifier_type: str) -> str

validate_primitive(primitive: str) -> str | None

validate_hex_color(color: str) -> str | None

normalise_render_engine(engine: str) -> str

validate_import_format(fmt: str) -> str | None

validate_file_path(path: str) -> str | None

validate_polyhaven_slug(slug: str) -> str | None

normalise_polyhaven_resolution(res: str) -> str

Return one of {1k,2k,4k,8k}; defaults to '2k' for unknown/empty input.

MCP Tools

Operation Source
discover_capabilities blender_mcp
capabilities blender_mcp
create_primitive blender_mcp
apply_modifier blender_mcp
set_material blender_mcp
animate_keyframe blender_mcp
render blender_mcp
export_obj blender_mcp
export_stl blender_mcp
export_gltf blender_mcp
export_fbx blender_mcp
list_objects blender_mcp
get_metadata blender_mcp
run_script blender_mcp
set_camera blender_mcp
set_lighting blender_mcp
merge_scenes blender_mcp
duplicate blender_mcp
array_modifier blender_mcp
import_file blender_mcp
transform_object blender_mcp
delete_object blender_mcp
add_named_light blender_mcp
render_animation blender_mcp
set_scene_range blender_mcp
boolean_op blender_mcp
select_objects blender_mcp
parent_objects blender_mcp
join_objects blender_mcp
create_collection blender_mcp
move_to_collection blender_mcp
create_armature blender_mcp
add_bone blender_mcp
parent_to_armature blender_mcp
pose_bone blender_mcp
add_shape_key blender_mcp
set_shape_key_value blender_mcp
add_driver blender_mcp
add_constraint blender_mcp
set_physics blender_mcp
bake_animation blender_mcp
scene_save blender_mcp
scene_load blender_mcp
scene_list blender_mcp
scene_delete blender_mcp
preset_list blender_mcp
preset_apply blender_mcp
stats blender_mcp
get_info blender_mcp
session_new blender_mcp
session_get blender_mcp
session_delete blender_mcp
session_list blender_mcp
run_workflow blender_mcp
viewport_preview blender_mcp
polyhaven_hdri blender_mcp
polyhaven_texture blender_mcp
polyhaven_model blender_mcp
polyhaven_cache_list blender_mcp
recommend_technique blender_mcp
list_patterns blender_mcp
backend_native_op blender_mcp
native_op blender_mcp
build_scene_graph blender_mcp
build_material_nodes blender_mcp
build_geometry_nodes blender_mcp
asset_import blender_mcp
asset_export blender_mcp
render_export blender_mcp