Metadata-Version: 2.4
Name: blender-studio-pro-mcp
Version: 0.1.2
Summary: Comprehensive Blender MCP server with search+execute architecture — 51 tools, AI generation, Poly Haven, and more
License: MIT
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp[cli]>=1.5.0
Requires-Dist: pillow>=10.0.0
Requires-Dist: pyyaml>=6.0.0
Provides-Extra: dev
Requires-Dist: pyright>=1.1.0; extra == 'dev'
Requires-Dist: pytest-timeout>=2.3.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Description-Content-Type: text/markdown

# Blender Studio MCP

A comprehensive [Model Context Protocol](https://modelcontextprotocol.io/) server for Blender, giving AI assistants full control over a running Blender session. Built with a **search + execute** architecture that exposes 185 tools through just three MCP endpoints — keeping your AI's context window lean while retaining the full capability set.

Compatible with Claude, Cursor, VS Code, and any MCP-capable client.

---

## Features

- **185 Blender tools** across 48 categories — objects, materials, UV, shape keys, constraints, rigging, animation, NLA, rendering, physics, mesh cleanup, compositor, curves, drivers, library linking, custom properties, vertex attributes, world/environment, timeline markers, node groups, batch execution, and more
- **Search + execute architecture** — LLMs call `search_tools` to discover capabilities, then `execute_tool` or `execute_tools` to act, without loading all tool schemas into context
- **Batch execution** — `execute_tools` runs multiple tools in one call, eliminating round-trips for multi-step workflows
- **Full Blender 5.x support** — tested against Blender 5.2 including the Grease Pencil v3 API
- **AI model generation** — text-to-3D via Hyper3D Rodin, TripoAI, and Tencent Hunyuan3D
- **Asset library integration** — search and import from [Poly Haven](https://polyhaven.com), [Ambient CG](https://ambientcg.com) (both free, no key), and [Sketchfab](https://sketchfab.com)
- **Headless mode** — spawn `blender --background` for batch operations without a GUI session
- **Arbitrary Python execution** — run any `bpy` code in the live Blender session and capture output
- **Command history** — rolling log of the last 50 executed commands, available as an MCP resource

---

## Architecture

```
AI Client (Claude, Cursor, etc.)
       │
       │  MCP (stdio)
       ▼
blender-studio-mcp  ←── search_tools / execute_tool / execute_tools
       │
       │  TCP socket (port 9877, newline-delimited JSON)
       ▼
Blender addon (blender_studio_addon.py)
       │
       │  bpy.app.timers (main thread)
       ▼
Blender Python API
```

All `bpy` calls execute on Blender's main thread via a queue + timer, satisfying Blender's strict thread-safety requirements. Every executed command is recorded in a rolling history log.

---

## Installation

### 1. Install the Blender addon

1. Open Blender → **Edit → Preferences → Add-ons → Install from Disk**
2. Select `addon/blender_studio_addon.py` from this repository
3. Enable **Blender Studio MCP** in the add-ons list
4. In the **3D Viewport → Sidebar (N) → MCP** tab, click **Start MCP Server**

The server binds to `localhost:9877` by default. Port and host are configurable in the panel.

### 2. Install the MCP server

**Via `uvx` (recommended — no install required):**

```bash
uvx blender-studio-mcp
```

**Via `uv` (persistent install):**

```bash
uv tool install blender-studio-mcp
blender-studio-mcp
```

**Via `pip`:**

```bash
pip install blender-studio-mcp
blender-studio-mcp
```

---

## MCP Client Configuration

### Claude Desktop / Claude Code

Add to your `claude_desktop_config.json` or `.mcp.json`:

```json
{
  "mcpServers": {
    "blender-studio": {
      "type": "stdio",
      "command": "uvx",
      "args": ["blender-studio-mcp"],
      "env": {
        "BLENDER_PORT": "9877"
      }
    }
  }
}
```

### Cursor

Add to `.cursor/mcp.json` in your project root:

```json
{
  "mcpServers": {
    "blender-studio": {
      "command": "uvx",
      "args": ["blender-studio-mcp"]
    }
  }
}
```

---

## Environment Variables

| Variable | Required | Description |
|---|---|---|
| `BLENDER_HOST` | No | Blender addon host (default: `localhost`) |
| `BLENDER_PORT` | No | Blender addon port (default: `9877`) |
| `BLENDER_TIMEOUT` | No | Socket timeout in seconds (default: `60`) |
| `BLENDER_EXECUTABLE` | No | Path to Blender binary (default: `blender` on `$PATH`) |
| `RODIN_API_KEY` | For Rodin | [Hyper3D Rodin](https://hyper3d.ai) API key |
| `TRIPO_API_KEY` | For Tripo | [TripoAI](https://www.tripo3d.ai) API key |
| `HUNYUAN_API_KEY` | For Hunyuan | Tencent Hunyuan3D API key |
| `SKETCHFAB_API_KEY` | For Sketchfab | [Sketchfab](https://sketchfab.com/settings/password) API key |

Poly Haven and Ambient CG require no API key.

---

## Usage

The server exposes three MCP tools. An AI assistant uses `search_tools` to discover what's available, then `execute_tool` for single operations or `execute_tools` for multi-step workflows.

### search_tools

```
search_tools(query="material", limit=10)
```

Returns matching tool names, descriptions, and full parameter schemas. Use an empty query to list all 77 tools.

### execute_tool

```
execute_tool(tool_name="create_material", params={
  "name": "Chrome",
  "color": [0.8, 0.8, 0.8],
  "metallic": 1.0,
  "roughness": 0.05
})
```

Routes to Blender or a custom handler (for AI generation, asset downloads, headless execution).

### execute_tools

Run multiple tools in one call — each step reports success or failure independently:

```
execute_tools(tools=[
  {"tool_name": "create_object",   "params": {"object_type": "SPHERE", "name": "Ball"}},
  {"tool_name": "create_material", "params": {"name": "Red", "color": [1, 0, 0]}},
  {"tool_name": "assign_material", "params": {"object_name": "Ball", "material_name": "Red"}},
  {"tool_name": "unwrap_uv",       "params": {"object_name": "Ball"}}
])
```

Set `stop_on_error: false` to continue the sequence even if an individual step fails.

---

## MCP Resources

In addition to the tools, three MCP resources provide live read-only access to Blender state:

| Resource | Description |
|---|---|
| `blender://scene-info` | Live snapshot of the current scene (objects, engine, frame range) |
| `blender://history` | Rolling log of the last 50 commands with timing and success/error status |
| `blender://system-prompt` | Bundled LLM instructions for working with this server |

---

## Tool Reference

Full parameter documentation is in the [`docs/tools/`](docs/README.md) directory.



### Scene & Inspection
| Tool | Description |
|---|---|
| `get_scene_info` | Scene name, frame range, render engine, all objects |
| `get_object_info` | Location, rotation, scale, materials, modifiers, vertex count |
| `get_blend_file_summary` | Data-block counts (meshes, materials, images, etc.) |
| `take_screenshot` | Capture viewport as base64 PNG |
| `get_history` | Return rolling command log with timing and error info |

### Objects
| Tool | Description |
|---|---|
| `create_object` | Create mesh, light, camera, armature, Grease Pencil, and more (15 types) |
| `delete_object` | Remove an object from the scene |
| `duplicate_object` | Duplicate with optional linked mesh data |
| `select_object` | Select and make active |
| `set_object_visibility` | Show/hide in viewport or render |

### Transforms
| Tool | Description |
|---|---|
| `set_location` | World-space position (meters) |
| `set_rotation` | Euler XYZ rotation (degrees) |
| `set_scale` | Scale multiplier per axis |
| `apply_transforms` | Apply location/rotation/scale to reset to identity |
| `set_parent` | Parent one object to another |

### Materials
| Tool | Description |
|---|---|
| `create_material` | Principled BSDF with color, metallic, roughness, emission |
| `assign_material` | Assign to an object's material slot |
| `set_material_property` | Adjust any BSDF input on an existing material |
| `add_image_texture` | Connect an image file to BASE_COLOR, ROUGHNESS, NORMAL, etc. |

### UV Unwrapping
| Tool | Description |
|---|---|
| `unwrap_uv` | Unwrap UVs using ANGLE_BASED, CONFORMAL, or Smart UV Project |
| `mark_seam` | Mark or clear seams on all selected edges |
| `pack_uvs` | Pack UV islands into 0–1 space with configurable margin |

### Shape Keys
| Tool | Description |
|---|---|
| `add_shape_key` | Add a shape key (morph target) — first key becomes the Basis |
| `set_shape_key_value` | Set a shape key's influence (0–1) |
| `remove_shape_key` | Delete a shape key by name |
| `list_shape_keys` | Return all shape keys with current values and ranges |

### Object Constraints
| Tool | Description |
|---|---|
| `add_constraint` | Add COPY_LOCATION, TRACK_TO, LIMIT_ROTATION, CHILD_OF, and more |
| `remove_constraint` | Remove a named constraint from an object |

### Modeling
| Tool | Description |
|---|---|
| `add_modifier` | Add SUBSURF, ARRAY, MIRROR, BEVEL, BOOLEAN, DECIMATE, and more |
| `apply_modifier` | Bake a modifier to real geometry |
| `boolean_operation` | DIFFERENCE, UNION, or INTERSECT between two meshes |
| `set_smooth_shading` | Toggle smooth vs flat shading |
| `join_objects` | Merge multiple objects into one |

### Animation
| Tool | Description |
|---|---|
| `insert_keyframe` | Set location/rotation/scale and add a keyframe |
| `delete_keyframe` | Remove a keyframe from an object |
| `set_frame` | Jump to a specific frame |
| `set_frame_range` | Set start/end frame and FPS |

### Camera & Lighting
| Tool | Description |
|---|---|
| `set_camera_properties` | Focal length, sensor size, depth of field, clipping |
| `set_active_camera` | Choose which camera the scene renders from |
| `set_light_properties` | Energy, color, radius, spot angle |
| `set_hdri_environment` | Set HDRI world lighting from a `.hdr` or `.exr` file |

### Rendering
| Tool | Description |
|---|---|
| `set_render_settings` | Engine (Cycles/EEVEE), resolution, samples, output path |
| `render_image` | Render and return base64 PNG |
| `render_animation` | Render a frame sequence to disk |

### Texture Baking
| Tool | Description |
|---|---|
| `bake_texture` | Bake AO, DIFFUSE, NORMAL, ROUGHNESS, or SHADOW to a PNG (requires Cycles) |

### Physics
| Tool | Description |
|---|---|
| `add_rigid_body` | ACTIVE or PASSIVE rigid body with mass and friction |
| `add_cloth_simulation` | Cloth physics with Cotton/Denim/Leather/Silk presets |
| `add_particle_system` | EMITTER or HAIR particle system |

### Geometry Nodes
| Tool | Description |
|---|---|
| `add_geometry_nodes` | Add a Geometry Nodes modifier (creates a new node group) |

### File I/O
| Tool | Description |
|---|---|
| `import_file` | Import OBJ, FBX, GLTF/GLB, USD, PLY, STL |
| `export_file` | Export selected or full scene to any supported format |
| `save_blend` | Save the current `.blend` file |

### Collections
| Tool | Description |
|---|---|
| `create_collection` | Create a new collection in the outliner |
| `move_to_collection` | Move an object into a collection |

### Grease Pencil
| Tool | Description |
|---|---|
| `create_grease_pencil` | Create an empty Grease Pencil object |
| `add_gp_stroke` | Add a stroke to a layer and frame (supports GP v2 and v3 API) |

### Video Sequence Editor
| Tool | Description |
|---|---|
| `add_video_strip` | Add a video file as a VSE strip |
| `render_vse` | Render the VSE timeline to MP4 |

### Python Execution & Undo
| Tool | Description |
|---|---|
| `execute_python` | Run arbitrary `bpy` code in the live session. Assign `__result__` to return data. |
| `execute_python_headless` | Spawn `blender --background` subprocess for batch operations |
| `undo` | Undo the last N operations in Blender |

### Asset Libraries
| Tool | Description |
|---|---|
| `search_poly_haven_assets` | Search Poly Haven (HDRIs, textures, models) — free, no key required |
| `download_poly_haven_asset` | Download and auto-import into the scene |
| `search_ambientcg_assets` | Search Ambient CG PBR materials and HDRIs — free, no key required |
| `download_ambientcg_asset` | Download a PBR material and auto-wire Color, Roughness, Normal, Metalness maps |
| `search_sketchfab_models` | Search Sketchfab for downloadable models (requires `SKETCHFAB_API_KEY`) |

### AI Model Generation
| Tool | Description |
|---|---|
| `generate_model_rodin` | Text-to-3D via Hyper3D Rodin, imported as GLB (requires `RODIN_API_KEY`) |
| `generate_model_tripo` | Text-to-3D via TripoAI (requires `TRIPO_API_KEY`) |
| `generate_model_hunyuan` | Text-to-3D via Tencent Hunyuan3D (requires `HUNYUAN_API_KEY`) |

### Scene Utilities
| Tool | Description |
|---|---|
| `set_origin` | Set origin to geometry center, cursor, center of mass, or center of volume |
| `get_material_info` | Inspect a material's full node graph — all nodes, input values, and links |
| `rename_object` | Rename an object and its data block |
| `apply_all_modifiers` | Apply every modifier in stack order (common pre-export step) |
| `set_world_color` | Set a flat solid background color with optional transparency |

### Shader Nodes
| Tool | Description |
|---|---|
| `add_shader_node` | Add any node type to a material's node tree (ShaderNodeMath, ShaderNodeTexNoise, etc.) |
| `connect_nodes` | Link an output socket of one node to an input socket of another |
| `set_node_value` | Set an input socket's default value (float, vector, or color) |

### Rigging
| Tool | Description |
|---|---|
| `add_bone` | Add a bone to an armature at given head/tail positions |
| `set_bone_parent` | Parent one bone to another (offset or connected) |
| `set_vertex_group` | Assign vertex indices to a named vertex group with a given weight |
| `add_armature_modifier` | Link a mesh to an armature for skeletal deformation |

### Mesh Cleanup
| Tool | Description |
|---|---|
| `recalculate_normals` | Fix inside-out normals — recalculate to point outward (or inward) |
| `merge_by_distance` | Weld overlapping vertices within a threshold (remove doubles) |
| `flip_normals` | Invert all face normals on a mesh object |

### Scene Utilities
| Tool | Description |
|---|---|
| `set_3d_cursor` | Place the 3D cursor at a world position or snap to an object's origin |
| `clean_scene` | Remove all orphan data blocks (meshes, materials, images, etc.) with zero users |
| `clear_scene` | Delete all objects, optionally preserving camera and/or lights |
| `pack_textures` | Embed all external images into the .blend file |
| `unpack_textures` | Extract packed images back to disk |

### Materials (Extended)
| Tool | Description |
|---|---|
| `set_blend_mode` | Set alpha blend mode — OPAQUE, BLEND, CLIP, or HASHED (required for transparency in EEVEE) |
| `duplicate_material` | Clone an existing material into an independent copy |
| `list_materials` | List all materials in the scene with user counts |

### Animation (Extended)
| Tool | Description |
|---|---|
| `set_keyframe_interpolation` | Set interpolation mode (LINEAR, BEZIER, CONSTANT) on an object's keyframes |
| `clear_animation` | Remove all keyframes and drivers from an object |
| `bake_action` | Bake constraints and driven values to direct keyframes — required before game-engine export |

### Text Objects
| Tool | Description |
|---|---|
| `set_text_content` | Set the body text of a Text (FONT) object |
| `set_text_font` | Load a .ttf/.otf font file and assign it to a Text object |

### Queries (Extended)
| Tool | Description |
|---|---|
| `list_objects_by_type` | Return all objects matching a given type (MESH, LIGHT, CAMERA, ARMATURE, etc.) |
| `get_modifier_info` | Read back a modifier's current settings |
| `find_orphan_data` | List unused data blocks by category before running clean_scene |

### Compositor
| Tool | Description |
|---|---|
| `enable_compositing` | Toggle the compositor and its node graph on the current scene |
| `add_compositor_node` | Add a node to the compositor tree (Glare, Blur, ColorBalance, BrightContrast, etc.) |

### Custom Properties
| Tool | Description |
|---|---|
| `set_custom_property` | Set a custom property on an object (string, int, float, bool) |
| `get_custom_property` | Read a named custom property from an object |
| `list_custom_properties` | List all custom properties with their values |
| `remove_custom_property` | Delete a named custom property |

### Curves
| Tool | Description |
|---|---|
| `set_curve_properties` | Set bevel depth, resolution, fill mode, extrude, and cyclic on a curve object |
| `convert_to_mesh` | Convert a curve, text, or surface object to a mesh |

### NLA Editor
| Tool | Description |
|---|---|
| `push_action_to_nla` | Push the active action down to an NLA strip |
| `create_nla_track` | Add a named NLA track to an object |

### Image Management
| Tool | Description |
|---|---|
| `create_image` | Create a blank image data block (required as a bake target) |
| `save_image` | Save an image data block to disk |
| `reload_image` | Reload an image from disk after external edits |

### Viewport
| Tool | Description |
|---|---|
| `set_viewport_shading` | Switch 3D viewport between SOLID, MATERIAL, RENDERED, WIREFRAME |

### Library / Asset Pipeline
| Tool | Description |
|---|---|
| `append_from_blend` | Append objects, materials, or collections from another .blend file |
| `link_from_blend` | Link (read-only) assets from another .blend file |

### Drivers
| Tool | Description |
|---|---|
| `add_driver` | Attach a scripted driver expression to any animatable property |
| `remove_driver` | Remove a driver from a property |

### Render Passes
| Tool | Description |
|---|---|
| `enable_render_pass` | Enable/disable a render pass (Z, AO, Normal, Diffuse, Glossy, Shadow, UV, etc.) |

### Vertex Attributes
| Tool | Description |
|---|---|
| `add_attribute` | Add a named vertex attribute layer (FLOAT_COLOR, FLOAT, FLOAT_VECTOR, etc.) |
| `set_vertex_colors` | Fill a color attribute with a solid color across all vertices |

---

## Requirements

- **Blender 3.0+** (tested on Blender 5.2)
- **Python 3.10+**
- **uv** or **pip** for server installation

---

## Development

```bash
git clone git@github.com:skyionblue/blender-studio-mcp.git
cd blender-studio-mcp

# Install dependencies
uv sync --dev

# Run tests (requires Blender running with addon active on port 9877)
uv run pytest

# Run the server locally
uv run blender-studio-mcp
```

---

## License

MIT
