# Alpha Scene Gen

> >

- **Type:** Skill
- **Install:** `agentstack add skill-ig-shadow-walker-blenderxalpha-3dgenskill-alpha-scene-gen`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ig-shadow-walker](https://agentstack.voostack.com/s/ig-shadow-walker)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ig-shadow-walker](https://github.com/ig-shadow-walker)
- **Source:** https://github.com/ig-shadow-walker/BlenderXAlpha-3DGenSkill/tree/main/skills/alpha-scene-gen

## Install

```sh
agentstack add skill-ig-shadow-walker-blenderxalpha-3dgenskill-alpha-scene-gen
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Alpha3D Scene Generator (for Blender)

Turns a plain-language scene or asset description into real, AI-generated 3D
models, placed and scaled correctly inside the user's currently open Blender
file. You are the orchestrator: your 3D provider's MCP connector does the AI
generation, the Blender MCP connector does the placement, and you do the
scene reasoning that ties them together, deciding what to generate, how big
it should be, where it goes, and (by actually looking at the result) whether
it landed right.

Three files carry the parts of this skill that are pure mechanism rather than
judgment, so you don't have to re-derive them each time:
- `references/providers/.md`: the adapter for your chosen 3D
  provider (`alpha3d`, `tripo`, or `meshy`). Each maps that provider's MCP
  tools to the workflow's primitives. Read the one that matches
  `provider.json` (see "Which 3D provider" below).
- `references/blender_helpers.md`: proven Python (download, sanitize,
  import, normalize, place, and render a view so you can see the scene) to
  adapt inside your `execute_blender_code` calls. The sanitize step in
  particular fixes a real, previously-debugged Blender import failure. Don't
  skip it or try to reinvent it.
- `references/troubleshooting.md`: what to do when a specific thing goes
  wrong (bridge disconnected, malformed GLB, job errored, insufficient
  credits).

## Which 3D provider (read this first)

This skill works with one configured 3D-generation provider. Before anything
else, determine which one:

- Read `provider.json` in this skill's own folder (next to this SKILL.md).
  Its `provider` value is one of `alpha3d` (default), `tripo`, or `meshy`. If
  the file is missing or unreadable, default to `alpha3d`; if that provider's
  MCP is not connected but a different one is, tell the user which is
  connected and ask which to use.
- Read the matching adapter, `references/providers/.md`. Each maps
  that provider's real MCP tools to the four primitives this workflow needs:
  **generate** (text/image to a job), **poll** (job status), **download URL**
  (a GLB), and **balance** (credits, if the provider exposes it), plus
  refinement and reuse.

Throughout this workflow the Alpha3D tool names (`generate_3d`, `get_job`,
`fetch`, `get_credit_balance`, `list_generation_options`) appear as the
running example, since Alpha3D is the default and most complete provider. If
your configured provider is Tripo or Meshy, substitute the equivalent tool
from its adapter table; the logic of every step is identical. The Blender
half (download, sanitize, import, scale, ground, place, look) is the same for
every provider. The user picked the provider at install time and can change
it by editing `provider.json` or re-running the installer with `--provider`.

## Before anything else: confirm both connections are actually alive

This skill depends on two *independent* MCP connections, and either one can
be missing or can have silently dropped since it was last used (the Blender
bridge in particular is session-scoped to a running Blender instance and
does not survive Blender closing or its add-on server being stopped). Don't
assume either is up just because the tools appear in your tool list. Verify
with a cheap, free call to each:

1. **Your 3D provider's MCP**: make a cheap read call to confirm it is
   connected and authenticated (Alpha3D `get_credit_balance`; Meshy
   `meshy_check_balance`; Tripo has no balance tool, so just confirm its tools
   are listed, or call `get_task_status` on a throwaway id). See your
   provider's adapter.
2. **Blender MCP bridge**: run a trivial `execute_blender_code` call, e.g.
   `result = {"blender_version": bpy.app.version_string}`. If this errors
   with a connection failure, the bridge server isn't running.

The exact tool names you call may carry a connector-specific prefix (e.g.
`mcp____generate_3d`) that varies by session. If the plain names aren't
already visible in your tool list, use your tool-search mechanism to find
them by their short name (`generate_3d`, `execute_blender_code`, etc.)
rather than assuming a fixed prefix.

If either check fails, **stop and tell the user plainly what's missing and
how to fix it** (see `references/troubleshooting.md` for exact wording).
Don't proceed partway and produce a confusing failure later.

## Step 1: Turn the description into an asset plan

First, understand what you are building into. The scene is often not empty.
If the request references existing content ("on the desk", "next to the
character", "fill the empty corner") or the scene may already have objects,
inspect it with a free `execute_blender_code` call (`summarize_scene` in
`references/blender_helpers.md`) for the exact coordinates, and, for anything
beyond a trivial empty scene, also **look** at it: use your bridge's
screenshot tool or render a view (`render_scene`, see "Seeing the scene" in
`references/blender_helpers.md`). A picture tells you the layout and
orientation that a list of bounding boxes cannot. Anchor new assets to the
real coordinates of what is already there, and keep them clear of existing
geometry. Treat the scene as an empty floor only if it actually is one.

Then build a structured plan, one entry per distinct object. For each,
decide:

- **name**: a short, descriptive label.
- **count**: how many of this exact object. If the user wants several
  identical copies ("three crates", "a row of six pillars"), plan ONE entry
  with count > 1, not N separate entries. You generate or fetch the asset
  once and duplicate it in Blender (Step 4), so nine identical crates still
  cost a single generation. Only make separate entries when the copies
  should genuinely differ ("three different cottages" is three entries).
- **source**: `generate`, `reuse`, `primitive`, or `skip`. This decision
  drives cost, so make it deliberately:
  - **`reuse`** (free): if the user refers to something they already made
    ("my dragon from last week", "the crate I generated earlier", "use my
    existing models"), find it and import its download link instead of
    regenerating. This spends zero credits, so always prefer it. How you find
    it depends on the provider: Alpha3D `search`/`list_library` then `fetch`;
    Meshy `meshy_list_tasks`; Tripo can only re-fetch by a task id you kept
    (no library listing). If your provider can't list past work and you don't
    have the id, you may have to regenerate.
  - **`generate`** (spends credits): reserve AI generation for objects where
    it earns its keep, like hero props, organic shapes, characters, anything
    with visual complexity or a specific look the user described.
  - **`primitive`** (free): a flat table, a simple crate, a wall, a floor
    plane: build these with ordinary `bpy` primitives instead; generating a
    cube costs a full generation's credits for something
    `bpy.ops.mesh.primitive_cube_add()` does for free with an identical result.
  - **`skip`**: purely atmospheric elements (sky, fog, ambient light) aren't
    meshes at all; note them in your final report and move on.
- **prompt** (for `generate` items): a clear, specific text prompt, or an
  image URL if the user gave you a reference image.
- **quality**: `standard` (fast/cheap, no PBR, fine for a rough
  placeholder), `pbr` (full materials, the right default for anything the
  camera will actually see and that should look finished), or `low_poly`
  (real-time/game-ready). Don't default to the most expensive tier without
  a reason; ask yourself what the user actually needs it for.
- **target_size_m**: the object's largest real-world dimension in meters,
  reasoned from what it is (a house is meters tall, a coin is centimeters).
  Generated meshes come back at an arbitrary internal scale, not the real
  world size. You normalize this after import in Step 4.
- **needs_postprocess**: does this asset need `rig_3d` (a character or
  creature the user wants to animate or pose), `segment_3d` (a mechanical
  object the user wants to manipulate part-by-part), `retopologize`, or
  `uv_unwrap`? Most background/dressing props need none of these; each one
  roughly doubles that asset's cost, so only add them when the user's intent
  calls for it (e.g. "rig it so I can pose it" clearly wants `rig_3d`;
  "make a village" alone does not imply any background prop needs rigging).
- **placement**: reason out where this belongs relative to everything else
  from the description itself (and relative to any existing objects you found
  above). "Around a well" implies a circle; "along a path" implies points
  spaced along a line; an unordered list of props implies a simple grid with
  spacing derived from each item's `target_size_m` so nothing ends up
  overlapping. For a count > 1, write one coordinate per copy. Write down
  actual (x, y) coordinates now, you'll apply them in Step 4. If the
  description implies a facing (a cart "facing the well", chairs "around a
  table"), note a Z rotation too; generated meshes have no guaranteed front,
  so treat facing as best-effort and call it out in your report so the user
  can spin any that end up backwards.

Two provider-dependent tricks are worth knowing while planning (see your
provider's adapter for what it supports):
- If the user dropped a **local image** into the chat, or wants
  **multi-view-to-3D** (several angles of one object), you may not be able to
  submit it directly. Alpha3D has `open_generator` (hands them a web link);
  Tripo's community server has `multiview_to_3d` / `upload_file`; otherwise
  ask the user for image URLs. Then pick the result up with the provider's
  poll/list tools and import it like any other asset.
- A **concept image first** can lock a look before spending 3D credits: with
  Alpha3D, `generate_image` (free) makes one you can feed into image mode.
  Check your adapter for whether your provider offers an equivalent.

## Step 2: Show the plan, then STOP for explicit confirmation

This step is not optional and there is no phrasing of the user's original
request that counts as already having given this confirmation, no matter
how detailed their description was. Credits are debited the moment a job is
*submitted* (refunded automatically only if that job later fails). So a
misunderstood prompt, an unnecessarily high quality tier, or a postprocess
step the user didn't actually want is real spent money, not something an
undo button fixes.

Get the balance and pricing from your provider (never hardcode credit
amounts; the provider is the source of truth and pricing can change).
Alpha3D: `get_credit_balance` + `list_generation_options` (live per-op cost).
Meshy: `meshy_check_balance` (per-op cost varies, so estimate from its
pricing). Tripo: no MCP balance tool, so you cannot show a live number; say
so, point the user at their Tripo console, and still show the plan and
confirm. Then show the user a plan table: asset name, source, quality,
credits (if known), any postprocess + its credits, subtotal, the grand
total, and the balance remaining after. Reuse, primitive, and skip rows are
free; only `generate` and postprocess rows cost credits.

If any credits will be spent, wait for an explicit go-ahead in the
conversation before calling `generate_3d` (or any other credit-spending
tool). If the whole plan happens to be free (all reuse/primitive/skip), you
can proceed once you've shown it, but still show it first so the user can
correct anything before you build.

If the balance will not cover the whole plan, say so now. Generation runs
one asset at a time (Step 3) and stops when credits run out, so tell the
user roughly how many assets their balance covers and let them top up, trim,
or reprioritize before you start. Order the plan by importance so that if it
does stop early, the scene still got the assets that matter most.

## Step 3: Generate and place, one asset at a time (a queue)

Work through the plan as a **queue, one credit-spending job at a time, not
in parallel**. Sequential generation is what lets the run stop on a clean
boundary the moment credits run out, instead of having already submitted
(and paid for) a batch it cannot finish.

Reuse and primitive assets are free, so handle those whenever convenient
(fetch + import, or build the primitive); they don't affect the credit
logic. For the `generate` assets, go in the priority order you set at Step 2
and, for each one in turn:

1. **Check you can afford it first.** Track the remaining balance from the
   figure you showed at Step 2, subtracting each job as it completes. If the
   next asset's cost is more than what's left, **stop here**: do not submit
   it. A free `get_credit_balance` call confirms the real number if you are
   unsure.
2. **Submit exactly one job** with `generate_3d`, passing a clear, unique
   `title` (the asset's name from your plan; it labels the asset in the
   user's library, which is what makes recovery and reuse possible later).
3. **Poll `get_job(job_id)` every 15-30 seconds until it is `completed` or
   `error`.** Real generations take minutes; that is normal, so don't
   shorten the interval or give up early. This waiting naturally spans
   several of your own turns.
4. On `completed`, **import and place it right away** (Step 4) so the user
   watches the scene fill in as it goes. On `error`, record the reason (the
   credits auto-refund) and move on; one failed asset should not sink the
   rest.
5. Continue to the next asset in the queue.

Stopping for lack of credits is not a failure, so don't report it as one:
say what got built, what is still queued, and how many more credits the rest
would need. The assets already placed stay in the scene, and anything
generated is saved in the user's library, so once they top up you can resume
from where you left off (via the `reuse` path) without repaying for what is
already done.

> Why one at a time and not in parallel: submitting every job at once debits
> every job's credits up front. If the balance cannot cover the whole plan, a
> parallel batch spends on work it cannot complete and ends in a messy,
> half-done state. A queue keeps spend predictable and stops cleanly.

## Step 4: Import and place one asset (one `execute_blender_code` call)

Each asset has a GLB download URL: for a `generate` asset it comes from its
completed `get_job`; for a `reuse` asset it comes from `fetch(id)`. The
import is identical either way.

Do the whole thing in a single call rather than several round trips:
download the GLB bytes, truncate them if Blender's strict loader would
otherwise reject them ("Bad GLB: file size doesn't match" is a real,
previously-hit failure; see why in `references/blender_helpers.md`), write to
a temp file, import, compute its bounding box, scale to `target_size_m`, drop
it to the ground plane, group it under a named Empty, and move that Empty to
the coordinates you planned in Step 1. The working code is in
`references/blender_helpers.md`. Read it and adapt the parameters per asset
rather than writing it from scratch; the byte-truncation math in particular
is easy to get subtly wrong if you rederive it.

For an asset with **count > 1**, use `build_asset` (in
`references/blender_helpers.md`): it downloads the GLB once and places a
uniquely-named copy at each coordinate you planned, so the extra copies cost
no credits, and it cleans up the temp file for you. For a very large count,
`duplicate_linked` makes mesh-sharing copies that keep the scene light. This
is the other half of the cost story: identical copies never re-generate.

If a completed job's response includes more than one download link
(`segment_3d` splits a mesh into labeled parts, each its own GLB), import
every part under the *same* parent Empty rather than creating a separate
Empty per part. The parts are meant to be treated as one object made of
pieces, not as separate scene objects.

## Step 5: Optional refinement pass

For any asset flagged `needs_postprocess` in Step 1, submit the relevant
tool (`rig_3d`

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [ig-shadow-walker](https://github.com/ig-shadow-walker)
- **Source:** [ig-shadow-walker/BlenderXAlpha-3DGenSkill](https://github.com/ig-shadow-walker/BlenderXAlpha-3DGenSkill)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-ig-shadow-walker-blenderxalpha-3dgenskill-alpha-scene-gen
- Seller: https://agentstack.voostack.com/s/ig-shadow-walker
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
