text-to-blender

Drive Blender from natural language. Converts plain-English requests ("model a sword and render it with cinematic lighting", "make this glass look frosted", "set up three-point lighting", "export this scene as glTF for the web") into Blender Python code executed via the Blender MCP server. Acts as t

By roble3 · 390 installs

npx skills add roble3/cc-blender-skill --skill text-to-blender

Source repository · Upstream listing

MCP backend Use when: User asks for any 3D creation, modification, lighting, rendering, animation, or export task. Anything involving Blender or that should reasonably be done in Blender. Before the first Blender call, read [references/mcp backends.md](references/mcp backends.md). Prefer official MCP for shared capabilities; preserve the selected backend for the whole task. Tool names in recipes are client/legacy examples: map them through that reference and its agent host guide. Text to Blender Orchestrator Turn plain English requests into Blender work. You are the conductor: read the request, decide which sub skills to chain load, sequence them in the right order, and execute via the Blender MCP. Multi skill harmonization For complex tasks that trigger multiple Blender skills, especially reference/template/brand work, load blender skill harmonizer before choosing the execution order. It owns precedence, handoff artifacts, and conflict policy. If the user rejects an output as sub par, says the same issue is recurring, or asks to improve the skill stack before retrying, load quality refinement autoloop before further product work. It turns evidence into a sanitized reusable lesson, patches generic skills/docs/versioning when explicitly requested, and only then resumes the Blender repair loop. How this skill works The user speaks in tasks ("render a hero shot of a sword on a stone"); you: 1. Identify intent → which capabilities are needed (modeling? materials? lighting? rendering? export?). 2. Check prerequisites → MCP server reachable, scene state. 3. Reset world to a known good baseline (see World reset below) — prevents leftover broken HDRI / Environment Texture nodes from previous runs corrupting the render. 4. Look up real world dimensions for the subject ( references/common object dimensions.md ) BEFORE generating Python. A "sword" has specific proportions; a "chair" has specific proportions; do not guess. 5. Route to sub skills → load the relevant ones with the host's file reading tool and follow their instructions. 6. Sequence the work in the order pros use (see references/assembly order.md ). 7. Execute generated Python with the selected backend's code execution tool. 8. Validate with the selected backend's scene/object inspection and screenshot or render tools — see Visual validation checkpoint below. Numerical validation alone is not enough: the API can report success while geometry is grossly wrong. 9. Iterate — if the visual check shows an obvious problem (subject barely visible, wrong proportions, wrong orientation), fix and re render BEFORE reporting success. 10. Report to the user with concrete numbers AND a path to the proof render they can inspect. World reset (always step 3, before any composition) Previous tests can leave the scene's world in a broken state — particularly an Environment Texture node with image=None cascading into Background, which produces a magenta flooded render. Reset world to a neutral baseline at the start of every scene build: If the user wants HDRI lighting, override this AFTER it runs (load the actual .hdr file and verify env.image is not None ). Visual validation checkpoint (always between steps 8 and 10) After rendering, always : 1. Inspect the completed render (on official MCP, read the returned filepath). For quick GUI checks use the selected backend's screenshot tool. Headless sessions require a render, not a screenshot. 2. Visually verify against the user's request. Specifically: Subject is visible and recognisable (not a thin streak, not magenta flooded, not entirely in shadow) Proportions match the real world reference dimensions for that subject Composition is reasonable (subject in frame, not clipped at edges, not microscopic in one corner) Materials have visible variation (not perfectly flat plastic looking surfaces) — for production quality scenes, add procedural texture nodes 3. If the render is obviously wrong , do NOT report success. Iterate: identify the specific problem, fix it, re render, re check. A render passing every numerical check (object count, vertex count, file size, no error messages) can still look completely wrong. The user only sees the picture. Make sure the picture matches the request before declaring done. Set viewport to Material Preview mode (last step before reporting) The user is often looking at Blender's viewport, not the rendered file. Blender defaults the viewport to Solid shading mode which ignores all materials and shows everything as flat grey. After scene assembly, switch the viewport to Material Preview so the user actually sees the materials they got: Skip this only when the user has explicitly asked you to leave the viewport alone. Real world dimension lookup Before sizing any subject from natural language, consult references/common object dimensions.md . It lists realistic proportions for common requests: Subject Total Notes One handed sword ~95 100 cm long Blade 78cm × 4.5cm × 0.8cm; guard 20cm × 2.5cm; grip 13cm; pommel 5.6cm Chair seat ~45cm × 45cm × 4cm Seat height 45cm; back ~45cm tall Bottle 25 30cm tall Body ø8 10cm; neck ø2 3cm The full reference list lives in references/common object dimensions.md . Do not guess. Prerequisites — always check first Before any work, verify: 1. Blender MCP is reachable . Use the selected backend's scene query from references/mcp backends.md . If it cannot connect: "Start the selected backend's add on socket and matching MCP client process, then re run. Official MCP requires Blender 5.1+." Stop and ask the user to fix this. 2. Scene state . get scene info returns the current objects. Decide: Empty scene? → Start fresh; build from primitives. Existing objects? → Operate on them; do NOT delete unless asked. Default cube only? → Probably safe to delete ( bpy.ops.object.delete() ). 3. The user's actual request . If ambiguous, ask one question. Otherwise proceed with sensible defaults. Intent → sub skill routing table For each intent the user expresses, load (with the host's file reading tool) the matching sub skill's SKILL.md and follow its patterns. Multiple intents = chain multiple sub skills. User intent (paraphrased) Load these sub skills Order "Make a 3D model of X" blender modeling 1st "From this wireframe drawing" wireframe to 3d 1st "Use these materials / make it look like X" blender materials After modeling "Light it / studio setup / cinematic" blender lighting After geometry exists "Hero shot / camera angle / DoF" blender cameras After lighting "Render it / produce an image" blender rendering Last visual step "Animate / move / rotate over time" blender animation After geometry "Export as glTF / FBX / OBJ / for web / for Unity" blender export Final step "Set up a scene / production quality result" blender pro workflow First — guides everything "I'm new / not sure where to start" blender pro workflow First "This is sub par / still wrong / same issue again" quality refinement autoloop , then blender skill harmonizer First — learn, sanitize, patch, then retry "Match these templates / wireframes / textures exactly" blender skill harmonizer , then reference specific fit skills First — establish source of truth gates Multi intent example : "Model a sword with materials, light it dramatically, and export as glTF" → 1. blender pro workflow (sequencing strategy) 2. blender modeling (sword geometry) 3. blender materials (steel + leather grip) 4. blender lighting (dramatic 1 point or rim setup) 5. blender export (glTF settings) Pro assembly order (when in doubt) This order minimizes rework. When the user gives a multi step request, follow it: 1. Reference + plan — note the goal. 2. Block out — primitives + camera + composition. Cheapest to iterate. 3. Camera lock — pick focal length, frame the shot. 4. Light v1 — three point (key/fill/rim) before any material work. Light defines mood. 5. Refine geometry — replace primitives with real models. 6. Materials v1 — flat colors first, get values right. 7. Light v2 — color + ratios. 8. Detail pass — only after the above is right. 9. Final render — production samples + denoise. 10. Composite — color grade, glare, vignette. 11. Export — for the target platform. Source: references/assembly order.md (deeper rationale). Code execution rules — non negotiable When emitting Python for the selected backend's code execution tool: Each call is a fresh namespace. Only bpy is pre imported; re import math , bmesh , numpy , etc. each call. Identify objects by stable name , never by Python variable. bpy.data.objects['GEO sword'] works across calls; a sword = ... assignment does not. Check backend response status as well as stdout. On official MCP assign a JSON serializable result dict; print only recipes remain supported. Print structured output so you can parse it back. End each chunk with print(f"...") reporting what changed (object names, vertex counts, file paths). Chunk the work. 180 second timeout per call. Don't dump 500 lines in one call — split into ~5–20 line chunks. Use Blender Studio naming conventions for everything you create: GEO , MAT , LGT , CAM , ARM , COL . Never leave anything as Cube.027 . Standard skeleton for every operation Naming conventions (apply to everything you create) Prefix Meaning GEO Geometry / mesh objects MAT Materials LGT Lights CAM Cameras ARM Armatures (rigs) COL Collections WGT Custom bone shapes / widgets Suffix .L / .R for left/right. Examples: GEO sword blade , MAT steel brushed , LGT key . Validation rule of thumb After significant work, call mcp blender get scene info and verify: Expected objects exist with correct names. Object counts make sense (no runaway duplication). Polycount roughly matches target. Before reporting success on a render or export, confirm the file actually exists (use the host's shell tool: ls la /path/to/output ). When to load deeper references references/assembly order.md — the canonical scene assembly sequence, time budgets, recovery patterns. Load when planning a multi step pipeline or when the user asks "what's the right order?". references/intent routing.md — fuller intent to skill mapping with edge cases. Load when the request is ambiguous and you need to disambiguate. references/code execution rules.md — detailed rules for execute blender code (namespace, timeouts, stdout capture). Load when tracking down execution errors. Reporting back to the user When work is done, report concretely: ✅ Created : list objects + polycounts. ✅ Lit : list lights + their roles. ✅ Rendered : file path + size + dimensions + render time. ⚠️ Warnings : any auto decimation, naming conflicts, fallback materials. Example: Created GEO sword blade (1 240 verts), GEO sword grip (320 verts). Materials: MAT steel brushed , MAT leather dark . Lit with LGT key (warm 3200K), LGT fill (cool 5500K), LGT rim (cool blue). Rendered to /tmp/sword hero.png (1920×1080, 2.3 MB, 38 s with 256 samples + OptiX denoise). Failure modes — what to do when… Problem Action MCP timeout Break the failing chunk into smaller pieces Code execution error: <line Read the error; fix that one line; retry Object not found in next call You used a Python var instead of bpy.data.objects['name'] Render took too long Reduce samples, enable adaptive sampling, lower resolution File not at expected path Use absolute paths; verify with the shell tool ls Material looks wrong after export You used non