Install
$ agentstack add mcp-djeada-blender-mcp-server ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Blender MCP Server
Control Blender from any AI assistant using the Model Context Protocol (MCP).
27 tools across 7 namespaces — create objects, assign materials, render images, export scenes, execute Python scripts, manage async jobs, and more.
How It Works
┌─────────────┐ stdio ┌──────────────────┐ JSON/TCP ┌─────────────────┐
│ MCP Client │ ◄──────────────► │ MCP Server │ ◄─────────────► │ Blender Add-on │
│ (any host) │ │ (Python) │ localhost:9876 │ (runs in bpy) │
└─────────────┘ └──────────────────┘ └─────────────────┘
- The Blender add-on runs inside Blender and listens on
localhost:9876. - The MCP server connects to your AI client via stdio and forwards tool calls to Blender over TCP.
- You ask the AI → it calls MCP tools → Blender executes commands → results flow back.
Quick Start
1. Install the MCP Server
git clone https://github.com/djeada/blender-mcp-server.git
cd blender-mcp-server
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
This creates the executable .venv/bin/blender-mcp-server.
2. Install the Blender Add-on
Build the add-on zip:
./scripts/build_addon_zip.sh
Then in Blender:
- Go to Edit → Preferences → Add-ons → Install.
- Select
dist/blender_mcp_bridge.zipand enable Blender MCP Bridge. - In the 3D Viewport, press N → open the MCP tab.
- Confirm it shows Listening on 127.0.0.1:9876.
3. Connect Your MCP Client
Claude Desktop
Add to your config file:
| OS | Path | |---|---| | macOS | ~/Library/Application Support/Claude/claude_desktop_config.json | | Windows | %APPDATA%\Claude\claude_desktop_config.json | | Linux | ~/.config/Claude/claude_desktop_config.json |
{
"mcpServers": {
"blender": {
"command": "/absolute/path/to/blender-mcp-server/.venv/bin/blender-mcp-server"
}
}
}
Replace the path with the actual location of your clone.
Codex CLI
Register the server once:
codex mcp add blender -- /absolute/path/to/blender-mcp-server/.venv/bin/blender-mcp-server
Verify with codex mcp list. Then start Codex from any directory — it launches the server automatically.
Other MCP clients
Point any MCP-compatible client at the server executable:
/absolute/path/to/blender-mcp-server/.venv/bin/blender-mcp-server
The server uses stdio transport. No additional flags are needed.
4. Start Using It
Make sure Blender is open with the add-on listening, then ask your AI assistant:
- "What objects are in my Blender scene?"
- "Create a cube named TestCube at [0, 0, 1]"
- "Render the scene to /tmp/render.png"
The AI calls MCP tools like blender_scene_list_objects and blender_object_create, which the server forwards to Blender.
Example Prompts
🔍 Inspecting your scene
- "What objects are in my scene?"
- "Show me the transform of the Camera object"
- "List all materials in the file"
🔨 Creating objects
- "Create a sphere named 'Earth' at position [0, 0, 2] with size 3"
- "Add a cylinder at the origin, then scale it to [0.5, 0.5, 4] to make a tall pillar"
- "Create 5 cubes in a row spaced 3 units apart"
🎨 Materials & colors
- "Create a red material and assign it to the Cube"
- "Make a material called 'Ocean' with color [0.0, 0.3, 0.8] and assign it to the Sphere"
- "Change the color of 'RedMaterial' to orange"
📐 Transforming objects
- "Move the Cube up 2 units on the Z axis"
- "Rotate the Cylinder 45 degrees on the Z axis"
- "Scale the Sphere to [2, 2, 2]"
📸 Rendering & exporting
- "Render the scene at 1920×1080 and save it to /tmp/render.png"
- "Export the scene as a GLB file to /tmp/scene.glb"
🐍 Python execution
- "Run this Blender Python:
bpy.ops.mesh.primitive_monkey_add(location=(0,0,2))" - "Execute the fluid_domain.py script from the library with resolution 128"
- "Start an async bake job for the fluid simulation and tell me the job ID"
⏪ Undo / Redo
- "Undo the last change"
- "Redo what was just undone"
Tool Reference
Scene Inspection
| Tool | Description | |---|---| | blender_scene_get_info | Scene metadata — name, frame range, render engine, resolution, object count | | blender_scene_list_objects | List all objects, optionally filter by type (MESH, CAMERA, LIGHT, …) | | blender_object_get_transform | Get position, rotation, and scale of an object by name | | blender_object_get_hierarchy | Parent/child hierarchy tree (full scene or subtree) |
Object Manipulation
| Tool | Description | |---|---| | blender_object_create | Create primitives: cube, sphere, cylinder, plane, cone, torus | | blender_object_delete | Delete an object by name | | blender_object_translate | Move — absolute location or relative offset | | blender_object_rotate | Set rotation [x, y, z] in degrees (default) or radians | | blender_object_scale | Set scale [x, y, z] | | blender_object_duplicate | Duplicate with optional new name |
Materials
| Tool | Description | |---|---| | blender_material_list | List all materials in the file | | blender_material_create | Create a material with optional base color [r, g, b] (0–1) | | blender_material_assign | Assign a material to an object | | blender_material_set_color | Set the Principled BSDF base color | | blender_material_set_texture | Set an image texture as base color |
Rendering & Export
| Tool | Description | |---|---| | blender_render_still | Render still image — output path, resolution, engine | | blender_render_animation | Render animation — frame range, output path, engine | | blender_export_gltf | Export as glTF/GLB | | blender_export_obj | Export as OBJ | | blender_export_fbx | Export as FBX |
History
| Tool | Description | |---|---| | blender_history_undo | Undo the last operation | | blender_history_redo | Redo the last undone operation |
Python Execution
| Tool | Description | |---|---| | blender_python_exec | Run a Python script synchronously. Accepts code or script_path, optional args, timeout_seconds, and transport (bridge or headless). | | blender_python_exec_async | Start a long-running script asynchronously. Returns a job_id. | | blender_job_status | Poll an async job's status, result, stdout, stderr, and error. | | blender_job_cancel | Cancel a running or queued async job. | | blender_job_list | List known async jobs with IDs, status, and creation time. |
Script Library
Pre-built scripts in scripts/library/ for use with blender_python_exec via script_path:
| Script | Description | |---|---| | create_mesh.py | Create primitive meshes through the data API (no bpy.ops) | | fluid_domain.py | Create a Mantaflow fluid domain | | fluid_inflow.py | Create an inflow source | | effector.py | Set objects as collision effectors | | rigid_body.py | Add rigid body physics | | frame_range.py | Set scene frame range | | camera.py | Create and configure a camera | | keyframes.py | Insert transform keyframes | | collections.py | Organize objects into collections | | apply_transforms.py | Apply transforms to objects | | save_blend.py | Save the .blend file |
See [scripts/library/README.md](scripts/library/README.md) for full argument docs and a dam-break walkthrough.
> Tips for physics workflows: > - Prefer create_mesh.py (data API) over bpy.ops.mesh.primitive_*_add in live sessions — the operator path can destabilize view-layer updates around fluid setup. > - Keep Mantaflow liquid modifiers hidden in the viewport to avoid crashes in Blender 4.x. > - Use transport="headless" for heavy physics bakes — this runs scripts in a separate blender -b process.
Safety & Security
| Feature | Description | |---|---| | Automatic undo push | Mutation tools push an undo step before executing (Python exec excluded for stability). | | Safe Mode | Restricts file I/O to the project directory only. | | Tool whitelist | Limits which commands the bridge accepts. | | Script path restrictions | script_path must be under configured approved roots. | | Inline code toggle | Disable inline code execution via add-on preferences. | | Module blocklist | subprocess, shutil, socket, webbrowser, ctypes, multiprocessing are blocked by default. |
Add-on Preferences
In Blender → Edit → Preferences → Add-ons → Blender MCP Bridge:
| Setting | Default | Description | |---|---|---| | Safe Mode | Off | Restrict file I/O to the project directory | | Port | 9876 | TCP port for the MCP bridge | | Allow Inline Code | On | Allow python.execute to run inline code strings | | Approved Script Roots | (blend file dir) | Semicolon-separated directories for script file access |
Advanced Usage
Direct bridge testing (no MCP client)
The helper scripts in scripts/ connect directly to the Blender add-on on 127.0.0.1:9876, bypassing the MCP server entirely. Useful for verifying the add-on works:
python3 scripts/blender_scene_info.py
python3 scripts/blender_create_test_cube.py --name TestCube --x 0 --y 0 --z 1 --size 2
python3 scripts/blender_bridge_request.py scene.get_info
python3 scripts/blender_bridge_request.py object.translate --params '{"name":"TestCube","offset":[0,0,2]}'
All scripts accept --host, --port, and --timeout flags.
Headless / background mode
Run Blender without a GUI for automation:
blender -b --python your_script.py
Where your_script.py starts the MCP bridge:
import sys
sys.path.insert(0, "/path/to/blender-mcp-server")
from addon import CommandHandler, BlenderMCPServer
server = BlenderMCPServer()
server.start()
import socket
s = socket.socket()
s.bind(("127.0.0.1", 9877))
s.listen(1)
s.accept() # Blocks until shutdown signal
Programmatic tool call examples
Inline code — create a fluid domain:
{
"tool": "blender_python_exec",
"args": {
"code": "import bpy\nbpy.ops.mesh.primitive_cube_add(size=4, location=(0,0,2))\ndomain = bpy.context.active_object\ndomain.name = 'FluidDomain'\nbpy.ops.object.modifier_add(type='FLUID')\ndomain.modifiers['Fluid'].fluid_type = 'DOMAIN'\nsettings = domain.modifiers['Fluid'].domain_settings\nsettings.domain_type = 'LIQUID'\nsettings.resolution_max = 64\n__result__ = {'domain': domain.name, 'resolution': 64}",
"args": {"resolution": 64}
}
}
Script file — set up colliders:
{
"tool": "blender_python_exec",
"args": {
"script_path": "scripts/library/effector.py",
"args": {
"objects": ["Ground", "Building_01", "Building_02"],
"effector_type": "COLLISION"
}
}
}
Async bake and poll:
{"tool": "blender_python_exec_async", "args": {"code": "import bpy\nbpy.ops.fluid.bake_all()\n__result__ = {'baked': True}", "timeout_seconds": 1800}}
→ {"job_id": "job-f8e2a1b3"}
{"tool": "blender_job_status", "args": {"job_id": "job-f8e2a1b3"}}
Development
git clone https://github.com/djeada/blender-mcp-server.git
cd blender-mcp-server
pip install -e ".[dev]"
pytest tests/ -v
Project Structure
blender-mcp-server/
├── addon/ # Blender add-on (TCP server + command handlers + job manager)
├── src/blender_mcp_server/ # MCP server (stdio transport + tool definitions)
├── scripts/
│ ├── library/ # Reusable Blender scripts for common tasks
│ ├── demos/ # End-to-end demo scenes
│ └── blender_bridge_request.py # Direct bridge test helpers
├── tests/ # Unit tests (mocked bpy, no Blender required)
├── docs/ # Architecture & design docs
├── pyproject.toml
└── README.md
Contributing
- Fork the repository.
- Create a feature branch.
- Add tests for your changes.
- Run
pytest tests/ -vto verify all tests pass. - Submit a pull request.
License
MIT
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: djeada
- Source: djeada/blender-mcp-server
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.