Skip to main content
Glama
README.md
<p align="center">
  <img src="docs/logos/banner_2_wireframe.svg" alt="BlenderMCP — Talk to Blender." width="700"/>
</p>

<p align="center">
  <a href="https://github.com/kleer001/blender-mcp/blob/main/LICENSE"><img src="https://img.shields.io/github/license/kleer001/blender-mcp?color=blue" alt="License: MIT"/></a>
  <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10%2B-blue?logo=python&logoColor=white" alt="Python 3.10+"/></a>
  <a href="https://modelcontextprotocol.io/"><img src="https://img.shields.io/badge/MCP-compatible-green?logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJ3aGl0ZSI+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6Ii8+PC9zdmc+" alt="MCP Compatible"/></a>
  <a href="https://www.blender.org/"><img src="https://img.shields.io/badge/Blender-4.2%20LTS-E87D0D?logoColor=white" alt="Blender 4.2 LTS"/></a>
  <a href="https://github.com/kleer001/blender-mcp/commits/main"><img src="https://img.shields.io/github/last-commit/kleer001/blender-mcp" alt="Last Commit"/></a>
  <a href="https://github.com/kleer001/blender-mcp/issues"><img src="https://img.shields.io/github/issues/kleer001/blender-mcp" alt="Issues"/></a>
  <a href="https://github.com/kleer001/blender-mcp/network/members"><img src="https://img.shields.io/github/forks/kleer001/blender-mcp?style=social" alt="Forks"/></a>
  <a href="https://github.com/kleer001/blender-mcp/watchers"><img src="https://img.shields.io/github/watchers/kleer001/blender-mcp?style=social" alt="Watchers"/></a>
  <a href="https://github.com/kleer001/blender-mcp/stargazers"><img src="https://img.shields.io/github/stars/kleer001/blender-mcp?style=social" alt="GitHub Stars"/></a>
</p>

<p align="center">
  <strong>175 MCP tools</strong> &middot; <strong>25 domains</strong> &middot; <strong>Integration-tested on Blender 4.2.5 LTS</strong>
</p>

---

Control **Blender** from **Claude** (or any MCP-compatible AI) using the **Model Context Protocol**. BlenderMCP connects to your running Blender instance over a local TCP socket — your machine, your scenes, your assets.

Unlike existing Blender MCP projects that rely on `execute_blender_code` as a catch-all, this project provides **dedicated, typed tools** for every major Blender subsystem: objects, materials, shader nodes, geometry nodes, modifiers, animation, rigging, physics, compositing, and more.

## Status

**All 175 tools implemented and integration-tested against Blender 4.2.5 LTS.** Full handler coverage across all 25 domains.

## Requirements

- Python 3.10+
- [uv](https://docs.astral.sh/uv/) (recommended) or pip
- Blender 4.0+ (for the addon)

## Quick Start

```bash
# Clone and install
git clone https://github.com/kleer001/blender-mcp
cd blender-mcp
uv sync

# Run with mock Blender (no Blender needed)
uv run blender-mcp --mock

# Run against a real Blender instance
uv run blender-mcp
```

### Blender Addon Setup

1. Copy the `blender_addon/` directory to your Blender addons path, or symlink it
2. Enable **Blender MCP** in Blender → Edit → Preferences → Add-ons
3. In the 3D Viewport sidebar (N panel), find the **MCP** tab and click **Start Server**
4. Start the MCP server: `uv run blender-mcp`

### Claude Code

The `.mcp.json` in the repo root auto-configures Claude Code. Just run `claude` from the project directory.

### Claude Desktop

```json
{
  "mcpServers": {
    "blender-mcp": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/blender-mcp", "blender-mcp"]
    }
  }
}
```

## Architecture

```
AI Client (Claude, Cursor, ChatGPT)
    │ MCP Protocol (stdio)
    ▼
MCP Server (src/blendermcp/)
    │ TCP Socket (localhost:9334)
    ▼
Blender Addon (blender_addon/)
    │ bpy API (main thread via timer queue)
    ▼
Blender
```

- **MCP Server** — FastMCP-based, runs as a separate process, communicates via stdio
- **Blender Addon** — TCP server inside Blender, dispatches commands to handlers on the main thread via `bpy.app.timers`
- **Connection** — JSON over TCP with newline framing, exponential backoff reconnection

## Available Tools (175)

| Domain | Count | Tools |
|---|---|---|
| Scene | 6 | `ping` · `get_scene_info` · `load_file` · `save_file` · `set_frame` · `set_frame_range` |
| Objects | 12 | `get_object_info` · `list_objects` · `create_object` · `delete_object` · `set_transform` · `apply_transform` · `duplicate_object` · `rename_object` · `set_parent` · `clear_parent` · `set_origin` · `select_objects` |
| Materials | 8 | `list_materials` · `get_material_info` · `create_material` · `assign_material` · `remove_material` · `set_material_property` · `duplicate_material` · `delete_material` |
| Shader Nodes | 12 | `get_node_tree` · `create_shader_node` · `delete_shader_node` · `connect_shader_nodes` · `disconnect_shader_node` · `set_node_input` · `get_node_input` · `set_node_position` · `list_shader_node_types` · `create_node_group` · `add_node_group_instance` · `layout_node_tree` |
| Geometry Nodes | 10 | `get_geonodes_tree` · `create_geonodes_modifier` · `create_geonode` · `delete_geonode` · `connect_geonodes` · `disconnect_geonode` · `set_geonode_input` · `get_geonode_input` · `list_geonode_types` · `set_geonodes_input` |
| Modifiers | 8 | `list_modifiers` · `add_modifier` · `remove_modifier` · `set_modifier_property` · `apply_modifier` · `move_modifier` · `toggle_modifier_visibility` · `copy_modifiers` |
| Animation | 10 | `get_keyframes` · `set_keyframe` · `set_keyframes` · `delete_keyframe` · `clear_animation` · `get_action_info` · `list_actions` · `set_interpolation` · `set_playback_range` · `playback_control` |
| Rigging | 10 | `create_armature` · `get_armature_info` · `add_bone` · `set_bone_property` · `get_bone_info` · `parent_mesh_to_armature` · `assign_vertex_weights` · `add_bone_constraint` · `set_pose_bone_transform` · `list_bone_constraints` |
| Constraints | 6 | `list_constraints` · `add_constraint` · `remove_constraint` · `set_constraint_property` · `set_constraint_influence` · `reorder_constraint` |
| Lighting | 7 | `list_lights` · `create_light` · `set_light_property` · `create_hdri_world` · `set_world_property` · `get_world_info` · `create_light_rig` |
| Camera | 6 | `list_cameras` · `create_camera` · `set_camera_property` · `set_active_camera` · `camera_look_at` · `setup_camera_dof` |
| Mesh Editing | 8 | `get_mesh_info` · `get_vertices` · `set_vertices` · `get_vertex_groups` · `create_vertex_group` · `set_smooth_shading` · `separate_mesh` · `join_meshes` |
| Curves | 5 | `create_curve` · `get_curve_info` · `set_curve_points` · `set_curve_property` · `convert_to_mesh` |
| Physics | 10 | `add_physics` · `remove_physics` · `set_physics_property` · `get_physics_info` · `setup_rigid_body_world` · `setup_cloth_sim` · `setup_fluid_domain` · `setup_softbody` · `bake_physics` · `free_physics_bake` |
| Particles | 6 | `add_particle_system` · `remove_particle_system` · `set_particle_property` · `get_particle_info` · `setup_hair` · `bake_particles` |
| Compositing | 8 | `get_compositor_tree` · `enable_compositor` · `create_comp_node` · `delete_comp_node` · `connect_comp_nodes` · `set_comp_node_input` · `list_comp_node_types` · `setup_basic_composite` |
| Sculpting | 4 | `enter_sculpt_mode` · `set_sculpt_brush` · `remesh` · `apply_sculpt_mask` |
| Grease Pencil | 6 | `create_grease_pencil` · `get_gp_info` · `add_gp_layer` · `set_gp_layer_property` · `create_gp_stroke` · `add_gp_modifier` |
| Textures & UV | 6 | `list_images` · `load_image` · `get_uv_maps` · `create_uv_map` · `smart_uv_project` · `pack_images` |
| Viewport | 6 | `get_viewport_info` · `capture_viewport` · `set_viewport_shading` · `set_viewport_camera` · `frame_selected` · `frame_all` |
| Rendering | 6 | `get_render_settings` · `set_render_settings` · `render_image` · `render_animation` · `render_viewport` · `list_render_engines` |
| Collections | 5 | `list_collections` · `create_collection` · `move_to_collection` · `set_collection_visibility` · `delete_collection` |
| Import/Export | 4 | `import_file` · `export_file` · `list_supported_formats` · `export_selection` |
| Code Execution | 2 | `execute_python` · `evaluate_expression` |
| Batch Operations | 4 | `find_objects` · `batch_set_property` · `batch_delete` · `find_error_objects` |

## Development

```bash
# Install with dev dependencies
uv sync

# Run tests (unit, no Blender needed)
uv run pytest tests/ --ignore=tests/integration -v

# Run integration tests (requires Blender at /opt/blender-4.2/blender)
uv run pytest tests/integration/ -v -m integration

# Run with mock (no Blender needed)
uv run blender-mcp --mock --debug

# Lint
uv run ruff check src/ tests/
```

## License

MIT

TDQS

C2.7/5.0

Scored across 175 tools

Disambiguation4/5

The vast majority of tools target distinct domains (objects, materials, cameras, modifiers, nodes, etc.) with clear action-resource pairs. However, a few tools like execute_python vs evaluate_expression and set_frame_range vs set_playback_range could cause confusion, though descriptions clarify their intents.

Naming Consistency4/5

Tool names overwhelmingly follow a verb_noun snake_case pattern (list_objects, create_material, set_transform, delete_object), making navigation predictable. Minor deviations include 'ping', 'remesh', 'playback_control' and the adjective-initial 'smart_uv_project', which break strict consistency but remain readable.

Tool Count1/5

With 175 tools, this server is drastically over-scaled for any agent to effectively choose from, far exceeding the 50+ threshold for extreme mismatch. Even for a comprehensive application like Blender, the tool surface should be partitioned into several smaller, purpose-specific servers.

Completeness3/5

The server covers an impressively wide range of Blender functionality, including objects, materials, lighting, animation, physics, nodes, armatures, and particles. However, notable lifecycle gaps exist, such as no mode-switching tool, no rename/material/action/image operations, no action deletion, and no way to delete UV maps or vertex groups, forcing reliance on escape hatches like execute_python.

Maintenance

ActivityInactive
ResponsivenessNo issues