Skip to main content
Glama
EL4CTEO

Roblox Studio MCP

Creator Store

assets
Destructive

Search Roblox's Creator Store for models or audio, then inspect or insert them into your place safely. Filter by scripts, triangles, votes and verified creators before adding.

Instructions

Searches Roblox's Creator Store and inserts models into the place.

search looks through the same public index Studio's own asset browser uses. It reports script COUNT, triangles, whether the creator is verified, whether the asset is free, and what Roblox thinks it is ("Door/Furniture"). insert puts one into the place by id.

Results are ranked by approval WEIGHTED BY vote count, because the raw percentage lies: 100% from two voters outranks 82% from five thousand unless the count is taken into account. The vote count is shown beside the percentage for the same reason.

Filters — excludeScripts, maxTriangles, verifiedOnly, freeOnly, minVotes — are applied here, not by Roblox, and several pages are fetched to fill the results. Roblox's own sort and creator filters are accepted by the endpoint and silently ignored, so they are not offered.

ALWAYS check hasScripts before inserting. Free models carrying scripts are the oldest hazard on the platform, and a model dropped into someone's game can run whatever it likes. The insert reports the script count again, and names them, so it can still be undone.

peek is the safer half of that: it loads the asset in memory WITHOUT putting it in the place and tells you exactly what is inside — every class, every script by name. Nothing is parented, so there is nothing to undo. Use it whenever hasScripts says YES and the model still looks worth having.

Audio searches take a different path from everything else here. They go to the engine's own audio index, so results carry duration, artist and whether the clip is music or a sound effect — the fields that actually decide which sound you want. They return SOUND EFFECTS by default; pass audioType: "Music" for tracks. Filter with minDuration / maxDuration — a footstep is under a second and a music bed is minutes.

Only public assets can be inserted. A private or deleted id fails with a message saying so rather than inserting nothing quietly.

bake is unrelated to the Creator Store and does not upload anything. It turns EditableMesh and EditableImage data into static content, which frees the editable memory budget and lets a mesh built at runtime replicate from the server down to clients.

READ THIS BEFORE REACHING FOR IT. What it produces is scoped to the data model session it was made in. Baking in edit mode therefore carries NOTHING into a playtest — a playtest is a new data model, and the content reads as empty there. Measured, not assumed. Its real use is against a RUNNING playtest server session: pass that studioId, and baking a mesh the game just built is what lets clients see it.

It does not help generate at all. Generated meshes hold opaque content, which the engine refuses to bake.

THE OTHER DIRECTION: upload sends a local file TO Roblox and gives you the asset id. Audio, an image, a 3D model or a video, picked by extension — .mp3/.ogg/.wav/.flac, .png/.jpg/.bmp/.tga, .fbx/.gltf/.glb, .mp4/.mov. This closes the one hole nothing else here covers: a sound effect sitting in a folder on disk used to need Studio's import dialog before anything could reference it.

Uploads are moderated and count against a real monthly quota. Do not guess what it is — Roblox's own guide and the live API disagree, and the account's verification level changes it. Ask op="quota". Do not upload speculatively, and do not re-upload to retry: the first one probably worked.

grant gives a game or a person permission to use assets you own. You do NOT need this for your own assets in your own game — those always work. It is for a collaborator's place, or a group game you do not own. A grant to a game is PERMANENT; Roblox provides no way to revoke one, so it needs confirm: true.

publish sends a .rbxl or .rbxlx from disk to a place. It SAVES a new version by default and only goes live with confirm: true. Note a real limitation: Roblox's publishing API does not update EditableImage, EditableMesh, PartOperation, SurfaceAppearance or BaseWrap instances, and reports success anyway — publish from Studio if the place uses any of those.

Publishing alone does NOT move anyone already playing — they stay on their server running the old code until it empties. Pass restart: true to roll live servers onto the new version, which bleeds them off over 10 minutes rather than dropping players.

quota reports how many uploads are left before Roblox starts refusing them, per asset type, read from the account itself. Check it before a batch rather than discovering the ceiling halfway through.

All of these need an Open Cloud API key. The user sets it once by typing cloud in the Studio panel; never ask them to paste a key into this conversation.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
opYes'search' finds assets, 'peek' shows what is inside one without inserting it, 'insert' adds one to the place, 'bake' makes in-memory mesh and image data replicate, 'upload' sends a local file to Roblox, 'grant' shares one you own with another game or person, 'publish' pushes a place file live.
fileNoupload/publish: path to the file on disk. Omit on `upload` to check whether the credentials are set up without sending anything.
nameNoinsert only: rename it on the way in.
limitNosearch only: how many results.
pathsNobake only: MeshParts to convert, or models containing them.
parentNoinsert only: where to put it. Defaults to Workspace.
assetIdNoinsert and peek only: the asset id.
confirmNoRequired to make a `publish` go live rather than only save, and required for `grant`, whose effect Roblox cannot undo.
keywordNosearch only: what to look for, e.g. "medieval door".
placeIdNopublish only: which place. Omit to use `cloud place`.
restartNopublish only: also roll live servers onto the new version. Without this, players already in a server keep running the old code until it empties.
assetIdsNogrant only: the assets to share. You must own them.
categoryNosearch only: what kind of asset. Only models insert as instances.model
freeOnlyNosearch only: drop paid assets, which cannot just be inserted.
insertAsNoupload only: put the finished asset in the place at this parent path once it is approved. Decals and Models only — an audio id belongs in an AudioPlayer, so use `audio op="graph"` with the id this returns.
minVotesNosearch only: require at least this many votes. Filters out models with a perfect score from three people.
positionNoinsert only: where to place it, e.g. "0, 10, 0". Defaults to wherever it was saved.
studioIdNoTarget Studio; omit for the active one.
assetTypeNoupload only: override the type derived from the extension. Rarely right — Roblox validates the type against the file's real content.
audioTypeNoaudio search only. Defaults to SoundEffect, which is what a noise in a game is. Ask for "Music" only when you want a track — the engine's own default is Music, and it makes "footstep" return three-minute ambient songs with footsteps in the title.SoundEffect
subjectIdNogrant only: the universe, user or group id. Omit for a Universe grant to use the one set with `cloud universe <id>`.
universeIdNopublish only: which game. Omit to use `cloud universe`.
descriptionNoupload only: public description. Moderated.
maxDurationNoaudio search only: longest clip to return, in seconds. Set it to 3 or so for effects — otherwise full-length music dominates the results.
minDurationNoaudio search only: shortest clip to return, in seconds.
subjectTypeNogrant only: who gets access. 'Universe' is a game and is the usual one. Defaults to 'Universe'.
maxTrianglesNosearch only: drop models heavier than this. A prop you place fifty times wants to be in the hundreds, not the tens of thousands.
stripScriptsNoinsert only: delete every Script, LocalScript and ModuleScript from the asset on the way in. The safe way to take geometry from a free model without taking whatever its scripts do.
verifiedOnlyNosearch only: only results from verified creators.
excludeScriptsNosearch only: drop every result that contains scripts. The single safest filter — a free model's scripts run with your game's full permissions.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed14 schema fields changedv0.6.8
    • addedInput schema / properties / assetIds
      Added value: +{
      +  "description": "grant only: the assets to share. You must own them.",
      +  "items": {
      +    "maximum": 9007199254740991,
      +    "minimum": -9007199254740991,
      +    "type": "integer"
      +  },
      +  "maxItems": 50,
      +  "type": "array"
      +}
    • addedInput schema / properties / assetType
      Added value: +{
      +  "description": "upload only: override the type derived from the extension. Rarely right — Roblox validates the type against the file's real content.",
      +  "enum": [
      +    "Audio",
      +    "Decal",
      +    "Model",
      +    "Video"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / confirm
      Added value: +{
      +  "description": "Required to make a `publish` go live rather than only save, and required for `grant`, whose effect Roblox cannot undo.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / description
      Added value: +{
      +  "description": "upload only: public description. Moderated.",
      +  "type": "string"
      +}
    • addedInput schema / properties / file
      Added value: +{
      +  "description": "upload/publish: path to the file on disk. Omit on `upload` to check whether the credentials are set up without sending anything.",
      +  "type": "string"
      +}
    • addedInput schema / properties / insertAs
      Added value: +{
      +  "description": "upload only: put the finished asset in the place at this parent path once it is approved. Decals and Models only — an audio id belongs in an AudioPlayer, so use `audio op=\"graph\"` with the id this returns.",
      +  "type": "string"
      +}
    • changedInput schema / properties / op / description
      Previous value: -"'search' finds assets, 'peek' shows what is inside one without inserting it, 'insert' adds one to the place, 'bake' makes in-memory mesh and image data replicate."New value: +"'search' finds assets, 'peek' shows what is inside one without inserting it, 'insert' adds one to the place, 'bake' makes in-memory mesh and image data replicate, 'upload' sends a local file to Roblox, 'grant' shares one you own with another game or person, 'publish' pushes a place file live."
    • changedInput schema / properties / op / enum
      Previous value: -[
      -  "search",
      -  "peek",
      -  "insert",
      -  "bake"
      -]New value: +[
      +  "search",
      +  "peek",
      +  "insert",
      +  "bake",
      +  "upload",
      +  "grant",
      +  "publish",
      +  "quota"
      +]
    • addedInput schema / properties / placeId
      Added value: +{
      +  "description": "publish only: which place. Omit to use `cloud place`.",
      +  "type": "string"
      +}
    • addedInput schema / properties / restart
      Added value: +{
      +  "description": "publish only: also roll live servers onto the new version. Without this, players already in a server keep running the old code until it empties.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / stripScripts
      Added value: +{
      +  "description": "insert only: delete every Script, LocalScript and ModuleScript from the asset on the way in. The safe way to take geometry from a free model without taking whatever its scripts do.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / subjectId
      Added value: +{
      +  "description": "grant only: the universe, user or group id. Omit for a Universe grant to use the one set with `cloud universe <id>`.",
      +  "type": "string"
      +}
    • addedInput schema / properties / subjectType
      Added value: +{
      +  "description": "grant only: who gets access. 'Universe' is a game and is the usual one. Defaults to 'Universe'.",
      +  "enum": [
      +    "Universe",
      +    "User",
      +    "Group"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / universeId
      Added value: +{
      +  "description": "publish only: which game. Omit to use `cloud universe`.",
      +  "type": "string"
      +}
  2. Changed11 schema fields changedv0.6.5
    • changedInput schema / properties / assetId / description
      Previous value: -"insert only: the asset id to insert."New value: +"insert and peek only: the asset id."
    • addedInput schema / properties / audioType
      Added value: +{
      +  "default": "SoundEffect",
      +  "description": "audio search only. Defaults to SoundEffect, which is what a noise in a game is. Ask for \"Music\" only when you want a track — the engine's own default is Music, and it makes \"footstep\" return three-minute ambient songs with footsteps in the title.",
      +  "enum": [
      +    "SoundEffect",
      +    "Music"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / excludeScripts
      Added value: +{
      +  "default": false,
      +  "description": "search only: drop every result that contains scripts. The single safest filter — a free model's scripts run with your game's full permissions.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / freeOnly
      Added value: +{
      +  "default": false,
      +  "description": "search only: drop paid assets, which cannot just be inserted.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / maxDuration
      Added value: +{
      +  "description": "audio search only: longest clip to return, in seconds. Set it to 3 or so for effects — otherwise full-length music dominates the results.",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / maxTriangles
      Added value: +{
      +  "description": "search only: drop models heavier than this. A prop you place fifty times wants to be in the hundreds, not the tens of thousands.",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / minDuration
      Added value: +{
      +  "description": "audio search only: shortest clip to return, in seconds.",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • addedInput schema / properties / minVotes
      Added value: +{
      +  "description": "search only: require at least this many votes. Filters out models with a perfect score from three people.",
      +  "maximum": 9007199254740991,
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • changedInput schema / properties / op / description
      Previous value: -"'search' finds assets, 'insert' adds one to the place, 'bake' makes in-memory mesh and image data replicate."New value: +"'search' finds assets, 'peek' shows what is inside one without inserting it, 'insert' adds one to the place, 'bake' makes in-memory mesh and image data replicate."
    • changedInput schema / properties / op / enum
      Previous value: -[
      -  "search",
      -  "insert",
      -  "bake"
      -]New value: +[
      +  "search",
      +  "peek",
      +  "insert",
      +  "bake"
      +]
    • addedInput schema / properties / verifiedOnly
      Added value: +{
      +  "default": false,
      +  "description": "search only: only results from verified creators.",
      +  "type": "boolean"
      +}
  3. Changed3 schema fields changedv0.4.5
    • changedInput schema / properties / op / description
      Previous value: -"'search' finds assets, 'insert' adds one to the place."New value: +"'search' finds assets, 'insert' adds one to the place, 'bake' makes in-memory mesh and image data replicate."
    • changedInput schema / properties / op / enum
      Previous value: -[
      -  "search",
      -  "insert"
      -]New value: +[
      +  "search",
      +  "insert",
      +  "bake"
      +]
    • addedInput schema / properties / paths
      Added value: +{
      +  "description": "bake only: MeshParts to convert, or models containing them.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 200,
      +  "type": "array"
      +}
  4. First observedv0.1.8

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only supply coarse hints (destructiveHint, openWorldHint, readOnlyHint=false); the description supplies the specifics an agent actually needs: grants are permanent with no revocation, publish silently fails to update EditableImage/Mesh/PartOperation, restart bleeds servers over 10 minutes, uploads are moderated and quota-bound, bake is scoped to the data model session and does not survive into a playtest, and an API key must be set via the `cloud` command. This is far beyond what the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

For an 8-operation, 30-parameter tool, the length is largely earned and each paragraph is scoped to one operation, with safety-critical guidance front-loaded. It loses a point for editorializing asides ('the raw percentage lies', 'the oldest hazard on the platform') and for restating schema content such as the `restart` behavior, which already appears in the restart property.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's breadth, the absence of an output schema, and only one required parameter, the description covers everything an agent must know: which op to pick, the auth prerequisite, quota/moderation caveats, irreversibility, and sibling routing (e.g. audio ids belong in `audio op="graph"`). Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema descriptions are already rich, so the baseline is 3. The description adds genuine non-schema meaning: the filters are applied client-side with multiple pages fetched, Roblox's own sort/creator filters are accepted and silently ignored (so they are deliberately not exposed), and minVotes/minDuration exist to correct for vote-count and duration skew.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description enumerates eight distinct operations with specific verb+resource pairs ('search looks through...', 'insert puts one into the place by id', 'publish sends a .rbxl or .rbxlx from disk to a place') and even calls out that 'bake' is unrelated to the Creator Store. An agent can identify each capability and distinguish it from siblings like 'audio', 'generate' and 'universe' without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit when/when-not rules and named alternatives: check `hasScripts` before inserting, use `peek` when scripts are present but the model still looks worth having, ask `op="quota"` before a batch, do not upload speculatively. It also states when `grant` is NOT needed ('You do NOT need this for your own assets in your own game').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.