---
name: blender-live
trigger: /blender-live
description: >
  Drive a live Blender session via BlenderMCP to create bespoke 3D objects
  for game projects — iterative modeling, viewport verification, GLB export,
  and Godot import validation. Use for organic, hand-crafted, or otherwise
  non-parametric shapes. NOT for parametric low-poly props (use a headless
  generator) or stock catalog art (check a CC0 asset library first).
user_invocable: true
---

> **Public / shared version** — trimmed from a private Claude Code setup and
> posted at smereski.com as a reusable pattern.

# blender-live — drive BlenderMCP to make game-ready 3D objects

BlenderMCP connects a running Blender GUI to Claude via an MCP server
(`uvx blender-mcp`) and a socket-server addon. Claude drives Blender with
`mcp__blender__*` tools. Use this path when you need a bespoke object the
headless parametric generator can't express; hand the result to Godot (or any
other engine) as a verified GLB.

## When to reach for this (cheapest-first)

1. Stock CC0 asset exists? → grab it from a library. Stop.
2. Simple primitive prop? → use a headless parametric script. Stop.
3. Bespoke / organic / editing an existing mesh → **this skill.**

## Prerequisites

- Blender (5.0 recommended) installed with the BlenderMCP addon enabled.
- MCP server registered: `claude mcp add blender -s user -- cmd /c uvx blender-mcp`
  (or the equivalent for your OS/shell).
- Godot or your target engine available for import verification.

**Verify setup (both must pass):**
```bash
claude mcp list | grep blender
# -> "blender: ... ✔ Connected"
```

Missing server: re-run the `claude mcp add` command above.
Missing addon: reinstall via Blender → Preferences → Add-ons → Install.

## Bring the tools online (every session — the #1 gotcha)

1. **Open Blender (GUI).** 3D view → press `N` → **BlenderMCP** tab →
   **Connect to Claude**. (This is a human click — a headless Blender has no
   live socket server. Never try to script this.)
2. **Restart Claude Code.** MCP tools load at startup; a session that began
   before the server was registered does NOT have them.
3. Tools may be deferred → load with ToolSearch:
   `select:mcp__blender__execute_code,mcp__blender__get_scene_info,mcp__blender__get_viewport_screenshot,mcp__blender__get_object_info`

## Tool surface

Always available:

| Tool | Use |
|------|-----|
| `execute_code` | Run arbitrary `bpy` Python — build, edit, apply, export. |
| `get_scene_info` | List scene objects. Call FIRST before building. |
| `get_object_info` | Inspect one object (mesh stats, transform, materials). |
| `get_viewport_screenshot` | Render viewport → self-verify visually before export. |
| `get_polyhaven_status` / `get_hyper3d_status` / `get_sketchfab_status` / `get_hunyuan3d_status` | Check whether a provider is enabled BEFORE using it. |

Opt-in providers (need their checkbox ticked in the BlenderMCP N-panel;
Rodin/Sketchfab also need an API key):

| Provider | Tools | Use |
|----------|-------|-----|
| PolyHaven | `search_polyhaven_assets`, `download_polyhaven_asset`, `set_texture` | Pull CC0 models / HDRIs / textures. |
| Hyper3D Rodin | `create_rodin_job`, `poll_rodin_job_status`, `import_generated_asset` | Text/image → 3D mesh. Best for organic shapes. |
| Sketchfab | `search_sketchfab_models`, `download_sketchfab_model` | Search + import existing models. |
| Hunyuan3D | `create_hunyuan_job`, `poll_hunyuan_job_status`, `import_generated_asset_hunyuan` | Alt text-to-3D generator. |

## Provider on-ramp

Before using ANY provider, call its status tool and act on the result:
- `get_hyper3d_status` / `get_hunyuan3d_status` — text/image → 3D.
- `get_polyhaven_status` / `get_sketchfab_status` — stock pulls.

If a status says disabled or no-key: tell the user the one-time step (tick
the provider's checkbox in Blender's BlenderMCP N-panel; Rodin/Sketchfab
also need an API key pasted there) and STOP that path. Rodin ships a free
trial key in the panel; Hunyuan3D can run against a local endpoint. For
simple shapes, `execute_code` hand-modeling needs no provider at all —
prefer it when the shape is straightforward.

## The effective recipe (verifier at every step)

1. `get_scene_info` — understand the starting state.
2. **Build/edit/generate:**
   - Precise/parametric edit → `execute_code` with explicit `bpy` (name the
     object, `transform_apply` scale, set materials).
   - Organic/complex → `create_rodin_job(text_prompt=...)` → poll until done
     → `import_generated_asset`. Or use PolyHaven/Sketchfab for stock.
3. `get_viewport_screenshot` → **look at it.** Right shape/scale/material?
   If not, fix with `execute_code` and screenshot again.
4. **Export GLB via execute_code** (no need to save .blend):
   ```python
   import bpy
   bpy.ops.object.select_all(action='DESELECT')
   bpy.data.objects['<name>'].select_set(True)
   bpy.ops.export_scene.gltf(
       filepath=r'<your-export-path>/<name>.glb',
       export_format='GLB',
       use_selection=True
   )
   ```
5. **Engine import verify** — import the GLB into your target engine (Godot,
   Unity, etc.) and confirm it loads without errors and looks correct.
6. **Attribution** — append one line to your project's `CREDITS.md`:
   `- <name>.glb — modeled via BlenderMCP (blender-live), own work.`

**Done means:** screenshot inspected, GLB imports cleanly, one attribution
line written. Report tri-count and what the object is.

## execute_code patterns

- Keep it low-poly for game use: few subdivisions, `transform_apply` scale,
  flat shading via `for p in obj.data.polygons: p.use_smooth = False`.
- Always NAME the object (`obj.name = '<name>'`) — becomes the engine node name.
- One object per GLB unless the engine wants a rig/hierarchy.
- After Rodin/Sketchfab import, the mesh is often dense → decimate to your
  tri budget before exporting.

## Animation (keyframed transforms → animated GLB)

glTF carries node-transform animation; Godot imports an animated GLB as a
scene with an AnimationPlayer.

1. Split static vs. moving parts; put the MOVING object's ORIGIN on the
   rotation axis.
2. Set frame range: `sc.frame_start=1; sc.frame_end=60; sc.render.fps=30`.
3. Set interpolation before inserting keys (Blender 5.0+):
   `bpy.context.preferences.edit.keyframe_new_interpolation_type='LINEAR'`
4. For a full 360° spin, key at ≤90° steps (0/90/180/270/360) — a single
   0→360 pair collapses to NO motion because both quaternions are identical.
5. Export with `export_animations=True`.
6. Verify the GLB reports `animations >= 1`; set loop mode in your engine.

**Screenshot gotcha:** `get_viewport_screenshot` returns black if the Blender
window is minimized or occluded (GL readback of a hidden window). Fix: add a
camera, set `sc.render.engine='BLENDER_WORKBENCH'`, render offscreen to a
PNG with `render.render(write_still=True)`, then Read that file.

## Worked example

Situation: "Model a weathered escape-pod hatch."
1. Confirm setup → `get_scene_info` returns.
2. Organic → `create_rodin_job(text_prompt="low-poly weathered circular
   escape-pod hatch, sci-fi, game asset")` → poll → `import_generated_asset`.
3. `get_viewport_screenshot` → too dense → `execute_code` decimate to ~0.2,
   screenshot again.
4. Export GLB to your project's asset directory.
5. Import into engine → confirms load OK.
6. Append credits. Report: "escape_pod_hatch (312 tris) modeled + verified."

## Ambiguity rule

If it's unclear whether live modeling is needed vs. a parametric prop, or the
target object is unspecified, STOP and ask. Default to the cheaper tier
(catalog → parametric) unless the object is genuinely bespoke.

## Never-do

- Do NOT script the "Connect" click or expect `mcp__blender__*` against a
  headless Blender — the socket server runs only in a GUI session.
- Do NOT claim the tools work in a session that started before the server was
  registered — a restart is required.
- Do NOT use a provider without first checking its `get_*_status` tool.
- Do NOT ship a Rodin/Sketchfab import un-decimated into a low-poly game.

## Stop conditions

- `mcp__blender__*` errors → Blender not open / not Connected. Give the exact
  click; do NOT retry more than once.
- Engine import fails → STOP, report the error.
- Provider job polls forever → cap at a few polls, fall back to `execute_code`
  hand-modeling. No infinite poll loops.

## Gotchas

- Provider tools are gated by BOTH a panel checkbox AND (Rodin/Sketchfab) an
  API key — check both before reporting "provider unavailable."
- Rodin/Hunyuan output = dense organic mesh → decimate to tri budget for games.
- Export via `execute_code` avoids saving a .blend; verify the file lands.
- Godot `--import` may hang on exit; kill after ~120 s and still check for the
  imported scene file.
