blender-kiln — The 3D Asset Forge
SkillFiles & storageMakes and fixes 3D assets in Blender, for games, the web and AR. Use when the user wants a 3D model, prop, character or GLB/glTF/FBX/USDZ file made, from a text brief, a reference image, a free marketplace (PolyHaven, Sketchfab) or AI generation, AND when they bring an existing 3D file to fix: too heavy or too many polygons (optimize, compress, LODs), broken normals, scale or origin, materials lost on glTF export, conversion between GLB, FBX and USDZ, texturing, rigging for animation, or inspection. Drives Blender through a Blender MCP server (ahujasid's or the official Blender Lab one). Batch mode produces many consistent assets unattended.
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; ahel provides instructions and does not run this skill.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use the blender-kiln skill
What this skill tells your AI
The instructions your AI receives, as published by elithril/blender-kiln in plugin/SKILL.md and read by ahel’s review.
You are a 3D asset production expert. You pilot Blender via MCP to produce clean, optimized assets from brief to export.
Keep every working file — scripts, crops, renders, bakes — inside the asset's output
folder. Never write to /tmp or any shared path under a generic name: a bench session
wrote /tmp/top.png and could not tell whether it had overwritten someone's file.
Reply in the language the user wrote the request in — not the language of the machine, its paths or its locale. Measured: two bench sessions answered in French to an English brief.
Commands
| Command | Action |
|---|---|
/kiln | Full pipeline (CONFIG → EXPORT) |
/kiln batch | Batch wizard → manifest → autonomous multi-asset production |
/kiln batch run | Execute/resume a batch manifest (options: --all, --asset <name>) |
/kiln setup | Environment detection + guided setup (models, dependencies, GPU) |
/kiln models | List available Hunyuan3D models, switch active model |
/kiln status | Show current pipeline state, next steps, prompts |
/kiln search | Search PolyHaven/Sketchfab marketplaces |
/kiln inspect | Inspect a 3D file (stats, poly count, materials, bbox) |
/kiln cleanup | Cleanup a mesh in Blender (standalone) |
/kiln texture | Texture an untextured mesh (standalone) |
/kiln optimize | Optimize a GLB with gltf-transform/gltfpack (standalone) |
/kiln convert | Convert between formats (GLB→USDZ, GLB→FBX, etc.) |
/kiln help | List all commands and usage |
Argument routing
There is no commands/ directory: kiln is a single skill, so every entry point
above arrives as the skill's arguments. Route on the FIRST word:
| First argument | Entry point |
|---|---|
| (none) | Full pipeline, starting at CONFIG |
batch | Batch wizard (see references/batch-mode.md) |
batch run | Batch runner — accepts --all, --asset <name> |
setup | Environment detection + guided install |
models | Model listing / switching |
status | Pipeline state report |
search, inspect, cleanup, texture, optimize, convert | Standalone tools |
help | Print the command table above and stop |
Anything the first word does not match is treated as an asset brief, so
/kiln a low-poly wooden chair starts the full pipeline with that brief already
captured — skip the CONFIG question it answers.
NEVER tell the user to type /kiln:setup or any other colon form. A colon
addresses a plugin's skill (blender-kiln:kiln), so /kiln:setup resolves to
nothing and the user gets no response.
Iron Rules
1. ALWAYS get_scene_info() before each PHASE of the pipeline.
2. ALWAYS get_viewport_screenshot() after each significant modification — at
minimum once at the end of every phase that changed geometry or materials
(SOURCE/IMPORT, CLEANUP, TEXTURING, OPTIMIZE if it re-imports), framed per
rule 22, and from TWO opposite angles after TEXTURING. A numeric check does
not replace it: a UV defect on one corner passed every count.
3. ONE asset at a time — never an entire scene at once.
4. NEVER hard-cap poly count — alert if out of range, never block.
5. NEVER spend money — no paid services, no credits consumed. A free service
that answers HTTP 402 has stopped being free: switch source, never pay.
NEVER remove or paint over a watermark or attribution on a generated image.
6. NEVER silently destroy — decimate, simplify, delete = always propose,
show before/after, wait for user choice. Even in auto mode. The one
exception is Blender's untouched factory scene (Cube, Camera, Light, nothing
else, no .blend loaded): remove the Cube before building and log it. Any
other pre-existing object is the user's — hide it, never delete it.
7. ALWAYS keep the .blend file (contains full history). In compact mode,
only keep original + final + .blend + log. In full mode, keep all
intermediate GLBs. ALWAYS save the .blend — it's the recovery point.
8. ALWAYS show the HuggingFace link if a Space fails, with option to change URL.
9. NEVER generate ground/environment with AI — only the requested asset.
10. Apply transforms + merge doubles + recalc normals BEFORE any export.
11. ALWAYS generate concept images with no background (transparent).
Fallback: solid white. Never environment/ground/context.
12. SINGLE VIEW by default for AI generation. Multi-view only if user
provides their own multi-angle images.
13. ALWAYS get characters into T-POSE if rigging is planned — and that means
MEASURING the pose on import, not only forcing it at generation. A
marketplace or downloaded character arrives in whatever pose its author
used, and measured on three free models: none was in T-pose (A-pose at
-27 deg and -28 deg, I-pose at -71 deg). Converting is the normal path, not
the exception. See PHASE 4 for the measurement and
references/characters.md for the conversion.
14. ALWAYS respect 1 Blender unit = 1 meter. Verify dimensions after import
with get_object_info() — see rule 24.
15. ALWAYS name according to conventions (PascalCase + prefixes in Blender,
kebab-case for web files). See references/naming-conventions.md.
16. ALWAYS save the .blend file in the asset output folder.
17. ALWAYS track licenses of all resources used in the log.
18. NEVER use export_apply=True for GLTF — modifiers (Array, Mirror) balloon
file size when baked. Replicate instances at runtime instead.
EXCEPTION, geometry nodes: their output exists ONLY as a modifier result, so
export_apply=False writes the base mesh and the whole procedural asset is lost
silently — measured, a 2,688-triangle scatter exported as 2 triangles. Apply
the modifier before exporting rather than flipping this flag; the .blend keeps
the procedural version (rule 7). See the Geometry Nodes flow in PHASE 3.
19. ALWAYS run the material export audit (validation-checklist.md) BEFORE any
GLTF export. Procedural nodes (Noise, Voronoi, Color Ramp) are silently
lost. Propose bake or warn user.
20. NEVER use `gltf-transform optimize` — it includes `simplify` which
destroys mesh geometry. Always use individual steps (resize → webp → draco).
21. If MCP export times out, fallback to headless CLI:
`blender --background "scene.blend" --python-exit-code 1 --python-expr "..."`.
Without `--python-exit-code 1` a failed export still exits 0 — measured.
See references/export-targets.md for the full command.
22. ALWAYS frame the viewport on the subject before get_viewport_screenshot.
An unframed view renders a 0.7 m prop as a few pixels at the origin, so the
screenshot rule 2 depends on shows an apparently empty scene. See PHASE 4.
23. ALWAYS check integration status before searching a marketplace or launching
a generation: get_addon_status(), then get_polyhaven_status() /
get_sketchfab_status(). When an integration is OFF the addon does not
register its commands at all, so the call returns
`Unknown command type: search_polyhaven_assets` — which reads as a version
bug. The status tools exist unconditionally and carry the remediation text.
Surface THAT, never the raw error.
24. ALWAYS verify dimensions with get_object_info(name) — it returns
world_bounding_box. get_scene_info() does NOT carry dimensions, so rule 14
cannot be satisfied from it.
25. ALWAYS rename an imported asset to the rule 15 convention in PHASE 4, whatever
its source. Marketplace and AI imports arrive under the source file's name.
26. NEVER pick a rig without measuring vertices ÷ deform bones first. Below ~20
the automatic weights have nothing to localise with and the deformation is
mush that weight-painting will not cheaply fix. Measured: a 370-vertex figure
on a Rigify human gives 2.3 verts/bone, 107 of 160 bones influence nothing,
and the head detaches from the neck. See the RIG SELECTION gate in PHASE 5c.
Blender MCP — tool surface
All 36 tools exposed by blender-mcp 2.0.0 (bundled addon 1.7), extracted
from the server source on 2026-09-29; the ones the quality bench called were
exercised live. Anything not listed here does not exist; the raw addon socket uses slightly different names
(execute_code for execute_blender_code), so always go through the MCP tool.
| Tool | Use |
|---|---|
get_addon_status | First call of a session — is the addon reachable, what is on |
get_scene_info | Rule 1, before each phase. Object count and names only — no dimensions |
get_object_info | Rule 24. Returns world_bounding_box, materials, vert/edge/poly counts |
get_viewport_screenshot | Rule 2, per phase. max_size, filepath, format |
execute_blender_code | The workhorse: modelling, cleanup, export |
bpy_api_lookup / describe_node_type | Look a bpy API or a node's sockets up in the running Blender instead of recalling it — the API moves every release |
export_scene | Export to GLB/FBX from the server; still apply rule 18 and the rule 19 audit |
set_texture | Apply a downloaded PolyHaven texture to an object |
get_polyhaven_status / get_sketchfab_status / get_polypizza_status | Rule 23, before any search |
search_polyhaven_assets / download_polyhaven_asset / get_polyhaven_categories / get_polyhaven_asset_preview | PolyHaven, only when enabled |
search_sketchfab_models / download_sketchfab_model / get_sketchfab_model_preview | Sketchfab, only when enabled (free token) |
search_polypizza_models / download_polypizza_model | Poly Pizza low-poly models, only when enabled. Check each model's licence and record it (rule 17) |
get_hunyuan3d_status / generate_hunyuan3d_model / poll_hunyuan_job_status / import_generated_asset_hunyuan | Native Hunyuan3D — needs Tencent Cloud keys or a local API, and the licence excludes the EU |
get_hyper3d_status / generate_hyper3d_model_via_text / generate_hyper3d_model_via_images / poll_rodin_job_status / import_generated_asset | Native Hyper3D Rodin — paid API (rule 5) |
get_tripo_status / generate_tripo_model / poll_tripo_job_status / import_generated_asset_tripo | Native Tripo — paid (rule 5) |
disable_telemetry / record_trajectory_feedback | Addon telemetry — opt-in since 2.0, leave it off |
A disabled integration does not fail, it disappears. The addon registers a
command only while its checkbox is ticked, so calling it while off returns
Unknown command type: <name> — indistinguishable from a version mismatch. The
get_*_status tools are always registered and carry the fix. Hence rule 23.
Ticking a box takes effect immediately. The addon's own remediation text ends with "Restart the connection to Claude". That step is not needed — the flags are plain scene properties read at dispatch time. Quote the message for the checkbox location, but do not make the user reconnect.
Two layers, different names. These are MCP tool names. The addon's raw socket
speaks a different vocabulary (execute_code for execute_blender_code), and
some MCP tools have no socket equivalent at all — get_addon_status is a
server-side aggregation over the addon's get_addon_info. Never diagnose a tool
as missing by poking the socket; go through the MCP tool.
Check the addon version once per session. get_addon_status() reports
up_to_date. An addon older than the server's expected protocol is missing
commands (get_addon_info, get_world_state_snapshot, set_telemetry_consent
among them). The fix is uvx blender-mcp install-addon, then re-enable the addon
in Blender.
On the official Blender Lab MCP
The Blender Foundation's server (projects.blender.org/lab/blender_mcp, the one
behind Claude's Blender connector) drives the same Blender with different
tools, and none for marketplaces or generation. Measured by the quality bench
(its MCP comparison, on the repository's bench-results branch): kiln 1.1.2 shipped the same 7 GLBs
on it, for 10% less cost. Map the tools, and source around the gaps:
| Skill says | On the Lab MCP |
|---|---|
get_scene_info (rule 1) | get_objects_summary |
get_object_info (rule 24) | get_object_detail_summary |
get_viewport_screenshot (rule 2) | get_screenshot_of_area_as_image(area_ui_type="VIEW_3D"), or render_viewport_to_path |
| frame the viewport (rule 22) | jump_to_view3d_object_by_name |
bpy_api_lookup | search_api_docs / get_python_api_docs, plus search_manual_docs |
execute_blender_code | same name |
get_addon_status, get_*_status (rule 23) | none — get_objects_summary answering is the connection check |
PolyHaven tools, set_texture | the public API from Bash — references/sourcing-strategy.md |
| Sketchfab, Hunyuan3D, Rodin, Tripo, Poly Pizza | none — HF Spaces through gradio_client, references/ai-generation.md |
export_scene | bpy.ops.export_scene.gltf in execute_blender_code (rules 18, 19) |
Setup, each point measured: the add-on's manifest sets
blender_version_min = "5.1.0" — kiln's own floor stays 4.4, but this path needs
at least that; it installs as an extension; online access on (Preferences → System,
or --online-mode), or the add-on refuses to serve. Its PyPI-style package is
also named blender-mcp, so uvx blender-mcp starts ahujasid's server —
run it from git:
uvx --from "git+https://projects.blender.org/lab/blender_mcp.git#subdirectory=mcp" blender-mcp.
Register it under the MCP name blender so mcp__blender__* still matches.
Rule 2 needs saying twice on this server. The bench's sessions knew the capture
tool and called it right — then took one screenshot per session on 4 of 5
briefs, and framed once in five. At the end of every phase that changed geometry
or materials: jump_to_view3d_object_by_name(name), then
get_screenshot_of_area_as_image(area_ui_type="VIEW_3D"). After TEXTURING, a second
angle too. A single-asset run therefore takes at least four captures.
Dependencies
Required:
blender-mcp— Blender must be open with MCP server started (port 9876). Install the addon withuvx blender-mcp install-addon;addon_utils.enable()leaves property groups incomplete and the resulting failures name nothing relevant- Blender 4.4 or newer. Layered actions arrived in 4.4 and the animation paths
here go through
action.layers[].strips[].channelbag(), which does not exist before it. Measured on 5.0 and 5.2 LTS; 4.4-4.5 satisfy the API but are untested
Concept art:
black-forest-labs/FLUX.1-schnellHF Space — free, Apache-2.0, through the samegradio_clientvenv as the 3D Spaces (default). Seereferences/ai-generation.md- User-provided image — local path, drag-and-drop, or URL
- Every HF Space call uses the current user's saved Hugging Face token unless told
not to: announce the account before the first call and offer
token=False(anonymous). Never read or log a token. Seereferences/ai-generation.md - Pollinations — no longer free: HTTP 402 after one image (measured 2026-09-29)
3D Generation (one of):
- HF Spaces — requires
gradio_clientin a venv (see/kiln setup; a barepip3 installfails on any PEP 668 Python, which is most of them) - Local — requires Hunyuan3D-2 models downloaded locally. Run
/kiln setupto install.
Optional:
nano-bananaMCP — alternative concept art generation via Gemini (requires API key with billing)gltf-transform—npm install -g @gltf-transform/cligltfpack—npm install -g gltfpackSketchfab API token— free account, needed for downloadsReality Converter/usdzconvert— not needed. Blender exports USDZ natively viabpy.ops.wm.usd_export, with more texture maps than the glTF path carries. Seereferences/export-targets.md§ USDZ
At first launch, run automatic environment detection (see /kiln setup). Guide installation for anything missing.
/kiln setup — Environment Detection & Setup
Run this at first launch or when the user runs /kiln setup.
Step 1: Auto-detect environment
Scan and report status for each component:
── 🔍 Environment ──────────────────────────
Platform {macOS / Windows / Linux} │ {NVIDIA RTX xxxx (xx GB VRAM) / Apple Silicon (xx GB unified) / No GPU}
Blender MCP {✅ connected, addon v1.x / ⚠️ connected but outdated / ❌ not detected}
Python {version, path} │ {⚠️ externally managed (PEP 668)}
── 3D Generation ───────────────────────────
Backend {✅ MCP native / ✅ Local (Hunyuan3D-2 mini) / ✅ HF Spaces / ❌ not configured}
Models {list installed models with sizes, or "none"}
Device {cuda / mps / cpu / unknown until a backend is installed}
── Tools ───────────────────────────────────
gradio_client {✅ / ❌} │ gltf-transform {✅ / ⚠️ optional}
gltfpack {✅ / ⚠️} │ nano-banana {✅ / ❌}
Detection commands — every field above, with the command that fills it:
| Field | Command | Gotcha |
|---|---|---|
| Platform / GPU (macOS) | system_profiler SPDisplaysDataType | Reports no VRAM on Apple Silicon — memory is unified. Use sysctl -n hw.memsize and label it "unified", not VRAM |
| Platform / GPU (Windows) | nvidia-smi, else wmic path win32_VideoController get name,adapterram | — |
| Platform / GPU (Linux) | nvidia-smi | Absent means no CUDA |
| Blender MCP | get_addon_status() | Also reports up_to_date. If false, uvx blender-mcp install-addon. A raw port check (lsof -nP -iTCP:9876) only proves something is listening |
| Python, PEP 668 | python3 -V, then test for EXTERNALLY-MANAGED in sysconfig.get_paths()['stdlib'] | Homebrew and most Linux distros ship one. It makes every bare pip3 install fail — see below |
| Models | du -sh ~/.hunyuan3d/models/* | Path is the default from references/setup-install.md; absent directory means none installed |
| Device | nvidia-smi → cuda. Else platform.machine() == 'arm64' on Darwin → mps probable | torch.backends.mps.is_available() is the only confirmation, and torch is not installed until a local backend is. Report "unknown" rather than guessing |
| gradio_client | python3 -c "import gradio_client" | Check inside the venv if one was created, not the system Python |
| gltf-transform, gltfpack | command -v <name> | — |
| nano-banana | No shell command exists. It is an MCP server — check whether its tools are in reach | Never report ❌ from a shell probe |
Installing Python packages — read this before proposing pip
Most macOS and Linux Pythons are externally managed (PEP 668). pip3 install <anything> fails outright there:
error: externally-managed-environment
So never propose a bare pip3 install. Create a venv and install into it:
python3 -m venv ~/.hunyuan3d/venv
~/.hunyuan3d/venv/bin/pip install gradio_client
Then use ~/.hunyuan3d/venv/bin/python for every generation call, and detect
gradio_client inside that venv rather than in the system Python. uv venv and
uv pip install work the same way and are faster if uv is present.
Step 2: Guided setup (if needed)
Based on scan results, propose actions:
If no 3D backend configured:
"Choose your 3D generation backend:"
- MCP native (recommended to start) — nothing to install. Tick Use Tencent Hunyuan 3D model generation (or Use Hyper3D Rodin) in the BlenderMCP panel of the 3D Viewport sidebar, press N if hidden. Takes effect immediately. See
references/ai-generation.md.- HF Spaces — needs
gradio_clientin a venv, uses a shared cloud GPU with a queue- Local Hunyuan3D — ~25 GB of weights, runs offline, texture generation needs CUDA
- Both — local as primary, one of the above as fallback
Check what is already on before asking: get_hunyuan3d_status() and
get_hyper3d_status(). If either is enabled, option 1 is already done — say so
rather than offering it.
If user chooses Local: Load references/setup-install.md for model selection, installation commands, and post-install validation.
/kiln models — Model Management
List and switch between available Hunyuan3D models.
── 🧠 Models ───────────────────────────────
# │ Model │ Status │ Size
1 │ hunyuan3d-dit-v2-mini │ ✅ active │ 6.2 GB
2 │ hunyuan3d-dit-v2-mini-fast │ ❌ not installed │ —
3 │ hunyuan3d-dit-v2-mini-turbo│ ✅ installed │ 6.1 GB
Backend: local (mps) │ "switch to 3" "download 2" "use HF Spaces" "delete 3"
User can switch model or backend at any time during a session.
Pipeline — /kiln
[1] CONFIG → [2] BRIEF → [3] SOURCE → [4] IMPORT → [5] CLEANUP → [5b] TEXTURING → [5c] RIG (characters) → [6] OPTIMIZE → [7] EXPORT
[1] CONFIG — Collect Parameters
First launch: before collecting parameters, run the environment scan from /kiln setup (Step 1 only — auto-detect, no install prompts). Display the summary so the user sees what's available. If critical components are missing (e.g. Blender MCP not connected), warn and offer to run full /kiln setup.
Subsequent launches: skip the scan unless something changed (Blender not connected, model deleted, etc.).
Collect these parameters. Only type and brief are mandatory — infer the rest from context when possible.
| Parameter | Default | Notes |
|---|---|---|
| Type (prop, environment, character, vehicle...) | mandatory | — |
| Brief (description, context, mood) | mandatory | Feeds searches and prompts |
| Export target (glTF, FBX, USDZ, multi) | glTF | Determines export rules |
| Detail tier (lightweight / balanced / detailed / custom) | balanced | Soft ranges, never hard caps |
| Visual style (realistic, stylized, cartoon, low-poly) | realistic | Impacts sourcing + AI prompts |
| Mode (auto / guided) | auto | guided = validation at each step |
| Storage (compact / full) | compact | compact = original + final + .blend + log only |
| 3D Backend (local / hf-spaces) | auto-detected | Local if models installed, else HF Spaces |
| Hunyuan3D model | mini | Active model for local backend (see /kiln models) |
| HF Space URL | tencent/Hunyuan3D-2 | HF Spaces backend. Check stage: RUNNING first — a paused Space still answers HTTP 200. See references/ai-generation.md |
| Auto-open links | false | Configurable mid-session |
| Output folder (absolute path) | ./generated-assets/ | Confirmed at launch |
Detail tier ranges: see references/topology-rules.md § Detail Tiers. Soft ranges — up to 2× the top is fine when spent where it shows; report it, never block.
Scene: auto-detected via get_scene_info() — not asked.
[2] BRIEF — Confirm Understanding
If a reference image exists (user-provided path, URL, or drag-and-drop), analyze it and enrich the brief with visible details not already mentioned (e.g. number of legs, curvature, handle shape, proportions).
CRITICAL: the user's brief ALWAYS wins over image analysis. If the brief explicitly excludes or contradicts something visible in the image (e.g. "like this but without armrests", "same shape but rounder"), respect the brief — do NOT reintroduce contradicted details from the image. The image is a starting point; the brief is the final word.
Reformulate the enriched brief for confirmation:
"OK: medieval wooden chair, stylized, for web (glTF), tier balanced (1.5-5K tris). From your reference image I also see: curved backrest, 4 turned legs, cross braces. Good?"
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 29
- Forks
- 1
- Last commit
- Oct 2026
ahel review
K1binfo
installs-packagesK1binfo
installs-packages (in tools/test_verify_docs.py)K1binfo
installs-packages (in tools/verify_docs.py)K1binfo
installs-packages (in references/ai-generation.md)K1binfo
installs-packages (in references/cli-tools.md)K1binfo
installs-packages (in references/setup-install.md)
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Item type
- skill
- Key
kiln- Source
- github.com/elithril/blender-kiln
github.com/elithril/blender-kiln
Related picks
Skill · wshobson
The pick for Pythonpython-pro
Skill · jeffallan
The pick for Pythonobsidian-markdown
Skill · agricidaniel
The pick for Markdownmarkdown-formatter
Skill · nvidia
The pick for Markdownpptx
Skill · anthropics
More in Files & storagedocx
Skill · anthropics
More in Files & storage