{"skill":{"slug":"blender-skill","displayName":"Blender MCP Skill","summary":"Connect to and control Blender via the official Blender MCP Server. Covers 20+ built-in tools plus arbitrary bpy code execution. Compatible with Blender 5.1...","description":"---\nname: blender-mcp\ndescription: \"Connect to and control Blender via the official Blender MCP Server. Covers 20+ built-in tools plus arbitrary bpy code execution. Compatible with Blender 5.1 and 5.2 LTS.\"\nhomepage: https://www.blender.org/lab/mcp-server/\nauthor: taosiuman\nversion: 2.0.0\nmetadata:\n  openclaw:\n    requires:\n      bins: [\"blender\", \"mcporter\"]\n    install:\n      - id: mcporter\n        kind: node\n        package: mcporter\n        bins: [\"mcporter\"]\n        label: \"Install mcporter (npm)\"\n---\n\n# Blender MCP Server Connection Skill\n\nConnect to and control a running Blender instance via the official Blender MCP Server.\n\n**Version support**: Blender 5.1+ and 5.2 LTS Beta (API compatibility notes included below)\n\n---\n\n## Architecture Overview\n\n```\n┌─────────────┐     TCP Socket      ┌──────────────────     MCP Protocol     ┌──────────────\n│  LLM Client │ ◄─────────────────► │  MCP Server      │ ◄──────────────────► │   Blender    │\n│  (OpenClaw) │    stdio / HTTP     │  (Python process) │    port 9876         │   (Addon)    │\n└─────────────┘                     └──────────────────┘                      └──────────────\n```\n\n**Two-component architecture**:\n1. **Blender Addon** — runs inside Blender, provides a TCP Socket Server (default `localhost:9876`)\n2. **MCP Server** — standalone Python process that bridges the LLM client and the Blender Addon\n\n---\n\n## Installation\n\n### 1. Install the Blender Addon\n\n**Option A: From ZIP**\n1. Download addon ZIP: `https://projects.blender.org/lab/blender_mcp/releases/download/v1.0.0/mcp-1.0.0.zip`\n2. Blender → Edit → Preferences → Add-ons → Install from Disk\n3. Enable the \"Blender MCP\" addon\n4. Confirm Host/Port in addon settings (default `localhost:9876`)\n\n**Option B: Drag & Drop**\n- Drag the ZIP file into the Blender window (twice: first to add the Blender Lab repository, second to install the addon)\n\n**Option C: From Source**\n- Source code locations: `mcp/blmcp/` and `addon/blender_mcp_addon/`\n\n### 2. Start the Blender MCP Server\n\n```bash\n# Install dependencies\ncd path/to/blender_mcp\npip install mcp pyyaml starlette\n\n# Start MCP Server (stdio mode)\npython -m blmcp --transport stdio\n\n# Or HTTP mode (default 127.0.0.1:8000)\npython -m blmcp --transport http --host 127.0.0.1 --port 8000\n```\n\n### 3. Configure mcporter\n\n```bash\n# Add Blender MCP Server config\nmcporter config add blender-mcp --transport stdio --command \"python -m blmcp --transport stdio\"\n\n# Or use HTTP mode\nmcporter config add blender-mcp --transport http --url \"http://127.0.0.1:8000\"\n\n# Verify connection\nmcporter list blender-mcp --schema\n```\n\n---\n\n## Usage\n\n### Method 1: Via mcporter (recommended)\n\n```bash\n# List all available tools\nmcporter list blender-mcp --schema\n\n# Call a specific tool\nmcporter call blender-mcp.execute_blender_code code='import bpy; result = {\"objects\": [o.name for o in bpy.data.objects]}'\n\nmcporter call blender-mcp.get_objects_summary\nmcporter call blender-mcp.get_object_detail_summary object_name=\"Cube\"\n\n# Search API docs\nmcporter call blender-mcp.search_api_docs query=\"bpy.ops.object.delete\"\n\n# Search user manual\nmcporter call blender-mcp.search_manual_docs query=\"Geometry Nodes\"\n\n# Screenshot\nmcporter call blender-mcp.get_screenshot_of_window_as_image\n\n# Render viewport\nmcporter call blender-mcp.render_viewport_to_path output_path=\"C:\\\\render.png\"\n```\n\n### Method 2: Direct TCP Socket to Blender Addon (lightweight)\n\n⚠️ **Warning**: This mode sends caller-supplied code directly to Blender with no guardrails. Review code before execution.\n\n```python\nimport socket\nimport json\n\ndef send_to_blender(code: str, host=\"localhost\", port=9876, timeout=30.0) -> dict:\n    \"\"\"Send Python code directly to Blender Addon for execution.\"\"\"\n    request = json.dumps({\n        \"type\": \"execute\",\n        \"code\": code,\n        \"strict_json\": False,\n    }) + \"\\0\"\n\n    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:\n        sock.settimeout(timeout)\n        sock.connect((host, port))\n        sock.sendall(request.encode(\"utf-8\"))\n\n        buf = bytearray()\n        while True:\n            chunk = sock.recv(65536)\n            if not chunk:\n                break\n            buf.extend(chunk)\n            if b\"\\0\" in buf:\n                break\n\n    line, _, _ = buf.partition(b\"\\0\")\n    return json.loads(line.decode(\"utf-8\"))\n\n# Example: get all object names in the scene\nresponse = send_to_blender(\n    'import bpy\\nresult = {\"objects\": [o.name for o in bpy.data.objects]}'\n)\nprint(response)\n# {\"status\": \"ok\", \"result\": {\"objects\": [\"Cube\", \"Camera\", \"Light\"]}}\n```\n\n### Method 3: Blender Background Mode (headless rendering / batch)\n\n```bash\n# Start Blender background MCP Server\nblender --background myscene.blend --command blender_mcp --host localhost --port 9876\n\n# Or execute code via CLI\nblender --background myscene.blend --python-expr \"\nimport bpy\n# your code\nresult = {'count': len(bpy.data.objects)}\nprint('__BLMCP_RESULT__' + str(result))\n\"\n```\n\n---\n\n## Built-in Tools (20 total)\n\n### Core\n| Tool | Description | Params |\n|------|-------------|--------|\n| `execute_blender_code` | Execute arbitrary Python code (full bpy access) | `code: str` |\n| `execute_blender_code_for_cli` | Execute code in a background Blender process | `blend_file: str, code: str` |\n\n### Scene Analysis\n| Tool | Description | Params |\n|------|-------------|--------|\n| `get_objects_summary` | Get scene object hierarchy and basic info | none |\n| `get_object_detail_summary` | Get detailed info for a specific object | `object_name: str` |\n| `get_blendfile_summary_datablocks` | Analyze .blend file data-blocks | `blend_file: str` |\n| `get_blendfile_summary_missing_files` | Check for missing external file references | `blend_file: str` |\n| `get_blendfile_summary_of_linked_libraries` | List linked external libraries | `blend_file: str` |\n| `get_blendfile_summary_path_info` | Analyze .blend file path information | `blend_file: str` |\n| `get_blendfile_summary_usage_guess` | Guess the purpose of a .blend file | `blend_file: str` |\n\n### Screenshots & Rendering\n| Tool | Description | Params |\n|------|-------------|--------|\n| `get_screenshot_of_window_as_image` | Capture Blender window screenshot | none |\n| `get_screenshot_of_area_as_image` | Capture specific area screenshot | `area_type: str` |\n| `get_screenshot_of_window_as_json` | Get window layout as JSON description | none |\n| `render_viewport_to_path` | Render viewport to file | `output_path: str` |\n| `render_thumbnail_to_path` | Render thumbnail to file | `output_path: str` |\n\n### Navigation\n| Tool | Description | Params |\n|------|-------------|--------|\n| `jump_to_tab_by_name` | Jump to a named editor tab | `tab_name: str` |\n| `jump_to_tab_by_space_type` | Jump to a space type | `space_type: str` |\n| `jump_to_view3d_object_by_name` | Focus on an object in 3D View | `object_name: str` |\n| `jump_to_view3d_object_data_by_name` | Focus on object data in 3D View | `data_name: str` |\n\n### Documentation Search\n| Tool | Description | Params |\n|------|-------------|--------|\n| `search_api_docs` | Search Blender Python API docs | `query: str` |\n| `search_manual_docs` | Search Blender user manual | `query: str` |\n| `get_python_api_docs` | Get Python API docs | `query: str` |\n\n---\n\n## Communication Protocol\n\n### TCP Socket Protocol\n\n**Request format** (null-byte delimited JSON):\n```json\n{\"type\": \"execute\", \"code\": \"import bpy\\nresult = {'key': 'value'}\", \"strict_json\": false}\\0\n```\n\n**Response format**:\n```json\n// Success\n{\"status\": \"ok\", \"result\": {\"key\": \"value\"}, \"stdout\": \"\", \"stderr\": \"\"}\\0\n\n// Error\n{\"status\": \"error\", \"message\": \"Traceback...\", \"stdout\": \"\", \"stderr\": \"\"}\\0\n```\n\n### Code Execution Conventions\n\n- Assign return value to the `result` variable (must be a dict)\n- `strict_json=True`: strict JSON serialization; non-serializable values will error\n- `strict_json=False`: uses `repr()` as fallback for non-JSON values\n- Supports deferred responses: return a `check_is_finished` callable for long-running tasks\n\n### Example: Get Object Info\n\n```python\nimport bpy\nobj = bpy.data.objects.get(\"Cube\")\nif obj:\n    result = {\n        \"name\": obj.name,\n        \"type\": obj.type,\n        \"location\": list(obj.location),\n        \"vertices\": len(obj.data.vertices) if obj.type == \"MESH\" else 0,\n    }\nelse:\n    result = {\"error\": \"Object not found\"}\n```\n\n### Example: Create an Object\n\n```python\nimport bpy\nbpy.ops.mesh.primitive_torus_add(\n    align='WORLD',\n    location=(0, 0, 0),\n    major_radius=1.0,\n    minor_radius=0.3,\n)\nresult = {\"status\": \"created\", \"name\": bpy.context.active_object.name}\n```\n\n---\n\n## Environment Variables\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `BLENDER_MCP_HOST` | `localhost` | Blender Addon host address |\n| `BLENDER_MCP_PORT` | `9876` | Blender Addon port |\n| `BLENDER_PATH` | `blender` | Path to Blender executable |\n\n---\n\n## Security Notes\n\n⚠️ **Official security warning**: The MCP Server executes LLM-generated code with **no sandboxing**.\n\n**Built-in weak sandbox** (`WeakSandboxForLLM`):\n- Blocks `sys.exit()` calls\n- Blocks dangerous operators: `wm.quit_blender`, `wm.read_factory_settings`, `wm.read_factory_userpref`, `wm.read_userpref`\n\n### Security Best Practices\n\n1. **Keep server local only** — Always use `localhost` / `127.0.0.1`; never bind to `0.0.0.0`\n2. **Review code before execution** — Prefer scoped built-in tools over raw `execute_blender_code`\n3. **Protect your projects** — Keep backups of important `.blend` files\n4. **Verify external dependencies** — Download addon only from official Blender Lab sources\n\n---\n\n## Troubleshooting\n\n| Error | Cause | Solution |\n|-------|-------|----------|\n| `ConnectionRefusedError` | Blender not running or Addon not started | Start Blender, enable MCP Addon, click \"Start Server\" |\n| `ConnectionError: Empty response` | Network timeout or Addon crashed | Check Blender console output, verify port |\n| `result is not JSON-serializable` | Returned a Blender object | Use `strict_json=False` or manually convert to dict |\n| `Blender executable not found` | Blender command not found | Set `BLENDER_PATH` environment variable |\n| `Deferred responses not supported` | Background mode doesn't support deferred responses | Use synchronous code or switch to GUI mode |\n\n---\n\n## Blender 5.1 API Compatibility Notes\n\n### Action Layered Structure (Breaking Change)\n\nIn Blender 5.1, `Action.fcurves` was removed. The new layered animation system uses:\n\n```python\n# ❌ Old (5.0 and earlier)\nfcurves = action.fcurves\n\n# ✅ Blender 5.1+\nfcurves = action.layers[0].strips[0].channelbags[0].fcurves\n```\n\n### Brush API: `use_*` → `stroke_method` Enum\n\n```python\n# ❌ Old (5.0)\nbrush.use_airbrush = True\n\n# ✅ 5.1+\nbrush.stroke_method = 'AIRBRUSH'  # Options: AIRBRUSH, SPACE, ANCHORED, LINE, CURVE, DRAG_DOT\n```\n\n### VSE Time Property Renames\n\n| Old (5.0) | New (5.1) |\n|-----------|-----------|\n| `frame_final_duration` | `duration` |\n| `frame_final_start` | `left_handle` |\n| `frame_final_end` | `right_handle` |\n| `frame_duration` | `content_duration` |\n\n### Principled BSDF Input Renames\n\n| Old (5.0) | New (5.1) |\n|-----------|-----------|\n| `inputs['Transmission']` | `inputs['Transmission Weight']` |\n| `inputs['Emission']` | `inputs['Emission Color']` + `inputs['Emission Strength']` |\n\n### Other 5.1 Changes\n- `sculpt.sample_color` → `paint.sample_color`\n- `bpy.app.cachedir` — new standard cache directory\n- `bpy.app.handlers.exit_pre` — new exit handler\n- Python 3.13 runtime\n\n---\n\n## Blender 5.2 LTS Compatibility Notes (Beta)\n\n> Blender 5.2 LTS entered Beta on 2026-06-03. API is frozen; RC expected 2026-07-08, release 2026-07-14.\n\n### 🔴 Breaking Changes (12 total — all Beta confirmed)\n\n#### 1. Geometry Nodes Modifier API Rewrite\n\n```python\n# ❌ 5.1 and earlier\nmodifier[\"SocketName\"] = 5.0\nmodifier[\"SocketName_use_attribute\"] = True\nmodifier[\"SocketName_attribute_name\"] = \"some_input\"\n\n# ✅ 5.2+\nmodifier.properties.inputs.SocketName.value = 5.0\nmodifier.properties.inputs.SocketName.type = \"ATTRIBUTE\"\nmodifier.properties.inputs.SocketName.attribute_name = \"some_input\"\nmodifier.properties.outputs.SocketName.attribute_name = \"some_output\"\n\n# ✅ Compatible pattern\nimport bpy\nif bpy.app.version >= (5, 2, 0):\n    val = modifier.properties.inputs.SocketName.value\nelse:\n    val = modifier[\"SocketName\"]\n```\n\n#### 2. Principled BSDF Node Renamed\n- `Transmission` → `Transmission Weight`\n- Already applies from 5.1; ensure plugin references match\n\n#### 3. `paint.eraser_brush` API Removed\n- No longer needs manual setting; last eraser brush auto-activates\n\n#### 4. Automasking → MeshAutomaskingSettings (17 properties migrated)\n\n```python\n# ❌ Old\nbrush.use_automasking_topology = True\nbrush.automasking_cavity_factor = 0.5\n\n# ✅ 5.2+\nbrush.mesh_automasking_settings.use_automasking_topology = True\nbrush.mesh_automasking_settings.cavity_factor = 0.5\n```\n\nAll 17 properties: `use_automasking_topology`, `use_automasking_face_sets`, `use_automasking_boundary_edges`, `use_automasking_boundary_face_sets`, `use_automasking_cavity`, `use_automasking_cavity_inverted`, `use_automasking_start_normal`, `use_automasking_view_normal`, `automasking_boundary_edges_propagation_steps`, `automasking_cavity_factor`, `automasking_cavity_blur_steps`, `automasking_cavity_curve`, `automasking_cavity_curve_op`, `automasking_start_normal_limit`, `automasking_start_normal_falloff`, `automasking_view_normal_limit`, `automasking_view_normal_falloff`\n\n#### 5. VSE `strip.use_linear_modifiers` Removed\n#### 6. VSE `timecode files` Feature Removed\n#### 7. `UILayout.template_palette` `color` Parameter Removed\n#### 8. Compare / Random Value Node Socket Identifiers Changed\n#### 9. Asset Library Index Shift — \"All Libraries\" and \"Essentials\" now occupy first two indices\n#### 10. Evaluated Meshes Naming Change — Geo Nodes created meshes no longer share object's original mesh name\n#### 11. Brush `use_*` → `stroke_method` (see 5.1 section above)\n#### 12. VSE Time Property Renames (see 5.1 section above)\n\n---\n\n### 🟢 High-Value New APIs (5.2 LTS)\n\n#### Python API\n| API | Description |\n|-----|-------------|\n| `bpy.data.all_ids` | Single iterator over ALL data-blocks |\n| `WindowManager.reports` | Read-only reports list with session-wide unique uid |\n| `bpy.data.libraries.load()` input | Now exposes nested library paths |\n| `Window.screenshot()` | Get window pixel data without saving to file |\n| `gpu.init()` | Initialize GPU backend in `--background` mode |\n| `mathutils` slice step | `vector[begin:end:step]` for Vector/Matrix/Color/Euler |\n| Blender Arrays slice step | `image.pixels[begin:end:step]` — e.g., `pixels[3::4]` for alpha channel |\n| `path_foreach` options | EXPAND_TOKENS, EXPAND_SEQUENCES, EXPAND_CACHES |\n| Annotations API | `frame.strokes.new()`, `stroke.points.add(count, pressure, strength)`, `stroke.points.remove(index)`, `frame.strokes.remove(stroke)` |\n| `UILayout.link` / `textbox` | Styled link buttons and multi-line text buttons |\n| `imbuf` extended | Pixel-level image access, format conversion, buffer protocol |\n| Node panel collapse | Programmatically open/close node panels from Python |\n| Node Tool input values | Set Node Tool parameters programmatically in 5.2 |\n\n#### Geometry Nodes\n| Node / Feature | Description |\n|----------------|-------------|\n| **Physics (experimental)** | XPBD Solver, Cloth Dynamics modifier, Hair Dynamics, Effector system |\n| **Mesh Bevel** | Long-awaited procedural bevel node |\n| **Geometry Bundles** | Set/Get Geometry Bundle — attach arbitrary data (fields, closures) to geometry |\n| **Lists data type** | New core type alongside single/field/grid — Length, Get, Filter, Sort |\n| **Sample Sound Frequencies** | Audio-driven animation without keyframe baking |\n| **PCA** | Principal Component Analysis for auto-alignment |\n| **Transfer Attributes** | Transfer attributes between two geometries |\n| **3D ↔ Screen Space** | Bundled transform nodes (3D to Screen, Screen to 3D, Project with Depth) |\n| **Collection Children** | Recursive access to collection children as lists |\n| **Empty Objects** | Geo Nodes modifiers on Empty objects |\n| **Capture Attribute Selection** | Selection input for efficiency |\n| **NURBS Order/Weight** | Set NURBS Order and Weight nodes |\n| **Scene Frame default input** | Float/int sockets default to current frame |\n| **Self-object default** | Object sockets can default to self-object |\n| **Merge by Distance split** | Now: Merge Points + Cluster by Distance + Cluster by Connected |\n\n#### Cycles\n| Feature | Description |\n|---------|-------------|\n| **Texture Cache** | `.tx` files reduce memory 34-77% in texture-heavy scenes. Enable: Performance > Texture Cache + Auto Generate. CLI: `blender scene.blend --command maketx` |\n| **Raycast Attributes** | Access attributes at intersection point (Cycles only) |\n| **SSS Negative Anisotropy** | Principled/Subsurface BSDF: -1 to 1 range |\n| **World Cast Shadows** | World can now cast shadows |\n| **OSL GPU** | Texture cache improves OSL performance + adds GPU support |\n| **Simplify Texture Resolution** | Percentage-based texture scaling (50%, 25%) |\n\n#### EEVEE\n| Feature | Description |\n|---------|-------------|\n| **Shader Raycast** | Screen-space raytracing node |\n| **Light Path Intensity** | Global indirect light intensity control |\n| **Texture pool -40%** | Vulkan: 406MB → 245MB |\n\n#### Grease Pencil\n| Feature | Description |\n|---------|-------------|\n| **Fill Tool Delaunay** | New Delaunay solver: precise geometry, auto gap detection, scale-independent, faster |\n| **Draw Tool curves** | Bézier / Catmull-Rom / NURBS curve types |\n| **Line Materials placement** | Count / Density / Radius modes with randomization |\n| **`layer.layer_masks` API** | Add/remove layer masks via Python |\n\n#### Video Sequencer\n| Feature | Description |\n|---------|-------------|\n| **Compositor Effect Strip** | Use compositor node trees for VSE transitions/effects (0/1/2 inputs + fader) |\n| **Compositor GPU acceleration** | In VSE modifiers |\n| **`strip.connections`** | API to find connected strips |\n\n#### Sculpt\n| Feature | Description |\n|---------|-------------|\n| **Scene Project brush** | Displace vertices toward other objects (like Shrinkwrap) |\n| **Add Primitive in Sculpt Mode** | Cube/Cone/Cylinder directly in sculpt |\n| **Color Filter unified color** | Uses scene unified colors; Ctrl-X quick fill |\n| **Dyntopo confirmation removed** | No more confirmation dialog when switching back to Sculpt |\n| **Voxel Remesher attribute interpolation** | Smooth vertex/corner attribute interpolation |\n\n#### Assets\n| Feature | Description |\n|---------|-------------|\n| **Online Asset Library** | Browse and download from remote hosted libraries |\n| **Asset Library index shift** | \"All Libraries\" and \"Essentials\" now at indices 0 and 1 |\n\n#### Other\n| Feature | Description |\n|---------|-------------|\n| **LoopTools built-in** | Circle/Space/Flatten now native — no addon needed |\n| **Hydra 2.0 API** | OpenUSD provides abstraction layer |\n| **Animation +125%** | Action evaluation 32.8→74.1 fps (4 threads) |\n| **Gaussian Smooth F-Curve** | Non-destructive curve smoothing modifier |\n\n---\n\n## OpenClaw Integration\n\n### Configure openclaw.json\n\n```json\n{\n  \"plugins\": {\n    \"entries\": {\n      \"mcp\": {\n        \"servers\": {\n          \"blender-mcp\": {\n            \"command\": \"python\",\n            \"args\": [\"-m\", \"blmcp\", \"--transport\", \"stdio\"],\n            \"cwd\": \"path/to/blender_mcp\",\n            \"env\": {\n              \"BLENDER_MCP_HOST\": \"localhost\",\n              \"BLENDER_MCP_PORT\": \"9876\"\n            }\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Via mcporter CLI\n\n```bash\n# List tools\nmcporter call blender-mcp.get_objects_summary\n\n# Execute code\nmcporter call blender-mcp.execute_blender_code code='import bpy; result = {\"count\": len(bpy.data.objects)}'\n```\n\n---\n\n## Quick Start Checklist\n\n- [ ] Blender 5.1+ installed\n- [ ] MCP Addon installed and enabled\n- [ ] MCP Server started (`python -m blmcp --transport stdio`)\n- [ ] mcporter installed (`npm install -g mcporter`)\n- [ ] Port 9876 available (default)\n- [ ] `BLENDER_PATH` environment variable set (if needed)\n","tags":{"latest":"2.0.0"},"stats":{"comments":0,"downloads":476,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":4},"createdAt":1777686671906,"updatedAt":1780857123762},"latestVersion":{"version":"2.0.0","createdAt":1780857123762,"changelog":"Add Blender 5.2 LTS Beta compatibility: 12 breaking changes with migration code, 40+ new APIs across all 17 modules. Includes XPBD Physics, Mesh Bevel, Geometry Bundles, Lists, Sample Sound, Texture Cache, Delaunay Fill, Compositor Effect Strip.","license":"MIT-0"},"metadata":{"setup":[],"os":null,"systems":null},"owner":{"handle":"taosiuman","userId":"s17fkgns47174kx42nm8z7c5g184249f","displayName":"Taosiuman","image":"https://avatars.githubusercontent.com/u/3102173?v=4"},"moderation":null}