# MCP tool reference All tools operate on the world selected by your credential and its owner's asset library. Tool success includes `structuredContent` plus equivalent JSON text. Tool failure uses `isError: true`; inspect the returned message even when HTTP itself succeeded. ## world_download Input: `{}`. Returns `worldId`, `name`, `revision`, `document`, `assets`, `sources`, `gameScale`, `catalog`, `limits` and `schema`. Asset entries include owner-scoped hash, name, size, triangles, pixels, mesh-part count and a public immutable GLB URL. Source URLs identify the platform's prop, game and shell templates. This reads your editable draft, which can differ from the published version. Batch related changes to keep downloads efficient. ## world_upload Replaces the full draft. It does not publish. ```json { "revision": 1, "document": { "version": 1, "floor": "#dad4c4", "walls": "#e8e1cf", "entities": [ {"id":"dice:0","kind":"game","asset":"dice","position":[-8,0,4],"yaw":0,"scale":[1,1,1],"color":"#d7ba7f"}, {"id":"pillar-west","kind":"prop","asset":"pillar","position":[-14,0,-10],"yaw":0,"scale":[1,3,1],"color":"#ddd6c4"} ] } } ``` The result contains `revision` and `budget`, including `entities`, `bytes`, `manifestBytes`, `memoryBytes`, `triangles` and `pixels`. The submitted revision must exactly match the current draft. Validation includes owner asset membership, game identity, transforms, duplicate IDs and budgets. ## world_edit_entities Adds or replaces entities by ID and removes selected IDs in one revision: ```json { "revision": 2, "upsert": [ {"id":"bench-east","kind":"prop","asset":"bench","position":[14,0,8],"yaw":1.5707963267948966,"scale":[1,1,1],"color":"#42756b"} ], "remove": ["pillar-west"] } ``` Both arrays are optional and default to empty. Each permits at most 1,000 entries. Removal happens first; an upsert with the same ID then recreates it. Unmentioned entities and room colors are preserved. The entire resulting world must pass validation. This avoids a huge upload request, but validation and database serialization still process the complete draft; batch related changes together. ## asset_upload ```json {"name":"Ivory planter","glbBase64":"BASE64_OF_A_SELF_CONTAINED_GLB"} ``` The decoded GLB must be at most 4,000,000 bytes; the encoded JSON is larger. Returns `hash`, `name`, `size`, `triangles`, `pixels` and `meshes`. Reference it as `upload:` in a prop entity. The content hash is owner-scoped. Uploads are validated and re-encoded; the returned bytes can differ from the source file. ## asset_download ```json {"hash":"64_lowercase_hexadecimal_characters"} ``` Returns the library entry and its GLB URL. The hash must belong to the credential's owner. Download the URL as binary GLB data. ## REST transfer alternatives The official bridge uses MCP. Tools that need a binary transfer can also use the following Bearer-authenticated endpoints on `https://betworld.gg`: | Method | Path | Purpose | |---|---|---| | GET | `/api/worlds/ai/export/world` | Full draft and source metadata | | GET | `/api/worlds/ai/draft/document` | Draft, catalog and schema | | PUT | `/api/worlds/ai/draft/document` | Save `{revision,document}` | | POST | `/api/worlds/ai/assets/upload` | Raw GLB with `Content-Type: model/gltf-binary` and `X-Model-Name` | Use `Authorization: Bearer …`. Native clients can omit `Origin`; if supplied, it must match the Betworld origin. See the [complete HTTP API](/world-api/) for owner routes, publishing, credentials, request limits and error responses. ## Rate and concurrency limits World service calls are limited to 120 requests per minute per client IP. Heavy draft writes and reads have bounded admission slots; a busy server returns 503 with `Retry-After`. Retry transient errors with backoff and jitter. Do not flood retries or parallelize revisions for the same world. Public GLB downloads use a separate higher read limit. ## `game_skin_contract` Input: exactly `{"game":"blackjack"}`; `game` must be a supported asset ID. Read-only. Returns the game's fingerprint, `bodyBounds`, `sourceToWorldScale`, ordered `controls`, optional `parts`, `runtimeMounts`, `presentation` (targets, motion channels, triggers and units), v2 starter `template`, strict manifest `schema`, limits and documentation URL. The starter body is an all-zero placeholder, not an uploaded asset. Replace it before saving. The ordered control catalog describes action/index/seat mappings owned by Betworld. Upload only the slot ID and an asset hash. Doubler/Crash return no physical button slots because their controls are live display regions. ## `game_skin_save` ```json { "revision": 12, "skin": { "version": 2, "id": "ivory-blackjack", "game": "blackjack", "contract": "REPLACE_WITH_CURRENT_FINGERPRINT", "body": "REPLACE_WITH_CONVERTED_BODY_HASH", "bindings": [], "placements": [], "clips": [], "motions": [] }, "entityIds": ["blackjack:0"] } ``` Use real values from `game_skin_contract` and `asset_upload`; placeholders above are not valid hashes. Input fields are exactly `revision`, `skin`, `entityIds`. The entity array contains 0–64 unique existing matching game IDs. An empty array saves an unassigned definition. Saving a matching definition ID updates that draft definition; existing entity references remain attached. The response is `{revision,budget}`. A revision conflict requires downloading and reconciling the latest draft. Validation rejects wrong-game assignments, missing IDs, unknown/duplicate slots, foreign assets, stale fingerprints, arbitrary action arguments, callbacks and extra fields. Existing references to a replaced definition must still match its game. The saved definition belongs to your connected draft. Publish the finished revision from your world panel. Read [the complete contract](/game-skin-contract/) for every accepted field, fitting rule and resource limit. `world_upload` may carry the same definitions, and `world_edit_entities` preserves the existing `skins` array while editing references. ## `background_upload` Pass `{name, imageBase64}` to upload a PNG, JPEG or WebP panorama. Maximum decoded input: 12,000,000 bytes; width 512–8192; height 256–4096; aspect 2:1 to 8:1; maximum 16,777,216 pixels. The result contains `{hash, name, size, width, height, pixels}`. Use the hash in `document.background` with `mode: "image"` and a numeric `yaw`, then save through `world_upload`. Terrain parameters use `document.terrain`. See [terrain and backgrounds](/terrain-backgrounds/).