Skip to main content
Glama
README.md
English | [中文](README.zh-CN.md)

# blender_mcp — a local blender-mcp

Drive your local **Blender 5.2 LTS** from Claude Code (or any MCP client) in plain language:
**17 categories, 159 typed tools** covering modeling, materials, node trees, lighting, animation, cameras, rendering, import/export, UV and baking, batch operations, assets, rigging, and one-shot workflows.

- Platforms: macOS / Windows / Linux (all three tested)
- Blender: 5.2 LTS (not compatible with 4.x)
- Requirements: Python 3.11+, [uv](https://docs.astral.sh/uv/)
- License: MIT

## Highlights

- **159 typed tools**: every tool has an explicit signature and description, so the model never has to guess the bpy API. `execute_code` is the escape hatch for arbitrary Python.
- **Fully local, zero-network add-on**: the Blender add-on only listens on `127.0.0.1:9877` and never touches the network. Poly Haven / Sketchfab downloads happen in the MCP server process and are written to disk before the add-on imports them by path.
- **Readable errors**: when an object / material / node / socket is not found, the error lists candidate names and is passed through to the model verbatim, so it can self-correct.
- **Undoable**: every write is a Ctrl+Z step in Blender; `undo` / `redo` tools are available in GUI mode.
- **One-shot workflows**: three-point lighting, studio scene, turntable animation, product render, material from a texture folder, surface scatter, game-asset export.
- **Offline API docs**: `get_api_docs("bpy.types.Object.location")` looks up bpy documentation without going online.
- **Visual feedback**: `render_image` / `viewport_screenshot` can return the image straight to the model.

## Architecture

```
Claude Code ──stdio──▶ MCP server (src/blender_mcp_pro, Python 3.11+ managed by uv)
                            │  each tool: typed signature → {tool, params} JSON forward
                            ▼
                    127.0.0.1:9877 (4-byte length prefix + JSON frames, persistent connection)
                            │
                Blender 5.2 extension (addon/blender_mcp_pro, Blender's bundled Python 3.13)
                            │  daemon thread receives → main thread runs bpy serially → auto undo_push
                            ▼
                    handlers/<category>.py: the actual bpy code
```

Fat add-on, thin server: all bpy logic lives in the add-on; the server only validates parameters and forwards. Tool names match one-to-one on both sides and a parity test keeps them in sync.

## Tool catalog (17 categories, 159 tools)

Full signatures are in [docs/tools.md](docs/tools.md) (generated by `dump-tools`).

| Category | Count | Tools |
|---|---|---|
| **Scene & Objects** | 16 | `get_scene_info` `list_objects` `get_object_info` `create_primitive` `delete_object` `duplicate_object` `set_transform` `rename_object` `set_parent` `set_visibility` `select_objects` `manage_collection` `join_objects` `apply_transforms` `set_origin` `set_custom_property` |
| **Materials** | 9 | `list_materials` `get_material_info` `create_material` `assign_material` `set_principled_inputs` `set_material_settings` `add_image_texture` `create_pbr_material` `delete_material` |
| **Shader Nodes** | 10 | `list_shader_nodes` `add_shader_node` `remove_shader_node` `set_node_input` `set_node_property` `link_nodes` `unlink_nodes` `set_color_ramp` `build_node_tree` `get_node_types` |
| **Lights** | 6 | `list_lights` `get_light_info` `create_light` `set_light` `point_light_at` `set_world_lighting` |
| **Modifiers** | 8 | `list_modifier_types` `list_modifiers` `get_modifier_settings` `add_modifier` `set_modifier` `remove_modifier` `apply_modifier` `move_modifier` |
| **Animation** | 15 | `get_animation_info` `set_frame_range` `set_current_frame` `insert_keyframe` `insert_keyframes_batch` `delete_keyframe` `list_keyframes` `set_interpolation` `add_fcurve_modifier` `assign_action` `nla_push_down` `add_nla_strip` `bake_animation` `list_shape_keys` `set_shape_key` |
| **Geometry Nodes** | 11 | `list_node_groups` `create_geometry_nodes` `get_node_tree` `add_geometry_node` `remove_geometry_node` `link_geometry_nodes` `unlink_geometry_nodes` `set_geometry_node_input` `add_group_socket` `set_gn_modifier_input` `build_geometry_node_tree` |
| **Camera** | 7 | `list_cameras` `get_camera_info` `create_camera` `set_camera` `set_active_camera` `point_camera_at` `frame_objects` |
| **Render** | 7 | `get_render_settings` `list_render_engines` `set_render_settings` `set_color_management` `render_image` `render_animation` `viewport_screenshot` |
| **Import / Export** | 5 | `import_file` `export_file` `append_from_blend` `save_blend` `open_blend` |
| **UV & Texture** | 10 | `list_uv_maps` `add_uv_map` `remove_uv_map` `unwrap_uv` `pack_uv_islands` `mark_seams` `create_image` `bake_texture` `save_image` `list_images` |
| **Batch** | 8 | `batch_transform` `batch_rename` `batch_apply_material` `batch_add_modifier` `batch_set_property` `batch_delete` `distribute_objects` `randomize_transform` |
| **Assets** | 8 | `polyhaven_categories` `polyhaven_search` `polyhaven_download` `sketchfab_search` `sketchfab_download` `list_asset_libraries` `search_local_assets` `import_local_asset` |
| **Rigging** | 12 | `create_armature` `list_bones` `add_bone` `set_bone` `remove_bone` `parent_to_armature` `add_bone_constraint` `set_pose` `reset_pose` `set_vertex_group_weights` `add_rigify_metarig` `generate_rigify_rig` |
| **Rig Diagnostics** | 7 | `check_rig` `check_bone_hierarchy` `check_bone_naming` `find_unweighted_vertices` `get_bone_influence` `list_constraint_issues` `normalize_weights` |
| **Utilities** | 13 | `execute_code` `get_blender_info` `get_api_docs` `undo` `redo` `purge_orphans` `set_units` `set_cursor` `measure_distance` `get_bounding_box` `ray_cast` `check_mesh` `mesh_cleanup` |
| **Workflows** | 7 | `setup_three_point_lighting` `setup_studio_scene` `turntable_animation` `quick_product_render` `material_from_texture_folder` `scatter_objects` `export_for_game` |

A few capabilities worth calling out:

- **Whole node trees in one call**: `build_node_tree` / `build_geometry_node_tree` take `nodes=[{type,name,location,inputs,properties}]` and `links=[...]` and build the entire tree at once, with no per-node round trips.
- **PBR materials**: `create_pbr_material` builds a material from a set of texture paths; `material_from_texture_folder` scans a folder and recognises basecolor / roughness / metallic / normal / height / ao by filename.
- **Import / export formats**: obj / fbx / gltf / glb / usd / usda / usdc / stl / ply / abc / blend, detected by extension, with `options` passed straight to the Blender operator. `export_for_game` duplicates → applies modifiers → triangulates → scales → exports.
- **Assets**: Poly Haven HDRIs are wired into world lighting after download, textures become PBR materials, models are imported directly. Sketchfab needs an API token. Local asset libraries can be searched by type / keyword and imported.
- **Rigging**: build armatures from scratch, add constraints, pose, write vertex-group weights; Rigify metarigs (human / quadruped / cat / wolf / horse / shark / bird) and generation; `check_rig` checks zero-length bones, multiple roots, unweighted vertices, un-normalised weights, unapplied scale, missing constraint targets, and asymmetric naming in one pass.
- **Baking**: `bake_texture` bakes DIFFUSE / NORMAL / AO / ROUGHNESS / EMIT / COMBINED and more with Cycles, including selected-to-active.
- **Camera framing**: `frame_objects` backs the camera off along its current direction until the targets just fit; `point_camera_at` / `point_light_at` aim at an object or coordinate.
- **Geometry queries**: `ray_cast`, `measure_distance`, `get_bounding_box`, `check_mesh` (non-manifold, loose vertices, degenerate faces, and so on).

## Installation

Prerequisites: Blender 5.2 LTS and [uv](https://docs.astral.sh/uv/).

```bash
git clone <this repo> blender_mcp && cd blender_mcp
uv sync
uv run blender-mcp-pro install-addon
```

`install-addon` links `addon/blender_mcp_pro` into Blender's user extensions directory, then enables the extension with headless Blender and saves preferences.

| Platform | Default Blender lookup | Extensions directory | Link type |
|---|---|---|---|
| macOS | `/Applications/Blender.app` | `~/Library/Application Support/Blender/5.2/extensions/user_default` | symlink |
| Windows | `C:\Program Files\Blender Foundation\Blender 5.2\blender.exe` | `%APPDATA%\Blender Foundation\Blender\5.2\extensions\user_default` | symlink; falls back to a directory junction when symlinks are not permitted (no admin needed) |
| Linux | `blender` on `PATH`, `/usr/bin`, `/snap/bin` | `~/.config/blender/5.2/extensions/user_default` | symlink |

- Blender installed elsewhere: set `BLENDER_MCP_BLENDER=<blender executable>` first; likewise `BLENDER_MCP_EXT_DIR` for the extensions directory.
- Prefer a copy over a link: `install-addon --copy` (re-run after editing the add-on source).
- **If a GUI Blender is open during installation**, it will overwrite the preferences with its in-memory copy on exit. Confirm once more in the running Blender: Edit ▸ Preferences ▸ Add-ons, search "MCP Pro", tick it.
- Once enabled the server starts automatically. Press N in the 3D viewport; the "MCP Pro" panel shows status, manual Start / Stop, and the port.

### Connect to Claude Code

```bash
claude mcp add --scope user blender-pro -- uv --directory <absolute repo path> run blender-mcp-pro serve
claude mcp list        # expect: blender-pro … Connected
```

Windows example:

```bash
claude mcp add --scope user blender-pro -- uv --directory C:\work\blender_mcp run blender-mcp-pro serve
```

Other MCP clients (Cursor, Claude Desktop, and so on) use the same stdio command: `uv --directory <repo> run blender-mcp-pro serve`.

Optional environment variables: `BLENDER_MCP_HOST` / `BLENDER_MCP_PORT` (default `127.0.0.1` / `9877`), `SKETCHFAB_API_TOKEN`.

### Uninstall

```bash
uv run blender-mcp-pro uninstall-addon
claude mcp remove blender-pro -s user
```

## Usage examples

With a GUI Blender open, just tell Claude Code:

- "What's in the scene?" → `get_scene_info` / `list_objects`
- "Make a 2 m tall cylinder with a brushed-metal material" → `create_primitive` + `create_material` + `set_principled_inputs`
- "Three-point light this object and render a 1080p product shot" → `quick_product_render`, or `setup_three_point_lighting` + `frame_objects` + `render_image`
- "Grab a 2k indoor HDRI from Poly Haven for the environment" → `polyhaven_search` + `polyhaven_download`
- "Turn the textures in `textures/wood/` into a material and put it on the table" → `material_from_texture_folder`
- "Add a Rigify humanoid rig to the character and check it" → `add_rigify_metarig` + `generate_rigify_rig` + `check_rig`
- "Export the selection as a game-ready GLB" → `export_for_game`
- "Build a blocky Gundam out of bmesh" → `execute_code` (any bpy script), then `frame_objects` + `render_image` to look at it

## Conventions

- Location / rotation / scale are `[x, y, z]`; rotation is an Euler in **radians**. Colours are `[r, g, b]` or `[r, g, b, a]` in 0–1.
- Any tool that accepts `objects` takes a list of names, or `{"pattern": "Cube*"}` / `{"collection": "Props"}` / `{"type": "MESH"}` / `{"selected": true}`.
- When an object / material / node / socket is not found, the error lists candidate names.
- Every write is undoable with Ctrl+Z in Blender; read-only tools stay out of the undo stack.
- Principled BSDF sockets use the 5.2 names: `Base Color, Metallic, Roughness, IOR, Alpha, Emission Color, Emission Strength, Specular IOR Level, …`
- `execute_code` has `bpy / bmesh / mathutils / Vector / math` preloaded; `return_var` returns a variable.
- Render and download caches live in `~/.cache/blender-mcp-pro/` (`renders/` `hdris/` `textures/` `models/` `sketchfab/`) and can be cleared at any time.

## Development and testing

```bash
uv run pytest -q                                   # 154 tests; integration tests spawn headless Blender automatically
BLENDER_MCP_ONLINE_TESTS=1 uv run pytest tests/test_assets.py   # also runs the Poly Haven online tests
uv run blender-mcp-pro dump-tools > docs/tools.md  # regenerate the tool catalog
```

- Three test layers: protocol unit tests (fake Blender), handler integration tests (headless Blender, `--factory-startup`), and MCP stdio end-to-end (real MCP client → server → headless Blender).
- Changed the add-on: F3 → "Reload Scripts" in Blender (takes effect immediately with a symlink / junction install).
- Changed the server: restart it from Claude Code with `/mcp`.
- Adding a tool: `@command("name")` in `addon/blender_mcp_pro/handlers/<category>.py` plus `@mcp.tool()` in `src/blender_mcp_pro/tools/<category>.py`; `tests/test_parity.py` keeps the names in sync.
- Handler modules **must not call bpy at module top level** (the parity test loads the add-on with a fake bpy); use it inside function bodies only.

## Known limitations

- `viewport_screenshot` and `undo` / `redo` need a GUI Blender; headless mode raises a clear error.
- Whether EEVEE renders in headless mode depends on the GPU context; tests pin WORKBENCH. In the GUI both EEVEE and Cycles work.
- Sketchfab downloads need an API token: Preferences ▸ Add-ons ▸ Blender MCP Pro, or the `SKETCHFAB_API_TOKEN` environment variable.
- 5.2 LTS only; not compatible with 4.x.
- The schemas of 159 tools take up some context; if it feels slow, trimming by category is a possible follow-up.

## Documentation

The detailed docs are currently in Chinese.

- Installation and development details: [docs/README.md](docs/README.md)
- All tool signatures: [docs/tools.md](docs/tools.md)
- Design and decision record: [docs/superpowers/specs/2026-09-07-blender-mcp-pro-design.md](docs/superpowers/specs/2026-09-07-blender-mcp-pro-design.md)

## License

[MIT](LICENSE)

TDQS

C2.4/5.0

Scored across 159 tools

Disambiguation4/5

Tools have specific names and descriptions that clearly distinguish their purposes, such as list_lights vs set_light vs create_light. While there are many tools, each targets a distinct operation or data type with minimal overlap.

Naming Consistency3/5

Most tools follow verb_noun with underscores, but there is a mix of prefixes (get_, list_, set_, create_, add_, remove_, check_, setup_, batch_) and some verbs are used inconsistently (e.g., list_* vs get_* for similar queries). The pattern is recognizable but not perfectly uniform.

Tool Count1/5

With 159 tools, the server has far more than the typical 3-15 range, exceeding even the 50+ threshold for extreme counts. This large number may overwhelm agents and suggests a need for consolidation or grouping.

Completeness4/5

The toolset covers a wide range of Blender functionality including objects, materials, nodes, lights, cameras, animation, modifiers, constraints, and asset management. While some niche areas like physics are not directly exposed, the execute_code tool fills gaps, making the coverage fairly complete.

Maintenance

ActivityMaintained
ResponsivenessNo issues