blender-ai-mcp

mcp
Guvenlik Denetimi
Uyari
Health Uyari
  • License — License: NOASSERTION
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 9 GitHub stars
Code Gecti
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested
Purpose
This MCP server acts as a secure translation layer, enabling Large Language Models to control Blender for 3D modeling workflows via curated, sandboxed tools rather than executing raw, arbitrary Python scripts.

Security Assessment
The overall risk is rated as Low. The architecture is designed with safety in mind, acting as a buffer between the AI and Blender's internal state machine to prevent arbitrary code execution crashes. An automated code scan of 12 files found no dangerous patterns, no hardcoded secrets, and no requests for dangerous system permissions. The primary communication method relies on standard JSON-RPC over local TCP sockets. Because it interacts with an external application via sockets, you should be aware of the local network communication, though it does not pose a severe threat.

Quality Assessment
The project is actively maintained, with its last push occurring today. It utilizes a modern, clean architecture (FastMCP server paired with a Blender Addon) and includes CI/CD pipelines alongside Docker support. The community visibility is currently low, marked by only 9 GitHub stars, which reflects its early-stage or niche status rather than a lack of quality. The repository declares a BUSL-1.1 license in the documentation, though the automated check returned a "NOASSERTION" status. You should verify the license terms before using it in commercial production environments.

Verdict
Safe to use, though verify the BUSL-1.1 license terms for commercial applications.
SUMMARY

Production-shaped MCP server for Blender with goal-first routing, curated tools, deterministic verification, and vision-assisted 3D modeling workflows.

README.md

blender-ai-mcp

License: BUSL-1.1
Python 3.10+
Docker
CI Status

💡 Support the Project

This project is currently developed after hours as a passion project. Creating a stable bridge between AI and Blender's complex API requires significant time and effort.

If you find this tool useful or want to accelerate the development of advanced features (like Edit Mode tools, Auto-Rigging, or Macro Generators), please consider supporting the project. Your sponsorship allows me to dedicate more time to:

  • Implementing critical Mesh Editing Tools (Extrude, Bevel, Loop Cut).
  • Creating high-level Macro Tools (e.g., "Create Human Blockout", "Organify").
  • Ensuring day-one support for new Blender versions.

💖 Sponsor on GitHub | ☕ Buy me a coffee

Modular MCP Server + Blender Addon for AI-Driven 3D Modeling.

Enable LLMs (Claude, ChatGPT) to control Blender reliably. Built with Clean Architecture for stability and scalability.

Watch demo video

🚀 Why use this MCP Server instead of raw Python code?

Most AI solutions for Blender rely on asking the LLM to "write a Python script". This often fails because:

  1. Hallucinations: AI frequently uses outdated bpy API methods (mixing Blender 2.8 with 5.0).
  2. Context Errors: Running operators requires specific context (active window, selected object, correct mode). Raw scripts often crash Blender due to poll() failures.
  3. No Feedback Loop: If a script fails, the AI doesn't know why. Our MCP server returns precise error messages.
  4. Safety: Executing arbitrary Python code is risky. Our tools are sandboxed endpoints with validated inputs.

Blender AI MCP acts as a stable Translation Layer, handling the complexity of Blender's internal state machine so the AI can focus on creativity.


🏗️ Architecture

This project uses a split-architecture design:

  1. MCP Server (Python/FastMCP): Handles AI communication.
  2. Blender Addon (Python/bpy): Executes 3D operations.

Communication happens via JSON-RPC over TCP sockets.

See ARCHITECTURE.md for deep dive.

✅ Support Matrix

  • Blender: tested on Blender 5.0 (E2E). The addon declares minimum Blender 4.0, but 4.x support is best-effort.
  • Python (MCP server): 3.11 is the CI baseline. 3.10+ works for core tools, but Router semantic features (LaBSE/LanceDB) require 3.11+.
  • OS: macOS / Windows / Linux (Docker recommended). On Linux, use host networking or proper host resolution for BLENDER_RPC_HOST.
  • Memory: Router semantic matching uses a local LaBSE model (~2GB RAM).

🧪 Testing

Unit Tests (no Blender required):

PYTHONPATH=. poetry run pytest tests/unit/ -v

To see the current unit test count:

poetry run pytest tests/unit --collect-only

E2E Tests (requires Blender):

# Automated: build → install addon → start Blender → run tests → cleanup
python3 scripts/run_e2e_tests.py

To see the current E2E test count:

poetry run pytest tests/e2e --collect-only
Type Coverage
Unit Tests All tool handlers
E2E Tests Blender addon integration (Scene, Mesh, Material, UV, Export, Import, Baking, System, Sculpt, Router)

See _docs/_TESTS/README.md for detailed testing documentation.

📋 Example E2E Test Output (click to expand)
tests/e2e/tools/extraction/test_face_group_analysis.py ....
tests/e2e/tools/extraction/test_render_angles.py ....
tests/e2e/tools/import_tool/test_import_tools.py .........
tests/e2e/tools/knife_cut/test_knife_cut_tools.py .........
tests/e2e/tools/lattice/test_lattice_tools.py .............
tests/e2e/tools/material/test_material_tools.py ..............
tests/e2e/tools/mesh/test_mesh_cleanup.py .................
tests/e2e/tools/mesh/test_mesh_edge_weights.py ...............
tests/e2e/tools/mesh/test_mesh_symmetry_fill.py ............................
tests/e2e/tools/scene/test_camera_focus.py ....
tests/e2e/tools/scene/test_camera_orbit.py ......
tests/e2e/tools/scene/test_hide_object.py ...
tests/e2e/tools/scene/test_isolate_object.py ...
tests/e2e/tools/scene/test_rename_object.py ..
tests/e2e/tools/scene/test_scene_inspect_material_slots.py ....
tests/e2e/tools/scene/test_show_all_objects.py ...
tests/e2e/tools/scene/test_snapshot_tools.py ...
tests/e2e/tools/sculpt/test_sculpt_tools.py .............
tests/e2e/tools/system/test_system_tools.py ............
tests/e2e/tools/text/test_text_tools.py ....................
tests/e2e/tools/uv/test_uv_tools.py ................

============================= 352 passed in 46.21s ==============================

🗺️ Roadmap & Capabilities

Legend: ✅ Done | 🚧 To Do

Our goal is to enable AI to model complex 3D assets—from organs and biological structures to hard-surface precision parts (cars, devices).


Scene Tools (`scene_*`) — ✅

Object Mode operations for scene management and inspection.

Tool Description Status
scene_list_objects List all objects in scene
scene_delete_object Delete object by name
scene_clean_scene Remove all objects
scene_duplicate_object Duplicate object
scene_set_active_object Set active object
scene_get_viewport Capture viewport image (AI vision)
scene_get_mode Report current Blender mode
scene_list_selection List selected objects/components
scene_inspect_object Detailed object info
scene_snapshot_state Capture scene snapshot
scene_compare_snapshot Compare two snapshots
scene_inspect_material_slots Material slot assignments
scene_inspect_mesh_topology Topology stats
scene_inspect_modifiers Modifier stack info
scene_rename_object Rename object by name
scene_hide_object Hide/show object in viewport
scene_show_all_objects Show all hidden objects
scene_isolate_object Isolate object (hide all others)
scene_camera_orbit Orbit viewport around target
scene_camera_focus Focus viewport on object
scene_get_custom_properties Get object metadata/custom properties
scene_set_custom_property Set/delete custom property on object
scene_get_hierarchy Get parent-child hierarchy
scene_get_bounding_box Get precise bounding box corners
scene_get_origin_info Get origin/pivot point info

Note: scene_get_constraints is now internal to scene_inspect(action="constraints").

Modeling Tools (`modeling_*`) — ✅

Object Mode operations for creating and transforming objects.

Tool Description Status
modeling_create_primitive Create cube, sphere, cylinder, etc.
modeling_transform_object Move, rotate, scale objects
modeling_add_modifier Add modifier to object
modeling_apply_modifier Apply (bake) modifier
modeling_list_modifiers List modifiers on object
modeling_convert_to_mesh Convert curve/text to mesh
modeling_join_objects Join multiple objects
modeling_separate_object Separate by loose parts/material
modeling_set_origin Set object origin point

Note: modeling_get_modifier_data is now internal to scene_inspect(action="modifier_data").

Lattice Deformation

Tool Description Status
lattice_create Create lattice fitted to object
lattice_bind Bind object to lattice deformer
lattice_edit_point Move lattice control points
lattice_get_points Get lattice point positions

Text Objects

Tool Description Status
text_create Create 3D text object
text_edit Modify text content and properties
text_to_mesh Convert text to mesh for export

Skin Modifier (Tubular Structures)

Tool Description Status
skin_create_skeleton Create skeleton for skin modifier
skin_set_radius Set skin radius at vertices

Mesh Tools (`mesh_*`) — ✅

Edit Mode operations for geometry manipulation.

Selection

Tool Description Status
mesh_select_all Select/deselect all geometry
mesh_select_by_index Select by vertex/edge/face index
mesh_select_linked Select connected geometry
mesh_select_more Grow selection
mesh_select_less Shrink selection
mesh_select_boundary Select boundary edges
mesh_select_loop Select edge loop
mesh_select_ring Select edge ring
mesh_select_by_location Select by 3D position

Note: Mesh introspection actions are consolidated under mesh_inspect (internal mesh_get_*).

Core Operations

Tool Description Status
mesh_extrude_region Extrude selected faces
mesh_delete_selected Delete selected geometry
mesh_fill_holes Fill holes with faces
mesh_bevel Bevel edges/vertices
mesh_loop_cut Add loop cuts
mesh_inset Inset faces
mesh_boolean Boolean operations
mesh_merge_by_distance Merge nearby vertices
mesh_subdivide Subdivide geometry

Transform & Geometry

Tool Description Status
mesh_transform_selected Move/rotate/scale selected geometry
mesh_bridge_edge_loops Bridge two edge loops
mesh_duplicate_selected Duplicate selected geometry

Deformation

Tool Description Status
mesh_smooth Smooth vertices
mesh_flatten Flatten to plane
mesh_randomize Randomize vertex positions
mesh_shrink_fatten Move along normals

Precision Tools

Tool Description Status
mesh_bisect Cut mesh with plane
mesh_edge_slide Slide edges along topology
mesh_vert_slide Slide vertices along edges
mesh_triangulate Convert to triangles
mesh_remesh_voxel Voxel remesh

Procedural

Tool Description Status
mesh_spin Spin/lathe geometry around axis
mesh_screw Create spiral/helix geometry
mesh_add_vertex Add single vertex
mesh_add_edge_face Create edge/face from selection

Vertex Groups

Tool Description Status
mesh_list_groups List vertex groups
mesh_create_vertex_group Create new vertex group
mesh_assign_to_group Assign vertices to group
mesh_remove_from_group Remove vertices from group

Edge Weights & Creases

Tool Description Status
mesh_edge_crease Set crease weight for subdivision
mesh_bevel_weight Set bevel weight for bevel modifier
mesh_mark_sharp Mark/clear sharp edges

Cleanup & Optimization

Tool Description Status
mesh_dissolve Dissolve vertices/edges/faces (limited dissolve)
mesh_tris_to_quads Convert triangles to quads
mesh_normals_make_consistent Recalculate normals
mesh_decimate Reduce polycount on selection

Knife & Cut

Tool Description Status
mesh_knife_project Project cut from selected geometry
mesh_rip Rip/tear geometry at selection
mesh_split Split selection from mesh
mesh_edge_split Split mesh at selected edges

Symmetry & Fill

Tool Description Status
mesh_symmetrize Make mesh symmetric
mesh_grid_fill Fill boundary with quad grid
mesh_poke_faces Poke faces (add center vertex)
mesh_beautify_fill Rearrange triangles uniformly
mesh_mirror Mirror selected geometry
mesh_set_proportional_edit Enable soft selection falloff

Curve Tools (`curve_*`) — ✅

Curve creation and conversion.

Tool Description Status
curve_create Create Bezier/NURBS/Path/Circle curve
curve_to_mesh Convert curve to mesh
curve_get_data Get curve splines and settings

Collection Tools (`collection_*`) — ✅

Collection management and hierarchy.

Tool Description Status
collection_list List all collections
collection_list_objects List objects in collection
collection_manage Create/delete/move collections

Material Tools (`material_*`) — ✅

Material creation and assignment.

Tool Description Status
material_list List all materials
material_list_by_object List materials on object
material_create Setup PBR materials
material_assign Assign to objects/faces
material_set_params Adjust roughness, metallic, etc.
material_set_texture Bind image textures
material_inspect_nodes Inspect shader node graph

UV Tools (`uv_*`) — ✅

UV mapping operations.

Tool Description Status
uv_list_maps List UV maps on object
uv_unwrap Smart UV Project / Cube Projection
uv_pack_islands Pack UV islands
uv_create_seam Mark/clear UV seams

System Tools (`system_*`) — ✅

Global project-level operations.

Tool Description Status
system_set_mode High-level mode switching
system_undo Safe undo for AI
system_redo Safe redo for AI
system_save_file Save .blend file
system_new_file Create new file
system_snapshot Quick save/restore checkpoints

Export Tools (`export_*`) — ✅

File export operations.

Tool Description Status
export_glb Export to GLB format
export_fbx Export to FBX format
export_obj Export to OBJ format

Import Tools (`import_*`) — ✅

File import operations.

Tool Description Status
import_obj Import OBJ file
import_fbx Import FBX file
import_glb Import GLB/GLTF file
import_image_as_plane Import image as textured plane (reference)

Baking Tools (`bake_*`) — ✅

Texture baking for game dev workflows.

Tool Description Status
bake_normal_map Bake normal map (high-to-low or self)
bake_ao Bake ambient occlusion map
bake_combined Bake full render to texture
bake_diffuse Bake diffuse/albedo color

Extraction Tools (`extraction_*`) — ✅

Analysis tools for the Automatic Workflow Extraction System. Enables deep topology analysis, component detection, symmetry detection, and multi-angle rendering for LLM Vision integration.

Tool Description Status
extraction_deep_topology Deep topology analysis with feature detection
extraction_component_separate Separate mesh into loose parts
extraction_detect_symmetry Detect X/Y/Z symmetry planes
extraction_edge_loop_analysis Analyze edge loops and patterns
extraction_face_group_analysis Analyze face groups by normal/height
extraction_render_angles Multi-angle renders for LLM Vision

Metaball Tools (`metaball_*`) — ✅

Organic blob primitives for medical/biological modeling.

Tool Description Status
metaball_create Create metaball object
metaball_add_element Add element (ball, capsule, ellipsoid)
metaball_to_mesh Convert metaball to mesh

Macro Tools (`macro_*`) — 🚧

High-level abstractions where one command executes hundreds of Blender operations.

Tool Description Status
macro_organify Convert blockouts to organic shapes 🚧
macro_create_phone_base Generate smartphone chassis 🚧
macro_human_blockout Generate proportional human mesh 🚧
macro_retopologize Automate low-poly conversion 🚧
macro_panel_cut Hard-surface panel cutting 🚧
macro_lowpoly_convert Reduce polycount preserving silhouette 🚧
macro_cleanup_all Scene-wide mesh cleanup 🚧

Sculpting Tools (`sculpt_*`) — ✅

Organic shaping and sculpt workflows.

Core Brushes

Tool Description Status
sculpt_auto High-level sculpt operation (mesh filters)
sculpt_brush_smooth Smooth brush
sculpt_brush_grab Grab brush
sculpt_brush_crease Crease brush

Organic Brushes

Tool Description Status
sculpt_brush_clay Add clay-like material
sculpt_brush_inflate Inflate/deflate areas
sculpt_brush_blob Create organic bulges
sculpt_brush_snake_hook Pull long tendrils (vessels, nerves)
sculpt_brush_draw Basic sculpt draw
sculpt_brush_pinch Pinch geometry together

Dynamic Topology

Tool Description Status
sculpt_enable_dyntopo Enable dynamic topology
sculpt_disable_dyntopo Disable dynamic topology
sculpt_dyntopo_flood_fill Apply detail level to entire mesh

Armature Tools (`armature_*`) — ✅

Skeletal rigging and animation.

Tool Description Status
armature_create Create armature with initial bone
armature_add_bone Add bone to armature
armature_bind Bind mesh to armature (auto weights)
armature_pose_bone Pose armature bone
armature_weight_paint_assign Assign weights to vertex group
armature_get_data Get armature bones and hierarchy

🤖 Router Supervisor ✅

Intelligent Router acting as supervisor over LLM tool calls - not just an "intent matcher". Intercepts, corrects, expands, and overrides tool calls before execution.

Status:Complete | All 6 Phases Done | Test counts vary — see 🧪 Testing for up-to-date numbers

Documentation: See _docs/_ROUTER/ for full documentation including Quick Start, Configuration, Patterns, and API Reference.

All Phases Complete ✅

Phase Components Status
Phase 1: Foundation Directory structure, Domain entities, Interfaces, Metadata loader (119 JSON files), Config
Phase 2: Analysis Tool interceptor, Scene context analyzer, Geometry pattern detector, Proportion calculator
Phase 3: Engines Tool correction, Tool override, Workflow expansion, Error firewall, Intent classifier (LaBSE)
Phase 4: Integration SupervisorRouter orchestrator, MCP integration, Logging & telemetry
Phase 5: Workflows Phone workflow, Tower workflow, Screen cutout workflow, Custom YAML workflows
Phase 6: Testing & Docs E2E test suite (see 🧪 Testing), Complete documentation (6 guides)

Key Features

Feature Description
LLM Supervisor Intercepts and corrects LLM tool calls before execution
Scene-Aware Analyzes Blender state via RPC for informed decisions
Pattern Detection Recognizes 9 patterns: tower, phone, table, pillar, wheel, box, sphere, cylinder
Auto-Correction Fixes mode violations, missing selection, invalid parameters
Workflow Expansion Single tool → complete multi-step workflow
Error Firewall Blocks/fixes invalid operations before they crash
100% Offline No external API calls - LaBSE runs locally (~1.8GB RAM)
Multilingual LaBSE supports 109 languages for intent classification
Semantic Matching Match workflows by meaning, not just keywords (LaBSE embeddings)
Generalization Use similar workflow when exact match missing
Feedback Learning Improve matching from user corrections
LanceDB Vector Store O(log N) HNSW search with metadata filtering
Confidence Adaptation HIGH/MEDIUM/LOW confidence → full/filtered/core workflow
Parametric Variables $variable syntax with defaults and modifiers for dynamic params

Workflow-First Quick Start (recommended)

Use this when you want the LLM to prefer existing YAML workflows and only fall back to manual tool-calling when no workflow matches.

1) Optional: import external workflow YAML/JSON
   workflow_catalog(action="import", filepath="/path/to/workflow.yaml")
   workflow_catalog(action="import", content="<yaml or json>", content_type="yaml")
   workflow_catalog(action="import_init", content_type="json", source_name="chair.json", total_chunks=2)
   workflow_catalog(action="import_append", session_id="...", chunk_data="...", chunk_index=0)
   workflow_catalog(action="import_append", session_id="...", chunk_data="...", chunk_index=1)
   workflow_catalog(action="import_finalize", session_id="...", overwrite=true)
   - if status == "needs_input": repeat with overwrite=true or overwrite=false

2) Optional: preview likely workflow matches
   workflow_catalog(action="search", query="<your prompt>", top_k=5, threshold=0.0)

3) Set the goal (mandatory)
   router_set_goal(goal="<your prompt including modifiers>")

4) Handle Router response
   - status == "needs_input": call router_set_goal(goal, resolved_params={...})
   - status == "ready": proceed (workflow executes / expands into tool calls)
   - status == "no_match": switch to manual tool-calling
   - status == "error": router malfunction (fail-fast). Check logs and open a GitHub issue.

Example: LLM sends mesh tool in wrong mode

LLM: mesh_extrude(depth=0.5)  # In OBJECT mode, no selection

Router detects:
  - Mode: OBJECT (mesh tool needs EDIT)
  - Selection: None (extrude needs faces)
  - Pattern: phone_like

Router outputs:
  1. system_set_mode(mode="EDIT")
  2. mesh_select(action="all", mode="FACE")
  3. mesh_inset(thickness=0.03)
  4. mesh_extrude(depth=-0.02)
  5. system_set_mode(mode="OBJECT")

Result: Screen cutout created instead of crash!

Semantic Workflow Matching

User: "zrób krzesło" (make a chair)

Router behavior:
  → LaBSE semantic similarity search
  → Found: table_workflow (0.72), tower_workflow (0.45)
  → Uses table_workflow with inherited proportions
  → Chair has proper leg ratios from table, vertical proportions from tower

Parametric Variables

# In workflow YAML:
defaults:
  leg_angle: 0.32        # A-frame legs (default)

modifiers:
  "straight legs":
    leg_angle: 0         # Override for vertical legs
  "proste nogi":         # Polish support
    leg_angle: 0

steps:
  - tool: modeling_transform_object
    params:
      rotation: [0, "$leg_angle", 0]  # Uses variable
User: "table with straight legs"
→ Modifier "straight legs" matches
→ leg_angle = 0 (vertical legs instead of A-frame)

User: "stół z proste nogi"
→ Polish modifier matches
→ Same result: vertical legs

Configuration Presets

from server.router.infrastructure.config import RouterConfig

# Default (recommended)
config = RouterConfig()

# Strict mode (no auto-fixes)
config = RouterConfig(auto_mode_switch=False, auto_selection=False)

# Performance mode (longer cache)
config = RouterConfig(cache_ttl_seconds=2.0, log_decisions=False)

🧠 LLM Context Optimization

Unified "mega tools" that consolidate multiple related operations to reduce LLM context usage.
Mega tools are wrappers only; action-level handlers live as internal functions backed by Blender addon RPC.
Standalone MCP tools are exposed only where explicitly listed.
Router can still execute internal actions via handler mappings and per-tool JSON metadata.

Mega Tools (LLM Context Optimization)

Scene Mega Tools

Mega Tool Actions Savings Status
scene_context mode, selection -1
scene_create light, camera, empty -2
scene_inspect object, topology, modifiers, materials, constraints, modifier_data -5

Mesh Mega Tools

Mega Tool Actions Savings Status
mesh_select all, none, linked, more, less, boundary -4
mesh_select_targeted by_index, loop, ring, by_location -3
mesh_inspect vertices, edges, faces, uvs, normals, attributes, shape_keys, group_weights, summary -7

Total: 28 tools → 6 mega tools (-22 definitions for LLM context).

mesh_inspect.summary sources (recommended): scene_inspect(topology), uv_list_maps, mesh_get_shape_keys, mesh_get_loop_normals, mesh_list_groups, modeling_list_modifiers.


🚀 Quick Start

1. Install the Blender Addon

  1. Download blender_ai_mcp.zip from the Releases Page.
  2. Open Blender -> Edit -> Preferences -> Add-ons.
  3. Click Install... and select the zip file.
  4. Enable the addon. It will start a local server on port 8765.

2. Configure your MCP Client (Cline / Claude Code / Codex CLI)

We recommend using Docker to run the MCP Server.

Cline / Claude Code — cline_mcp_settings.json (macOS/Windows)
{
  "mcpServers": {
    "blender-ai-mcp": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-e", "BLENDER_RPC_HOST=host.docker.internal",
        "ghcr.io/patrykiti/blender-ai-mcp:latest"
      ],
      "disabled": false,
      "autoApprove": [
        "scene_list_objects",
        "scene_delete_object",
        "scene_clean_scene",
        "scene_duplicate_object",
        "scene_set_active_object",
        "scene_get_viewport",
        "scene_set_mode",
        "scene_context",
        "scene_create",
        "scene_inspect",
        "scene_snapshot_state",
        "scene_compare_snapshot",
        "scene_rename_object",
        "scene_hide_object",
        "scene_show_all_objects",
        "scene_isolate_object",
        "scene_camera_orbit",
        "scene_camera_focus",
        "scene_get_custom_properties",
        "scene_set_custom_property",
        "scene_get_hierarchy",
        "scene_get_bounding_box",
        "scene_get_origin_info",
        "collection_list",
        "collection_list_objects",
        "collection_manage",
        "material_list",
        "material_list_by_object",
        "material_create",
        "material_assign",
        "material_set_params",
        "material_set_texture",
        "material_inspect_nodes",
        "uv_list_maps",
        "uv_unwrap",
        "uv_pack_islands",
        "uv_create_seam",
        "modeling_create_primitive",
        "modeling_transform_object",
        "modeling_add_modifier",
        "modeling_apply_modifier",
        "modeling_convert_to_mesh",
        "modeling_join_objects",
        "modeling_separate_object",
        "modeling_set_origin",
        "modeling_list_modifiers",
        "mesh_select",
        "mesh_select_targeted",
        "mesh_inspect",
        "mesh_delete_selected",
        "mesh_extrude_region",
        "mesh_fill_holes",
        "mesh_bevel",
        "mesh_loop_cut",
        "mesh_inset",
        "mesh_boolean",
        "mesh_merge_by_distance",
        "mesh_subdivide",
        "mesh_smooth",
        "mesh_flatten",
        "mesh_list_groups",
        "mesh_randomize",
        "mesh_shrink_fatten",
        "mesh_create_vertex_group",
        "mesh_assign_to_group",
        "mesh_remove_from_group",
        "mesh_bisect",
        "mesh_edge_slide",
        "mesh_vert_slide",
        "mesh_triangulate",
        "mesh_remesh_voxel",
        "mesh_transform_selected",
        "mesh_bridge_edge_loops",
        "mesh_duplicate_selected",
        "mesh_spin",
        "mesh_screw",
        "mesh_add_vertex",
        "mesh_add_edge_face",
        "mesh_edge_crease",
        "mesh_bevel_weight",
        "mesh_mark_sharp",
        "mesh_dissolve",
        "mesh_tris_to_quads",
        "mesh_normals_make_consistent",
        "mesh_decimate",
        "mesh_knife_project",
        "mesh_rip",
        "mesh_split",
        "mesh_edge_split",
        "mesh_symmetrize",
        "mesh_grid_fill",
        "mesh_poke_faces",
        "mesh_beautify_fill",
        "mesh_mirror",
        "curve_create",
        "curve_to_mesh",
        "curve_get_data",
        "text_create",
        "text_edit",
        "text_to_mesh",
        "export_glb",
        "export_fbx",
        "export_obj",
        "sculpt_auto",
        "sculpt_brush_smooth",
        "sculpt_brush_grab",
        "sculpt_brush_crease",
        "sculpt_brush_clay",
        "sculpt_brush_inflate",
        "sculpt_brush_blob",
        "sculpt_brush_snake_hook",
        "sculpt_brush_draw",
        "sculpt_brush_pinch",
        "sculpt_enable_dyntopo",
        "sculpt_disable_dyntopo",
        "sculpt_dyntopo_flood_fill",
        "metaball_create",
        "metaball_add_element",
        "metaball_to_mesh",
        "skin_create_skeleton",
        "skin_set_radius",
        "lattice_create",
        "lattice_bind",
        "lattice_edit_point",
        "lattice_get_points",
        "mesh_set_proportional_edit",
        "system_set_mode",
        "system_undo",
        "system_redo",
        "system_save_file",
        "system_new_file",
        "system_snapshot",
        "bake_normal_map",
        "bake_ao",
        "bake_combined",
        "bake_diffuse",
        "import_obj",
        "import_fbx",
        "import_glb",
        "import_image_as_plane",
        "extraction_deep_topology",
        "extraction_component_separate",
        "extraction_detect_symmetry",
        "extraction_edge_loop_analysis",
        "extraction_face_group_analysis",
        "extraction_render_angles",
        "armature_create",
        "armature_add_bone",
        "armature_bind",
        "armature_pose_bone",
        "armature_weight_paint_assign",
        "armature_get_data",
        "workflow_catalog",
        "router_set_goal",
        "router_get_status",
        "router_clear_goal"
      ]
    }
  }
}
Cline / Claude Code — cline_mcp_settings.json (Linux)
{
  "mcpServers": {
    "blender-ai-mcp": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "--network", "host",
        "-e", "BLENDER_RPC_HOST=127.0.0.1",
        "ghcr.io/patrykiti/blender-ai-mcp:latest"
      ],
      "disabled": false,
      "autoApprove": [
        "scene_list_objects",
        "scene_delete_object",
        "scene_clean_scene",
        "scene_duplicate_object",
        "scene_set_active_object",
        "scene_get_viewport",
        "scene_set_mode",
        "scene_context",
        "scene_create",
        "scene_inspect",
        "scene_snapshot_state",
        "scene_compare_snapshot",
        "scene_rename_object",
        "scene_hide_object",
        "scene_show_all_objects",
        "scene_isolate_object",
        "scene_camera_orbit",
        "scene_camera_focus",
        "scene_get_custom_properties",
        "scene_set_custom_property",
        "scene_get_hierarchy",
        "scene_get_bounding_box",
        "scene_get_origin_info",
        "collection_list",
        "collection_list_objects",
        "collection_manage",
        "material_list",
        "material_list_by_object",
        "material_create",
        "material_assign",
        "material_set_params",
        "material_set_texture",
        "material_inspect_nodes",
        "uv_list_maps",
        "uv_unwrap",
        "uv_pack_islands",
        "uv_create_seam",
        "modeling_create_primitive",
        "modeling_transform_object",
        "modeling_add_modifier",
        "modeling_apply_modifier",
        "modeling_convert_to_mesh",
        "modeling_join_objects",
        "modeling_separate_object",
        "modeling_set_origin",
        "modeling_list_modifiers",
        "mesh_select",
        "mesh_select_targeted",
        "mesh_inspect",
        "mesh_delete_selected",
        "mesh_extrude_region",
        "mesh_fill_holes",
        "mesh_bevel",
        "mesh_loop_cut",
        "mesh_inset",
        "mesh_boolean",
        "mesh_merge_by_distance",
        "mesh_subdivide",
        "mesh_smooth",
        "mesh_flatten",
        "mesh_list_groups",
        "mesh_randomize",
        "mesh_shrink_fatten",
        "mesh_create_vertex_group",
        "mesh_assign_to_group",
        "mesh_remove_from_group",
        "mesh_bisect",
        "mesh_edge_slide",
        "mesh_vert_slide",
        "mesh_triangulate",
        "mesh_remesh_voxel",
        "mesh_transform_selected",
        "mesh_bridge_edge_loops",
        "mesh_duplicate_selected",
        "mesh_spin",
        "mesh_screw",
        "mesh_add_vertex",
        "mesh_add_edge_face",
        "mesh_edge_crease",
        "mesh_bevel_weight",
        "mesh_mark_sharp",
        "mesh_dissolve",
        "mesh_tris_to_quads",
        "mesh_normals_make_consistent",
        "mesh_decimate",
        "mesh_knife_project",
        "mesh_rip",
        "mesh_split",
        "mesh_edge_split",
        "mesh_symmetrize",
        "mesh_grid_fill",
        "mesh_poke_faces",
        "mesh_beautify_fill",
        "mesh_mirror",
        "curve_create",
        "curve_to_mesh",
        "curve_get_data",
        "text_create",
        "text_edit",
        "text_to_mesh",
        "export_glb",
        "export_fbx",
        "export_obj",
        "sculpt_auto",
        "sculpt_brush_smooth",
        "sculpt_brush_grab",
        "sculpt_brush_crease",
        "sculpt_brush_clay",
        "sculpt_brush_inflate",
        "sculpt_brush_blob",
        "sculpt_brush_snake_hook",
        "sculpt_brush_draw",
        "sculpt_brush_pinch",
        "sculpt_enable_dyntopo",
        "sculpt_disable_dyntopo",
        "sculpt_dyntopo_flood_fill",
        "metaball_create",
        "metaball_add_element",
        "metaball_to_mesh",
        "skin_create_skeleton",
        "skin_set_radius",
        "lattice_create",
        "lattice_bind",
        "lattice_edit_point",
        "lattice_get_points",
        "mesh_set_proportional_edit",
        "system_set_mode",
        "system_undo",
        "system_redo",
        "system_save_file",
        "system_new_file",
        "system_snapshot",
        "bake_normal_map",
        "bake_ao",
        "bake_combined",
        "bake_diffuse",
        "import_obj",
        "import_fbx",
        "import_glb",
        "import_image_as_plane",
        "extraction_deep_topology",
        "extraction_component_separate",
        "extraction_detect_symmetry",
        "extraction_edge_loop_analysis",
        "extraction_face_group_analysis",
        "extraction_render_angles",
        "armature_create",
        "armature_add_bone",
        "armature_bind",
        "armature_pose_bone",
        "armature_weight_paint_assign",
        "armature_get_data",
        "workflow_catalog",
        "router_set_goal",
        "router_get_status",
        "router_clear_goal"
      ]
    }
  }
}
GitHub Copilot CLI

Copilot uses a slightly different config structure. Ensure you map the temp directory properly if you want file outputs.

{
  "mcpServers": {
    "blender-ai-mcp": {
      "type": "local",
      "command": "docker",
      "tools": [
        "*"
      ],
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "/tmp:/tmp",
        "ghcr.io/patrykiti/blender-ai-mcp:latest"
      ],
      "env": {
        "BLENDER_AI_TMP_INTERNAL_DIR": "/tmp",
        "BLENDER_AI_TMP_EXTERNAL_DIR": "/tmp",
        "BLENDER_RPC_HOST": "host.docker.internal"
      }
    }
  }
}
Codex CLI — ~/.codex/config.toml

Create/update ~/.codex/config.toml:

[mcp_servers.blender-ai-mcp]
command = "docker"
# Optional
args = [
  "run",
  "-i",
  "-v",
  "/tmp:/tmp",
  "-e",
  "BLENDER_AI_TMP_INTERNAL_DIR=/tmp",
  "-e",
  "BLENDER_AI_TMP_EXTERNAL_DIR=/tmp",
  "-e",
  "ROUTER_ENABLED=true",
  "-e",
  "LOG_LEVEL=DEBUG",
  "-e",
  "BLENDER_RPC_HOST=host.docker.internal",
  "blender-ai-mcp:latest"
]

# Optional: propagate additional env vars to the MCP server.
# A default whitelist of env vars will be propagated to the MCP server.
# https://github.com/openai/codex/blob/main/codex-rs/rmcp-client/src/utils.rs#L82
env = {}

enabled_tools = [
  "scene_list_objects",
  "scene_delete_object",
  "scene_clean_scene",
  "scene_duplicate_object",
  "scene_set_active_object",
  "scene_get_viewport",
  "scene_set_mode",
  "scene_context",
  "scene_create",
  "scene_inspect",
  "scene_snapshot_state",
  "scene_compare_snapshot",
  "scene_rename_object",
  "scene_hide_object",
  "scene_show_all_objects",
  "scene_isolate_object",
  "scene_camera_orbit",
  "scene_camera_focus",
  "scene_get_custom_properties",
  "scene_set_custom_property",
  "scene_get_hierarchy",
  "scene_get_bounding_box",
  "scene_get_origin_info",
  "collection_list",
  "collection_list_objects",
  "collection_manage",
  "material_list",
  "material_list_by_object",
  "material_create",
  "material_assign",
  "material_set_params",
  "material_set_texture",
  "material_inspect_nodes",
  "uv_list_maps",
  "uv_unwrap",
  "uv_pack_islands",
  "uv_create_seam",
  "modeling_create_primitive",
  "modeling_transform_object",
  "modeling_add_modifier",
  "modeling_apply_modifier",
  "modeling_convert_to_mesh",
  "modeling_join_objects",
  "modeling_separate_object",
  "modeling_set_origin",
  "modeling_list_modifiers",
  "mesh_select",
  "mesh_select_targeted",
  "mesh_inspect",
  "mesh_delete_selected",
  "mesh_extrude_region",
  "mesh_fill_holes",
  "mesh_bevel",
  "mesh_loop_cut",
  "mesh_inset",
  "mesh_boolean",
  "mesh_merge_by_distance",
  "mesh_subdivide",
  "mesh_smooth",
  "mesh_flatten",
  "mesh_list_groups",
  "mesh_randomize",
  "mesh_shrink_fatten",
  "mesh_create_vertex_group",
  "mesh_assign_to_group",
  "mesh_remove_from_group",
  "mesh_bisect",
  "mesh_edge_slide",
  "mesh_vert_slide",
  "mesh_triangulate",
  "mesh_remesh_voxel",
  "mesh_transform_selected",
  "mesh_bridge_edge_loops",
  "mesh_duplicate_selected",
  "mesh_spin",
  "mesh_screw",
  "mesh_add_vertex",
  "mesh_add_edge_face",
  "mesh_edge_crease",
  "mesh_bevel_weight",
  "mesh_mark_sharp",
  "mesh_dissolve",
  "mesh_tris_to_quads",
  "mesh_normals_make_consistent",
  "mesh_decimate",
  "mesh_knife_project",
  "mesh_rip",
  "mesh_split",
  "mesh_edge_split",
  "mesh_symmetrize",
  "mesh_grid_fill",
  "mesh_poke_faces",
  "mesh_beautify_fill",
  "mesh_mirror",
  "curve_create",
  "curve_to_mesh",
  "curve_get_data",
  "text_create",
  "text_edit",
  "text_to_mesh",
  "export_glb",
  "export_fbx",
  "export_obj",
  "sculpt_auto",
  "sculpt_brush_smooth",
  "sculpt_brush_grab",
  "sculpt_brush_crease",
  "sculpt_brush_clay",
  "sculpt_brush_inflate",
  "sculpt_brush_blob",
  "sculpt_brush_snake_hook",
  "sculpt_brush_draw",
  "sculpt_brush_pinch",
  "sculpt_enable_dyntopo",
  "sculpt_disable_dyntopo",
  "sculpt_dyntopo_flood_fill",
  "metaball_create",
  "metaball_add_element",
  "metaball_to_mesh",
  "skin_create_skeleton",
  "skin_set_radius",
  "lattice_create",
  "lattice_bind",
  "lattice_edit_point",
  "lattice_get_points",
  "mesh_set_proportional_edit",
  "system_set_mode",
  "system_undo",
  "system_redo",
  "system_save_file",
  "system_new_file",
  "system_snapshot",
  "bake_normal_map",
  "bake_ao",
  "bake_combined",
  "bake_diffuse",
  "import_obj",
  "import_fbx",
  "import_glb",
  "import_image_as_plane",
  "extraction_deep_topology",
  "extraction_component_separate",
  "extraction_detect_symmetry",
  "extraction_edge_loop_analysis",
  "extraction_face_group_analysis",
  "extraction_render_angles",
  "armature_create",
  "armature_add_bone",
  "armature_bind",
  "armature_pose_bone",
  "armature_weight_paint_assign",
  "armature_get_data",
  "workflow_catalog",
  "router_set_goal",
  "router_get_status",
  "router_clear_goal"
]

⚠️ Important Network Configuration:

  • macOS/Windows: Use host.docker.internal (as shown in the first config). The --network host option does NOT work on Docker Desktop for Mac/Windows.
  • Linux: Use --network host with 127.0.0.1 (as shown in the second config).
  • Troubleshooting: If the MCP server starts but cannot connect to Blender (timeout errors), ensure Blender is running with the addon enabled and that port 8765 is not blocked.
Viewport Output Modes & Temp Directory Mapping

The scene_get_viewport tool supports multiple output modes via the output_mode argument:

  • IMAGE (default): returns a FastMCP Image resource (best for Cline / clients with native image support).
  • BASE64: returns the raw base64-encoded JPEG string for direct Vision-module consumption.
  • FILE: writes the image to a temp directory and returns a message with host-visible file paths.
  • MARKDOWN: writes the image and returns rich markdown with an inline data: URL plus host-visible paths.

When running in Docker, map the internal temp directory to a host folder and configure env vars:

# Example volume & env mapping
docker run -i --rm \
  -v /host/tmp/blender-ai-mcp:/tmp/blender-ai-mcp \
  -e BLENDER_RPC_HOST=host.docker.internal \
  -e BLENDER_AI_TMP_INTERNAL_DIR=/tmp/blender-ai-mcp \
  -e BLENDER_AI_TMP_EXTERNAL_DIR=/host/tmp/blender-ai-mcp \
  ghcr.io/patrykiti/blender-ai-mcp:latest

📈 Star History

Star History Chart


🤝 Contributing

We welcome contributions! Please read CONTRIBUTING.md to understand our Clean Architecture standards before submitting a Pull Request.

🧩 Community & Support

👨‍💻 Author

Patryk Ciechański

License

This project is licensed under the Business Source License 1.1 (BSL 1.1)
with a custom Additional Use Grant authored by Patryk Ciechański (PatrykIti).

The license automatically converts to Apache 2.0 on 2029-12-01.

For the full license text, see: LICENSE

Change License text (Apache 2.0): LICENSE-APACHE-2.0.txt

Yorumlar (0)

Sonuc bulunamadi