Blender-MCP
by soozs1
README.md
# BlenderMCP — Blender integration via Model Context Protocol
**English** | [Русский](README.ru.md)
> A fork of [ahujasid/blender-mcp](https://github.com/ahujasid/blender-mcp) reworked with a focus on security:
> all telemetry removed, token authentication added, vulnerabilities fixed.
> Your data never leaves your machine.
BlenderMCP connects Blender to an AI agent through the Model Context Protocol (MCP), letting the agent drive Blender directly: create and modify 3D objects, apply materials, download assets, and execute Python code.
## Features
- **Two-way communication**: AI agent ↔ Blender over a token-authenticated socket server
- **Object manipulation**: create, modify, and delete 3D objects
- **Materials**: apply and configure materials and textures
- **Scene inspection**: get detailed information about the current Blender scene
- **Code execution**: run arbitrary Python code inside Blender
- **Viewport screenshots**: the agent can see the current state of the scene (locally, nothing is uploaded anywhere)
- **Integrations**: [Poly Haven](https://polyhaven.com/) (HDRIs, textures, models), [Sketchfab](https://sketchfab.com/), [Hyper3D Rodin](https://hyper3d.ai/), Hunyuan3D
- **Compatibility**: Blender 3.0+ including **Blender 5.2 LTS**
## Security
### What was removed compared to the original
| Removed | Reason |
|---|---|
| Telemetry (collection of prompts, code, screenshots) | Data was sent to a third-party Supabase |
| `config.py` with Supabase keys | The file was missing from the repository — a supply-chain risk |
| Screenshot uploads to Supabase Storage | Scene screenshots left the machine |
| `httpx` dependency | Used only by telemetry |
| Aggressive ToS (perpetual license on prompts) | No longer applicable — there is nothing to collect |
### What was added
| Added | Description |
|---|---|
| **Token authentication** | If a token is set in the **Custom Token** field, the server uses it (static mode: pairing closed, no token file created). Otherwise the addon generates a random token (`secrets.token_hex(32)`) and makes it discoverable until the first successful authentication. The active token is always visible in the panel (**Token** field). Validated with `secrets.compare_digest` (timing-safe). |
| **Pairing and token lifecycle** | On a fresh start (no Custom Token) the client obtains the token either from the temporary file `blendermcp_token_<port>` or via the `pair` socket command — **loopback connections only**, and only while pairing is open. After the first successful authentication the random token is pinned into **Custom Token** (becomes static across restarts), pairing closes, and the temporary token files are deleted. The MCP client takes the token from `BLENDERMCP_TOKEN` (highest priority), `BLENDERMCP_TOKEN_FILE`, the token file, or — failing all of those — via socket pairing (the obtained token is cached on the MCP side — see the **MCP-side token cache** row). To revoke access or connect a new client — **Reset token & re-pair** button. |
| **MCP-side token cache** | After the first successful authentication the MCP server itself stores the working token in a per-user cache (see `BLENDERMCP_CACHE_DIR`), so reconnects work without manual copying and without editing `settings.json`. Token resolution order: `BLENDERMCP_TOKEN` → `BLENDERMCP_TOKEN_FILE` → MCP cache → addon token file → loopback pairing. Empty values **and unedited placeholders** (`<input-your-token-here>`, "Input your token here") are ignored. Every candidate is tried in turn: on an `invalid token` response the stale cache is dropped and the client automatically moves on to the next source, down to pairing. |
| **Zip-slip protection** | All ZIP archives (Sketchfab, Hunyuan3D) are checked for path traversal before extraction |
| **HTTP timeouts** | All external HTTP requests have `timeout=30` (many previously had none) |
| **Safe logging** | API keys, prompts, and command contents never reach the logs |
| **Egress control (SSRF guard)** | All outbound integration requests go through a single egress gate: http/https only, per-integration host allow-list, DNS resolution with rejection of loopback/private/link-local/metadata IPs, redirects disabled, and a download size cap. Downloaded files are validated by magic bytes (PNG/JPEG/EXR/HDR/GLB/ZIP) before import, so a GLB that is actually HTML is rejected. |
| **Loopback-only socket** | The addon's socket server refuses to bind to a non-loopback host unless `allow_remote_host` is enabled and a >= 32-character Custom Token is set. `execute_code` (arbitrary Python) logs a prominent security notice on startup. |
| **`execute_code` AST guard (opt-in)** | When `restrict_execute_code` is enabled, `execute_code` is checked by an AST allow-list that rejects unsafe imports, `eval`/`exec`/`compile`/`__import__`/`getattr`/etc., dunder access, and attribute chains into `os`/`sys`/`subprocess`/etc. This is a footgun-reducer, not a sandbox. |
### Architecture
```
Zed / MCP client
│ stdio (JSON-RPC)
▼
MCP server (server.py)
│ TCP localhost:9876 + token
▼
Blender Addon (addon.py)
│ HTTPS (only when integrations are enabled)
▼
Poly Haven / Sketchfab / Hyper3D / Hunyuan3D
```
The socket server listens on `localhost` only. The token file is created with `0600` permissions (Unix). No data is sent to third parties except the integrations you enable (Poly Haven, Sketchfab, etc.).
### Limitations and cautions
- `execute_blender_code` runs **arbitrary** Python code inside Blender. Powerful, but potentially dangerous. Always save your project before using it.
- Poly Haven / Sketchfab / Hyper3D / Hunyuan3D integrations are **disabled** by default. Enable only what you need.
- The socket server on `localhost:9876` is token-protected, but malware on the machine could read the token. An acceptable risk for a single-user workstation.
## Components
1. **Blender Addon (`addon.py`)** — the Blender addon that runs a socket server to receive and execute commands
2. **Egress guard (`egress.py`)** — the addon's single gate for outbound HTTP (SSRF protection + file validation)
3. **MCP Server (`src/blender_mcp/server.py`)** — the Python server implementing MCP and connecting to the addon
## Installation
### Requirements
- Blender 3.0 or newer (including 5.2 LTS)
- Python 3.10 or newer
- The [uv](https://docs.astral.sh/uv/getting-started/installation/) package manager
**Installing uv:**
```bash
# macOS
brew install uv
# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
# Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
```
> ⚠️ Use the official uv installer, **not** `pip install uv`.
### Installing the addon in Blender
1. Copy the `addon.py` and `egress.py` files from this repository into Blender's add-ons directory (they must sit side by side)
2. Open Blender → Edit → Preferences → Add-ons
3. Enable the addon by checking "Interface: Blender MCP"
The server starts automatically when the addon is enabled (auto-start). In the BlenderMCP panel (press `N` in the 3D View → **BlenderMCP** tab) you can set your own token in the **Custom Token** field before starting the server; if left empty, a token is generated automatically. After startup the active token is shown in the **Token** field. The easiest path is to configure no token in the MCP client at all: it will fetch the token itself via loopback pairing and cache it (see Step 2 of the Zed Quick Start). To pin a token manually, copy it into the MCP client's `BLENDERMCP_TOKEN` variable.
### Environment variables
| Variable | Default | Description |
|---|---|---|
| `BLENDER_HOST` | `localhost` | Address of the Blender socket server |
| `BLENDER_PORT` | `9876` | Port of the Blender socket server |
| `BLENDERMCP_TOKEN` | — | Authentication token (read by the MCP server). Highest-priority source: paste the token from the **Token** field of the BlenderMCP panel here. **Empty values and placeholders** (`<input-your-token-here>`, "Input your token here") **are ignored** — this disables the override and returns to auto-resolution. An invalid (e.g. stale) token is tried first, after which the client automatically falls back to the next source, down to pairing |
| `BLENDERMCP_TOKEN_FILE` | — | Explicit path to a file containing the token (used when `BLENDERMCP_TOKEN` is not set); empty/placeholder contents are ignored |
| `BLENDERMCP_CACHE_DIR` | OS per-user cache | Directory where the MCP server stores the working token for zero-config reconnects. Defaults: Windows `%LOCALAPPDATA%\blender-mcp`, macOS `~/Library/Caches/blender-mcp`, Linux `~/.cache/blender-mcp` |
> The `BLENDERMCP_TOKEN` and `BLENDERMCP_TOKEN_FILE` variables are used by the **MCP server**. Full token resolution order: `BLENDERMCP_TOKEN` → `BLENDERMCP_TOKEN_FILE` → MCP cache (`BLENDERMCP_CACHE_DIR`) → the freshest `blendermcp_token_<port>` token file → loopback pairing. Empty and placeholder values are ignored, and a rejected token does not break the connection — the client tries the next source.
### Persistent API keys
Keys are stored in the addon preferences: `Edit → Preferences → Add-ons → Blender MCP`
- Sketchfab API Key
- Hyper3D API Key
- Hunyuan3D SecretId / SecretKey / API URL
For headless/CI you can pass them via environment variables:
- `BLENDERMCP_SKETCHFAB_API_KEY`
- `BLENDERMCP_HYPER3D_API_KEY`
- `BLENDERMCP_HUNYUAN3D_SECRET_ID`
- `BLENDERMCP_HUNYUAN3D_SECRET_KEY`
- `BLENDERMCP_HUNYUAN3D_API_URL`
---
## 🚀 Quick start for Zed
### Step 1. Install uv
Make sure `uvx` is available on PATH:
```bash
# Windows
where uvx
# macOS / Linux
which uvx
```
If `uvx` is not found, add `~/.local/bin` (Linux/macOS) or `%USERPROFILE%\.local\bin` (Windows) to PATH.
### Step 2. Configure the MCP server in Zed
Open Zed settings (`Ctrl+,` or `Cmd+,`) and add to the `context_servers` section.
**Option 1 — zero-config (recommended).** No token is specified: on the first connection the MCP server fetches it from Blender via loopback pairing and stores it in a local cache — subsequent reconnects (including after restarting Blender) work with no configuration at all:
```json
{
"context_servers": {
"blender-mcp": {
"command": "uvx",
"args": ["--python", "3.11", "blender-mcp"],
"env": {
"UV_PYTHON_PREFERENCE": "only-managed"
}
}
}
}
```
**Option 2 — fixed token.** If you want to pin a specific token in the config forever (take the value from the **Token** field of the BlenderMCP panel):
```json
{
"context_servers": {
"blender-mcp": {
"command": "uvx",
"args": ["--python", "3.11", "blender-mcp"],
"env": {
"UV_PYTHON_PREFERENCE": "only-managed",
"BLENDERMCP_TOKEN": "<input-your-token-here>"
}
}
}
}
```
> You can leave the placeholder `"<input-your-token-here>"` in the config as-is: like an empty value, it is ignored and zero-config pairing kicks in. An invalid (e.g. stale) token is not a blocker either: the client tries it, receives `invalid token`, and automatically falls back to the next source, down to pairing.
**Windows** — if `uvx` is not found from the GUI, use the full path or a `cmd` wrapper (for Option 2, additionally add the `BLENDERMCP_TOKEN` line to `env`):
```json
{
"context_servers": {
"blender-mcp": {
"command": "cmd",
"args": ["/c", "uvx", "--python", "3.11", "blender-mcp"],
"env": {
"UV_PYTHON_PREFERENCE": "only-managed"
}
}
}
}
```
> The full path to `uvx` can be found with `where uvx` (Windows) or `which uvx` (macOS/Linux), e.g. `C:\Users\you\.local\bin\uvx.exe` or `/opt/homebrew/bin/uvx`.
### Step 3. Install the addon in Blender and set up the token
1. Open Blender
2. Copy `addon.py` and `egress.py` into Blender's add-ons directory (side by side)
3. Edit → Preferences → Add-ons → enable the "Interface: Blender MCP" checkbox
4. The server starts automatically (port 9876)
5. Press `N` in the 3D View → **BlenderMCP** tab:
- **Option A (your own token):** press **Disconnect from MCP server**, enter the token into the **Custom Token** field, then press **Connect to MCP server** again.
- **Option B (auto-generation):** leave the field empty — the server generates a random token itself.
- **Option C (auto-pair, no manual copying):** leave the field empty and do not set `BLENDERMCP_TOKEN` — on the first connection the MCP client fetches the token itself via loopback pairing. After the first successful authentication the token is pinned into **Custom Token** (becomes static), pairing closes, and the temporary files are removed; the MCP server caches the token — so reconnects (including after restarting Blender) work without manual copying.
6. Copy the value from the **Token** field — you will need it for the Zed config (for Option C — only if you want to pin the token in the config forever).
### Step 4. Verify the connection
1. Restart the context server in Zed to apply the config from Step 2. For zero-config there is nothing else to do: on the first call the MCP server fetches the token from Blender itself and caches it. For a fixed token, make sure the `BLENDERMCP_TOKEN` value matches the **Token** field of the BlenderMCP panel.
2. In Zed open the assistant panel (`Ctrl+Shift+A` / `Cmd+Shift+A`)
3. The context server list should show **blender-mcp** with status "running"
4. Try a prompt:
```
Get information about the current Blender scene
```
The agent will call `get_scene_info` and return the list of objects.
### Step 5. Enable integrations (optional)
Check the boxes you need in the BlenderMCP panel:
- ☑ Use assets from Poly Haven — HDRIs, textures, models
- ☑ Use Sketchfab — search and download 3D models (API key required)
- ☑ Use Hyper3D Rodin — text/image-to-3D model generation (API key required)
- ☑ Use Tencent Hunyuan 3D — 3D model generation (SecretId/SecretKey or local API required)
### Example prompts for Zed
```
Create a sphere and place it above the cube
```
```
Make this car red and metallic
```
```
Set up studio lighting and point the camera at the scene
```
```
Take a viewport screenshot so I can see the current state
```
```
Create a low-poly dungeon scene with a dragon guarding a pot of gold
```
### Troubleshooting in Zed
| Problem | Solution |
|---|---|
| `spawn uvx ENOENT` | Specify the full path to `uvx` in `"command"` or use a `cmd /c` wrapper |
| Server does not connect | Make sure the Blender addon is running (BlenderMCP panel → "Running on port 9876") |
| `Authentication failed: invalid token` | On this error the MCP server automatically discards the stale token cache and retries via the token file/pairing. If it persists — compare the active token in the **Token** field of the BlenderMCP panel with your `BLENDERMCP_TOKEN` value (if set), pin a single token in the **Custom Token** field, reconnect the server (Disconnect → Connect), and restart the MCP server in Zed. Diagnostics: `python test_connection.py <token>` |
| `Pairing is closed` | This is normal: pairing closes after the first successful authentication, and the MCP server uses the cached token (zero-config reconnect). You can only see this message when there is no cache and no token file — press **Reset token & re-pair** in the BlenderMCP panel to issue a new token and reopen pairing. |
| Timeouts | Simplify the request or split it into several steps |
| Python version conflict | Add `"--python", "3.11"` to `args` and `"UV_PYTHON_PREFERENCE": "only-managed"` to `env` |
| uv cache after a failed install | `uv cache clean blender-mcp && uvx --refresh blender-mcp` |
> ⚠️ Run only **one** instance of the MCP server. Do not keep parallel configs in Zed and another client.
---
## Usage
### Starting the connection
1. In Blender open the 3D View sidebar (press `N`)
2. Find the **BlenderMCP** tab
3. Enable the integrations you need (optional)
4. The server starts automatically when the addon registers
5. Set a token in the **Custom Token** field (before starting) or rely on auto-pairing and the MCP-side cache; to pin manually, copy the generated token from the **Token** field into the MCP client's `BLENDERMCP_TOKEN`
6. Make sure the MCP server is running in your client (Zed, Claude Desktop, etc.)
### Capabilities
- Get scene and object information
- Create, delete, and modify objects
- Apply and create materials
- Execute arbitrary Python code in Blender
- 3D viewport screenshots
- Download models, textures, and HDRIs via Poly Haven
- Search and download models from Sketchfab
- Generate 3D models via Hyper3D Rodin and Hunyuan3D
## Hyper3D
The free trial key allows a limited number of model generations per day. When the limit is exhausted, wait for the reset or get your own key at [hyper3d.ai](https://hyper3d.ai) and [fal.ai](https://fal.ai).
## Technical details
### Protocol
The system uses a JSON protocol over TCP sockets. Responses are framed with a 4-byte big-endian length prefix (length-prefix framing) so message boundaries are unambiguous:
- **Commands** are sent as JSON objects with `type`, `params`, and `token` fields
- **Responses** are length-prefixed JSON objects with `status` and `result` or `message` fields
- Authentication: every command carries a `token` checked with a timing-safe comparison
### Blender compatibility
| Blender version | Status |
|---|---|
| 3.0 — 3.6 | ✅ Supported |
| 4.0 — 4.x | ✅ Supported (version guards for `ShaderNodeSeparateColor`) |
| 5.0 — 5.2 LTS | ✅ Supported |
## Feedback
Original project: [github.com/ahujasid/blender-mcp](https://github.com/ahujasid/blender-mcp)
## License
MIT. This is a third-party integration, not affiliated with the Blender Foundation.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues