Blender MCP

Blender MCP

An MCP server that enables AI agents to control Blender through natural language for 3D scene creation, animation, and rendering. It provides over 550 actions and direct Python execution via a bridge to a live local Blender session.

Category
Visit Server

README

Inspired by blender-mcp by Siddharth Ahuja — the original proof-of-concept that demonstrated connecting AI agents to Blender over MCP. This project builds on that idea with a production-grade architecture: 69 tool groups, 550+ actions, multilingual intent routing, BVH assembly analysis, thread-safe execution, and a 499-test suite.


Blender MCP

Control Blender with AI — naturally, reliably, at production scale.

Give Claude, GPT, or any MCP-capable AI the ability to create, inspect, and animate 3D scenes in Blender using plain language and structured tool calls.

Python 3.10+ Blender 5.0+ MCP License: MIT


What is this?

MCP (Model Context Protocol) is an open standard that lets AI assistants call structured tools — the same way a programmer calls an API. This project implements an MCP server that bridges your AI assistant to a live Blender session running on your computer.

In practice: tell your AI "create a red metallic sphere above the cube" or "check if all drone parts are touching" and it will call the right Blender tools, get real geometry data back, and show you a screenshot — no Python required from your side.

Local-only. Blender must be installed and running on your machine. The bpy API only exists inside Blender's own Python — there is no cloud version.

execute_blender_code is the primary tool. Almost everything you can do with the other 68 tools can also be done directly with execute_blender_code (which gives full bpy Python access). The specialized tools exist for three reasons: they provide structured, validated inputs the AI can use reliably; they implement complex operations (like BVH assembly analysis or multi-view screenshots) that would be verbose to write from scratch each time; and they are useful for learning how specific Blender operations work.

Note on tool errors. Some tools may return errors in certain Blender states (e.g. sculpt tools require an active mesh in sculpt mode, render tools require a camera). The AI may also occasionally call a tool with slightly wrong parameters — this is normal. The parameter validator will coerce or reject bad values with a clear error message, and the AI will self-correct on the next attempt. If a tool consistently fails, execute_blender_code can usually accomplish the same thing directly.


Architecture

<details> <summary><strong>System diagram</strong></summary>

Claude / AI Agent
       │  stdio  (JSON-RPC 2.0 / MCP)
       ▼
stdio_bridge.py              ← MCP bridge  [standard Python, runs outside Blender]
       │                       · Validates JSON schemas before forwarding
       │                       · Caches tool list from Blender on first connect
       │  TCP localhost:9879  (4-byte Big-Endian length-prefix + JSON body)
       ▼
Blender Addon                ← blender_mcp/__init__.py  [runs inside Blender]
  ├── dispatcher.py            Command router + handler registry (HANDLER_REGISTRY)
  ├── handlers/                52 handler modules (manage_*.py)
  │     manage_scene_comprehension.py   11-action scene intelligence suite
  │     manage_rendering.py             Render, screenshot, view control
  │     manage_scripting.py             execute_blender_code (safe eval)
  │     polyhaven / sketchfab / hunyuan / hyper3d  (4 external integrations)
  └── core/
        protocol.py           Wire protocol (4-byte header + JSON)
        thread_safety.py      All bpy calls routed to Blender's main thread
        execution_engine.py   Safe bpy.ops wrapper + ExecutionPolicy
        parameter_validator.py Type coercion + JSON schema validation
        intent_router.py      Multi-language intent classification (EN/TR/FR)
        semantic_memory.py    Tag-based object resolution
        security.py           High Mode / Safe Mode toggle
        job_manager.py        Async subprocess + internal job queue

All bpy operations are marshalled to Blender's main thread via bpy.app.timers, preventing EXCEPTION_ACCESS_VIOLATION crashes that would occur if a background TCP thread touched the Blender API directly.

See docs/ARCHITECTURE.md for detailed diagrams.

</details>


Installation

<details open> <summary><strong>Prerequisites</strong></summary>

Requirement Version Notes
Platform Windows / macOS / Linux All three are supported — the MCP protocol and wire format are platform-agnostic
Blender 5.0 or later Must be installed and running locally
Python 3.10 or later For the MCP bridge (outside Blender)
uv latest Recommended — fast, isolated environments
git any To clone the repository

</details>

Step 1 — Clone the repository

git clone https://github.com/glonorce/Blender_mcp.git
cd Blender_mcp

Step 2 — Set up the Python environment

<details> <summary>Using <strong>uv</strong> (recommended)</summary>

# Create .venv and install all dependencies in one command
uv sync --all-extras

# Verify everything works (no Blender needed for tests)
uv run pytest tests/unit -q
# → 499 passed in ~1.4s

uv sync creates .venv/ in the project directory — your system Python stays clean. All uv run <cmd> calls use this environment automatically, no manual activation needed.

</details>

<details> <summary>Using <strong>pip</strong> (alternative)</summary>

python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS / Linux:
source .venv/bin/activate

pip install -e ".[dev]"

</details>

Step 3 — Build the Blender addon ZIP

python create_release_zip.py
# → blender_mcp_v1.0.0.zip

Step 4 — Install the addon in Blender

Blender → Edit → Preferences → Add-ons → Install
  → select blender_mcp_v1.0.0.zip
  → enable "Blender MCP"

The addon starts a TCP server on port 9879 automatically. Verify: press N in the 3D Viewport → MCP tab → status should show Listening on :9879.


MCP Client Configuration

Replace <path-to-blender-mcp> with the absolute path where you cloned this repo.

<details open> <summary><strong>Claude Desktop</strong> — <code>claude_desktop_config.json</code></summary>

Windows: %APPDATA%\Claude\claude_desktop_config.json macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "blender": {
      "command": "python",
      "args": ["-u", "<path-to-blender-mcp>/stdio_bridge.py"],
      "env": {
        "BLENDER_HOST": "localhost",
        "BLENDER_PORT": "9879",
        "MCP_TRANSPORT": "stdio",
        "PYTHONPATH": "<path-to-blender-mcp>"
      }
    }
  }
}

</details>

<details> <summary><strong>Cursor / Windsurf / VS Code</strong> — <code>.cursor/mcp.json</code> or <code>.vscode/mcp.json</code></summary>

{
  "mcpServers": {
    "blender": {
      "command": "python",
      "args": ["-u", "<path-to-blender-mcp>/stdio_bridge.py"],
      "env": {
        "BLENDER_HOST": "localhost",
        "BLENDER_PORT": "9879",
        "MCP_TRANSPORT": "stdio",
        "PYTHONPATH": "<path-to-blender-mcp>"
      }
    }
  }
}

</details>

<details> <summary><strong>OpenAI Codex CLI</strong> — <code>~/.codex/config.toml</code></summary>

[mcp_servers.blender]
command = "python"
args = ["-u", "<path-to-blender-mcp>/stdio_bridge.py"]
cwd = "<path-to-blender-mcp>"
enabled = true

[mcp_servers.blender.env]
BLENDER_HOST = "localhost"
BLENDER_PORT = "9879"
MCP_TRANSPORT = "stdio"
PYTHONPATH = "<path-to-blender-mcp>"

</details>

<details> <summary><strong>Generic shell / .env</strong></summary>

export BLENDER_HOST=localhost
export BLENDER_PORT=9879
export MCP_TRANSPORT=stdio
export PYTHONPATH=<path-to-blender-mcp>

python -u <path-to-blender-mcp>/stdio_bridge.py

</details>

-u flag — disables Python's stdout/stderr buffering. Required for stdio transport. Without it, MCP messages may be held in Python's internal buffer and never reach the client.

<details> <summary>Environment variables reference</summary>

Variable Default Description
BLENDER_HOST localhost Hostname where Blender's addon is listening
BLENDER_PORT 9879 TCP port of the Blender addon
MCP_TRANSPORT stdio Transport mode (stdio for all current clients)
PYTHONPATH Must include the project root so blender_mcp is importable

</details>


Verify the Connection

Tool: get_server_status
→ {
    "status": "active",
    "blender_version": [5, 0, 0],
    "blender_language": "en_US",
    "handler_count": 69,
    "next_step": "Call list_all_tools to see all available tools…"
  }

Recommended First Workflow

1. manage_agent_context  GET_PRIMER       → full quick-start guide for the AI
2. get_scene_graph       GET_OBJECTS_FLAT → what objects exist + world positions
3. get_viewport_screenshot_base64         → see the current viewport
4. execute_blender_code                   → create or modify objects
5. get_viewport_screenshot_base64         → confirm the result visually

ESSENTIAL Tools (priority 1–9)

<details open> <summary>These 9 tools handle the vast majority of tasks. The AI discovers them first.</summary>

Pri Tool Purpose
1 execute_blender_code Full bpy Python API — the primary tool for everything
2 get_scene_graph 11-action scene intelligence suite
3 get_viewport_screenshot_base64 Visual verification — see what Blender sees
4 get_object_info Deep object inspector — modifiers, constraints, animation
5 get_local_transforms Parent-relative coordinates
6 manage_agent_context Workflow guides (GET_PRIMER, GET_TACTICS)
7 list_all_tools Tool discovery with intent filtering (77% token savings)
8 get_server_status Health check — version, language, handler count
9 new_scene Create an empty scene

</details>

⚡ execute_blender_code

The primary and most powerful tool. Executes arbitrary Python with full bpy access inside Blender.

Note: Almost all of the other 68 tools are essentially wrappers around things you can also do with execute_blender_code. The specialized tools add structured validation, complex analysis algorithms, and clear action names — which makes them more reliable and readable for AI agents. But for one-off operations or learning what bpy can do, execute_blender_code is often the fastest path.

One hardcoded guard: bpy.ops.render.render() is always blocked — it freezes Blender's main thread for the entire render duration, making the MCP unresponsive. Use manage_rendering action=RENDER_FRAME instead (async subprocess).

# Create a metallic sphere
import bpy, bmesh
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.5, location=(0, 0, 1))
obj = bpy.context.active_object
mat = bpy.data.materials.new("Metal")
mat.use_nodes = True
bsdf = mat.node_tree.nodes["Principled BSDF"]
bsdf.inputs["Metallic"].default_value = 1.0
bsdf.inputs["Roughness"].default_value = 0.1
obj.data.materials.append(mat)
print(f"Created: {obj.name}")

🔍 get_scene_graph

11-action scene intelligence suite. The AI uses this to understand what's in the scene before modifying it.

<details> <summary>All 11 actions</summary>

Action Description
GET_OBJECTS_FLAT All objects: world transforms, hierarchy, matrix_world, geometry_center_world
GET_SCENE_MATRIX Deep spatial analysis: AABB center, nearest neighbors, distances
ANALYZE_ASSEMBLY Integrity score 0–100: BVH surface gaps, interpenetration, hierarchy-aware pairs
CHECK_INTERSECTION AABB intersection test between two objects
GET_SPATIAL_REPORT Spatial summary for one object: bounds, nearby objects
CAST_RAY Ray cast from origin=[x,y,z] in direction=[dx,dy,dz]
VERIFY_ASSEMBLY Rule-based checks: must_touch, parent_must_be
DETECT_GEOMETRY_ERRORS Per-object: non_manifold_edges, boundary_edges, zero_area_faces
GEOMETRY_COMPLEXITY Triangle/vertex/ngon counts + complexity tier
CHECK_PRODUCTION_READINESS Manifold, UV, materials, naming, origin alignment; score 0–100
GET_HIERARCHY_TREE BFS parent→children tree up to max_depth

</details>

📸 get_viewport_screenshot_base64

Captures the viewport as a base64 PNG the AI can directly see and reason about.

<details> <summary>Key parameters</summary>

Parameter Example Description
view_direction "MULTI" FRONT, RIGHT, TOP, ISOMETRIC, or MULTI (all four)
target_objects ["Arm_L", "Body"] Frame specific objects instead of full scene
gap_focus_m 0.002 Auto-zoom to show a gap of this distance
display_mode "MATERIAL" SOLID, MATERIAL, or WIREFRAME
action "SMART_SCREENSHOT" Automatically picks the best view

</details>


Tool Tier System

The AI context window would overflow if all 69 tools were listed in full detail every time. The tier system solves this:

Tier Priority Count Format in list_all_tools
ESSENTIAL 1–9 9 Full detail — title, description, all parameters
CORE 10–49 ~35 Compact table row
STANDARD 50–149 ~20 Compact table row
OPTIONAL 150+ 4 Listed last (external integrations)
# Filter by intent — reduces 69 tools to ~15 relevant ones (77% fewer tokens)
list_all_tools(intent="rig a character")
list_all_tools(intent="physics simulation")
list_all_tools(intent="export to Unity")

Supports English, Turkish, and French intent keywords.


Key Features

<details> <summary><strong>Assembly Intelligence</strong></summary>

get_scene_graph ANALYZE_ASSEMBLY gives a full integrity report:

  • BVH surface-gap measurement — actual vertex-to-face distance, not just bounding-box
  • INTERPENETRATION detection — BVH face overlap, not just AABB
  • Hierarchy-aware pairs — always tests parent↔child; skips distant objects to avoid O(N²)
  • Production readiness score 0–100 — manifold geometry, UV maps, materials, naming, origin alignment

</details>

<details> <summary><strong>Thread Safety</strong></summary>

All bpy calls from the TCP socket thread are automatically marshalled to Blender's main thread via bpy.app.timers. This prevents EXCEPTION_ACCESS_VIOLATION crashes that occur when background threads touch the Blender API.

</details>

<details> <summary><strong>Multilingual Intent Routing</strong></summary>

list_all_tools(intent="...") accepts keywords in English, Turkish, and French. The intent router maps your description to tool categories and returns only the relevant subset — dramatically reducing context window usage.

</details>

<details> <summary><strong>Visual Verification</strong></summary>

get_viewport_screenshot_base64 captures the viewport and returns it as base64 the AI can see:

  • Multi-view in one call: FRONT, RIGHT, TOP, ISOMETRIC
  • gap_focus_m — zoom precisely to the scale of an assembly gap
  • target_objects — frame specific parts, not the whole scene

</details>


Testing

Tests run without Blender — bpy is mocked with unittest.mock.MagicMock.

uv run pytest tests/unit -q              # 499 unit tests, ~1.4s
uv run pytest tests -v --tb=short        # Full suite
uv run pytest tests -v --cov=blender_mcp # With coverage report
uv run python scripts/quality/run_checks.py --fast   # 8 quality checks
uv run python scripts/quality/run_checks.py          # 12 quality checks

<details> <summary>Coverage map — 17 test files</summary>

Module Test File Tests
8 ESSENTIAL handlers test_essential_tools.py 183
core/parameter_validator.py test_parameter_validator.py 60
core/intent_router.py test_intent_router.py 35
core/execution_engine.py test_execution_engine.py 31
dispatcher.py test_dispatcher_deep.py + test_dispatch_routing.py 51
core/semantic_memory.py test_semantic_memory.py 25
core/job_manager.py test_job_manager.py 25
core/response_builder.py test_response_builder.py 21
core/protocol.py test_protocol.py 17
core/error_protocol.py test_error_protocol.py 13
Project structure test_smoke.py 10
MCP bridge validation test_engine.py 9
handlers/manage_history.py test_manage_history.py 9
core/security.py test_security.py 6
Geometry center computation test_scene_graph_geo_center.py 6
Total 17 test files 499

</details>

See tests/TESTS.md for full documentation.


Developer Guide

<details> <summary><strong>Environment setup</strong></summary>

uv sync --all-extras          # Install all dependencies

</details>

<details> <summary><strong>Quality gates</strong></summary>

make check           # 12 checks: lint + format + type-check + tests
make check-fast      # 8 checks: lint + custom checks
make test-fast       # Unit tests only, stop on first failure

</details>

<details> <summary><strong>Tool inspection</strong></summary>

make inspect-summary        # Compact table of all 69 tools
make inspect-essential      # ESSENTIAL tier full detail
uv run python scripts/inspect_tools.py --tool get_scene_graph
uv run python scripts/inspect_tools.py --cat animation

</details>

<details> <summary><strong>Adding a new handler</strong></summary>

Create a file in blender_mcp/handlers/ with @register_handler. Auto-discovered — no list to update.

from ..dispatcher import register_handler

@register_handler(
    "manage_my_feature",
    actions=["CREATE", "DELETE", "LIST"],
    schema={
        "type": "object",
        "properties": {
            "action": {"type": "string", "enum": ["CREATE", "DELETE", "LIST"]},
            "name":   {"type": "string"},
        },
        "required": ["action"],
    },
    category="scene",
    priority=60,          # 1-9=ESSENTIAL, 10-49=CORE, 50-149=STANDARD, 150+=OPTIONAL
    description="STANDARD — Create, delete, and list my features.",
)
def manage_my_feature(action, **params):
    if action == "CREATE":
        return {"created": params.get("name")}
    elif action == "LIST":
        return {"items": []}

</details>

<details> <summary><strong>Scripts reference</strong></summary>

See scripts/SCRIPTS.md for comprehensive documentation of every script.

python -m blender_mcp --help        # Quick CLI overview
python -m blender_mcp --list-tools  # List all tools
python -m blender_mcp --status      # Project health

</details>


Project Structure

<details> <summary>Click to expand</summary>

Blender_mcp/
├── blender_mcp/                     Blender addon (installs via ZIP)
│   ├── __init__.py                  Addon entry + BlenderMCPServer + N-panel UI
│   ├── __main__.py                  python -m blender_mcp CLI
│   ├── dispatcher.py                Handler registry + dispatch_command
│   ├── __version__.py               Single source of version truth
│   ├── handlers/                    52 handler modules
│   │   ├── manage_scene_comprehension.py   get_scene_graph (11 actions)
│   │   ├── manage_rendering.py             RENDER_FRAME, screenshot
│   │   ├── manage_scripting.py             execute_blender_code
│   │   ├── manage_agent_context.py         GET_PRIMER, GET_TACTICS
│   │   ├── manage_history.py               Session checkpoints
│   │   ├── get_local_transforms.py         Parent-relative coordinates
│   │   ├── polyhaven_handler.py            Polyhaven CC0 assets
│   │   ├── sketchfab_handler.py            Sketchfab 3D models
│   │   ├── hunyuan_handler.py              Hunyuan3D AI generation
│   │   ├── hyper3d_handler.py              Hyper3D Rodin AI generation
│   │   └── ...                             40+ more handlers
│   └── core/
│       ├── protocol.py              Wire protocol (4-byte header + JSON)
│       ├── thread_safety.py         Main-thread routing via bpy.app.timers
│       ├── execution_engine.py      Safe bpy.ops + ExecutionPolicy
│       ├── parameter_validator.py   Type coercion + schema validation
│       ├── intent_router.py         Multi-language intent classification
│       ├── semantic_memory.py       Tag-based object resolution
│       ├── security.py              High Mode / Safe Mode
│       ├── job_manager.py           Async subprocess queue
│       ├── response_builder.py      Structured response format
│       └── error_protocol.py        280+ ErrorCode enum values
├── stdio_bridge.py                  MCP bridge (runs outside Blender)
├── scripts/
│   ├── SCRIPTS.md                   Full scripts documentation
│   ├── inspect_tools.py             Tool catalog inspector
│   ├── count_tools.py               Handler count audit
│   ├── sync_version.py              Version synchronization
│   ├── test_blender_imports.py      Runtime import validation (needs Blender)
│   ├── remove_unused_ignores.py     mypy cleanup helper
│   └── quality/
│       ├── run_checks.py            Quality gate (8–12 checks)
│       ├── check_version.py         Version consistency
│       ├── check_forbidden.py       Fatal Blender 5.x pattern scanner
│       ├── check_handler_completeness.py  Registry audit
│       ├── check_handler_imports.py Import style validator
│       ├── check_schemas.py         JSON schema validator
│       ├── check_tool_groups.py     Tool group integrity
│       └── lint_imports.py          Import architecture rules
├── tests/
│   ├── unit/                        499 unit tests (17 files, no Blender needed)
│   ├── integration/                 24 mock + live integration tests
│   └── TESTS.md                     Test suite documentation
├── docs/
│   └── ARCHITECTURE.md              System design, wire protocol, thread model
├── create_release_zip.py            Builds the addon ZIP for Blender
├── Makefile                         Developer shortcuts
├── pyproject.toml                   Build + lint + type-check config
└── LICENSE                          MIT License

</details>


Contribution Guidelines

  1. Use @register_handler decorator on all handlers — no exceptions
  2. @ensure_main_thread on any handler that calls bpy
  3. No bpy.types.SimpleNamespace — not available in Blender 5.x
  4. No eval/exec outside the execute_blender_code security layer
  5. Use MCPLogger / get_logger() instead of print()
  6. Run make check before committing — all 12 checks must pass
  7. Add unit tests for new logic in tests/unit/

Log Files

Component Windows macOS / Linux
Addon (Blender side) %TEMP%\blender_server_debug.log /tmp/blender_server_debug.log
Bridge (MCP side) %TEMP%\mcp_bridge_debug.log /tmp/mcp_bridge_debug.log

License

MIT License — © 2026 GÖKSEL ÖZKAN

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured