Skip to main content
Glama
README.md
# Blender MCP — Streamable-HTTP bridge for Blender 5.2 LTS

A Model Context Protocol bridge that lets any MCP client (Antigravity,
Cursor, Claude Desktop, VS Code 1.101+, MiniMax Code, Windsurf, Continue,
Cline, OpenCode, Codex, MCP Inspector, …) drive **Blender 5.2 LTS**
through natural language.

The add-on runs an MCP Streamable-HTTP server inside Blender on a
background thread. The client just points at it — no subprocess is
spawned, no socket pair to babysit.

---

## Why this shape

* **Single install path inside Blender.** The MCP server runs in-process
  using `bpy`, so there's no `uvx`/`pipx` dance and no socket pair to
  keep in sync.
* **Streamable HTTP on localhost.** Works with every modern MCP client.
* **Hand-rolled MCP server in the add-on.** Blender 5.2 LTS bundles
  Python 3.13 with no external packages by default. A ~300-line MCP
  server is more portable than dragging in `mcp[cli]` and editing
  `sys.path`.
* **Client-agnostic.** No proprietary plugin format. Any MCP client
  that can hit an HTTP endpoint (or a stdio proxy that does) works.

---

## Project layout

```
blender_addon_mcp/
├── README.md                      ← you are here
├── LICENSE                        ← MIT
├── pyproject.toml                 ← dev tooling for the add-on (ruff, mypy, pytest)
├── .gitignore
├── addon/
│   └── blender_mcp_addon/         ← zips into a Blender-installable .zip
│       ├── __init__.py            ← bl_info, register/unregister, preferences
│       ├── server/
│       │   ├── __init__.py
│       │   ├── mcp_server.py      ← MCP protocol (initialize, tools/list, tools/call, ping)
│       │   ├── transport.py       ← stdlib http.server, runs on a daemon thread
│       │   └── protocol.py        ← JSON-RPC 2.0 + MCP 2025-03-26 types
│       ├── tools/
│       │   ├── __init__.py        ← tool registry
│       │   ├── scene.py           ← scene_info, frame control
│       │   ├── objects.py         ← list, get, create, delete, transform
│       │   ├── materials.py       ← create, assign, modify
│       │   ├── modifiers.py       ← add, set params, remove
│       │   ├── render.py          ← render_image, screenshot_viewport
│       │   └── code.py            ← execute_python (with confirmation)
│       └── utils/
│           ├── __init__.py
│           ├── bpy_helpers.py     ← bpy → JSON serialization
│           └── safe_eval.py       ← ast-validated code execution
├── scripts/
│   ├── install_addon.ps1          ← zip and install into Blender
│   ├── blender_mcp_proxy.js       ← optional stdio/socket ↔ HTTP bridge for
│   │                                Antigravity builds that don't accept `url`
│   └── start_blender_mcp_bridge.ps1  ← start/stop/status lifecycle for the bridge
├── examples/
│   ├── mcp-configs.md             ← copy-paste configs for every major MCP client
│   ├── basic_scene.md
│   ├── material_setup.md
│   └── render_workflow.md
└── docs/
    ├── architecture.md
    ├── blender_5_2_notes.md
    └── tools_reference.md
```

---

## Quickstart

### 1. Install the add-on

```powershell
# clone
git clone https://github.com/tattooinmtl/Blender_MCP.git
cd Blender_MCP

# install the add-on into every Blender version on this machine
pwsh ./scripts/install_addon.ps1
```

### 2. Enable the server in Blender

1. Open Blender.
2. **Edit → Preferences → Add-ons** → search "Blender MCP" → check the box.
3. Set the port (default `8765`) and click **Start Server** (or use the
   **Blender MCP** panel in the 3D Viewport sidebar).
4. The console should print:
   ```
   [Blender MCP] Server listening on http://127.0.0.1:8765/mcp
   ```

### 3. Wire up your MCP client

Pick the client you use and paste the matching snippet from
[`examples/mcp-configs.md`](examples/mcp-configs.md). The Antigravity
`url` form is the simplest:

```json
{
  "mcpServers": {
    "blender": { "url": "http://127.0.0.1:8765/mcp" }
  }
}
```

Snippets for Cursor, Claude Desktop, VS Code, MiniMax Code, Windsurf,
Continue, Cline, and the MCP Inspector are all in that file.

### 4. Verify

In any MCP client chat:

> Use the blender server: ping.

You should see the agent call `tools/call` on `ping` and report an empty
successful result. From a terminal:

```powershell
curl -s -X POST http://127.0.0.1:8765/mcp `
  -H "Content-Type: application/json" `
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}'
```

---

## Tools exposed

| Tool | Purpose | Read-only |
| --- | --- | --- |
| `get_addon_info` | Capability handshake — name, version, protocol, tools list. Call this first. | yes |
| `scene_info` | Scene summary (objects, lights, cameras, frame) | yes |
| `list_objects` | List scene objects, optional type filter | yes |
| `get_object` | Full object details (location, rotation, scale, modifiers, materials) | yes |
| `create_object` | Create primitive (cube, sphere, plane, cylinder, cone, torus, empty, camera, light) | no |
| `delete_object` | Delete an object by name | no |
| `transform_object` | Set location/rotation/scale | no |
| `set_material` | Create or assign a material with a Principled BSDF | no |
| `set_texture` | Apply an image file to a material input (base_color, roughness, normal, etc.) | no |
| `import_asset` | Import GLB/GLTF/FBX/OBJ/STL/PLY/DAE/USD/X3D/ABC | no |
| `add_modifier` | Add a modifier (subdivision, mirror, solidify, array, bevel) | no |
| `remove_modifier` | Remove a modifier by name | no |
| `frame_get` / `frame_set` | Read / move the timeline | mixed |
| `render_image` | Render the current frame to a file | no |
| `screenshot_viewport` | Capture the current viewport | no |
| `execute_python` | Run arbitrary `bpy` code (guarded by ast validation) | no |
| `ping` | Health check | yes |

See [`docs/tools_reference.md`](docs/tools_reference.md) for the full schema
and examples.

---

## Development

```powershell
# syntax-check the add-on (Blender's Python is at <blender>/python/bin/python.exe)
python -m py_compile addon/blender_mcp_addon/__init__.py
python -m py_compile addon/blender_mcp_addon/server/mcp_server.py
# ...etc

# lint
ruff check addon/
mypy addon/

# test the MCP server in isolation (no bpy required)
pytest addon/tests/ -v
```

---

## License

MIT. See [`LICENSE`](LICENSE).