blender-mcp-server 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- blender_mcp_server-0.1.0/.gitignore +13 -0
- blender_mcp_server-0.1.0/LICENSE +21 -0
- blender_mcp_server-0.1.0/PKG-INFO +377 -0
- blender_mcp_server-0.1.0/README.md +349 -0
- blender_mcp_server-0.1.0/addon/__init__.py +620 -0
- blender_mcp_server-0.1.0/docs/architecture.md +93 -0
- blender_mcp_server-0.1.0/docs/images/demo_render.png +0 -0
- blender_mcp_server-0.1.0/pyproject.toml +61 -0
- blender_mcp_server-0.1.0/src/blender_mcp_server/__init__.py +3 -0
- blender_mcp_server-0.1.0/src/blender_mcp_server/server.py +394 -0
- blender_mcp_server-0.1.0/tests/__init__.py +0 -0
- blender_mcp_server-0.1.0/tests/test_addon.py +141 -0
- blender_mcp_server-0.1.0/tests/test_server.py +192 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Adam Djellouli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: blender-mcp-server
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for controlling Blender via AI assistants
|
|
5
|
+
Project-URL: Homepage, https://github.com/djeada/blender-mcp-server
|
|
6
|
+
Project-URL: Repository, https://github.com/djeada/blender-mcp-server
|
|
7
|
+
Project-URL: Issues, https://github.com/djeada/blender-mcp-server/issues
|
|
8
|
+
Author-email: Adam Djellouli <adam@djellouli.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: 3d,ai,blender,claude,mcp,model-context-protocol
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: mcp>=1.0.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# Blender MCP Server
|
|
30
|
+
|
|
31
|
+
Control Blender from AI assistants like Claude Desktop using the [Model Context Protocol (MCP)](https://modelcontextprotocol.io).
|
|
32
|
+
|
|
33
|
+
**22 tools** across 6 namespaces — create objects, assign materials, render images, export scenes, and more, all through natural language.
|
|
34
|
+
|
|
35
|
+

|
|
36
|
+
|
|
37
|
+
*Scene above was created entirely through MCP commands: orange cube, blue sphere, stretched cylinder, and cone — with materials, transforms, and lighting.*
|
|
38
|
+
|
|
39
|
+
## How It Works
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
┌─────────────────┐ stdio ┌──────────────────────┐ JSON/TCP ┌────────────────────┐
|
|
43
|
+
│ Claude Desktop │ ◄──────────────► │ MCP Server (Python) │ ◄─────────────► │ Blender Add-on │
|
|
44
|
+
│ (MCP Client) │ │ src/server.py │ localhost:9876 │ (runs in Blender) │
|
|
45
|
+
└─────────────────┘ └──────────────────────┘ └────────────────────┘
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
1. The **Blender add-on** runs inside Blender, opening a TCP socket on `localhost:9876`
|
|
49
|
+
2. The **MCP server** connects to Claude Desktop via stdio and forwards tool calls to Blender over TCP
|
|
50
|
+
3. You talk to Claude → Claude calls MCP tools → Blender executes commands → results flow back
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
### Step 1: Install the Blender Add-on
|
|
55
|
+
|
|
56
|
+
1. Open Blender
|
|
57
|
+
2. Go to **Edit → Preferences → Add-ons → Install**
|
|
58
|
+
3. Select `addon/__init__.py` from this repository
|
|
59
|
+
4. Enable **"Blender MCP Bridge"**
|
|
60
|
+
5. The TCP bridge starts automatically — you'll see "● Listening on 127.0.0.1:9876" in the sidebar panel
|
|
61
|
+
|
|
62
|
+
### Step 2: Install the MCP Server
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install blender-mcp-server
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Or from source:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git clone https://github.com/your-org/blender-mcp-server
|
|
72
|
+
cd blender-mcp-server
|
|
73
|
+
pip install -e .
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Step 3: Configure Claude Desktop
|
|
77
|
+
|
|
78
|
+
Add this to your Claude Desktop config file:
|
|
79
|
+
|
|
80
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
81
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
82
|
+
**Linux**: `~/.config/Claude/claude_desktop_config.json`
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"mcpServers": {
|
|
87
|
+
"blender": {
|
|
88
|
+
"command": "blender-mcp-server"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Or with `uvx` (no install needed):
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"mcpServers": {
|
|
99
|
+
"blender": {
|
|
100
|
+
"command": "uvx",
|
|
101
|
+
"args": ["blender-mcp-server"]
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Step 4: Start Using It
|
|
108
|
+
|
|
109
|
+
1. Make sure Blender is running with the add-on enabled
|
|
110
|
+
2. Open Claude Desktop
|
|
111
|
+
3. Start asking Claude to work with your Blender scene!
|
|
112
|
+
|
|
113
|
+
## Example Prompts
|
|
114
|
+
|
|
115
|
+
Here's what you can ask Claude to do once everything is connected:
|
|
116
|
+
|
|
117
|
+
### 🔍 Inspecting Your Scene
|
|
118
|
+
> "What objects are in my scene?"
|
|
119
|
+
>
|
|
120
|
+
> "Show me the transform of the Camera object"
|
|
121
|
+
>
|
|
122
|
+
> "List all materials in the file"
|
|
123
|
+
|
|
124
|
+
### 🔨 Creating Objects
|
|
125
|
+
> "Create a sphere named 'Earth' at position [0, 0, 2] with size 3"
|
|
126
|
+
>
|
|
127
|
+
> "Add a cylinder at the origin, then scale it to [0.5, 0.5, 4] to make a tall pillar"
|
|
128
|
+
>
|
|
129
|
+
> "Create 5 cubes in a row spaced 3 units apart"
|
|
130
|
+
|
|
131
|
+
### 🎨 Materials & Colors
|
|
132
|
+
> "Create a red material and assign it to the Cube"
|
|
133
|
+
>
|
|
134
|
+
> "Make a material called 'Ocean' with color [0.0, 0.3, 0.8] and assign it to the Sphere"
|
|
135
|
+
>
|
|
136
|
+
> "Change the color of 'RedMaterial' to orange"
|
|
137
|
+
|
|
138
|
+
### 📐 Transforming Objects
|
|
139
|
+
> "Move the Cube up 2 units on the Z axis"
|
|
140
|
+
>
|
|
141
|
+
> "Rotate the Cylinder 45 degrees on the Z axis"
|
|
142
|
+
>
|
|
143
|
+
> "Scale the Sphere to [2, 2, 2]"
|
|
144
|
+
|
|
145
|
+
### 📸 Rendering & Exporting
|
|
146
|
+
> "Render the scene at 1920x1080 and save it to /tmp/render.png"
|
|
147
|
+
>
|
|
148
|
+
> "Export the scene as a GLB file to /tmp/scene.glb"
|
|
149
|
+
|
|
150
|
+
### ⏪ Safety
|
|
151
|
+
> "Undo the last change"
|
|
152
|
+
>
|
|
153
|
+
> "Redo what was just undone"
|
|
154
|
+
|
|
155
|
+
## Example Session
|
|
156
|
+
|
|
157
|
+
Here's a real session transcript showing every category of tool in action.
|
|
158
|
+
All output below was produced by a live Blender 4.0.2 instance controlled through the MCP bridge:
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
📋 STEP 1: Get Scene Info
|
|
162
|
+
─────────────────────────
|
|
163
|
+
{
|
|
164
|
+
"name": "Scene",
|
|
165
|
+
"frame_current": 1,
|
|
166
|
+
"frame_start": 1,
|
|
167
|
+
"frame_end": 250,
|
|
168
|
+
"render_engine": "BLENDER_EEVEE",
|
|
169
|
+
"resolution_x": 1920,
|
|
170
|
+
"resolution_y": 1080,
|
|
171
|
+
"object_count": 3
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
📦 STEP 2: List Default Scene Objects
|
|
175
|
+
──────────────────────────────────────
|
|
176
|
+
• Cube (MESH ) at [0.0, 0.0, 0.0]
|
|
177
|
+
• Light (LIGHT ) at [4.1, 1.0, 5.9]
|
|
178
|
+
• Camera (CAMERA ) at [7.4, -6.9, 5.0]
|
|
179
|
+
|
|
180
|
+
🔨 STEP 3: Create Mesh Objects
|
|
181
|
+
───────────────────────────────
|
|
182
|
+
✅ Created MyCube at [0.0, 0.0, 0.0]
|
|
183
|
+
✅ Created MySphere at [3.0, 0.0, 0.0]
|
|
184
|
+
✅ Created MyCylinder at [-3.0, 0.0, 0.0]
|
|
185
|
+
✅ Created MyCone at [0.0, 3.0, 0.0]
|
|
186
|
+
|
|
187
|
+
🔄 STEP 4: Transform Objects
|
|
188
|
+
─────────────────────────────
|
|
189
|
+
✅ Moved MyCube to [0.0, 0.0, 2.0]
|
|
190
|
+
✅ Rotated MySphere Z=45°
|
|
191
|
+
✅ Scaled MyCylinder to [1.0, 1.0, 3.0]
|
|
192
|
+
|
|
193
|
+
📑 STEP 5: Duplicate Object
|
|
194
|
+
────────────────────────────
|
|
195
|
+
✅ Duplicated 'MyCube' → 'MyCube.Copy'
|
|
196
|
+
|
|
197
|
+
📐 STEP 6: Inspect Object Transform
|
|
198
|
+
────────────────────────────────────
|
|
199
|
+
{
|
|
200
|
+
"name": "MyCube",
|
|
201
|
+
"location": [0.0, 0.0, 2.0],
|
|
202
|
+
"rotation_euler": [0.0, 0.0, 0.0],
|
|
203
|
+
"scale": [1.0, 1.0, 1.0]
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
🎨 STEP 7: Create & Assign Materials
|
|
207
|
+
─────────────────────────────────────
|
|
208
|
+
✅ Created 'RedMaterial'
|
|
209
|
+
✅ Assigned 'RedMaterial' → 'MyCube'
|
|
210
|
+
✅ Created 'BlueMaterial'
|
|
211
|
+
✅ Assigned 'BlueMaterial' → 'MySphere'
|
|
212
|
+
✅ Changed RedMaterial color → orange
|
|
213
|
+
|
|
214
|
+
🎨 STEP 8: List Materials
|
|
215
|
+
─────────────────────────
|
|
216
|
+
• BlueMaterial (nodes: True, users: 1)
|
|
217
|
+
• Material (nodes: True, users: 1)
|
|
218
|
+
• RedMaterial (nodes: True, users: 1)
|
|
219
|
+
|
|
220
|
+
🌳 STEP 9: Scene Hierarchy
|
|
221
|
+
───────────────────────────
|
|
222
|
+
• Cube (MESH) • MyCube (MESH)
|
|
223
|
+
• Light (LIGHT) • MySphere (MESH)
|
|
224
|
+
• Camera (CAMERA) • MyCylinder (MESH)
|
|
225
|
+
• MyCone (MESH)
|
|
226
|
+
|
|
227
|
+
🗑️ STEP 10: Delete Object
|
|
228
|
+
──────────────────────────
|
|
229
|
+
✅ Deleted 'MyCube.Copy'
|
|
230
|
+
|
|
231
|
+
📸 STEP 12: Render Still Image
|
|
232
|
+
───────────────────────────────
|
|
233
|
+
✅ Rendered: /tmp/blender_mcp_render.png
|
|
234
|
+
Engine: BLENDER_EEVEE, Resolution: [640, 480]
|
|
235
|
+
|
|
236
|
+
⏪ STEP 13: Undo & Redo
|
|
237
|
+
───────────────────────
|
|
238
|
+
✅ undo
|
|
239
|
+
✅ redo
|
|
240
|
+
|
|
241
|
+
📦 FINAL: Scene Summary — 7 objects, 3 materials
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Tool Reference
|
|
245
|
+
|
|
246
|
+
### Scene Inspection
|
|
247
|
+
|
|
248
|
+
| Tool | Description |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `blender_scene_get_info` | Scene metadata — name, frame range, render engine, resolution, object count |
|
|
251
|
+
| `blender_scene_list_objects` | List all objects, optionally filter by type (`MESH`, `CAMERA`, `LIGHT`, etc.) |
|
|
252
|
+
| `blender_object_get_transform` | Get position, rotation, and scale of an object by name |
|
|
253
|
+
| `blender_object_get_hierarchy` | Parent/child hierarchy tree (full scene or subtree) |
|
|
254
|
+
|
|
255
|
+
### Materials
|
|
256
|
+
|
|
257
|
+
| Tool | Description |
|
|
258
|
+
|---|---|
|
|
259
|
+
| `blender_material_list` | List all materials in the file |
|
|
260
|
+
| `blender_material_create` | Create a new material with optional base color `[r, g, b]` (0–1) |
|
|
261
|
+
| `blender_material_assign` | Assign a material to an object |
|
|
262
|
+
| `blender_material_set_color` | Set the Principled BSDF base color |
|
|
263
|
+
| `blender_material_set_texture` | Set an image texture as base color |
|
|
264
|
+
|
|
265
|
+
### Object Manipulation
|
|
266
|
+
|
|
267
|
+
| Tool | Description |
|
|
268
|
+
|---|---|
|
|
269
|
+
| `blender_object_create` | Create primitives: `cube`, `sphere`, `cylinder`, `plane`, `cone`, `torus` |
|
|
270
|
+
| `blender_object_delete` | Delete an object by name |
|
|
271
|
+
| `blender_object_translate` | Move — absolute `location` or relative `offset` |
|
|
272
|
+
| `blender_object_rotate` | Set rotation `[x, y, z]` in degrees (default) or radians |
|
|
273
|
+
| `blender_object_scale` | Set scale `[x, y, z]` |
|
|
274
|
+
| `blender_object_duplicate` | Duplicate with optional new name |
|
|
275
|
+
|
|
276
|
+
### Rendering & Export
|
|
277
|
+
|
|
278
|
+
| Tool | Description |
|
|
279
|
+
|---|---|
|
|
280
|
+
| `blender_render_still` | Render still image — set output path, resolution, engine |
|
|
281
|
+
| `blender_render_animation` | Render animation — set frame range, output path, engine |
|
|
282
|
+
| `blender_export_gltf` | Export as glTF/GLB |
|
|
283
|
+
| `blender_export_obj` | Export as OBJ |
|
|
284
|
+
| `blender_export_fbx` | Export as FBX |
|
|
285
|
+
|
|
286
|
+
### History
|
|
287
|
+
|
|
288
|
+
| Tool | Description |
|
|
289
|
+
|---|---|
|
|
290
|
+
| `blender_history_undo` | Undo the last operation |
|
|
291
|
+
| `blender_history_redo` | Redo the last undone operation |
|
|
292
|
+
|
|
293
|
+
## Safety Features
|
|
294
|
+
|
|
295
|
+
- **Automatic undo push** — every mutation tool pushes an undo step first, so you can always roll back
|
|
296
|
+
- **Safe Mode** — enable in add-on preferences to restrict file access to the project directory only
|
|
297
|
+
- **Tool whitelist** — limit which commands the bridge will accept
|
|
298
|
+
- **No arbitrary code execution** — the bridge only accepts predefined commands, never `exec` or `eval`
|
|
299
|
+
|
|
300
|
+
## Add-on Preferences
|
|
301
|
+
|
|
302
|
+
In Blender → Edit → Preferences → Add-ons → Blender MCP Bridge:
|
|
303
|
+
|
|
304
|
+
| Setting | Description | Default |
|
|
305
|
+
|---|---|---|
|
|
306
|
+
| **Safe Mode** | Restrict file I/O to project directory | Off |
|
|
307
|
+
| **Port** | TCP port for the MCP bridge | 9876 |
|
|
308
|
+
|
|
309
|
+
## Headless / Background Mode
|
|
310
|
+
|
|
311
|
+
You can also run Blender in background mode (no GUI) for automation:
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
blender -b --python your_script.py
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Where `your_script.py` starts the MCP bridge:
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
import sys
|
|
321
|
+
sys.path.insert(0, "/path/to/blender-mcp-server")
|
|
322
|
+
from addon import CommandHandler, BlenderMCPServer
|
|
323
|
+
|
|
324
|
+
server = BlenderMCPServer()
|
|
325
|
+
server.start()
|
|
326
|
+
|
|
327
|
+
# Keep Blender alive (use your preferred method)
|
|
328
|
+
import socket
|
|
329
|
+
s = socket.socket()
|
|
330
|
+
s.bind(("127.0.0.1", 9877))
|
|
331
|
+
s.listen(1)
|
|
332
|
+
s.accept() # Blocks until shutdown signal
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Development
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
# Clone and install with dev dependencies
|
|
339
|
+
git clone https://github.com/your-org/blender-mcp-server
|
|
340
|
+
cd blender-mcp-server
|
|
341
|
+
pip install -e ".[dev]"
|
|
342
|
+
|
|
343
|
+
# Run tests (no Blender required)
|
|
344
|
+
pytest tests/ -v
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Project Structure
|
|
348
|
+
|
|
349
|
+
```
|
|
350
|
+
blender-mcp-server/
|
|
351
|
+
├── addon/
|
|
352
|
+
│ └── __init__.py # Blender add-on — TCP server + command handlers
|
|
353
|
+
├── src/blender_mcp_server/
|
|
354
|
+
│ ├── __init__.py
|
|
355
|
+
│ └── server.py # MCP server — stdio transport + 22 tool definitions
|
|
356
|
+
├── tests/
|
|
357
|
+
│ ├── test_addon.py # Add-on tests (mocked bpy)
|
|
358
|
+
│ └── test_server.py # MCP server tests
|
|
359
|
+
├── docs/
|
|
360
|
+
│ ├── architecture.md # Architecture documentation
|
|
361
|
+
│ └── images/
|
|
362
|
+
│ └── demo_render.png # Render from demo session
|
|
363
|
+
├── pyproject.toml
|
|
364
|
+
└── README.md
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Contributing
|
|
368
|
+
|
|
369
|
+
1. Fork the repository
|
|
370
|
+
2. Create a feature branch
|
|
371
|
+
3. Make your changes with tests
|
|
372
|
+
4. Run `pytest tests/ -v` to verify all 23 tests pass
|
|
373
|
+
5. Submit a pull request
|
|
374
|
+
|
|
375
|
+
## License
|
|
376
|
+
|
|
377
|
+
MIT
|