Host your own asset library
Have your own models? Run the Holodeck Asset Library — a single Python file — next to them, and the Playground agent, the Unity client and MCP can search and place your assets exactly like the built-in library.
- One file, Python 3.10+ standard library only — no installs: holodeck_library.py
- Indexes GLB / glTF / FBX / OBJ models and PNG / JPG / TGA textures
- Reads real sizes from GLB / OBJ, Unity
.metaGUIDs, sidecar thumbnails - CORS-enabled file serving (browsers and Unity load files directly), optional Bearer token
- Docker files and full README:
clients/asset-library/in the Holodeck repo
Quickstart
curl -O https://arx.dev/docs/download/holodeck_library.py
python3 holodeck_library.py serve --root ./my-assets --name "My Studio" --port 8787 --token change-me
# browse http://localhost:8787 · API at http://localhost:8787/api/v1/assets
Organise your folder
my-assets/ ← --root
NaturePack/ ← every top-level folder is a pack
pack.json ← optional
Models/
SM_Env_Tree_01.glb
SM_Env_Tree_01.png ← sidecar thumbnail (same name), or NaturePack/Thumbnails/…
SM_Env_Tree_01.glb.meta ← optional Unity .meta → unity_guid
Textures/Nature_Atlas.png
Asset paths look like @my-studio/NaturePack/Models/SM_Env_Tree_01.glb — the same shape as
Holodeck’s own @synty/PolygonTown/…, so vendor locks work the same way.
pack.json (all optional):
| Key | Meaning |
|---|---|
atlas |
Texture applied to models with no embedded textures (Synty-style palette atlas). Textured GLBs keep their own. |
unit_scale |
Metres per file unit. Default 1.0; Synty FBX/GLB exports are centimetres → 0.01. |
tags |
Extra tags on every asset in the pack. |
Textured, metre-scale GLBs need no configuration at all.
Connect it to Holodeck
On a Holodeck deployment (web + worker), set:
PLAYGROUND_ASSET_API_BASE=https://assets.example.com
PLAYGROUND_ASSET_API_TOKEN=change-me
The Playground then builds from your library. Lock programs to @my-studio or a single pack with
the Assets ▾ menu.
Deploy
Put it behind any TLS proxy and tell it its public URL so file links are absolute:
python3 holodeck_library.py serve --host 0.0.0.0 --port 8787 --token change-me --base-url https://assets.example.com
assets.example.com { # Caddyfile
reverse_proxy 127.0.0.1:8787
}
Files are public by default (so browsers can load them); --private-files requires the token there
too. The index lives in <root>/.holodeck-index.json and refreshes itself as files change.
The API contract
Want to write your own server (in Node, Go, inside your asset manager…)? Implement these and
Holodeck will treat it as a library. All JSON; Authorization: Bearer <token> if you use tokens.
| Endpoint | Returns |
|---|---|
GET /api/v1/assets?q=&kind=&per=&page= |
{ "assets": [Asset], "meta": { "current_page", "total_pages", "total_count", "per_page" } } — q: every word must match name/path/tags; an @scope/Pack token restricts to that path prefix. kind=prefab may return []. |
GET /api/v1/assets/:id?viewer=1 |
Asset + "viewer": { "id", "name", "kind": "model", "glb_url", "model_url", "format", "unit_scale", "materials": [{ "texture_url" }], "material", "thumbnail_url" } |
GET /api/v1/packs |
{ "packs": [{ "key": "@scope/Pack", "name", "scope", "counts": { "model": n } }] } |
| files | any absolute URLs, served with Access-Control-Allow-Origin: * |
Asset: id (4–20 letters/digits), name, kind (model / prefab / texture), path, tags,
unity_guid (or null), url, filename, thumbnail_url, and
meta: { "has_geometry", "glb_url", "unit_scale", "stats": { "size_m": { "x", "y", "z" }, "triangles" } }.
Prefabs are optional: a library that has them returns kind: "prefab" and, in viewer, a
prefab_tree plus prefab_parts — see the Playground API.