blender-mcp-ultra
# blender-mcp-ultra
**MCP server untuk Blender** — pemodelan, material, animasi, proyek bertahap, dan review visual berbasis bukti.
Kendalikan Blender dari asisten AI mana pun (Claude, Cursor, Windsurf, opencode)
lewat Model Context Protocol (MCP), atau dari chat internal Blender dengan LLM
OpenAI-compatible. Tool statis dihasilkan dari spesifikasi `mcp_tools.py` untuk
FastMCP dan bridge STDIO; katalog registry tambahan memiliki discovery dan
signature sendiri.
## Demo End-to-End (LLM Nyata → MCP → Blender Headless)
Demo menggunakan model **`gpt-6-astra`** untuk mengendalikan Blender melalui
tool MCP: menyusun scene, mengatur material dan pencahayaan, lalu merender
istana medieval saat sunset.

Satu preview di atas menampilkan hasil render beserta workspace Blender 5.2.0
LTS. Screenshot berasal dari workflow pengguna; bukan sertifikasi bahwa semua
tool, jalur headless, atau kualitas visual telah diverifikasi.
Catatan demo headless terdahulu tetap tersedia di [`DEMO_LLM.md`](DEMO_LLM.md);
model, scene, jumlah aksi, dan lingkungan pada catatan historis tersebut berbeda
dari preview `gpt-6-astra` ini.
## Fitur
- **Tool MCP statis** dari `mcp_tools.py` → FastMCP + STDIO, serta bridge katalog registry
- **Alur "dari nol" per domain**: `model_from_scratch`, `colorize_from_scratch`,
`rig_from_scratch`, `animate_from_scratch`
- **Modeling**: primitive, modifier, bmesh (bevel/extrude/inset/loop cut/merge),
kurva, teks 3D, screw/lathe; dukungan background bergantung operasi dan build
- **Material**: PBR multi-map/packed map, normal OpenGL/DirectX, pemetaan fisik,
displacement terbatas, micro-bump dan imperfection terarah
- **Rigging**: armature + bone collections (4.0+), IK chain, 20+ constraint,
vertex group/weight, auto-rig, pose reset
- **Animation**: keyframe, animasi loc/rot/scale, action, interpolasi,
shape key, rigid body, gravitasi
- **Geometry Nodes**: modifier, node, scatter instance dengan jumlah eksplisit
- **UV/Printing/Batch/Analysis/IO**: unwrap dan packing island, density piksel/meter,
bake Cycles, manifold, batch, ringkasan scene, impor/ekspor sesuai format dan build
- **Proyek persisten**: manifest, tahapan macro/meso/micro, checkpoint `.blend`,
komponen linked ber-anchor, provenance aset, dan review render berulang
- **Kamera/Render**: framing fisik, HDRI, sky, compositor, render pass dan EXR
dengan pelaporan kemampuan engine/build, termasuk perubahan API Blender 5
- **Keamanan**: validasi AST, pelaporan error eksekusi asli, rate limiting
- **Multi-provider LLM**: OpenAI, Anthropic, Google, DeepSeek, OpenRouter, Ollama
## Mulai Cepat
### Prasyarat
- Python 3.10+
- Blender 4.2 LTS (atau 5.x) — addon memakai bone collections & EEVEE Next
- Klien MCP (Claude Desktop, Cursor, opencode, …)
### Pasang addon Blender
```bash
# Deteksi otomatis versi Blender, salin paket addon kanonik
python scripts/install.py # Linux/macOS/Windows
# atau pakai ekstensi .blender_manifest.toml langsung di Preferences > Add-ons
```
Lalu di Blender: **Edit → Preferences → Add-ons → aktifkan "blender-mcp-ultra"**.
Addon membuka bridge socket TCP `:9876`; server MCP embedded/SSE `:9879` bersifat
opsional dan memerlukan dependensinya. Proses MCP eksternal dapat memakai socket.
Setelah memperbarui salinan addon yang terpasang, **restart Blender dan proses
MCP/klien MCP** agar modul Python dan daftar tool tidak tetap memakai versi lama.
Mengedit checkout sumber saja tidak memperbarui addon yang sedang berjalan.
### Konfigurasi klien MCP
```json
{
"mcpServers": {
"blender": {
"command": "python",
"args": ["-m", "blender_mcp.server"],
"env": {
"BLENDER_HOST": "localhost",
"BLENDER_PORT": "9876"
}
}
}
}
```
Transport diatur `BLENDER_MCP_MODE` (`stdio` default, atau `sse` untuk :9879).
### Uji cepat
```bash
pip install -e .
# Suite scene-safe: tidak menjalankan tes integrasi/e2e yang dapat mengubah scene aktif
python -m pytest -q --ignore=tests/e2e --ignore=tests/integration --ignore=tests/test_e2e_socket.py
# Contoh socket berikut MENAMBAH objek/material: gunakan scene uji terpisah, bukan pekerjaan aktif
python - <<'EOF'
from blender_connection import BlenderConnection
c = BlenderConnection(); c.connect()
print(c.send_command("create_object", {"type": "CUBE", "name": "Tes"}))
print(c.send_command("create_material", {"name": "Merah", "color": [1, 0, 0, 1]}))
EOF
```
## Contoh Tool
Nama tool statis datar (bukan namespace bertitik fiktif); signature-nya ada di
`mcp_tools.py`. Helper scene/registry tambahan diekspos oleh bridge server:
| Domain | Tool |
|---|---|
| Modeling | `create_object`, `transform_object`, `duplicate_object`, `join_objects`, `add_modifier`, `subdivide_mesh`, `loop_cut`, `extrude_face`, `inset_face`, `merge_by_distance`, `clean_mesh`, `create_text`, `create_curve`, `create_screw_profile`, `model_from_scratch` |
| Coloring | `create_material`, `assign_material`, `set_color`, `set_emission`, `set_transparency`, `add_shader_node`, `connect_shader_nodes`, `set_node_value`, `create_image_texture`, `assign_image_texture`, `add_vertex_color`, `colorize_from_scratch` |
| Animation | `insert_keyframe`, `keyframe_animation`, `animate_location`, `animate_rotation`, `animate_scale`, `set_keyframe_interpolation`, `create_action`, `add_shape_key`, `add_rigid_body`, `set_gravity`, `set_render_range`, `animate_from_scratch` |
| Rigging | `create_armature`, `add_bone`, `mirror_bones`, `setup_ik_chain`, `add_constraint`, `add_vertex_group`, `assign_vertex_weights`, `auto_rig_weight`, `add_armature_modifier`, `reset_pose`, `rig_from_scratch` |
| Geometry Nodes | `add_geometry_nodes_modifier`, `gn_add_node`, `scatter_instances`, `list_gn_modifiers` |
| Scene/Render | `create_camera`, `set_camera_target`, `create_light`, `setup_three_point_lighting`, `set_render_engine`, `set_render_samples`, `set_render_resolution`, `set_cycles_device`, `render_frame`, `scene_summary`, `get_scene_graph`, `align_objects`, `measure`, `find_objects` |
| UV/Texture | `add_uv_map`, `unwrap_object`, `pack_uv_islands`, `measure_texel_density`, `texel_density`, `bake_texture` |
| Batch/Analysis | `batch_rename`, `batch_delete_by_type`, `apply_transforms_all`, `mesh_analysis`, `get_objects_summary`, `get_object_detail_summary` |
| Printing | `check_manifold`, `set_dimensions_mm`, `add_wall_thickness` |
| IO | `export_scene`, `export_selected`, `import_file`, `list_export_formats` |
Untuk katalog tambahan `src/tools/**`, panggil `list_registry_tools`, lalu
`describe_registry_tool` sebelum `call_registry_tool`. Nama bertitik yang benar
hanya nama yang dikembalikan katalog; jangan menebak alias untuk tool statis.
Kedua permukaan tidak identik dan tidak semua tool statis ada di registry.
`run_batch` menjalankan operasi berurutan dengan **upaya** rollback, bukan jaminan
transaksi yang mengembalikan setiap datablock persis seperti semula.
## Alur Material, Detail, dan Review
### PBR berskala fisik
`validate_texture_set` memeriksa file, resolusi dan deklarasi channel sebelum
`create_pbr_material_from_textures`. Map tersedia untuk `base_color`, `roughness`,
`metallic`, `normal`, `height`, `ao`, `opacity`, dan `emission`. Warna/emission
memakai sRGB; map data memakai Non-Color. Packed map mendukung `ORM`/`ARM`
(AO=R, roughness=G, metallic=B), `RMA`, `MRA`, atau `packed_channels` eksplisit
untuk role AO/roughness/metallic/height/opacity ke R/G/B/A. Jangan memasok role
yang sama sekaligus melalui map terpisah dan packed map.
- `normal_convention` harus dinyatakan `OPENGL` atau `DIRECTX`; DirectX membalik
channel hijau. Tool tidak dapat menebak konvensi dari gambar. Tangent normal
memerlukan UV yang sudah ada, `coordinate_space="UV"`, dan `projection="FLAT"`.
- `coordinate_space="WORLD"` memakai posisi dunia dan `texture_size_m` dalam
meter, memperhitungkan scene unit scale; hanya proyeksi FLAT/BOX. Tekstur
world-anchored: objek bergerak melewati tekstur. Repeat UV sendiri tidak
mempunyai ukuran fisik; kalibrasikan UV dengan density yang diukur.
- `displacement_scale` pada pembuatan material dan `scale` pada
`configure_displacement` adalah jarak meter. Mode `AUTO` melaporkan mode efektif;
true displacement perlu dukungan engine/build dan geometri yang cukup.
Pembuatan material tidak otomatis menambah subdivision. Konfigurasi displacement
membatasi subdivision dan menolak penggantian output displacement yang sudah
terhubung kecuali `replace_existing=true` diminta secara eksplisit.
- `add_micro_surface_detail` memakai `wavelength_mm`, `amplitude_mm`, dan seed
deterministik sambil mempertahankan rantai normal. Jika wavelength nol,
wavelength efektif adalah `1000 / scale` mm. Bump tidak mengubah siluet.
`add_surface_imperfections` membuat SCRATCHES/GRAIN terarah atau DUST bermasker
permukaan menghadap atas, bukan simulasi keausan; `coverage` adalah ambang noise,
bukan fraksi luas yang dijamin.
Contoh berikut adalah parameter panggilan MCP native `tools/call`, bukan Python.
Ganti path dan nama objek dengan aset/objek yang benar-benar tersedia; contoh
normal ini memerlukan UV pada `Panel`:
```json
{
"name": "create_pbr_material_from_textures",
"arguments": {
"material_name": "PanelPBR", "object_name": "Panel",
"base_color": "C:/assets/panel/basecolor.png",
"packed_map": "C:/assets/panel/orm.png", "packed_layout": "ORM",
"normal": "C:/assets/panel/normal_dx.png", "normal_convention": "DIRECTX",
"coordinate_space": "UV", "projection": "FLAT"
}
}
```
### UV, density, dan bake
`unwrap_object` mendukung SMART, CUBE, proyeksi PLANAR/SPHERE/CYLINDER, serta
unwrap berbasis seam ANGLE_BASED/CONFORMAL. SMART dan packing memakai operasi UV
Blender sebenarnya, bukan sekadar normalisasi koordinat. `pack_uv_islands`
memakai margin sebagai fraksi gambar dan opsi rotasi; konteks objek/mode dipulihkan.
Siapkan seam yang sesuai untuk unwrap berbasis seam.
`measure_texel_density` dan `texel_density` memakai **piksel per meter** berdasarkan
luas segitiga world-space, transform objek, scene units, serta `texture_width` dan
`texture_height`. Hasilnya density ekuivalen-luas, bukan jaminan distorsi lokal
nol. Packing dapat mengubah density; ukur ulang sesudah packing. Scaling ke
density tinggi dapat keluar dari tile 0–1, sehingga density dan cakupan atlas
harus diselesaikan sebelum bake.
`bake_texture` menyiapkan target image dan menjalankan bake Cycles nyata dengan
`object_name`, UV, resolusi, jenis/pass, serta source/cage eksplisit bila
`selected_to_active=true`. Target single-image harus memiliki UV nondegenerat di
0–1. Node material yang ada dan konteks/render settings dipertahankan; image bake
tidak otomatis mengganti shader. `filepath=""` menghasilkan image **belum
tersimpan**, bukan file di disk. Gunakan path output PNG/OPEN_EXR/TIFF dan minta
`overwrite=true` hanya jika memang ingin mengganti file.
### Kamera, HDRI, dan compositor
`setup_cinematic_camera` membingkai target dengan shot WIDE/HERO/PORTRAIT/MACRO,
lensa, azimuth/elevation, margin dan DOF; `auto_frame_subject` memakai objek
eksplisit. `configure_depth_of_field` memilih focus object atau jarak fokus.
`load_hdri` memisahkan strength pencahayaan dan background kamera;
`rotate_hdri` memakai derajat. Physical sky/daylight, gobo Cycles dan world fog
tersedia dengan batas kemampuan; world fog tidak berbatas volume lokal.
`setup_cinematic_compositor` menambahkan efek sebelum output aktif tanpa
menghapus seluruh graf. Implementasi memilih API node group compositor Blender 5
atau node tree lama berdasarkan kemampuan yang tersedia. Periksa hasil aktual,
`unsupported`, dan error pada sky, motion blur, displacement, dan render passes;
nama versi atau preset bukan jaminan setiap opsi didukung.
`add_custom_aov` masih memerlukan node Output AOV yang dihubungkan di material.
`render_multilayer_exr` menyimpan pass view-layer mentah, melewati compositor dan
sequencer untuk render itu lalu memulihkan output settings; bukan gambar final
compositor yang diratakan.
### Proyek durable dan komponen
`create_generation_project` menyimpan `project.json`, parameter JSON, seed,
stable stage IDs, hasil/error/attempt, checkpoint, referensi dan provenance aset.
`add_generation_stages` menerima `id`, `detail_level` (macro/meso/micro), `op`
terdaftar dan `params` eksplisit; bukan raw Python. Contoh daftar panggilan
berikut dikirim **satu per satu**, bukan sebagai satu batch MCP:
```json
[
{"name": "create_generation_project", "arguments": {
"project_dir": "C:/projects/panel", "name": "Panel", "seed": 7
}},
{"name": "add_generation_stages", "arguments": {
"project_dir": "C:/projects/panel", "stages": [{
"id": "macro_panel", "detail_level": "macro", "op": "create_object",
"params": {"type": "CUBE", "name": "Panel", "size": 1.0}
}]
}},
{"name": "run_generation_project", "arguments": {
"project_dir": "C:/projects/panel", "max_stages": 1
}}
]
```
Setelah restart, `open_generation_project` membuka **metadata saja**, tidak
memuat atau menimpa scene. Tahap sukses tidak diulang; tahap failed/interrupted
memblokir kelanjutan sampai direkonsiliasi dan ID-nya diberikan melalui
`retry_stage_ids`. Efek parsial dapat masih ada: jangan retry penciptaan objek
secara buta. Runner memeriksa identitas/revisi scene; pulihkan checkpoint yang
cocok, atau gunakan `confirm_scene=true` hanya setelah memeriksa scene secara
eksplisit. Ini bukan izin restore otomatis.
Dengan `project_dir`, `create_checkpoint` menyimpan salinan **seluruh `.blend`**
dan indeks durable tanpa mengubah filepath aktif. File eksternal diremap,
**tidak di-pack**: pertahankan texture/library/aset yang direferensikan.
`get_scene_diff` hanya membandingkan metadata, bukan kesetaraan semua geometri.
`rollback_checkpoint` membuka `.blend` tersimpan dan mengganti seluruh scene;
wajib `confirm_restore=true`. Simpan pekerjaan saat ini dahulu. Checkpoint tanpa
`project_dir` memakai indeks sesi, bukan alur resume proyek durable.
`register_component` memerlukan source mesh yang sudah dibuat, `dimensions_m`
dan `material_color` eksplisit. Ukuran harus cocok dengan pengukuran source;
registrasi tidak membentuk ulang source. `instantiate_component` membuat mesh
linked, snap/parent dengan anchor bounding box, toleransi meter dan `instance_id`
stabil yang tidak boleh dipakai ulang. Warna instance dapat berbeda tanpa
mengubah mesh bersama; pemeriksaan geometri FAST terbatas bukan bukti bebas
interseksi. `recommend_multiscale_detail` memberi heuristik geometry/displacement/
bump dari kamera dan ukuran fitur. `apply_multiscale_detail` menyimpan rincian
resep persis (`id`, `detail_level`, `op`, `params`), dan hanya menjalankannya jika
`run=true`; ini **bukan prompt-to-sculpt** atau generator bentuk dari deskripsi.
### Referensi → bundle → gambar native → review → refinement
1. Daftarkan gambar dengan `register_visual_reference` (`project_dir`, `filepath`,
role/view, `real_dimensions` [x,y,z] meter dan catatan bila tersedia).
Referensi PNG/JPEG disalin ke proyek; referensi baru membuat review lama stale.
2. Bangun tahap macro/meso/micro, lalu `create_render_review_bundle` dengan target
`object_names` eksplisit. Bundle berisi overall dan closeup; custom `views`
harus mencakup kedua role. Kamera/frame/render settings dipulihkan setelahnya;
ini bukan isolasi scene atau deteksi cacat otomatis.
3. Baca setiap referensi dan render melalui `read_project_image`, memakai
`image_path` hasil tool. Ini **content gambar MCP native**, bukan path teks
yang otomatis terlihat oleh model. Tool hanya membaca gambar proyek terdaftar
yang hash-nya cocok. Klien/model harus mendukung input gambar. Referensi
dibatasi 32 MiB, 16 juta piksel terdekode dan sisi 8192; transport gambar
dibatasi 2 MiB dengan resize sementara bila perlu, bukan mengubah file sumber.
4. Setelah gambar benar-benar diinspeksi, panggil `record_visual_review` dengan
`bundle_id` dan findings berisi tepat `category`, `severity`, `object`,
`evidence: {image_path, observation}`, dan `action`. Evidence harus render dari
bundle itu dan menampilkan target terkait. Verdict: CHANGES_REQUIRED, REJECTED,
atau ACCEPTED. ACCEPTED memerlukan observasi positif untuk **setiap** gambar
dan hanya severity `info`, tanpa temuan masalah yang belum selesai.
5. `execute_review_refinements` menerima `review_id` dan steps tepat
`{finding_id, op, params}` yang merujuk temuan actionable. Pilih operasi dari
`allowed_refinement_operations`, target eksplisit, dan batas `max_operations`
(default 8). Eksekusi membuat review lama stale; kegagalan/interupsi tidak
boleh diputar ulang otomatis.
6. Render **bundle baru**, inspeksi lagi dan catat review baru sesudah perubahan.
ACCEPTED hanya berlaku untuk gambar bundle yang diperiksa, bukan kualitas
scene saat ini, seluruh sudut, hasil ekspor atau frame yang tidak dilihat.
Contoh membaca satu gambar; ganti `BUNDLE_IMAGE_PATH` dengan `image_path` yang
dikembalikan `create_render_review_bundle`, bukan path file sembarang:
```json
{
"name": "read_project_image",
"arguments": {
"project_dir": "C:/projects/panel",
"image_path": "BUNDLE_IMAGE_PATH", "max_dimension": 1536
}
}
```
Addon tidak memiliki jaminan vision lokal. `record_visual_review` mencatat
observasi klien eksternal, bukan membuktikan bahwa klien melihat gambar.
`analyze_render_quality`/`compare_renders` mengukur statistik exposure, clipping
dan kontras; status sukses atau histogram baik tidak membuktikan kecocokan
referensi, perbaikan semantik, atau fotorealisme. Jangan menyatakan persetujuan
visual tanpa inspeksi gambar yang sebenarnya.
### Aset berlisensi dan batas resource
Gunakan `search_assets` → `get_asset_info` → `download_asset` →
`import_asset_package`. Periksa `source_url`, author, `license` dan
`license_requirements`, lalu tampilkan provenance tersebut kepada pengguna:
- **[Poly Haven](https://polyhaven.com/)**: aset CC0; atribusi aset dihargai tetapi
tidak wajib menurut [lisensi aset](https://polyhaven.com/license). Saat
menampilkan hasil integrasi API, tampilkan kredit Poly Haven, source dan
lisensinya secara terlihat; jangan mengesankan endorsement.
- **Sketchfab**: download hanya model yang memang downloadable, dengan OAuth
`access_token` resmi pengguna atau `api_key` akun yang berwenang. Izin download
bukan pelepasan syarat lisensi; pertahankan kredit creator/source/lisensi dan
periksa batas penggunaan komersial, turunan atau share-alike.
- **Lokal**: file tanpa metadata lisensi tetap **unknown**, bukan otomatis bebas
dipakai atau didistribusikan. Dapatkan hak penggunaan dari pemiliknya.
Paket memiliki manifest/provenance, checksum dan dependency lengkap yang
divalidasi dalam batas `max_download_mb`; batas mencakup payload/dependency dan
ekstraksi, bukan hanya file model utama. Impor model terkelola mendukung
glTF/GLB dan OBJ/MTL, serta paket PBR/HDRI. `.blend`/USDZ bukan jalur impor model
terkelola: tinjau file tepercaya di Blender dan ekspor paket glTF mandiri dahulu.
`source_unit_meters` berarti meter per unit file OBJ; pada glTF/GLB yang sudah
berbasis meter nilainya multiplier skala. Contoh impor lokal:
```json
{
"name": "import_asset_package",
"arguments": {
"filepath": "C:/assets/panel.glb", "project_dir": "C:/projects/panel",
"source_unit_meters": 1.0, "max_download_mb": 64
}
}
```
Credentials provider tidak disimpan ke manifest/cache/resep. Jangan masukkan
API key, token, URL bertanda tangan atau rahasia ke stage/parameter/metadata
proyek; kirim kredensial hanya pada panggilan provider yang memerlukannya.
Periksa `get_scene_budget`/`estimate_operation_cost` sebelum operasi berat;
`set_generation_budget` membatasi objek, geometri, instance, subdivision,
texture, import dan render. Batas diketahui dapat menolak operasi sebelum
mutasi. Biaya yang tidak diketahui **tetap diizinkan** sambil menegakkan batas
yang diketahui (`allow_unknown_costs_enforce_known_limits`), bukan diasumsikan
nol atau jaminan scene tidak akan kehabisan memori.
`audit_scene_resources`/`audit_vram_usage` membedakan base, prediksi modifier,
texture/decoded-buffer estimate, dan audit depsgraph opsional `evaluated=true`.
Audit evaluated adalah view layer/viewport saat ini, dapat dilewati/dibatasi,
dan tidak menjamin sama dengan render akhir. `actual_vram_bytes` tetap **null**;
BVH, cache, driver, pass render dan overhead renderer tidak seluruhnya terukur.
`scatter_instances` membuat **tepat `count` instance**, bukan density: sampel
acak bounding box diproyeksikan ke face terdekat dengan seed deterministik.
Distribusi **bukan uniform menurut luas permukaan**. Surface harus memiliki
face evaluated dan tidak sudah memakai modifier Geometry Nodes; instance tetap
unrealized. Penghapusan face setelahnya membatalkan asumsi penempatan.
## Chat Internal Blender (LLM)
Aktifkan di panel Axiom: pilih provider (OpenAI/Anthropic/Google/DeepSeek/
OpenRouter/Ollama), isi API key, lalu ketik perintah — mis. *"buat meja kayu
dan kursi di atas lantai, warna coklat, animasikan mejanya"*. Asisten memakai
`search_api_docs()` (dokumentasi RST lokal) sebelum menulis kode, memvalidasi AST,
dan mencoba membuat checkpoint `undo_push` sebelum menjalankan kode. Jika kode
gagal, error asli dilaporkan; perubahan parsial tidak dibatalkan otomatis.
## Keamanan
- **Validasi AST**: pola berbahaya (`os`, `subprocess`, `__import__`, dunder)
diblokir sebelum eksekusi
- **Eksekusi kode**: namespace baru per panggilan; validasi AST bukan sandbox
penuh. Jika eksekusi gagal, output dan traceback asli dikembalikan tanpa
menjalankan undo otomatis, karena undo dari timer dapat memicu crash Blender.
Periksa perubahan parsial atau buka kembali salinan `.blend` tersimpan sebelum
mencoba ulang. Batch/job atomik memakai upaya rollback terpisah; fallback
terbatas pada objek/parent/transform dan bukan pemulihan lengkap mesh/material.
- **Rate limiting**: token bucket per klien
- **Validasi input**: pencegahan traversal path, jenis argumen diperiksa
## Arsitektur
```
blender-mcp-ultra/
├── mcp_tools.py # Spesifikasi tool statis (FastMCP + STDIO)
├── mcp_server.py # FastMCP (SSE :9879 / stdio)
├── blender_connection.py # Klien socket TCP :9876
├── addon/ # Addon Blender (AXIOM): _axsock, handlers, modeling,
│ # materials, rigging, animation, scene_tools, ...
├── blender_mcp/ # CLI, rst_search (dokumentasi API lokal), validasi
├── src/tools/ # Katalog ToolRegistry tambahan (registry bridge)
├── data/api/ # Dokumentasi RST API Blender
├── scripts/ # install.py (auto-detect versi Blender)
├── skills/ # Instruksi workflow per domain
├── tests/ # Tes offline dengan stub + integrasi/e2e
└── demo_artifacts/ # Hasil demo LLM → Blender headless
```
## Verifikasi
Hasil verifikasi harus menyebut versi Blender, transport, dan operasi yang
benar-benar dijalankan. Tes offline memakai stub dan tidak menggantikan smoke
di Blender nyata. Demo historis di `DEMO_LLM.md` memakai Blender 4.2.23 headless melalui
socket; itu tidak membuktikan seluruh fitur baru, jalur installed/native MCP,
provider jaringan, atau build Blender 5 bekerja di setiap lingkungan.
Smoke terpisah pada **Blender 5.2.0 LTS (`fbe6228777e7`)** menjalankan proyek
setelah restart/interupsi, retry eksplisit, pemulihan mesh yang dihapus melalui
checkpoint, dan komponen linked; scatter tepat 11 instance, penolakan resource
dan impor GLB lokal. PBR diuji pada unit scene 0,01, normal DirectX, rantai
dust/grain dan displacement EEVEE; SMART packing/density, color bake serta
normal bake dengan cage menghasilkan output nyata. Framing portrait/landscape,
HDRI background terpisah, compositor Blender 5, sky/fog/gobo, dan EXR multilayer
dengan header pass Combined/Depth/Normal/CryptoObject juga dijalankan.
Poly Haven `wooden_table_02` dan material `wood_floor_deck` diuji dengan dependency
lengkap dan lisensi nyata. Transport MCP STDIO dan SDK-free mengirim gambar
native yang di-resize; image path di luar proyek ditolak. Ini bukti operasi
yang dijalankan, bukan verifikasi semua format, provider atau build.
Regresi terakhir: **510 passed, 10 skipped**, dengan tiga jalur live/e2e pada
perintah di atas dikecualikan. Dua skip terkait izin symlink Windows; delapan
lainnya kasus capability yang sudah ada. Smoke resource native juga memastikan
amplifikasi Array ditolak sebelum modifier baru dibuat, buffer image byte/float
dihitung, viewport dipulihkan, dan hanya mesh identik yang dibagikan.
Model inspeksi gambar yang dikonfigurasi pada verifikasi tersebut tidak
mendukung vision. Tidak ada approval semantik/fotorealisme; gambar berhasil
dirender atau dikirim tidak berarti sudah dilihat dan disetujui.
Perubahan PBR/UV/render perlu diperiksa pada hasil aktual, dan review visual
memerlukan gambar native yang benar-benar dibuka oleh klien berkemampuan vision.
Daftar fitur dan contoh di dokumen ini adalah kontrak penggunaan, bukan klaim
bahwa semua tes lulus atau bahwa hasilnya otomatis fotorealistik.
## Lisensi
MIT
TDQS
Scored across 148 tools
Many tools have overlapping purposes, e.g., solidify_mesh, add_wall_thickness, and add_modifier with SOLIDIFY; get_scene_info, get_scene_graph, and get_objects_summary all provide scene summaries. The distinction between create_object, model_from_scratch, and rig_from_scratch is also unclear, making it hard for an agent to pick the right operation.
Most tools follow a verb_noun pattern (create_object, list_materials, set_render_engine), but there are notable deviations like 'ping', 'measure', 'find_objects', 'array_object', and 'run_batch'. The mix of generic verbs (get, set, create, add, remove) is consistent, but compound phrases like 'setup_three_point_lighting' and 'colorize_from_scratch' break the pattern.
With 148 tools plus a registry of 228, the server is extremely over-scoped. This is far beyond the typical 3-15 tool range and even exceeds the 50+ threshold, making selection overwhelming and redundant. The count is clearly inappropriate for a coherent MCP server.
The tool surface covers a vast range of Blender operations: modeling, materials, lighting, animation, rigging, UV, geometry nodes, import/export, and scripting. The registry tools and run_batch provide a fallback for any missing operation. Minor gaps exist, such as no direct tool to delete a material or edit text content, but these are workaround-able via execute_blender_code or call_registry_tool.