mcpField
B
blender-python-scripting

blender-python-scripting

github.com/ra100Development2454 installsUpdated 26w ago
Repository

About blender-python-scripting

A Blender 5.x Python scripting skill for developers building add-ons, automations, and scene tools. It combines API templates and data-model references with an MCP-first workflow for inspecting and changing a live Blender session.

Key features

  1. 01Operator, panel, and add-on patterns
  2. 02Property, handler, and timer guidance
  3. 03Context management and debugging
  4. 04Batch processing examples
  5. 05Blender data-model reference

Use cases

  1. 01Creating a custom Blender operator or UI panel
  2. 02Developing an add-on for Blender 5.x
  3. 03Batch-processing files or renders
  4. 04Diagnosing context-related operator failures

MCP support

When the official Blender MCP Server is connected, the skill guides inspection, script execution, and visual verification in a running Blender session. Otherwise, it falls back to generating Python scripts.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/ra100/blender-claude-plugin --skill blender-python-scripting

After installing, type/blender-python-scriptingin Claude Code to confirm it loaded.

Bundled filesreferences/data_model_reference.mdreferences/python_api.md

Details

From the project README

Blender Python Scripting Expert

Overview

This skill provides expert guidance for Blender 5.x Python scripting: writing custom operators, building UI panels, developing add-ons, managing context, using handlers and timers, working with the property system, batch processing, and accessing Blender's data model. The reference files contain complete templates and the data model hierarchy.

MCP-First Approach

Prefer the official Blender MCP Server (Blender Lab, Blender 5.1+) for executing scripts, inspecting datablocks, mutating scene state directly in a running Blender session. Fall back to emitting Python scripts only when the MCP server is not connected.

Detection: at session start, look for tools whose names match execute_blender_code, get_objects_summary, or search_api_docs — these belong to the official blender-mcp server. If any are present, MCP is available.

Tools used by this skill:

  • execute_blender_code — run bpy Python in the live session (primary action)
  • get_objects_summary, get_object_detail_summary — inspect scene state before mutating
  • get_blendfile_summary_datablocks / _missing_files / _of_linked_libraries / _path_info / _usage_guess — inventory the file
  • search_api_docs, get_python_api_docs, search_manual_docs — confirm correct API/operator names before calling them
  • get_screenshot_of_window_as_image / _as_json, get_screenshot_of_area_as_image — verify visual results
  • jump_to_tab_by_name, jump_to_tab_by_space_type, jump_to_view3d_object_by_name, jump_to_view3d_object_data_by_name — drive the UI to make changes visible
  • render_thumbnail_to_path, render_viewport_to_path — capture quick visual feedback

Workflow: inspect with a get_* / search_* tool → mutate via execute_blender_code → verify with a screenshot or summary tool. Keep code blocks small and idempotent so failures are easy to localize.

Setup: see docs/blender-mcp-setup.md.

Task Decision Tree

  • "Create a custom operator" -> Consult references/python_api.md for operator templates
  • "Build a UI panel" -> See Panel templates in references/python_api.md
  • "Develop a Blender add-on" -> Follow the Add-on Structure section below
  • "Batch process files / renders" -> See Batch Processing patterns
  • "Access scene/object data" -> Consult references/data_model_reference.md
  • "Register a property" -> See Property System in references/python_api.md
  • "Run code on frame change / file load" -> See Handler patterns in references/python_api.md
  • "Context errors / poll failures" -> See Context Management below

Blender 5.1 Python Changes

Python 3.13 Upgrade
  1. Blender 5.1 bundles Python 3.13 (up from 3.12 in 5.0)
  2. Update bl_info["blender"] to (5, 1, 0) for version gating in add-ons
  3. Use type hint syntax (int | None instead of Optional[int]) — now fully supported
  4. Performance improvements in CPython 3.13: faster function calls, better GC
Removed Operators
  1. bpy.ops.anim.convert_legacy_action — removed; layered actions handle this automatically
API Additions
  1. bpy.ops.pose.apply_to_basis() — bake current pose as rest pose
  2. Node socket types: NodeSocketFont for font data
  3. Volume grid node types for geometry nodes (see blender-geometry-nodes skill)

Add-on Structure

A proper Blender add-on follows this layout:

my_addon/
├── __init__.py       # bl_info, register(), unregister()
├── operators.py      # Custom operators
├── panels.py         # UI panels
├── properties.py     # PropertyGroups
├── preferences.py    # AddonPreferences (optional)
└── utils.py          # Shared utilities
Minimal Single-File Add-on
bl_info = {
    "name": "My Add-on",
    "author": "Author",
    "version": (1, 0, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar > My Tab",
    "description": "Short description",
    "category": "Object",
}

import bpy

class MY_OT_my_operator(bpy.types.Operator):
    bl_idname = "my.my_operator"
    bl_label = "My Operator"
    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        # ... do work ...
        return {'FINISHED'}

class MY_PT_my_panel(bpy.types.Panel):
    bl_label = "My Panel"
    bl_idname = "MY_PT_my_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "My Tab"

    def draw(self, context):
        layout = self.layout
        layout.operator("my.my_operator")

classes = (MY_OT_my_operator, MY_PT_my_panel)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()
Naming Conventions
  • Operators: ADDON_OT_name → bl_idname = "addon.name"
  • Panels: ADDON_PT_name
  • Menus: ADDON_MT_name
  • UILists: ADDON_UL_name
  • PropertyGroups: ADDON_PG_name (convention, not enforced)
  • Headers: ADDON_HT_name

Context Management

Common Context Issues

Blender operations depend on the current context (active object, mode, area type). Many bpy.ops.* calls will fail if context is wrong.

Rule: Always check context before calling operators. Use poll() methods to guard operators.

Context Override (Blender 4.x+ / 5.x)
# Modern context override using temp_override (4.0+)
with bpy.context.temp_override(active_object=obj, selected_objects=[obj]):
    bpy.ops.object.delete()

# Override with area/region for UI-dependent ops
area = next(a for a in bpy.context.screen.areas if a.type == 'VIEW_3D')
region = next(r for r in area.regions if r.type == 'WINDOW')
with bpy.context.temp_override(area=area, region=region):
    bpy.ops.view3d.camera_to_view()
Mode Switching
# Safe mode switch
if bpy.context.object and bpy.context.object.mode != 'EDIT':
    bpy.ops.object.mode_set(mode='EDIT')

# Always return to object mode when done
bpy.ops.object.mode_set(mode='OBJECT')
Common Context Gotchas
  1. bpy.ops in background mode: Many viewport operators fail in --background mode. Use direct data API (bpy.data.*) instead.
  2. Operator context in handlers: Handlers run outside normal context. Use bpy.context.temp_override() or avoid bpy.ops in handlers.
  3. Active object is None: Always check context.active_object is not None before operations.
  4. Wrong mode: Object-mode operators fail in edit mode and vice versa. Check context.object.mode.
  5. Depsgraph not updated: After modifying data, call bpy.context.view_layer.update() or depsgraph.update() if needed.
  6. display_type values depend on object type: 'PLAIN_AXES' is only valid for Empties. Mesh objects use 'BOUNDS', 'WIRE', 'SOLID', or 'TEXTURED'.

Batch Processing

Batch Render
import bpy, os

scenes_dir = "/path/to/blend/files"
output_dir = "/path/to/output"

for filename in os.listdir(scenes_dir):
    if filename.endswith(".blend"):
        filepath = os.path.join(scenes_dir, filename)
        bpy.ops.wm.open_mainfile(filepath=filepath)
        bpy.context.scene.render.filepath = os.path.join(
            output_dir, filename.replace(".blend", ".png")
        )
        bpy.ops.render.render(write_still=True)
Batch Object Processing
import bpy

for obj in bpy.data.objects:
    if obj.type == 'MESH':
        # Select only this object
        bpy.ops.object.select_all(action='DESELECT')
        obj.select_set(True)
        bpy.context.view_layer.objects.active = obj
        # Apply all modifiers
        for mod in obj.modifiers:
            bpy.ops.object.modifier_apply(modifier=mod.name)
Command-Line Batch
blender --background scene.blend --python my_script.py
blender --background --python batch_render.py -- --input /files --output /renders

Access custom args after --:

import sys
argv = sys.argv[sys.argv.index("--") + 1:]

Debugging Tips

  1. System Console: Window > Toggle System Console (Windows) or run Blender from terminal
  2. Python Console: Open the Python Console editor area for interactive testing
  3. Info Editor: Shows Python equivalents of GUI actions — useful for discovering API calls
  4. dir() and help(): Use in Python Console to explore API objects
  5. bpy.context.copy(): Returns a dict of the current context for inspection
  6. Error in modal operator: Add print() statements or use traceback.print_exc() in exception handlers

Property System Quick Reference

TypeRegistrationValues
BoolPropertybpy.props.BoolProperty()True/False
IntPropertybpy.props.IntProperty()min, max, default, step
FloatPropertybpy.props.FloatProperty()min, max, default, precision
StringPropertybpy.props.StringProperty()default, maxlen, subtype
EnumPropertybpy.props.EnumProperty()items=[(id, name, desc)]
FloatVectorPropertybpy.props.FloatVectorProperty()size, default, subtype
IntVectorPropertybpy.props.IntVectorProperty()size, default
BoolVectorPropertybpy.props.BoolVectorProperty()size, default
PointerPropertybpy.props.PointerProperty()type=PropertyGroup
CollectionPropertybpy.props.CollectionProperty()type=PropertyGroup
Property Subtypes
  • Float/Int: 'PIXEL', 'PERCENTAGE', 'FACTOR', 'ANGLE', 'TIME', 'DISTANCE'
  • FloatVector: 'COLOR', 'TRANSLATION', 'DIRECTION', 'VELOCITY', 'ACCELERATION', 'EULER', 'QUATERNION', 'XYZ'
  • String: 'FILE_PATH', 'DIR_PATH', 'FILE_NAME', 'BYTE_STRING', 'PASSWORD'

Python API Reference

For complete templates including operators (basic, modal, file dialog, invoke with props), panels (conditional, sub-panels, collapsible), PropertyGroups, handlers, timers, keymaps, and context overrides, consult references/python_api.md.

Data Model Reference

For the complete Blender data hierarchy (bpy.data.*), ID types, object types, mesh/curve/armature data access patterns, and depsgraph usage, consult references/data_model_reference.md.

Comments

Markdown supported