Skip to main content
Glama
EL4CTEO

Roblox Studio MCP

Roblox Studio MCP

Let an AI agent drive Roblox Studio: read your place, edit scripts, build geometry, run playtests, take screenshots. 35 tools. MIT.

The Studio MCP panel

Install

1. The plugin

npx -y @el4cteo/rbx-studio-mcp --install-plugin

Or drop StudioMCP.rbxmx from Releases into your Studio plugins folder.

2. The server

claude mcp add roblox-studio -- npx -y @el4cteo/rbx-studio-mcp

Codex CLI:

codex mcp add roblox-studio -- npx -y @el4cteo/rbx-studio-mcp

Cursor, Claude Desktop, Gemini CLI, Windsurf — add to their config file:

{
  "mcpServers": {
    "roblox-studio": {
      "command": "npx",
      "args": ["-y", "@el4cteo/rbx-studio-mcp"]
    }
  }
}

VS Code / Copilot (.vscode/mcp.json) uses "servers" instead of "mcpServers", plus "type": "stdio".

opencode (opencode.json):

{
  "mcp": {
    "roblox-studio": {
      "type": "local",
      "command": ["npx", "-y", "@el4cteo/rbx-studio-mcp"],
      "enabled": true
    }
  }
}

3. Open Studio and accept the 127.0.0.1 prompt. Check it works with studio_status.

Something wrong? Run npx -y @el4cteo/rbx-studio-mcp doctor — it says what is broken and how to fix it.

Port is 44755, loopback only. Change it with --port and match it in the plugin.

Related MCP server: roblox-studio-mcp

Tools

Session

studio_status list_studios set_active_studio

Discover

tree inspect find api

Scripts

script_read script_edit script_grep script_create sync

Instances

create modify delete move

World

geometry terrain generate assets collision audio undo

Data & live game

datastore universe

Run & debug

playtest execute_luau character input console debug performance

Look

screenshot viewport device

Write tools take arrays — ten script edits is one call, one Ctrl+Z, and all-or-nothing.

Work on files

sync mirrors your scripts into a folder, so an agent can edit code with its own file tools and use Studio to test.

sync op="pull"      # Studio -> ./studio
sync op="push"      # ./studio -> Studio
sync op="watch"     # both ways, live, until op="stop"
  • Rojo-style layout: Main.server.luau, .client.luau, .luau; a script with children is a folder with init. A sourcemap.json is written for luau-lsp.

  • Rename or move a file and the script moves with it, keeping its attributes and references.

  • Edited on both sides? It's a conflict and neither side is touched. Studio's version waits in .rbx-sync/conflicts/; merge into the file and sync again, or pass prefer: "studio" / "disk".

  • Deleting a file deletes the script (one Ctrl+Z). A script deleted in Studio sends its file to .rbx-sync/trash.

  • export writes UI or any instance tree as a .build.json file; edit it and build rebuilds it, keeping its scripts. Edits made in Studio flow back into the file.

  • watch only works when something changes: about 0.5s each way, even with 2,000 scripts. Conflicts show up in the agent's next reply.

Open Cloud

Some calls reach past Studio to Roblox itself. All need one API key; everything else works without it.

assets op="upload"

send a local audio/image/model/video file, get an asset id

datastore target="live"

the running game's real player data

execute_luau target="live"

run a script on the published place

universe

restart servers, message them, ban players, read server logs, sell products and passes, read analytics, schedule events

also

assets op="grant", op="publish", script_read/script_edit target="live"

Make a key at Creator Dashboard → Credentials, adding the permissions you want: assets, universe-datastores, ordered-data-stores, luau-execution-sessions, universe-places, universe-place-instances, universe, messaging-service, user-restrictions, inventory, users, asset-permissions, developer-products, game-passes, universe-analytics. Scheduling events needs the universe.event:read and :write permissions.

Then in the Studio panel:

cloud key <paste>
cloud user <your user id>
cloud place <place id>

cloud place works out the universe for you. The typed key is masked in the log and in the history, and stored at ~/.rbx-studio-mcp/credentials.json (mode 0600) — never in the place file, never in the conversation. cloud shows what is set, cloud test re-checks it, cloud forget deletes it. ROBLOX_API_KEY and friends in the environment work too and take priority.

Two things to watch: a playtest connects a second session, so pass studioId and use the edit one for changes that must last; device emulation stays on until device op="stop".

The console panel

Every call is logged with how long it took. At the foot of the panel is a command line. Type a command — or run chat on and type a sentence to have a coding agent answer it.

help

list everything

doctor

check the setup

status version place clients

what this session is

studios use <n>

which Studio window calls go to

theme [name] visuals autoopen [on|off] log [level] clear copy

the panel

port [n] reconnect

the connection

cloud [key|user|group|test|forget]

the Open Cloud key upload uses

chat [on|off]

let an agent answer sentences (off by default)

agent [use <id>|new] stop

which agent runs your prompts

anything else

sent to that agent, once chat is on

Click the bar and every command is listed with what it does. Keep typing to filter, scroll for the rest, click one to fill it in.

With chat on, prompts start a real agent — whichever you have on PATH: Claude Code, Codex, opencode, Gemini, Cursor, Amp, Qwen Code, Factory Droid, goose, Copilot CLI, Aider, Crush, DeepSeek Harness. It runs headless, drives the same Studio, and its work appears in the log. It is a separate session from your terminal, billed separately, and allowed the rbx-studio tools only. stop cancels it.

Eight themes behind the tab on the right edge. Your pick is remembered.

Why this one

  • Push, not poll — 13.6 ms per call against 25.8 ms.

  • Safe script edits — writes go through the script editor, so unsaved work survives.

  • Stale edits are refused — pass back the rev from script_read and a write lands only if nobody else touched the file.

  • Property names are checked against the running engine, so Anchorred comes back as a suggestion, not a runtime error.

DeepSeek Harness (dsh)

This server registers as a dsh plugin. Append this row to $DSH_HOME/cordis.patch.yml, or to $DSH_HOME/profiles/<name>/cordis.patch.yml for one profile only:

- insert:
    - id: mcp-rbx-studio
      name: '@deepseek-ai/dsh-mcp-client'
      config:
        serverName: rbx-studio
        transport: stdio
        command: npx
        args: ['-y', '@el4cteo/rbx-studio-mcp']
        cwd: !!js process.cwd()

Then dsh --profile headless "what is in workspace". Needs DEEPSEEK_API_KEY. The same row, commented, is in config/dsh.cordis.yml for use with dsh --patch.

Security

Loopback only. Requests need a header a browser cannot set cross-origin and a loopback Host, so a web page cannot reach it, even through DNS rebinding. Your experience's "Allow HTTP Requests" setting is untouched.

Development

npm install
npm run build          # TypeScript -> dist/
npm run install:plugin # build the plugin and copy it into Studio
npm test

Needs luau, luau-compile and luau-analyze from the Luau releases on PATH or in tools/.

With Studio open and the plugin loaded, node scripts/test-live.mjs checks the transport and node scripts/test-live-tools.mjs [--playtest] runs every tool, node scripts/test-live-sync.mjs checks sync, and node scripts/test-live-sync-scale.mjs times it on 2,000 scripts. All clean up after themselves.

Licence

MIT.

Available Tools

35 tools
apiWhat a class can doA
Read-onlyIdempotent

Lists the properties, methods and events of any Roblox class, read from the engine that is running.

Use it before writing Luau against a class you are not certain of. Guessing a method name costs a runtime error and a round trip; this costs one call and is never out of date, because the answer comes from the running binary rather than from a published dump or from training data. That matters most for exactly the classes worth checking — new ones, and ones that changed recently.

Members come back as signatures rather than bare names — AddAccessory(accessory: Instance), HoldDuration: number — because a name tells you something exists and a signature tells you how to call it, which is the actual question.

describe takes a class name and gives the members it declares itself, counting the inherited ones separately. classes searches class names, which is how to find one whose exact spelling you do not have.

Deprecated members are never listed, only counted — Instance has eight, including clone, remove and getChildren. They still run, so picking one from a list gives you working code and a deprecation warning in the user's output. Members no script may use at all are counted with them.

This is not the same as inspect. inspect reads the values on an instance that exists; this reads the shape of a class whether or not anything in the place is one — which is what you need when deciding what to create in the first place.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'describe' details one class, 'classes' searches class names.describe
includeNodescribe only: which member kinds to return. Defaults to all three; narrow it when you only need one and the class is large.
containsNoclasses only: substring to match, case-insensitive, e.g. "constraint" or "gui". Omit to list everything.
studioIdNoTarget Studio; omit for the active one.
classNameNodescribe only: the class, e.g. "TweenService", "ProximityPrompt", "Humanoid". Case-sensitive.
inheritedNodescribe only: include members inherited from Instance and Object. Off by default because they swamp the answer — ProximityPrompt has 2 methods of its own and 42 inherited, and the two you want are not the ones you already know. The inherited count is reported either way.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint false, and the description adds valuable behavior beyond that: results come from the running binary, members are returned as signatures, deprecated members are only counted and never listed, and deprecated members still execute with warnings. This is non-obvious, important behavioral context that is fully consistent with the annotations.

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?

The description is front-loaded with purpose and every paragraph carries a distinct, useful point. It is longer than a minimal definition, but the length is warranted by the need to explain deprecation semantics, signature format, and sibling differentiation, so there is no wasted text.

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?

With no output schema, the description takes on the burden of explaining what the agent will receive: member signatures, inherited counts, and the fact that deprecated members are counted but not listed. It also covers both operations and their typical usage, making it complete for an introspection tool.

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 description coverage is 100%, so each parameter already has a meaningful description, giving a baseline of 3. The tool description adds genuine value by explaining the semantic difference between describe and classes and by justifying why inherited defaults to false, complementing rather than merely repeating the schema.

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 opens with a specific verb-resource pair: 'Lists the properties, methods and events of any Roblox class, read from the engine that is running.' It explicitly contrasts with the sibling inspect, which reads values on an existing instance, so the agent can differentiate the two tools without inspecting schemas.

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 explicitly states when to use the tool: 'Use it before writing Luau against a class you are not certain of.' It also explains when not to use it, drawing a clear line against inspect, and gives guidance for choosing between the describe and classes operations.

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

assetsCreator StoreA
Destructive

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.

ParametersJSON 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.

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.

audioWire up Roblox's audio graphA
Destructive

Builds and inspects the modern audio API — AudioPlayer, emitters, effects and the Wires between them.

Roblox's modern audio is a signal graph, not one instance with a Play method. An AudioPlayer holds the asset, an AudioEmitter puts the sound in the world or an AudioDeviceOutput sends it to the player's speakers, effects sit in between, and NOTHING is connected until a Wire joins two named pins. A place can hold a perfectly configured AudioPlayer with the right asset and the right volume and be completely silent, with no error anywhere, because the wire was never made. That is what this tool is for: create can make each instance, but the pin names, the direction and the choice of sink are where it actually goes wrong.

graph is the one to reach for: it builds a whole working chain in one undoable step. kind="world" gives a sound that comes from a part; kind="ui" gives one with no position, for menus and music. Add effects to splice reverb, EQ or a fader into the chain.

wire joins two instances you already have. inspect reads an existing graph back and reports every connection — including the ones that report Connected = false, which the Explorer does not show and which are the usual reason for silence.

The old Sound instance still works and is still shorter for a plain one-off noise; use create for that. Come here when the case needs effects, per-listener mixing, or one emitter fed by several sources.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'graph' builds a whole working chain, 'wire' joins two existing instances, 'inspect' reads a graph back.graph
toNowire only: the instance sound goes INTO.
fromNowire only: the instance sound comes OUT of.
kindNograph only: 'world' is a sound heard from a place — it needs a part to come from. 'ui' has no position: menu clicks, music. Defaults to 'world'.
nameNograph only: name for the AudioPlayer.
pathNoinspect only: where to look. Omit to walk the whole place, which is the right call when tracking down silence of unknown origin.
assetNograph only: the audio id, e.g. "rbxassetid://1234". Find one with `assets op="search" category="audio"`. Leave it out to build the chain now and set the asset later.
toPinNowire only: the target's input pin. Defaults to "Input". A wrong pin name is accepted by the engine and produces silence, so the name is checked against the instance before the wire is made.
parentNograph only: where the graph goes. For kind="world" this is the part or attachment the sound comes from.
effectsNograph only: effect classes to splice between the player and the output, in order, e.g. ["AudioFader", "AudioReverb"]. Also accepts AudioEqualizer, AudioCompressor, AudioEcho, AudioDistortion, AudioPitchShifter, AudioChorus, AudioFlanger and AudioLimiter.
fromPinNowire only: the source's output pin. Defaults to "Output", which is right for everything but a channel splitter.
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare destructive/openWorld/non-idempotent, so the bar is lower, and the description adds real value on top: the silent-failure mode ('completely silent, with no error anywhere'), that pin-name validation happens before wiring, that 'inspect' surfaces Connected = false links the Explorer hides, and that 'graph' runs in one undoable step. It never states what mutation is destructive, which keeps it from a 5.

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?

Front-loaded with the one-line summary and then the mental model, and every paragraph carries information (ops, failure mode, alternatives). It is somewhat long and ornate for a tool description, but the length is justified by 12 parameters and the subtle graph semantics.

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?

No output schema exists, and the description compensates by explaining what 'inspect' returns (every connection, including false ones). It covers the domain model, the three ops, and the parameter concepts well enough that an agent can call it correctly on a complex 12-parameter tool.

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%, so a 3 is the baseline. The description nonetheless adds conceptual meaning: it frames pin names, direction and sink choice as 'where it actually goes wrong', explains the world-vs-ui sink distinction, and justifies omitting 'path'/'asset'. That is more than repeating the schema.

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?

States specific verbs and resources for each op — 'graph builds a whole working chain', 'wire joins two existing instances', 'inspect reads a graph back' — and frames the tool as building/inspecting the modern audio API. It distinguishes itself from the sibling 'create' tool explicitly, so an agent can tell them apart without opening a 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?

Gives explicit when-to-use per op ('graph is the one to reach for', 'wire joins two instances you already have', 'inspect reads an existing graph back') and names the alternative: 'The old Sound instance still works... use create for that. Come here when the case needs effects, per-listener mixing, or one emitter fed by several sources.' When-not guidance is present.

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

characterDrive the player during a playtestA

Moves and acts as the player character in a running playtest, so gameplay can be tested without asking the user to play it.

moveTo walks to a position or to an instance, following a path computed around walls and gaps rather than a straight line into them. It reports whether it ACTUALLY ARRIVED and how far short it stopped — a route blocked by something you did not know about otherwise looks identical to a successful walk.

act does the one-shot things worth testing: jump, sit, stand, respawn, kill (to exercise the death and respawn path), teleport, and equip/activate to use a Tool — which is how combat gets tested, since Activate is exactly what a mouse click triggers. Note that teleport skips everything in between, so triggers and collisions along the route do not fire — walk if you are testing those.

state reports position, health, walk speed and what the humanoid is doing. Call it before and after anything else here.

This drives the Humanoid directly rather than simulating keystrokes, which is the right tool for going places: pathfinding around a wall is one call here and a sequence of guessed key presses otherwise. For anything bound to a control rather than to movement — does E open the door, does the sprint key work, does Escape close the menu — use input, which sends real key and mouse events.

REQUIRES A RUNNING PLAYTEST, and the character lives in the playtest's data model — address these to the playtest's studioId from list_studios, not the editor's. Run mode has no character at all; use playtest op=play.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'moveTo' walks somewhere, 'path' checks a route without walking it, 'act' performs an action, 'state' only reports.
toNoTarget position, e.g. "25, 5, -10". Used by moveTo and by teleport.
fromNopath only: where the route starts, e.g. "0, 5, 0". Defaults to the character.
pathNomoveTo only: walk to this instance instead of a coordinate.
toolNoequip only: the Tool's name.
costsNoMaterial or PathfindingModifier label → cost, e.g. { "Water": 20 } to avoid swimming. Higher is more avoided; the route chosen is the cheapest total, not the shortest.
actionNoact only: what to do. 'equip' takes a Tool from the Backpack or StarterPack, 'activate' uses it (what a mouse click triggers).
directNomoveTo only: walk straight at the target without pathfinding. Use when a route is reported unreachable but you want to see what happens.
playerNoWhich player, by name. Omit for the only one; needed in a multiplayer test.
toPathNopath only: an instance to end at instead of `to`.
canJumpNomoveTo only: allow the path to include jumps.
spacingNoStuds between waypoints, default 4. Tighter follows the geometry more closely; wider is a coarser route.
canClimbNoWhether it may climb truss. Off by default.
fromPathNopath only: an instance to start from, e.g. "Workspace.SpawnLocation".
studioIdNoThe PLAYTEST session's id — not the editor's. See list_studios.
agentHeightNoHow tall the walker is. Defaults to 5, a standard character.
agentRadiusNoHow wide the walker is, in studs. Defaults to 2 — a standard character. Raise it to ask whether a bigger NPC fits through the same gaps a player does.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations only declare generic flags (readOnlyHint=false, openWorldHint=true, destructiveHint=false, idempotentHint=false). The description adds real behavioral context beyond them: `kill` exercises the death/respawn path, `teleport` skips triggers and collisions, `moveTo` reports whether it ACTUALLY ARRIVED and how far short, and a running playtest is required. This is materially more than 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?

Front-loaded with the core purpose, then well-paragraphed by op and by sibling routing; almost every sentence carries actionable detail. Slightly long and a few clauses are decorative ('which is how combat gets tested'), keeping it short of a 5.

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

Completeness4/5

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

For a 17-parameter, multi-mode tool with openWorld semantics and no output schema, the description covers the operational context an agent needs (preconditions, mode selection, sibling routing, key side-effect caveats). It stops short only on how `state`/`path` results are shaped, which the missing output schema would otherwise have to cover.

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%, so the baseline is 3 and the schema already carries the per-parameter documentation. The description nevertheless adds cross-parameter semantics that the schema alone doesn't: teleport-vs-walk trade-offs, the equip/activate chain as the combat-test path, and the `costs` avoidance intent. That is worth one step above baseline.

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 names a concrete verb+resource (drives the player character during a running playtest) and enumerates its `op` modes with distinct purposes. It explicitly distinguishes itself from the `input` sibling for control-bound tests and from `playtest op=play` for entering run mode.

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?

Gives explicit routing: use `input` for anything bound to a control rather than movement, walk rather than teleport when testing triggers/collisions, call `state` before and after anything else, and note it requires a running playtest with the playtest's studioId, not the editor's.

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

collisionCollision groupsA
Destructive

Controls which parts physically collide with which.

This is the right answer to 'these should pass through each other'. The alternative — turning CanCollide off — disables collision against everything, so a ghost that should pass through walls also falls through the floor.

The order is: create a group, assign parts to it, then set what it is collidable with. A group with nothing assigned does nothing.

Assigning a Model assigns every part inside it, which is almost always what is meant.

Groups are not undoable and not scoped to a session: remove when one was created to try something and is no longer wanted, rather than leaving it registered in the place indefinitely. The built-in "Default" group cannot be removed.

Groups belong to a world, not to the place. The Workspace is the default and is what nearly every question is about; a WorldModel inside a ViewportFrame keeps its own separate registry, so pass worldModel to reach that one. A group of the same name in each is two different groups.

THE SAME TOOL ANSWERS WHAT IS ACTUALLY THERE. cast fires a ray, block or sphere and reports the first thing it meets — the part, the hit point, the surface normal, the material and the distance. overlap lists everything inside a box, a radius, or overlapping an existing part.

That is the one question the Explorer cannot answer. A path tells you an instance exists and where its pivot sits; it does not tell you the door frame is clipping into the wall, that the spawn is buried a stud inside the floor, or that nothing stands between the turret and the player. Geometry wrong in exactly those ways looks perfect in inspect.

The queries live here because they ARE collision queries: they honour the very groups the other half of this tool manages. A cast run in the wrong collisionGroup reports a clear path through a wall the player cannot walk through — a wrong answer indistinguishable from a right one. A miss comes back as hit: false, which is a real answer and usually the one being checked for.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNooverlap only: the centre, for region "box" or "radius".
toNocast only: a point to aim at. Use this for sightlines — it saves working out a direction vector, which is where sign errors live.
fromNocast only: where the cast starts, e.g. "12, 0, 5".
onlyNocast/overlap: consider ONLY these instances and their descendants.
pathNooverlap region="part" only: the part to test against.
sizeNocast shape="block" or overlap region="box": the volume size. Defaults to "1, 1, 1" for a cast and "4, 4, 4" for an overlap.
withNocollidable only: the other group.
groupNoThe group's name. Required for everything but list.
limitNooverlap only: how many parts to list. Defaults to 50.
pathsNoassign only: parts or models to put in the group.
shapeNocast only: 'ray' is a line and the usual choice. 'block' and 'sphere' sweep a volume along the same path — use them when the thing moving has width, e.g. whether a character fits through a gap rather than whether a point does.
actionNoGroups: 'list' shows them and changes nothing, then 'create', 'assign', 'collidable', 'remove' (which unregisters a group entirely — not the same as un-assigning parts). Queries: 'cast' fires a shape and reports the first hit, 'overlap' lists what is inside a volume.list
ignoreNocast/overlap: skip these and their descendants. The usual case is the character doing the looking, which otherwise blocks its own cast at zero distance.
radiusNocast shape="sphere" or overlap region="radius": the radius. Defaults to 1 for a cast and 4 for an overlap.
regionNooverlap only: 'box' and 'radius' need `at`; 'part' takes `path` and reports what overlaps that part — the fastest way to find things clipping through each other. Defaults to 'box'.
distanceNocast only: how far along `direction`. Defaults to 100.
studioIdNoTarget Studio; omit for the active one.
directionNocast only: which way to go, e.g. "0, -1, 0" for down. Used with `distance`.
collidableNocollidable only: whether the two groups collide. False makes them pass through.
worldModelNoPath to a WorldModel whose own collision groups this call is about, e.g. "StarterGui.Preview.Viewport.WorldModel". Omit for the Workspace, which is what you want unless the parts in question live inside a ViewportFrame.
ignoreWaterNocast only: pass through terrain water instead of hitting it.
collisionGroupNocast/overlap: run the query as if from a part in this group. Required for a truthful answer in any place that uses groups.
respectCanCollideNocast/overlap: skip parts with CanCollide off. Off by default, matching the engine — leave it off to ask what is there, turn it on to ask what would stop a player.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations declare destructiveHint=true and idempotentHint=false but say nothing concrete; the description supplies the specifics an agent needs — groups are not undoable, not session-scoped, the built-in Default group cannot be removed, and a same-named group in a WorldModel is a different group. It also discloses that a wrong collisionGroup yields a plausible-but-wrong answer and that a miss returns hit:false.

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?

Front-loaded with the core purpose and organized into clear conceptual blocks, and every section is relevant. It is on the long side for a single description and includes persuasive flourishes ('Geometry wrong in exactly those ways looks perfect in inspect') that, while justifying the tool, could be trimmed.

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?

For a 23-parameter, seven-action tool with no output schema, the description covers the group lifecycle, the world-vs-place scoping, the query semantics and their failure modes. An agent has enough to select the right action and interpret a null/false result without further inference.

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 description coverage is 100%, so the baseline is 3. The description adds genuine conceptual meaning beyond the schema — the create/assign/collidable ordering, that assigning a Model assigns every part inside it, that an empty group does nothing, and that collisionGroup is 'required for a truthful answer.' It stops short of per-parameter detail, but the added semantics exceed the schema's field-level docs.

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?

States a specific verb+resource ('controls which parts physically collide with which') and explicitly covers the tool's two halves: group management (create/assign/collidable/remove) and collision queries (cast/overlap). An agent can distinguish it from siblings like inspect, tree, or geometry because the description names exactly what unique question it answers.

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?

Explicitly routes between alternatives: use groups rather than turning CanCollide off, which 'disables collision against everything.' It gives the ordering (create → assign → collidable), the when-to-remove rule, the worldModel-vs-Workspace condition, and the cast-vs-overlap choice. This is close to exhaustive when/when-not guidance.

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

consoleRead Studio outputA
Read-onlyIdempotent

Reads Studio or playtest client output — prints, warnings and runtime errors, newest last.

This is how to find out what actually happened after a playtest or an execute_luau call. An error here usually names the script and line, which script_read can then open directly.

Use target="client" with the playtest server studioId to read continuously captured client output. In multiplayer, select a player by name. Pass the returned nextCursor as since to read only newer lines; cursors belong to one session and player. Evicted or limit-skipped lines are reported.

Filter with level to see only errors, or pattern to follow one subsystem's logging. Up to 2000 lines are held, so prefer a filter over a large limit.

mode="drain" reads a busy log without gaps: oldest unread matches first, and a cursor that stops at the first one not shown. Keep the same filters while draining. group collapses identical lines into one with a count. An error whose stack trace arrived late comes back once more, marked update.

Each connected session keeps its own log, recorded from the moment its plugin loaded — the editor session and a running playtest server do not share one. To read what a playtest printed, target the playtest's studioId (see list_studios); the editor's log will not have it. Nothing printed before the plugin or client relay loaded is recoverable.

A quiet log is not proof nothing was said. Messages Studio itself emits — the ones the Output window attributes to "Studio" rather than to a script — are inconsistent, and they arrive in the session that RAISED them, which is not always the one you are looking at: the warning that a Script with a non-legacy RunContext inside a starter container will run multiple times shows up in the playtest server's log, where the script actually loads, and never in the editor's, where it was created. Do not read silence as an all-clear — when a script misbehaves in a way nothing here explains, check the Output window yourself, or ask the user what it says.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNo'tail': the newest matches, cursor at the end of the log. 'drain': the oldest unread matches, cursor at the first one not shown, so a loop reads every line once.tail
groupNoCollapse identical lines into one row with a count and first/last times.
levelNoOnly this severity. Omit for everything.
limitNoMaximum items to return (1-500).
sinceNoOpaque nextCursor from a previous console response; return only newer matching lines.
playerNoClient only: player name, required when multiple players are present.
targetNoOutput source; client requires a running playtest server studioId.studio
patternNoLua pattern the message must match, e.g. "Combat" or "^%[Server%]". Lua patterns escape with %, not backslash.
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already cover the read-only/idempotent safety profile, yet the description adds substantial behavior beyond them: cursor is session-and-player scoped, 2000-line eviction, late stack traces reappearing as 'update', drain-mode cursor semantics, and the caveat that silence is not an all-clear. This is exactly the extra context annotations cannot carry.

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?

Long (nine parameters, dense caveats), but front-loaded with the purpose and mostly earned sentences. Some repetition exists — session isolation is stated twice and the closing paragraph on Studio-emitted messages runs long — which keeps it off a 5.

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?

With no output schema and nine parameters, the description still covers return semantics (nextCursor, update marker, evicted/skipped lines reported) and the multi-session model an agent must understand to target the right log. Nothing essential to correct invocation 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% so the baseline is 3, but the description goes further: it explains that cursors belong to one session/player, that filters must stay stable while draining, and that a filter beats a large limit. It doesn't restate every enum, which the schema already handles, so 4 rather than 5.

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?

States a specific verb and resource ('Reads Studio or playtest client output — prints, warnings and runtime errors') and immediately distinguishes itself from siblings execute_luau and script_read by positioning itself as the way to see what happened after a run. An agent can tell it apart from script_read/script_grep without opening a 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?

Explicit when-to-use ('after a playtest or an execute_luau call'), when to choose target="client" vs the editor log, when to filter vs raise limit, and a clear boundary case ('check the Output window yourself, or ask the user'). Alternatives and their selection conditions are named.

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

createCreate instancesA
Destructive

Creates instances with their properties, attributes and tags set at creation, as one undoable step.

Nest with children to build a whole model in a single call. That is both faster and safer than creating a parent and then addressing it: a new instance's path is not knowable until it exists, and same-named siblings make guessing it unreliable.

Property names are checked against the live Roblox API dump before anything is sent to Studio, so a typo comes back with the closest real names rather than an engine error.

Use script_create for Script, LocalScript and ModuleScript — it takes source directly.

ParametersJSON Schema
NameRequiredDescriptionDefault
studioIdNoTarget Studio; omit for the active one.
instancesYesInstances to create together as one undoable step.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the annotations, the description adds valuable behavioral context: creation happens "as one undoable step," nested builds are "both faster and safer," and property names are validated against the live Roblox API dump before anything is sent to Studio. It also explains why child creation is safer, which helps the agent reason about failure modes. No contradiction with the annotations.

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

Conciseness5/5

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

The description is compact and well-structured: one sentence for purpose, one paragraph for nesting strategy, one for API validation, and one for the sibling tool. Every sentence earns its place and no information is redundant with the schema.

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

Completeness4/5

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

For a complex creation tool, the description covers the key operational contexts: nesting, undo behavior, validation, and script-specific routing. The rich schema and annotations handle the parameter-level detail. The only minor gap is that with no output schema, the description does not describe the return value, though for a create operation this may be self-evident from Studio context.

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%, so the baseline is 3, but the description adds meaning beyond the schema by explaining the rationale for `children` (paths are not knowable until existence, same-named siblings make guessing unreliable) and by framing properties/attributes/tags as set-at-creation. It does not repeat parameter syntax, which is already well documented in the schema.

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 opens with a specific verb and resource: "Creates instances with their properties, attributes and tags set at creation, as one undoable step." It also differentiates from the closest sibling by saying "Use `script_create` for Script, LocalScript and ModuleScript," so an agent can distinguish this tool from script creation without opening either 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?

The description gives explicit when-to-use guidance: build whole models in one call via `children`, and avoid the separate create-then-address pattern because paths are unknowable until creation. It also names the exact alternative for scripts (`script_create`) and the condition for choosing it. This is concrete, actionable routing guidance.

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

datastoreRead and write saved dataA
Destructive

Reads and writes the game's saved data — DataStore and MemoryStore — from the connected Studio.

This is the only tool here that looks at anything outside the place file. Every other tool answers 'is the instance right'; this one answers 'is what the player saved right', which is a different question and the one behind most reports of lost progress, reset stats, or items that come back after a rejoin.

kind="data" (the default) is DataStoreService: permanent, per-player, and version-tracked. kind="memory" is MemoryStoreService: a shared scratchpad that expires on its own — queues, locks, live leaderboards.

The workflow for a bug report is: list with no store to see what exists, list with one to see its keys, get the player's key, and — the part worth knowing about — versions then get with a version to see what that same key held BEFORE it broke. You cannot diagnose a bad save by looking only at the bad save.

Writes need confirm: true on kind="data", because nothing in this server can undo one: there is no recording to cancel and no Ctrl+Z. Read the key first.

DataStore needs 'Enable Studio Access to API Services' ticked in Game Settings → Security, and a published place. If it is off, this tool says so in those words rather than reporting the raw 502. MemoryStore needs neither.

target="live" is the other half of this tool and the one that answers a real bug report. It goes to Roblox directly instead of through Studio, so it sees exactly what the running servers see — not what the place happens to be connected to, and with no Studio API toggle involved. Use it whenever the question is about a player who is actually playing. It needs an Open Cloud key and a universe id; the user sets both once with cloud in the Studio panel.

kind="ordered" (live only) is OrderedDataStoreService, the leaderboard backend: numbers only, always sorted, no history. list returns it ranked highest first, which is the leaderboard itself.

op="snapshot" is the safety net. It tells Roblox to snapshot every data store in the experience, so support can roll them back. TAKE ONE BEFORE ANY LIVE WRITE. Roblox allows one per experience per UTC day, and the result says whether this call actually took one — a second call the same day reports success while doing nothing, and anything written since the first one is not covered.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNoget only: read the version that was current at this Unix time in MILLISECONDS. Use when the player says when it broke but no version id is known.
opNo'list' shows stores (no `store`) or a store's keys (with one). 'versions' is DataStore only and is how you see a key's history.list
keyNoThe key. Usually the player's UserId as a string.
ttlNomemory set only: seconds before the value expires. Defaults to an hour.
kindNo'data' = DataStoreService, permanent and versioned. 'memory' = MemoryStoreService, shared and expiring. They are separate storage — a key in one is not in the other.data
limitNolist/versions only: rows to return. Defaults to 50.
scopeNoDataStore scope, if the game uses them. Omit for the default — but if a store reads as empty and you expected data, a scope is the usual reason.
storeNoData store name, or the sorted map's name for memory. Omit on `list` to see which stores exist.
valueNoset only: the new value as JSON — {"coins":10}, 42, or a bare string. Read the key first and edit what comes back rather than writing a value from scratch: a save is usually a whole table and writing part of one deletes the rest.
amountNolive increment only: how much to add. Negative subtracts. Safer than get-then-set for currency, which loses whatever the player earned in between.
createNolive set only: allow writing a key that does not exist yet. Off by default — Open Cloud separates create from update, and a typo'd key silently creating a second empty save beside the real one is exactly what looks like a player's data resetting.
cursorNolist only: continue from a previous call's cursor.
prefixNolist only: only names starting with this.
targetNo'studio' reads through the connected Studio — right while building. 'live' goes to Roblox over Open Cloud and sees what the published game's servers see — right for a bug report.studio
confirmNoRequired for set and remove on kind="data". This is real player data and nothing here can put it back.
versionNoget only: read this exact version instead of the current value. From `versions`.
studioIdNoTarget Studio; omit for the active one.
universeIdNolive only: which game. Omit to use the one set with `cloud universe <id>` in the panel.

TDQS

A4.9/5.0
Behavior5/5

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

The description goes well beyond the annotations, disclosing that writes on kind='data' cannot be undone, that confirm: true is required, that DataStore needs a Studio API access setting, and that live snapshots are limited to one per UTC day while still reporting success on duplicate calls. There is no contradiction with the annotations.

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

Conciseness5/5

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

The description is long but every section earns its place for an 18-parameter, dual-target tool. It is front-loaded with the core purpose and sibling differentiation, then moves through workflow, safety warnings, authentication prerequisites, live targeting, ordered stores, and snapshot limits in a labeled, scannable structure with no filler.

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?

For a tool with no output schema, it is remarkably complete: it covers preconditions, auth requirements, live vs studio behavior, per-kind constraints, failure wording, the snapshot safety net, and the exact workflow needed to diagnose lost progress. An agent has enough context to invoke every operation correctly and know what to expect.

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%, so the baseline is 3, but the description adds substantial operational meaning around parameters: the meaning of kind, the behavior of target='live', the confirm requirement, the read-before-write advice for value, and the special semantics of op='snapshot'. It does not repeat every schema field, which is appropriate given the schema already documents them.

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 opens with a specific verb and resource: 'Reads and writes the game's saved data — DataStore and MemoryStore.' It then distinguishes itself from all sibling tools by saying it is the only tool that looks outside the place file, answering a different question than 'is the instance right'.

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 guidance on when this tool is appropriate versus every other tool, and further divides usage between studio and live targets. It also outlines a concrete bug-report workflow: list stores, list keys, get the player's key, then versions and get with a version to see the prior state.

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

debugBreakpoints and runtime inspectionA

Sets breakpoints that record the stack and variables when they are hit, then reads back what they caught.

These are tracepoints, not a step debugger. A breakpoint fires, captures the call stack and the variables in scope, and lets execution continue; op: "snapshots" returns what was captured. Studio's debugger has to decide whether to resume the instant it stops, and cannot wait for a tool call to come back with an answer, so stepping through code line by line is not possible this way — but 'what was this value when it got here' is, which is usually the actual question.

condition is a Luau expression evaluated where the breakpoint sits, so a breakpoint can fire only on the case that matters — health < 0, player.Name == "someone".

logMessage is ALSO a Luau expression, not a template string: its value is printed when the breakpoint is hit, so write "health=" .. health rather than health={health}. Prose is a syntax error. Read the lines back with console.

Two things about it are measured, not assumed, and both waste your time otherwise. A breakpoint fires ONCE PER RUN, not once per pass: on a five-iteration loop it printed a single line, for the first iteration only. It is not a way to watch a value change inside a loop — to see every pass, have the code itself print and read that with console. And a log expression CANNOT SEE THE LOOP CONTROL VARIABLE: on for index = 1, 5 do, a breakpoint in the body read the body's own locals correctly and index as nil. Wrap values in tostring so a nil prints as "nil" instead of throwing.

A log expression that throws is reported as "Breakpoint ... ignored" in console, NOT here — set still returns Verified, because Studio only compiles the expression once the line is reached.

So the two kinds cost different things: a logMessage breakpoint never stops and gives you one line you composed in advance, while one without it stops briefly and gives you the whole frame — every local and its type, without having to guess beforehand which value would matter. Both give you that for one pass only. Reach for the log when you know what to watch, the capture when you do not.

Only one breakpoint exists per line, so the same line cannot both log and capture.

Put the breakpoint on a line that does something. A return, an end or a bare declaration can verify and then never fire — measured, not guessed: the same breakpoint moved from return squared, tag to the assignment above it went from silent to firing on every pass. If one verifies but catches nothing, suspect the line before suspecting the condition.

Breakpoints belong to the session that holds them. Set them in the editor session BEFORE starting a playtest, since code that already ran cannot be caught retroactively.

Nothing here leaves a thread stopped waiting for you. A capture breakpoint stops for as long as it takes to read the frame and then resumes itself, so a script with one mid-loop still runs to its last line, and the user is never left with a frozen Studio to rescue.

remotes passively observes RemoteEvent traffic for one playtest player in both directions. Returns counts, calls/sec and two short argument-shape samples per remote; no raw payload dumps or RemoteFunction interception. Requires the playtest server studioId. Captures 5 seconds by default (max 15), at most 2000 events and 40 rows within 12 KB; reports truncation when a limit is reached.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors, 'remotes' traces RemoteEvents.
lineNoclear only: which line to remove.
modeNoexceptions only: break on every error, only unhandled ones, or never. Defaults to Unhandled.
pathNoclear: script to clear. remotes: remote or subtree path, default game. Narrow this if discovery is truncated.
clearNosnapshots only: discard what is returned, so the next read starts fresh.
limitNosnapshots only: how many of the most recent to return.
playerNoremotes only: player name; required with multiple players. Both directions are scoped to this player.
secondsNoremotes only: capture seconds, default 5.
studioIdNoTarget Studio; omit for the active one.
breakpointsNoset only: breakpoints to add.

TDQS

A4.9/5.0
Behavior5/5

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

The description discloses many non-obvious behaviors beyond annotations: breakpoints fire once per run, log expressions cannot see loop control variables, a breakpoint on a return/end may never fire, and set can return Verified even when the log expression later throws. It also clarifies that capture breakpoints resume themselves and never leave Studio frozen. This far exceeds what annotations alone provide.

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?

The description is long but front-loaded with the core purpose and organized into thematic paragraphs covering limitations, parameters, and remotes. Some illustrative anecdotes and repeated 'measured, not guessed' phrasing add bulk, so it is not maximally concise, but the length is largely justified by the tool's complexity.

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?

Despite having no output schema, the description covers what each operation returns: snapshots returns captures, set returns Verified, and remotes returns counts, calls/sec, and argument-shape samples. It also explains truncation, session scoping, and the need to set breakpoints before playtesting. For a tool with 10 parameters and multiple modes, nothing essential is missing.

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

Parameters5/5

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

Schema coverage is already 100%, but the description adds crucial meaning: condition must be a Luau expression, logMessage is also a Luau expression rather than a template string, prose causes syntax errors, and line placement affects whether a breakpoint fires. This significantly deepens an agent's understanding of how to correctly set parameters.

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 states a specific verb and resource: it sets breakpoints that record stack and variables, then reads back captured snapshots. It also differentiates itself by explaining these are tracepoints, not a step debugger, which separates it from sibling inspection tools. The first sentence alone gives an agent a precise mental model.

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-to-use guidance, e.g., 'Reach for the log when you know what to watch, the capture when you do not.' It also names an alternative, console, for loop-by-loop value watching, and warns against using breakpoints for stepping. This is exactly the kind of routing information an agent needs.

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

deleteDelete instancesA
Destructive

Destroys instances and everything inside them, as one undoable step.

Deleting a container deletes its whole subtree, so the response reports how many descendants went with each one — check it before telling the user what happened.

Services cannot be deleted and are refused. Paths shift when same-named siblings are removed, so read fresh paths from find or tree before a second delete rather than reusing indexes from an earlier call.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathsYesInstances to destroy, e.g. ["Workspace.OldModel"].
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.4/5.0
Behavior4/5

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

Annotations already mark the tool as destructive and non-idempotent that the description reinforces by saying 'Destroys instances and everything inside them.' Beyond that, the description adds crucial behavioral details: it is undoable, it returns a descendant count, services are refused, and paths shift after deletion. This goes well beyond the annotation hints. Slight deduction because it doesn't mention authorization or rate limits, but those are not expected for this tool type.

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

Conciseness5/5

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

The description is concise and front-loaded: the first sentence captures the primary purpose)Skip subsequent sentences add exactly the details an agent needs (consequences, constraints, and pre/post-recommendations) without fluff. Each sentence earns its place, and the structure flows from the what to the how to the caveats.

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

Completeness4/5

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

Given there is no output schema, the description compensates by telling the agent what to expect in the response (descendant count). It also covers the major edge cases (services, path invalidation). It doesn't specify the exact format of the response or error cases, but for a destructive tool this is sufficient. A slight extra note about what happens on invalid paths (e.g., not found) would be helpful, but overall it's complete enough for an agent to use it correctly.

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?

The schema already covers both parameters (paths and studioId) fully (100% coverage), so the baseline is 3. The description adds value by warning that paths are volatile and must be re-read before a second delete, and that services are refused. That's behavioral context on the 'paths' parameter beyond the schema's type/item description, making it more useful for correct invocation.

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 opens with a specific verb and resource: 'Destroys instances' as one undoable step GOVERNED by one verb. It clearly distinguishes itself from the many sibling tools (create, modify, move, etc.) by focusing on destruction and by noting what it does NOT do (services cannot be deleted). Any agent can tell this is the delete operation without reading 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 Guidelines4/5

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

The description gives concrete usage guidance: it tells the agent to check the response's descendant count, to avoid deleting services, and to re-fetch paths from find/tree after a deletion because paths shift. This substantially helps the agent sequence operations. It doesn't explicitly say when NOT to use this tool relative to alternatives (e.g., vs. move or modify), but it does give clear operational guidance for correct use, so it earns above average.

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

deviceEmulate a phone, tablet or consoleA

Resizes the Studio viewport to a real device, so you can see what a player on that device sees.

Most Roblox players are on a phone and most UI is built on a desktop monitor, which is where interfaces break: a button under the notch, a menu off the bottom of a 393-pixel-tall screen, text sized for a display three times larger. None of that is visible in the data model — every one of those instances has perfectly correct properties — so this is the only way to find it short of owning the hardware.

The workflow is: set a device, screenshot, look. Pair it with playtest to check a running game's HUD rather than the editor.

list gives the ids, each with its real name, form factor and resolution — ids look like "iphone_16", "ipad_a16", "samsung_galaxy_s25_ultra", "xbox", "meta_quest_3".

network degrades the connection on purpose — latency, jitter and packet loss — which is the other half of what a phone player actually gets. A menu that works at 0ms is not evidence that it works at 300: the spinner that never stops, the button that fires twice, the HUD that arrives after the round started are all invisible on a local connection. Use a preset (wifi, 4g, 3g, poor, clear) or set the numbers yourself, then playtest and watch.

stop returns Studio to the normal editor viewport AND clears the network shaping. Do that when you are finished: a left-over emulated device makes every later screenshot the wrong shape, a left-over 400ms delay makes the whole place feel broken, and nothing on screen says why in either case.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'list' shows the available devices, 'set' switches to one, 'network' shapes the connection, 'stop' undoes both, 'state' only reports.state
formNolist only: show only devices of this form factor.
lossNonetwork only: percentage of packets thrown away, up to 0.5 — Roblox caps it there so the simulation does not fight congestion control. Latency makes a game feel slow; loss makes unreliable remotes arrive out of order or not at all.
deviceNoset only: the device id, e.g. "iphone_16". See `list`.
jitterNonetwork only: how much the delay varies, in milliseconds. Jitter breaks things steady latency does not — it is what makes replicated motion stutter rather than simply lag.
memoryNonetwork only: pretend the machine has this many MB of memory. A cheap phone is a small screen AND little memory; this is the half that makes textures unload. 0 removes the cap, restoring the real amount.
presetNonetwork only: a whole connection in one word. clear=0ms (normal), wifi=15ms, 4g=60ms/0.1% loss, 3g=150ms/0.3% loss, poor=400ms/0.5% loss. Named fields below override whichever part you name.
latencyNonetwork only: minimum delay in milliseconds, up to 1000 — the engine's own ceiling. 0 clears it.
studioIdNoTarget Studio; omit for the active one.
directionNonetwork only: which way to degrade. 'in' is the player with a bad connection, 'out' is everyone else seeing that player late. Defaults to both.
orientationNoset only: which way up. Portrait is worth testing separately — most mobile players hold the phone upright and most UI is only ever checked in landscape.

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already declare the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true), so the bar is lower, yet the description adds real side-effect context: `stop` restores the editor viewport AND clears network shaping, and a leftover device/network shapes every later screenshot invisibly. It does not restate reversibility explicitly, which keeps it below a 5.

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?

The core action is front-loaded in the first sentence, and the paragraph-per-op structure is easy to scan. Several passages are rhetorically padded ("A menu that works at 0ms is not evidence that it works at 300"), so it is longer than strictly necessary for an 11-param tool.

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

Completeness4/5

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

With no output schema and 11 optional params, the description carries the load well: it covers the workflow, the effect of each mutating op, network shaping rationale, and cleanup. The gap is the unmentioned `state` op and the absence of any indication of what `list`/`state` return.

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 description coverage is 100% (baseline 3), and the description still adds value by expanding the `preset` table, explaining the `loss` cap and the `direction` in/out semantics narratively, and giving per-op meaning for `list`/`set`/`network`/`stop`. It omits the `state` op entirely, so one enum value is undocumented in prose.

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

Purpose4/5

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

The description names a specific action and resource ("Resizes the Studio viewport to a real device") and separates its four sub-operations. It does not, however, differentiate itself from the closest sibling, `viewport`, which an agent must still disambiguate by inference.

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 states the workflow explicitly (`set` → `screenshot` → look), names companion tools (`playtest` for a running game's HUD, `screenshot`), and gives an imperative cleanup rule (run `stop` when finished) with the cost of skipping it. The sequencing and alternatives leave little to inference.

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

execute_luauRun Luau in StudioA
Destructive

Runs Luau in Studio's plugin context and returns whatever it printed, returned, or threw.

This is the escape hatch. Reach for it only when no dedicated tool fits — create, modify, delete, move, script_edit and find validate their input, type values from the live API dump, and wrap writes in an undo recording. Code run here does none of that, so a typo becomes a runtime error instead of a suggestion, and changes it makes may not be undoable as one step.

Good uses: reading something no tool exposes, a one-off calculation over many instances, or calling an engine API the tools do not cover.

Output printed while it runs is captured and returned, so print is a reasonable way to get values out. return works too, including returning a table — it comes back as a structure, not a summary. There is no timeout for target="studio": an infinite loop will hang Studio until it is force-quit.

Against a running playtest server, Studio disables loadstring, so the code is compiled through a ModuleScript instead and runs at script identity — plugin-only APIs are unavailable there. When that happens it is stated in the result rather than left to be inferred from a failure.

With target="studio", do not use require to read live state out of a running game. This runs in the plugin's own Luau VM with its own module cache, so require here returns a second, freshly-initialised copy of the ModuleScript — its counters and caches read as empty while the real one is running fine, and a zero is indistinguishable from a genuine zero. Read live state off the DataModel instead (instances, attributes, properties), or have the game print it and read that with console. The result warns when a call could have hit this.

target="client" runs in the selected player's actual playtest client VM, including its live require cache. Requires a running playtest server studioId. Output is capped at 200 lines, 10 returns, table depth 4 and 50 entries. The relay is removed on completion or timeout; non-yielding code can still stall the client. Connections/hooks created by the temporary relay (such as Connect or RenderStepped) do not persist after the call returns.

target="live" runs the script on Roblox's servers against the PUBLISHED place instead, with no Studio involved. That is how you read or repair production: a real player's data store entry, what the live game actually holds, a migration over saved data. Everything the script prints comes back in logs.

BE CAREFUL WITH IT. The Studio path has an undo stack and a place nobody is playing. This one touches live data and live players, and nothing here can put any of it back — so it needs confirm: true and you should read before you write. Roblox queues it as a task, so expect seconds, not milliseconds, and a state of COMPLETE or FAILED rather than a bare value.

ParametersJSON Schema
NameRequiredDescriptionDefault
playerNoclient only: player name; required with multiple players.
sourceYesLuau to run. In an editor session this has plugin permissions, so `game`, `workspace` and plugin-only APIs are all reachable.
targetNo'studio' runs in the connected Studio, with plugin permissions. 'live' runs on Roblox's servers against the published place — production, with no undo. 'client' runs in a player's playtest client VM.studio
confirmNoRequired for target="live". This runs against the game people are playing and nothing here can undo it.
placeIdNolive only: which place. Omit to use `cloud place`.
studioIdNoTarget Studio; omit for the active one.
universeIdNolive only: which game. Omit to use `cloud universe`.
timeoutSecondsNolive/client only: timeout in seconds. Defaults to 30.

TDQS

A4.8/5.0
Behavior5/5

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

The description carries an enormous amount of behavioral disclosure well beyond the readOnlyHint/destructiveHint annotations: input is not validated, writes may not be undoable as one step, no timeout on target='studio' (infinite loop hangs Studio), output caps (200 lines, 10 returns, table depth 4), the module-cache duplicate-copy problem with require, loadstring being disabled on playtest servers, relay cleanup, and the live-data danger requiring confirm. This all aligns with destructiveHint=true and readOnlyHint=false — no contradiction.

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?

The description is long, but length is justified for an escape-hatch tool that can hang a Studio session or mutate live production data. The highest-stakes warnings ('BE CAREFUL WITH IT', the live-data danger, confirm requirement) are front-loaded and surfaced in caps; each paragraph covers a distinct concern (usage, output, require caveat, per-target behavior) with no redundancy. Slightly more than needed, but every sentence earns its place given the blast radius.

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?

With no output schema and wildly variable return values, the description must explain return behavior on its own — and it does: print is captured and returned, return works for tables as structures, output caps are specified, and live returns a state of COMPLETE/FAILED rather than a bare value. It covers all three target modes, their prerequisites (running playtest server, published place), the exact caveats for each, and the confirmation flow. Nothing an agent needs to invoke this safely 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%, so the baseline is 3, but the description adds substantial semantic depth beyond the schema: it explains what each target actually means in practice ('live' runs against the PUBLISHED place with no undo; 'client' runs in the player's playtest VM with a live require cache), why confirm is mandatory for live, what timeouts imply, and that source carries plugin permissions. This meaningfully exceeds what the schema's property strings convey.

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 states a specific verb and resource ('Runs Luau in Studio's plugin context') and immediately frames it as 'the escape hatch' — the tool you reach for when dedicated tools don't fit. It explicitly names the siblings it is not (create, modify, delete, move, script_edit, find) and contrasts its behavior against them. An agent can unambiguously distinguish this from every one of the 34 siblings.

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?

Gives explicit when-to-use guidance ('reading something no tool exposes, a one-off calculation, calling an engine API the tools do not cover') and when-not-to ('only when no dedicated tool fits'). It further sub-divides usage by target: 'live' is for production reads/repairs, and it warns against using require for live state. No other tool in the sibling list gets this level of routing guidance.

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

findFind instancesA
Read-onlyIdempotent

Searches the data model by name, class, property value and/or tag. Every filter you supply must match, so one call answers questions that would otherwise take several: "anchored BaseParts under Workspace.Map whose name contains door" is a single request.

This replaces separate name / class / property / tag search tools. Prefer it over tree whenever you know what you are looking for.

Tag searches are answered from CollectionService's index rather than by walking the tree, so they stay fast on large places. Narrow with path if a search reports TOO_BROAD.

op="tags" lists which tags the place actually USES, with counts and a few example paths. Call it before filtering by tag on a place you do not know: a tag search that returns nothing looks the same whether you spelled it wrong or nothing carries it, and the tag names are often the clearest description of how a game is organised (Enemy, Checkpoint, Interactable say more than the folder layout does).

selector is the engine's own query language and is the fastest option of all — the matching happens in C++ and only survivors come back. Reach for it when the shape of the tree is part of the question (Model > Part) or when one call should answer two (Part, Model); the filters above still apply on top of it.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'find' searches for instances. 'tags' lists which CollectionService tags exist in the place, with counts — use it when you do not know the tag names yet.find
tagNoCollectionService tag the instance must carry.
pathNoLimit the search to this subtree, e.g. "Workspace.Map". Omit for everything.
limitNoMaximum items to return (1-500).
cursorNoOpaque cursor from a previous call's `nextCursor`. Omit for the first page.
detailNoconcise: compact identity. standard: selected facts. full: all readable properties for inspect; tree/find use the same columns as standard.standard
selectorNoEngine query selector, matched inside Studio. Supports a class name ("Part", superclasses included), "#ExactName", "[Anchored=true]", either-or with "Part, Model", direct children with "Model > Part" and descendants with "Model >> Part". No substring names and no < > comparisons — use nameContains and propertyValue for those. Combines with the other filters.
studioIdNoTarget Studio; omit for the active one.
classNameNoClass or superclass, e.g. "BasePart", "Script".
propertiesNoProject just these properties on matching rows, avoiding a second inspect call. Unreadable names are reported.
nameContainsNoSubstring of the instance name, case-insensitive.
propertyNameNoProperty that must exist, e.g. "Anchored". Combine with propertyValue.
propertyValueNoRequired value of `propertyName`, compared as text — "true", "0, 5, 0", "Enum.Material.Neon". Omit to match any instance that has the property.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already cover the safety profile (readOnly, idempotent, non-destructive, openWorld). The description still adds non-obvious behavior: tag searches are served from CollectionService's index rather than a tree walk (fast on large places), selector matching runs in C++ with only survivors returned, and results can come back TOO_BROAD. It does not discuss result shape or pagination beyond what the schema's cursor implies.

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?

Front-loaded with the core purpose, then layered paragraphs each carrying distinct operational advice. It is long for a description but nearly every sentence provides selection or invocation value, with no boilerplate.

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

Completeness4/5

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

For a 13-parameter, no-output-schema search tool, the description covers the conceptually hard parts: filter composition, the tag-discovery workflow, and selector's syntax boundaries. The remaining parameters (limit, cursor, detail, studioId) are fully specified in the schema, so the definition is sufficient to call correctly.

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%, so baseline is 3, but the description meaningfully extends it: it explains that all supplied filters are ANDed, that selector has no substring or < > comparisons (pushing those to nameContains/propertyValue), and why op="tags" exists. It does not add semantics for limit, cursor, detail, or studioId, but those are already fully documented.

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?

States a specific verb (searches) and resource (the data model) with the exact filter axes (name, class, property value, tag), and explicitly names the sibling it replaces and the one it supersedes (`tree`). An agent can select it 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?

Gives explicit routing rules: prefer over `tree` when you know what you are looking for, call op="tags" before filtering by tag on an unfamiliar place, and reach for `selector` when tree shape is the question. It also names the fallback (nameContains/propertyValue) when selector cannot express the query.

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

generateGenerate 3D modelsA
Destructive

Makes 3D geometry from a text prompt, using Roblox's Cube model.

THE SCHEMA IS THE IMPORTANT ARGUMENT. It decides how the result is broken up, and it cannot be changed afterwards without another generation:

  • Body1 — one MeshPart. Right for props: a crate, a tree, a lamp.

  • Car5 — a body and four wheels, under the fixed names body, front left wheel, front right wheel, rear left wheel, rear right wheel. Right for anything that has to drive, because a script can find the wheels by name.

  • groups — your own list of part names, for a structure the two predefined schemas do not cover.

Asking for a car under Body1 gives you a car-shaped rock. It looks right and nothing can be articulated. If you only realise afterwards, geometry op="segment" cuts an existing mesh into named parts without generating it again.

Expect tens of seconds per call. The service is metered and moderated: a rejected prompt and a rate limit both come back as a failure that says which, so read the hint before retrying.

imageAssetId conditions the generation on a picture — supply it with a prompt or instead of one. size suggests proportions and maxTriangles caps the poly count (low values give a faceted, low-poly look). Results are anchored on arrival, because a multi-part model dropped into the workspace unanchored falls apart.

EDIT MODE ONLY, for now. A generated mesh does not survive into a playtest: inside one, its MeshContent and TextureContent read as empty. assets op="bake" does not fix this — the engine refuses to bake the kind of content generation produces. So generate for building and greyboxing, and do not rely on a generated mesh being visible in a test or after a reopen until it has been published as a real asset.

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoName for the model.
sizeNoSuggested size as "x, y, z". Approximate — use `scaleTo` for exact.
anchorNoAnchor every part. Turn off only if physics should act on it.
groupsNoCustom part names to split into, e.g. ["body", "lid"]. Overrides `schema`.
parentNoWhere to put it. Defaults to Workspace.
promptNoWhat to generate, e.g. "a weathered stone well".
schemaNoHow to split the result. Ignored when `groups` is given.Body1
scaleToNoScale the result so its longest side is this many studs.
positionNoWhere to place it, e.g. "0, 10, 0".
studioIdNoTarget Studio; omit for the active one.
texturesNoGenerate textures. Off gives bare geometry.
imageAssetIdNoAn image asset id to condition the generation on.
maxTrianglesNoCap the triangle count. Lower is more faceted. Default is about 10000.

TDQS

A5/5.0
Behavior5/5

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

Beyond the annotations, the description discloses latency ('tens of seconds per call'), metering/moderating failures, anchoring on arrival, edit-mode-only persistence, and the emptiness of MeshContent/TextureContent in playtests. None of this contradicts the annotations.

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

Conciseness5/5

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

The definition is long but every sentence carries operational value, and the structure uses a clear opening, bullets, and bolded warnings. It front-loads the most important argument (schema) and organizes limitations so an agent can use it without rereading.

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?

For a 13-parameter generative tool with no output schema, the description covers purpose, schema selection, failure modes, retry behavior, anchoring, edit-mode limitations, and related tools. No critical operational gap remains.

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

Parameters5/5

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

Schema description coverage is 100%, but the description adds substantial meaning: it explains `Body1` vs `Car5`, fixed wheel names, `groups` as an override, `imageAssetId` conditioning, and the faceted effect of low `maxTriangles`. This goes well beyond the schema's field descriptions.

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 opening line, 'Makes 3D geometry from a text prompt,' states a specific verb and resource, and the rest of the description elaborates on the kinds of geometry and schemas. It is clearly distinct from siblings like `geometry` or `assets`, which are operation/modification tools.

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?

The description gives explicit when-to-use guidance for each schema ('Right for props', 'Right for anything that has to drive'), tells the agent to 'generate for building and greyboxing', and names alternatives such as `geometry op="segment"` for post-hoc cutting and `assets op="bake"` as a non-fix. It also conditions expectations around rate limits and retries.

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

geometryMesh operationsA
Destructive

Every operation that reshapes solid geometry, in one place.

Boolean - union merges parts into one solid, subtract cuts the with parts out of path, intersect keeps only the overlap. This is how to build a shape that is not a box without importing a mesh.

Breaking apart - fragment shatters a part into random debris, for destruction. segment is the opposite kind of break: it cuts a MeshPart into parts you NAME, so a solid car mesh becomes a body and four wheels a script can find and turn. Use fragment for rubble and segment for articulation.

Motion - sweep builds the volume a part passes through as it moves, which is the only real answer to 'does this door hit the wall when it opens'. Give to for a slide, or spin degrees with a pivot for a hinge. Pass checkAgainst and it reports what the swept volume overlaps; with keep: false it measures and cleans up after itself, leaving nothing behind.

subtract and intersect need the parts to actually overlap, and they fail differently when they do not. intersect returns nothing, which comes back as an error rather than a silent no-op. subtract returns the subject UNCHANGED - a full-size copy of it, reported as a created part - because cutting nothing out of something legitimately leaves it whole. So a subtract that succeeds is not proof that anything was cut: check the positions overlap with inspect first, or compare the result's size against the original.

Results keep the original's material, colour, texture and anchoring. Roblox returns bare grey MeshParts, so a brick wall with a hole cut in it would otherwise come back as a grey slab - correct geometry that looks like a mistake.

mesh reads the real triangle and vertex counts of MeshParts, which is the only way to tell a 40,000-triangle tree from a 400-triangle one — they are identical in the Explorer and in Properties, and the difference is whether the place runs on a phone. It also reports mesh size against part size: the same triangles stretched over a bigger object is the usual reason a model costs more than it looks like it should.

mesh only works on meshes the signed-in Studio user or the experience owner OWNS. Roblox refuses to open anyone else's, so a model inserted from the Creator Store cannot be measured this way — the tool says which parts were skipped rather than failing the whole batch.

mirror flips instances across a plane and has no engine API behind it — Studio simply cannot do this, which is why people ask for it. Mirroring about the middle of the selection is the default, because mirroring a building at x=200 about the world origin puts it 400 studs away rather than flipping it in place. It COPIES by default; pass copy: false to flip the originals. MeshParts move and rotate correctly but their meshes are not remade, so an asymmetric mesh still reads the same way round.

segment runs Roblox's Cube model and takes tens of seconds; the rest are fast. Each call is one undo step.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'union' merges, 'subtract' cuts `with` out of `path`, 'intersect' keeps only the overlap, 'fragment' shatters into debris, 'sweep' builds a motion volume, 'segment' cuts a mesh into named parts, 'mesh' reads triangle counts, 'mirror' flips instances across a plane.
toNosweep only: slide to this position, e.g. "0, 10, 0".
axisNosweep: axis to spin around, e.g. "0, 1, 0" (defaults to up). mirror: which axis to flip across — "X", "Y" or "Z", defaulting to X.
copyNomirror only: leave the originals and add mirrored copies. True by default — that is what builds a symmetrical structure from half of one. False flips the originals in place.
keepNosweep only: leave the volume as a part. Off measures and cleans up.
nameNoName for the result. Defaults to the original's.
pathNoThe part being operated on - the one cut from, for subtract. Required for every op except mesh and mirror, which take `paths`.
spinNosweep only: rotate this many degrees. Use with `pivot` for a hinge.
withNoThe other parts. Required for union, subtract and intersect.
aboutNomirror only: the plane position, e.g. "0, 0, 0". Defaults to the middle of what is being mirrored, which flips it in place.
pathsNomesh and mirror: the instances to read or flip.
pivotNosweep only: the hinge point. Defaults to the part's own centre, which spins it in place - a door needs its hinge edge here.
stepsNosweep only: how many samples along the motion. Too few cuts corners off an arc.
anchorNosegment only: anchor every part.
groupsNosegment only: the part names to cut into, e.g. ["body", "lid"]. Overrides `schema`.
parentNoWhere to put the result. Defaults to the original's parent.
piecesNofragment only: roughly how many pieces to break into.
schemaNosegment only: a built-in split. 'Car5' gives a body and four wheels under fixed names; 'Body1' gives one mesh. Ignored when `groups` is set.
scaleToNosegment only: scale so the longest side is this many studs.
positionNosegment only: where to place the result. Defaults to where the source was.
studioIdNoTarget Studio; omit for the active one.
positionsNosweep only: an explicit path of positions to sweep along.
splitApartNoReturn disconnected chunks as separate parts rather than one.
checkAgainstNosweep only: report what the volume overlaps. An empty array checks against everything; a list checks only those.
keepOriginalNosegment only: leave the source MeshPart in place instead of replacing it.
transparencyNosweep only: how see-through the volume is.
keepOriginalsNoLeave the input parts in place instead of consuming them.
collisionFidelityNoHow exactly the result collides. Precise is expensive - raise it only for a surface players walk on. Tunable picks a precision from the size and handles thin details better; adjust it afterwards with `modify` on CollisionPrecision.Default

TDQS

A4.8/5.0
Behavior5/5

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

Beyond the destructive/openWorld/idempotent annotations, the description discloses non-obvious failure semantics ('intersect' errors on no overlap while 'subtract' silently returns an unchanged full-size copy), ownership refusal on foreign meshes with per-part skip reporting, that material/colour/texture/anchoring are preserved, that mirror copies by default, that 'segment' takes tens of seconds, and that each call is one undo step.

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?

It is long for a description, but for an eight-op / 28-parameter tool most sentences carry distinct caveats, and bold group headers make it skimmable and front-loaded. Minor waste comes from restating schema defaults verbatim ('It COPIES by default; pass `copy: false`') and from prose that repeats default-value behavior already in the schema.

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?

For a high-complexity, multi-operation, destructive tool with no output schema, the description covers op selection, failure modes, side effects, permission limits, latency, and undo behavior. An agent has enough to choose an op and anticipate the result's shape and risks without further context.

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 description coverage is already 100%, so the baseline is 3, but the description adds op-level parameter interaction that the flat schema cannot: that `groups` overrides `schema`, that `checkAgainst` reports overlaps and `keep: false` measures then cleans up, and how `spin`+`pivot` compose for a hinge. It stops short of covering the generic plumbing params (`parent`, `studioId`, `name`), which the schema handles alone.

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 names the tool's domain (reshaping solid geometry) and then enumerates all eight operations with a specific verb+resource for each, grouped under Boolean/Breaking apart/Motion/Read/Mirror headings. An agent can tell which `op` value maps to which intent without opening the schema, and siblings like `inspect` and `modify` are named where relevant.

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?

Explicit routing guidance is given for overlapping ops: 'Use `fragment` for rubble and `segment` for articulation', `sweep` for 'does this door hit the wall', and 'check the positions overlap with `inspect` first' before relying on `subtract`. When-not conditions are also stated, e.g. mesh only works on meshes the user owns, and mirror exists because Studio has no engine API for it.

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

inputSend keyboard and mouse inputA

Sends real keyboard and mouse input to a running playtest — the same events a person pressing the keys would produce.

This is how to test what character cannot reach. character drives the Humanoid directly, which answers 'can it get to the door'; this answers 'does pressing E open it', 'does the sprint key work' — anything bound to input rather than to movement. Use character for going places and this for controls.

Roblox reserves some keys for its own menus and refuses to send them — Escape, Tab, F9, and others depending on the place (One is the backpack hotbar). A refused key comes back as a WARNING naming it; the other steps still run.

Steps run in order, so a sequence is one call: tap E, wait, click at a point, type a name. hold is how long a key or button stays down, after is how long to wait before the next step — a jump held for a second is a different test from a tapped one.

REQUIRES A RUNNING PLAYTEST, and must be addressed to the playtest's studioId from list_studios, not the editor's.

A pointer is drawn on screen and travels to each target before the click, so the user can see what you are aiming at. Turn it off with cursor: false.

How it works, because it explains the one thing that will surprise you: input belongs to the data model that creates it, and the character is driven by the CLIENT. Sending from the playtest's server succeeds and moves nothing. So this parents a short script into the player's PlayerGui, which runs on their client, and that reports back when the input has actually been delivered. Nothing is reported as sent until the client confirms it. If confirmation never arrives you get an error, not a success — check where things really are with character op="state".

Mouse coordinates are viewport pixels from the top-left, so pair this with screenshot to see what is where before clicking it, and send what you read off the picture unchanged. The reply's landed shows the same click in the game's own coordinates, which sit a topbar lower — that difference is two ways of describing one point, not an error to correct for. Under an emulated device it is a real distortion instead, and the reply says so; there, re-read it after each click rather than reusing an earlier one.

Take the screenshot immediately before clicking. The reply is measured against the viewport as it is NOW, and a Studio window that changed size since the picture was taken moves everything in it — measured, a window that went from 435 to 952 pixels wide between a screenshot and a click, where the click reported success and hit nothing.

A text step types into the FOCUSED TextBox. Click the box in the same call, one step before the text, and the focus is taken for you; with no box to type into the step is reported as having done nothing rather than as delivered.

ParametersJSON Schema
NameRequiredDescriptionDefault
stepsYesInput steps, delivered in order.
cursorNoDraw a pointer on screen that travels to each target before the click, with a ripple where it lands. On by default: synthetic input is otherwise invisible, so the user watching sees effects with no cause, and a click that misses looks identical to one that hit. Turn it off only when recording something where the pointer would be in the way.
playerNoWhich player, by name. Omit for the only one; needed in a multiplayer test.
studioIdNoThe PLAYTEST session's id — not the editor's. See list_studios.

TDQS

A5/5.0
Behavior5/5

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

Even with annotations present, the description adds a large amount of behavioral context: reserved keys are refused with a warning, steps execute in order, delivery is confirmed by the client before success is reported, failure produces an error, and input is parented into the client's PlayerGui. It also discloses pointer drawing, viewport measurement pitfalls, and emulated-device distortion, all beyond what the annotations state.

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

Conciseness5/5

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

The description is long but appropriately so for a high-complexity tool with no output schema. It is front-loaded with the core purpose and then organized into clearly motivated sections covering alternatives, reserved keys, sequencing, client execution, pointer behavior, screenshot timing, and text focus — each of which earns its place by preventing a likely misinvocation.

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 complexity, 4 parameters, and absent output schema, the description is remarkably complete. It covers prerequisites, return and error semantics, ordering, coordinate systems, failure modes, and interactions with siblings like `character` and `screenshot`, leaving no critical gap an agent would need to guess about.

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

Parameters5/5

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

Although schema coverage is 100%, the description adds meaning well beyond the schema: x/y are viewport pixels from the top-left, `after` and `hold` control sequencing and duration, `target` focuses TextBoxes, `cursor` defaults to on so users can see synthetic input, and `text` types into the focused TextBox. It even explains coordinate discrepancies between the reply's `landed` and viewport pixels so the agent does not treat them as an error.

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 first sentence states a specific verb and resource: sends real keyboard and mouse input to a running playtest, producing the same events as a person. It also explicitly distinguishes itself from the sibling `character` tool by contrasting 'can it get to the door' with 'does pressing E open it', so an agent can tell them apart without opening schemas.

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?

The description gives explicit selection guidance: use `character` for movement and this tool for controls, and pair it with `screenshot` for coordinate targeting. It also specifies the prerequisite of a running playtest and warns that the playtest's studioId from `list_studios` must be used, not the editor's.

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

inspectInspect instancesA
Read-onlyIdempotent

Reads properties, attributes, tags and children of one or more instances. Pass every path you care about in a single call — batching costs one round trip instead of N.

Property selection comes from the live Roblox API dump for each instance's actual class, so it stays correct across engine updates: concise — class and child count only standard — the properties that characterise the class (Part gets Size, Position, CFrame, Anchored, Material...) full — every readable property; expensive, use on one or two instances at most

Bad paths do not fail the call: they come back under failures while the valid ones still return, so one typo does not cost you the whole batch.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathsYesInstance paths, e.g. ["Workspace.Baseplate", "Lighting"].
detailNoconcise: compact identity. standard: selected facts. full: all readable properties for inspect; tree/find use the same columns as standard.standard
physicsNoAlso report mass, density, assembly root and centre of mass for any BasePart. Mass appears nowhere in Studio — it is computed from volume and material — so this is the only way to answer 'why does this fall over', 'why does it sink', or 'why did half the model stay behind when I moved it'.
studioIdNoTarget Studio; omit for the active one.
propertiesNoRead exactly these properties instead of the detail-level default. Use when you want one specific value across many instances.
includeChildrenNoInclude a name/class listing of direct children.

TDQS

A4.2/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the bar is low, and the description clears it with non-obvious behavior: bad paths do not fail the call, they are returned under `failures` while valid instances still resolve. That partial-success contract plus the cost profile of the 'full' detail level and the live API-dump sourcing are exactly the kind of context an agent cannot get from the annotations.

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?

Front-loaded with the core action, then the batching advice, then a scannable breakdown of the three detail levels, then the failure semantics. Every paragraph carries information, though the API-dump justification sentence is slightly more explanation than the agent strictly needs to make the call.

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

Completeness4/5

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

With six parameters, full schema coverage and a complete annotation set, the description fills the remaining gaps: it covers the detail-level tradeoff, batching strategy, and one failure key in the response. It is nearly complete, but with no output schema it still leaves the overall response shape to inference beyond the mention of `failures` and the child listing.

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%, so the baseline is 3, but the description adds meaning beyond the schema: it explains that property selection is derived from the live Roblox API dump for each instance's actual class and stays correct across engine updates, and gives a concrete example of what 'standard' yields for a Part (Size, Position, CFrame, Anchored, Material).

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

Purpose4/5

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

Opens with a specific verb and resource set: 'Reads properties, attributes, tags and children of one or more instances', which tells the agent exactly what comes back. It is clear and self-contained, but it never names or contrasts itself with the read-oriented siblings (tree, find, script_read), so the agent must infer the boundary from the schemas of those tools.

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

Usage Guidelines4/5

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

Gives real usage context: batch every path into one call because batching costs one round trip instead of N, and warns that 'full' is expensive and should be limited to one or two instances. It stops short of naming an alternative tool or stating an explicit when-not-to-use-this case (e.g. when 'tree' is the better choice).

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

list_studiosList connected StudiosA
Read-onlyIdempotent

Lists every Roblox Studio window currently connected to this server, with its studioId, place name, transport (sse or poll), when it connected, and which one is active.

Call this whenever a tool reports AMBIGUOUS_STUDIO, and whenever the user refers to 'the other place' or 'my other window'. With a single Studio open every other tool targets it automatically, so you can skip it then.

Nothing is targeted by default when several are connected: pick one with set_active_studio, or pass studioId to a single tool call to act on one place without changing the default.

Each Studio is queried live, so placeName is the published name the user would recognise. A place never saved to Roblox has no published name and falls back to its data model name ('Place1').

context matters more than it looks. Pressing Play adds a second entry for the playtest's server — same place, same name, same id as the editor session. Instances created or changed in a 'playtest' context are thrown away the moment the user stops, so building there looks like it worked and then vanishes. Target 'edit' unless the user specifically wants to inspect or affect the running game.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already mark readOnly, idempotent, non-destructive. The description adds crucial behavioral nuances not captured in annotations: 'Each Studio is queried live, so placeName is the published name,' and the playtest context explanation that a second entry appears and its changes are thrown away. It also clarifies that 'no Studio is targeted by default when multiple are connected,' which is a behavioral surprise. No contradiction with annotations.

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?

The description is somewhat long but well-organized into four paragraphs that each serve a purpose: listing result details, usage guidance, default targeting, and the playtest caveat. It front-loads the main action and then adds usage nuances. No redundant filler, though it could be tightened slightly. Still, for a tool with multiple gotchas, the length is justified.

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 there is no output schema, the description does the job of explaining return values. It covers the fields returnedholistically. It also covers edge cases (never-saved place name, playtest context) that are essential for correct interpretation. It clearly distinguishes when to use this vs set_active_studio. Fully complete.

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

Parameters5/5

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

There are zero parametersaine; schema description coverage is 100%. The description explains the output structure and the meaning of each field (studioId, placeName, transport, connected time) and the context field. Since there are no params, the description is the sole source of semantic meaning, and it fully explains the tool's behavior.

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 begins with a precise verb and resource: 'Lists every Roblox Studio window currently connected to this server,' then enumerates the exact fields returned (studioId, placeName, transport, connection time). It differentiates from siblings like set_active_studio and studio_status by explaining its role in discovery and the default targeting behavior.

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?

Explicitly states when to call it: after AMBIGUOUS_STUDIO, or when the user references 'the other place'/'my other window'. It also tells when NOT to call it (single Studio open, because others auto-target), and describes the workflow: default is no targeting, so pick with set_active_studio or pass studioId. This is clear decision guidance.

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

modifyModify instancesA
Destructive

Sets properties, attributes and tags on existing instances, as one undoable step.

Each entry takes a list of paths, so one entry can apply the same change to many instances — anchoring 200 parts is one entry, not 200. Combine with find to build the path list.

The batch is all-or-nothing: if any value is rejected the recording is cancelled and every instance reverts, rather than leaving the place half-changed.

Values use the same notation the Properties panel shows — see the properties field. To change a script's code use script_edit.

ParametersJSON Schema
NameRequiredDescriptionDefault
targetsYesChanges to apply together as one undoable step.
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.6/5.0
Behavior5/5

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

Beyond the annotations (destructiveHint, readOnlyHint), the description discloses important behavior: the batch is one undoable step, it is all-or-nothing, rejected values cancel the recording and revert every instance, and one entry can apply the same change to many instances. This gives agents an accurate model of side effects and failure semantics.

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

Conciseness5/5

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

Four short paragraphs, each with a distinct job: core purpose, batch path behavior, atomicity, and notation/alternative tool. The main capability is front-loaded and every sentence earns its place.

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

Completeness4/5

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

The description covers the essential operational context: batch semantics, failure atomicity, value notation, and the script_edit alternative. There is no output schema, but for a mutation tool the absence of a return-value description is acceptable. Slightly more could be said about success/error responses or prerequisites, but the definition is strong overall.

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%, so the baseline is 3. The description adds value by explaining that values use the same notation as the Properties panel, that one entry can apply a change to many paths, and that attribute values may need a { type, value } wrapper. These clarifications augment the schema rather than repeat it.

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 opens with a specific verb and resource: 'Sets properties, attributes and tags on existing instances.' It clearly distinguishes itself from siblings like create, delete, and move, and later explicitly distinguishes itself from script_edit. No ambiguity remains about what the tool operates on.

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

Usage Guidelines4/5

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

The description gives clear guidance: use it to set properties/attributes/tags on existing instances, combine with find to build path lists, and use script_edit instead for changing a script's code. It doesn't enumerate when to prefer create/delete/move, but the scope is clear enough for an agent to route correctly.

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

moveMove or clone instancesA
Destructive

Reparents instances, or clones them into a new parent, as one undoable step.

Set mode: "clone" to copy instead of move — that is how to duplicate something, optionally renaming it in the same call.

Moving an instance into itself or its own descendant is refused: it silently detaches the branch from the data model and undo does not bring it back.

ParametersJSON Schema
NameRequiredDescriptionDefault
itemsYesMoves to apply together as one undoable step.
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already mark destructiveHint=true and readOnlyHint=false, so the description doesn't need to restate that. It adds valuable behavioral context beyond annotations: the operation is undoable ('one undoable step'), and it discloses a critical edge case ('Moving an instance into itself or its own descendant is refused: it silently detaches... and undo does not bring it back'). This is genuine extra information that changes how an agent should call it.

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

Conciseness5/5

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

The description is compact (two short paragraphs) and front-loaded with the core purpose. Every sentence earns its place: purpose, mode distinction, and a critical caveat. The critical edge-case warning is placed at the end, clearly separated, which is appropriate since it's a warning rather than primary instruction.

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?

For a tool with 2 parameters, 100% schema coverage, and no output schema, the description covers everything an agent needs: what it does, how to switch modes, what happens on an invalid self-move, and that it's undoable. The annotations cover the destructive nature. Nothing critical is missing for correct invocation.

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% (all parameters have descriptions in the schema), so baseline is 3. The description adds extra value by explaining the mode semantics ('Set mode: clone to copy instead of move') and tying the 'name' parameter to the clone use case ('optionally renaming it in the same call'). It also explains the 'items' array semantics ('Moves to apply together as one undoable step'). This goes beyond the schema descriptions.

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 clearly states the tool's core function ('Reparents instances, or clones them into a new parent, as one undoable step') and explicitly differentiates 'move' vs 'clone' modes. It names what it operates on (instances) and the key action (reparent or clone), distinguishing it from siblings like 'create', 'delete', or 'modify'.

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

Usage Guidelines4/5

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

The description gives clear context for when to use clone ('that is how to duplicate something') and implies the main use case for moving. It doesn't explicitly list sibling alternatives or say when NOT to use this tool in favor of others, but the context and mode explanation provide useful guidance.

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

performancePerformance and memoryA
Read-onlyIdempotent

Reads the engine's own counters, and can run the script profiler.

snapshot returns what the Developer Console shows: frame, physics and render times in milliseconds, instance and part counts, draw calls, network rates, and memory broken down by category. Use it to answer 'why is this place heavy' with numbers instead of guesses.

profile runs Studio's script profiler — the Script Performance window — for seconds and reports which scripts consumed CPU. It blocks for that long, so keep it short. It only sees code that actually runs, so start a playtest first; profiling an idle edit session returns nothing.

coverage reports which lines of which scripts actually executed — dead code, untested branches, whether a fix was even reached. Pass enable first, then play, then read the coverage back FROM THE PLAYTEST session, not the editor: instrumenting is per data model, and the playtest is a different one. enable is remembered for the place and re-applied by each new session as it loads. Pass an empty enable array to stop.

What it can and cannot see: instrumentation is fixed when a script is first compiled, so it measures modules required after that point — where most game logic lives — but never a script that starts with the place, which the data model compiles before any plugin exists. Those report 0 lines and are named as unmeasurable rather than counted as dead code.

scene breaks the place down by what it is actually made of: instances by category, triangles and draw calls FOR WHAT THE CAMERA CAN SEE, and the assets holding script, animation and audio memory — each named, so "2.4GB of memory" becomes "this animation is 138KB and these are the Animators using it". It also reports UNPARENTED INSTANCES, which is the closest thing here to a leak detector: objects still alive with nothing holding them in the tree, invisible to find and to tree because they are in neither.

The triangle and draw-call section is the one number here that depends on where the camera is pointing, and it moves enormously: the same place measured 332 triangles looking at empty sky and 29,060 looking at 1,800 parts, seconds apart. So it answers "how heavy is this view", not "how heavy is this place" — point the camera first with viewport op="focus", and compare two views only if both were framed the same way.

audit is a health check rather than a performance one: it finds every reference in the place that points at NOTHING. A Sound whose id was deleted or made private plays silence, a Decal shows nothing, an Animation does nothing — none of them errors, none warns, and the instance looks perfectly healthy because the id is still a string. The only other way to find them is to play the game and notice something missing. It also reports ids left blank, scripts left Disabled, and same-named siblings, which is what makes WaitForChild return the wrong one.

audit fetches the assets to test them, so Studio's Output window will show load errors for the dead ones. That is the engine confirming the finding, not a fault in the tool.

Frame and network figures are only meaningful while something is running. Instance counts and memory are useful in edit mode too.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'snapshot' reads counters now; 'profile' samples running scripts; 'coverage' reports which lines have executed; 'scene' breaks the place down by what it is made of; 'audit' finds broken asset references and other silent faults.snapshot
enableNocoverage only: scripts to start measuring. Remembered for this place and switched on by every session that loads afterwards, so a playtest instruments them before its scripts run. An empty array stops instrumenting.
secondsNoprofile only: how long to sample. The call blocks for this long.
sectionNoscene only: return just one section instead of all six.
studioIdNoTarget Studio; omit for the active one.
frequencyNoprofile only: samples per second. Higher is more precise and costlier.
includePluginsNoprofile only: include Studio plugins in the results. Off by default — an idle Studio is mostly plugin activity, which buries the place's own scripts.

TDQS

A4.8/5.0
Behavior5/5

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

Annotations cover the safety profile (readOnly, idempotent, non-destructive), but the description adds substantial behavioral context beyond them: `profile` blocks for `seconds`, instrumentation is fixed at compile time and per-data-model, place-starting scripts report 0 lines as unmeasurable, `audit` deliberately surfaces asset load errors in Output, and frame/network figures are only meaningful while running. It even discloses that `enable` is remembered for the place and re-applied by future sessions, a persistent side effect worth flagging.

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?

It is long, but it is organized as op-labeled paragraphs front-loaded with the tool's role, and most sentences carry load-bearing detail. A few clauses (e.g. the restatement of camera-dependence) could be tightened, so it falls just short of fully efficient.

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?

With no output schema, the description carries the return-value burden and does so for every op: snapshot's counters, profile's CPU consumers, coverage's executed lines, scene's categories/triangles/assets/unparented, and audit's dead references. Given the tool's complexity and 7 parameters, nothing an agent needs to call it correctly 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 description coverage is 100%, so the schema already documents each parameter and the baseline is 3. The description nevertheless adds workflow meaning the schema lacks — the enable→play→read-back-from-playtest ordering, the per-data-model instrumentation caveat, and the camera-framing dependency for `scene` triangles — which raises it above baseline.

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?

Names a concrete verb+resource and then differentiates all five ops (`snapshot`, `profile`, `coverage`, `scene`, `audit`) with distinct purposes. It explicitly positions itself against siblings, noting unparented instances are 'invisible to `find` and to `tree`,' so an agent can separate this tool from those without opening a 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?

Gives explicit when/when-not and sequencing for each op: start a playtest before `profile`, pass `enable` first then play then read coverage from the playtest session, point the camera with `viewport op="focus"` before `scene`, and compare views only if framed identically. It also states the condition that selects `audit` over 'play the game and notice something missing.'

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

playtestRun, pause and stop the simulationA
Destructive

Starts and stops playtests, so scripts can be made to run and then observed without asking the user to press anything.

play is the Play button: a character spawns and Players.PlayerAdded fires. run is Run mode, which executes scripts with no player at all. multiplayer starts a test with several players for testing replication. addPlayers joins more players to a running multiplayer test, for late joins and lobby fill-up. state reports without changing anything.

Play and multiplayer return the playtest server's studioId once it connects. Use that ID directly for console, performance and execute_luau; the editor session has a separate log. If connection takes too long, the reply says so and list_studios can find it later.

A test does not block this call: it starts and the reply reports the state reached. Studio only ends it when something inside calls StudioTestService:EndTest(value) or when stop is used here; whatever EndTest passed comes back as lastResult on a later state. That makes a scripted check possible end to end: args is readable inside the test via StudioTestService:GetTestArgs(), so a test can be told what to do and report back what happened.

Stopping discards everything the playtest changed, exactly as pressing Stop does. Build in edit mode, then play — not the other way round.

The reply says whether the mode actually moved, not merely that Studio accepted the request.

The panel's playtests on grants permission, never a requirement: obey AGENTS.md, CLAUDE.md, user instructions and project guidance that prohibit playtesting even when ON. playtests off is a hard MCP lock: play, run, multiplayer and addPlayers are refused regardless of instructions to test; state and stop remain available. The lock only blocks starting simulation: screenshots, tree, inspect, script reads, edit-mode execute_luau and UI inspection stay available. Continue using edit-mode tools and static inspection where possible. Only the user can re-enable it with playtests on in the panel. Do not bypass the lock through execute_luau, Studio APIs or another operation. Manual Studio Play is unaffected.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'play' starts a playtest with a character, 'run' runs scripts with no player, 'multiplayer' starts a several-player test, 'addPlayers' joins more to a running multiplayer test, 'stop' ends it and discards its changes, 'state' only reports.
argsNoValue handed to the test, readable inside it with `StudioTestService:GetTestArgs()`. Use it to tell a test which case to exercise.
playersNomultiplayer: how many players to start (default 2). addPlayers: how many to add (default 1).
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.8/5.0
Behavior5/5

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

Far exceeds the annotations (destructiveHint, idempotentHint, openWorldHint): it discloses that stopping discards all playtest changes, that the call is non-blocking, that EndTest's value surfaces as lastResult, that play/multiplayer return a studioId, connection-timeout behavior, and the permission/lock model including an explicit anti-bypass warning.

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?

Front-loads the op semantics, then behavior, then permission rules, and every section is functional. It is on the long side (~300 words), but the tool has six ops plus a permission lock, so the length is largely justified rather than padding.

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?

With no output schema, the description carries return-value disclosure itself: studioId on connect, the state reached, and lastResult on a later state call. Nothing an agent needs to call this correctly 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% so the schema already documents each param, but the description adds meaning beyond it: the returned studioId is linked to downstream tools (console, performance, execute_luau), and args is framed as the way to tell a test which case to exercise.

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?

States a specific verb+resource (starts/stops playtests) and enumerates each op's distinct effect (play spawns a character, run executes scripts with no player, multiplayer/addPlayers manage multi-player tests, state reports only). It is clearly distinguishable from siblings like execute_luau and list_studios.

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?

Explicitly describes when each op applies and when not: build in edit mode then play, use studioId for console/performance/execute_luau, and use edit-mode tools when `playtests off` locks starting simulation. Names the alternative behaviors (state/stop remain available) and exclusions (lock only blocks starting simulation).

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

screenshotSee the Studio viewportA
Read-onlyIdempotent

Takes a picture of the Studio viewport and returns it as an image you can actually look at.

Every other tool here reads the data model — names, properties, numbers — which answers 'is it there' but never 'does it look right'. A part can be at the correct position, anchored, correctly sized, and still be buried inside a wall, facing backwards, or hidden behind a GUI. Take a screenshot after building something visual, and before reporting that it worked.

It captures the viewport as the user currently sees it, so it shows their camera angle, not a framing of your choosing. Frame the subject with viewport op="focus" first — that is what makes this tool worth calling.

Works during a playtest too — address it at the playtest's studioId and you get the player's own view, which is the only way to check what a GUI actually looks like in front of the game. That one is taken on the client and read back through the editor session, so it is a little slower and needs the editor window still connected; the caption says playtest client when it came from there.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoZoom to this instance at full resolution: a GUI element, a part, a model, or a folder of parts. Edit session only; it must be on screen.
rectNoZoom to "x, y, width, height" in viewport pixels. Read them off an earlier screenshot using the scale its caption states.
widthNoLargest width of the image, in pixels; height follows the aspect ratio. Never scales up. To read small text, zoom with `path` or `rect` rather than raising this.
playerNoPlaytest only: whose screen to capture. Required when the test has several players.
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.1/5.0
Behavior4/5

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

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds valuable behavioral context: it captures the user's current camera angle (not agent-controlled framing), playtest captures are slower, require editor window connection, and are labeled 'playtest client'.

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?

Well-structured with three focused paragraphs: purpose, usage context, and playtest specifics. Front-loads the core function. Slightly verbose in places but every sentence adds value - no obvious waste.

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

Completeness4/5

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

Covers the essential aspects: what it does, when to use it, the key limitation (user's camera angle), how to frame subjects, and playtest behavior. With no output schema, it explains that it returns an image. Could mention resolution limits tied to width parameter more explicitly, but that's in the schema.

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

Parameters3/5

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

Schema coverage is 100%, so parameters are fully documented in the schema. The description mentions `viewport op="focus"` for framing and playtest's studioId usage, but doesn't add significant meaning beyond what the schema already provides for each parameter.

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?

States a specific verb+resource ('Takes a picture of the Studio viewport'), and explicitly distinguishes itself from all sibling tools by noting 'Every other tool here reads the data model'. The agent immediately understands this is the only visual verification tool.

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

Usage Guidelines4/5

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

Clearly states when to use it ('after building something visual, and before reporting that it worked') and mentions playtest usage context. However, it doesn't explicitly name sibling alternatives like `inspect` or `tree` for when the agent needs data rather than visuals, though the distinction is strongly implied.

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

script_createCreate scriptsA
Destructive

Creates Script, LocalScript or ModuleScript instances with their source.

Batch related scripts into one call: they are created inside one ChangeHistoryService recording, so the user can drop a whole generated system in a single undo. The response says whether that recording was actually opened — Studio refuses while another one is in progress.

Prefer Script with runContext: "Client" over LocalScript in new work — a Script with an explicit RunContext runs wherever you parent it, while LocalScript only runs under a player's character, backpack or PlayerGui.

The exception is the starter containers — StarterGui, StarterPack, StarterPlayerScripts, StarterCharacterScripts. They are COPIED into each player, so a Script with a non-Legacy RunContext there runs once where it sits and again in every copy, while a Legacy one does not run at all. Use LocalScript inside those. Creating one anyway comes back with a warning, because Studio's own warning about it goes to its Output and never reaches console.

Use script_edit to change a script that already exists.

ParametersJSON Schema
NameRequiredDescriptionDefault
scriptsYesScripts to create together as one undoable step.
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.6/5.0
Behavior5/5

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

The description goes well beyond the annotations by disclosing that batch creation happens inside a single ChangeHistoryService recording, that Studio may refuse to open another recording, what the response indicates, and how Studio's warning output behaves for `LocalScript` in starter containers. These are meaningful behavioral details not available from the annotations alone. No contradiction with annotations.

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

Conciseness5/5

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

The description is front-loaded with the core purpose, then adds the batching/undo behavior, then the nuanced script-type guidance, and finally the sibling routing. Every sentence carries meaningful information and none is redundant with the schema or annotations.

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

Completeness4/5

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

For a creation tool with no output schema, the description covers the most important runtime caveats: undo batching, recording refusal, starter-container behavior, and warnings. It could be slightly more complete by describing the full response shape or error behavior, but the essential invocation context is present.

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%, so the schema already documents all parameters; the baseline is 3. The description adds valuable semantics for `className` and `runContext`, explaining where `LocalScript` actually runs and how starter containers behave. It does not cover `source`, `disabled`, `parent`, or `studioId`, but those are already described in the schema.

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 opens with a precise verb and resource: 'Creates Script, LocalScript or ModuleScript instances with their source.' It clearly distinguishes itself from the sibling `script_edit` by naming it directly, and the restriction to script classes separates it from the generic `create` sibling.

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

Usage Guidelines4/5

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

It gives explicit routing guidance: 'Use `script_edit` to change a script that already exists.' It also provides strong contextual guidance on when to prefer `Script` with `runContext: "Client"` vs `LocalScript`, including the starter-container exception. However, it does not mention the generic `create` sibling or when that should be used instead, so the alternative-selection guidance is not fully complete.

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

script_editEdit scriptsA
Destructive

Edits Luau source through the Studio script editor. This is the tool to use for any change to existing code.

Every edit in one call is all-or-nothing: the whole batch is resolved against current source before anything is written, so if one edit cannot be applied nothing is. Batch related changes together, even across different scripts.

Each edit picks exactly one mode: find/replace — literal text, not a pattern. Preferred: it survives line numbers shifting. Fails if the text is not unique, unless you set replaceAll, so include enough surrounding lines to pin it down. startLine/endLine + replacement — for line ranges from script_read. Numbers refer to the file as you read it; several line edits to one script are applied bottom-up so they do not shift each other. source — replaces the whole script. Only for small files or a rewrite; it discards anything the user changed since you read it.

Pass revision on every edit. script_read prints it as rev beside each file, and sending it back makes the write conditional: if the script changed since you read it the batch is refused with STALE_SCRIPT and nothing is written. Without it the edit is applied blind, which matters most for the two modes that cannot notice: a line range still applies cleanly to source somebody else moved, it just lands on the wrong lines, and source discards their work entirely. Another agent editing the same place, or the user typing in the editor, is enough.

Writes go through ScriptEditorService:UpdateSourceAsync, so an open editor tab updates in place and unsaved work is preserved. Undo for source changes is the script editor's own, per script — Ctrl+Z in a script tab reverts that script, not the whole batch.

target="live" edits the PUBLISHED place instead. It takes ONE edit, it replaces the whole source rather than finding and replacing, and there is no undo of any kind — so read the script with script_read target="live" first and send back the whole thing. Needs confirm: true.

It changes the SAVED place, not running servers: people already playing keep the old code until their server empties. Follow it with universe op="restart" to roll them over.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNolive only: the script, e.g. "ServerScriptService.Main".
editsNoEdits to apply together as one undoable step. Required unless target is "live". The result carries each script's new `rev`, so a follow-up edit needs no re-read.
sourceNolive only: the complete new source.
targetNo'studio' edits the open place. 'live' rewrites a script in the published place over Open Cloud — one file, whole source, no undo.studio
confirmNoRequired for target="live".
placeIdNolive only: omit to use `cloud place`.
studioIdNoTarget Studio; omit for the active one.
universeIdNolive only: omit to use `cloud universe`.

TDQS

A5/5.0
Behavior5/5

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

The description goes far beyond annotations, detailing all-or-nothing batch semantics, mode-specific failure conditions (non-unique find, STALE_SCRIPT), revision-based concurrency control, writes through ScriptEditorService with undo behavior, live vs studio differences, and effects on running servers. It even explains that `source` discards user changes. No contradiction with annotations; instead it enriches them.

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

Conciseness5/5

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

The description is long but every sentence earns its place—no filler. It is front-loaded with the core purpose, then systematically covers batch behavior, modes, revision, live target, and server effects. The structure is logical and scannable, with clear section breaks.

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 complexity (multiple modes, live vs studio, concurrency), the description is remarkably complete. It covers failure modes, undo scope, server rollout, prerequisites, and even notes the returned `rev` for follow-up edits. There is no obvious gap an agent would need to fill.

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

Parameters5/5

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

Even though schema coverage is 100%, the description adds critical meaning: it explains how modes correspond to parameter combinations (find/replace vs startLine/endLine vs source), clarifies `revision` as a concurrency guard, warns about `replaceAll` behavior, and describes `target="live"` constraints. It turns raw parameter descriptions into actionable guidance.

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 states a specific verb and resource ('Edits Luau source through the Studio script editor') and explicitly frames it as the tool for any change to existing code, which clearly distinguishes it from script_create (new scripts) and script_read (reading). The purpose is unambiguous and context-aware.

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-to-use guidance ('any change to existing code'), explains the three edit modes with conditions for each, advises to batch related changes, and names the alternative tool (script_read) for reading. It also specifies when to use `target="live"` and prerequisites like `confirm: true`. Nothing is left to inference.

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

script_grepSearch script sourceA
Read-onlyIdempotent

Searches inside Luau source across the place and returns matching lines with their paths and line numbers.

Use this to find where something is defined or used before editing it — it is far cheaper than reading whole scripts to look for one call.

Patterns are Lua patterns, which are not regular expressions: % escapes instead of backslash, there is no alternation, and - means a lazy quantifier. Set literal to search for text exactly as written, which is usually what you want for identifiers.

To look for several identifiers, pass them together as patterns (literal, up to 16): one pass over the place instead of one per name, and each line says which of them it matched. mode="files" lists matching scripts only; mode="counts" gives matching-line counts per pattern.

Results are grouped by script with its rev, which script_edit accepts as revision. Matches come from the script editor's live buffer, so unsaved edits are searched too.

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNo'lines': matching lines. 'files': one row per matching script. 'counts': matching-line counts per pattern.lines
pathNoLimit to this subtree, e.g. "ServerScriptService". Omit to search everywhere.
limitNoMaximum items to return (1-500).
cursorNoOpaque cursor from a previous call's `nextCursor`. Omit for the first page.
literalNoTreat `pattern` as plain text rather than a Lua pattern.
patternNoLua pattern, or exact text when `literal` is set, e.g. "PlayerAdded".
patternsNoSeveral literal strings searched in one pass, instead of `pattern`.
studioIdNoTarget Studio; omit for the active one.
classNameNoRestrict to one script class: "Script", "LocalScript" or "ModuleScript".
ignoreCaseNoCase-insensitive. Both sides are lowercased, so pattern classes like %u stop being meaningful — combine with `literal`.
contextLinesNoLines of context to show either side of each match.

TDQS

A4.7/5.0
Behavior4/5

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

Annotations already cover safety (readOnlyHint, destructiveHint=false, idempotentHint). The description adds valuable context: results come from the live editor buffer and include unsaved edits; results are grouped by script with a rev that script_edit accepts. This cross-tool hint is beyond what annotations provide. Lacks pagination/cursor behavior detail but implies it via schema.

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

Conciseness5/5

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

Front-loaded with the core verb/resource/return shape, then usage, then pattern semantics, then multi-pattern behavior, then result grouping and cross-tool link. Every sentence earns its place with no filler.

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 11 params, no output schema, and rich annotations, the description covers what the agent needs: when to use, pattern language differences, identifier-search guidance, result grouping format, and a cross-tool link (rev → script_edit revision). Nothing important is missing for correct invocation.

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 description coverage is already 100%, so baseline is 3. The description adds meaningful semantics on top: Lua patterns are not regex with specifics about %, alternation, and lazy quantifier; literal mode advice; multi-pattern single-pass guidance with max 16. This goes beyond schema descriptions and materially helps correct usage.

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?

States a specific verb (Searches) and resource (Luau source across the place), with a clear description of what it returns (matching lines with paths and line numbers). Differentiates from siblings by positioning it as cheaper than script_read and references script_edit.

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?

Explicitly says when to use ('find where something is defined or used before editing it') and implicitly when not to ('far cheaper than reading whole scripts'). Prescribes literal mode for identifiers and multi-pattern mode for several identifiers, giving concrete guidance across the alternatives available.

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

script_readRead scriptsA

Reads Luau source from one or more scripts, with line numbers that script_edit accepts back verbatim.

Source comes from the Studio script editor's live buffer, so anything the user has typed but not yet saved is included. Reading the saved property instead would hand you stale code and you would 'fix' the change they just made.

Pass every script you need in one call, including when you want a different part of each: an entry may be a bare path for the whole file, or {path, startLine, endLine} for a window into that one script. The top-level startLine/endLine are the default for entries that do not carry their own.

A script bound to a file on disk is flagged in the result. Editing one of those is a race: whatever writes the file wins, and your change disappears the next time it does, with nothing anywhere reporting a failure.

open puts a script on the user's screen at a line, instead of telling them where to look. Ask for it when you are pointing at something they should see; it is not automatic, and reading twenty scripts does not rearrange their editor.

target="live" reads the code of the PUBLISHED place instead, with no Studio involved — which is how you check what is actually deployed rather than what is on someone's machine. Two limits are real and worth knowing before you reach for it: Roblox's Instance API can only see Folders and scripts, so a path through a Model or a Part cannot be walked at all; and it addresses things by GUID with no search, so each segment of the path costs a round trip. Expect seconds. list: true shows what is under a path instead of reading it, which is how you find your way down.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'read' returns source. 'open' opens the first path in the user's Studio editor at `line` and returns nothing to read.read
lineNoopen only: line to put the cursor on.
listNolive only: list what is under the first path instead of reading it. Pass `paths: [""]` to see the top level.
pathsYesScripts to read, e.g. ["ServerScriptService.Systems.Combat"] or [{ path: "...Combat", startLine: 120, endLine: 180 }].
targetNo'studio' reads the open place. 'live' reads the published place over Open Cloud, Folders and scripts only.studio
endLineNoDefault last line for entries without their own, inclusive. Omit to read to the end.
placeIdNolive only: omit to use `cloud place`.
studioIdNoTarget Studio; omit for the active one.
startLineNoDefault first line for entries without their own, 1-based and inclusive. Omit to start at the top.
universeIdNolive only: omit to use `cloud universe`.

TDQS

A5/5.0
Behavior5/5

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

Annotations are sparse (readOnlyHint=false, openWorldHint=true, idempotentHint=false, destructiveHint=false), so the description carries the burden. It discloses that reading includes unsaved changes from the live buffer, that `open` modifies the user's editor view, and that live mode has real limitations (only Folders/scripts, GUID round trips, seconds). It also flags disk-bound scripts as a race. This goes well beyond what annotations provide.

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

Conciseness5/5

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

The description is long but every sentence earns its place. It front-loads the core purpose, then systematically covers the live buffer, multi-script batching, disk-bound race, `open` behavior, `target="live"` constraints, and `list`. The structure uses clear paragraphs and examples, making it easy to scan. No redundancy or filler.

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 complexity (10 parameters, multiple modes), the description covers all critical aspects: the live vs studio distinction, open vs read, line windows, defaults, list navigation, and output hints (line numbers for script_edit, disk-bound flag). It even notes the absence of output schema by implying return content. An agent can call this correctly without further clarification.

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

Parameters5/5

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

Schema coverage is 100%, but the description adds substantial meaning: it explains the default startLine/endLine behavior for entries without their own, the two entry formats (bare path vs object with window), the semantics of `open` (returns nothing, puts cursor at line), and the purpose of `list: true` for navigation. It also clarifies `target="live"` limitations that the schema only hints at. This is a model of parameter enrichment.

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 opens with a specific verb and resource: 'Reads Luau source from one or more scripts' and immediately ties it to `script_edit` by mentioning line numbers it accepts back. It clearly distinguishes from siblings like `script_edit` (editing) and `script_grep` (search) by focusing on reading. The mention of the live buffer vs saved property further clarifies its unique role.

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?

The description explicitly advises when to use this tool: 'Pass every script you need in one call' and contrasts with reading the saved property to avoid stale code. It explains when `open` is appropriate ('when you are pointing at something they should see') and when `target="live"` is the right choice (checking deployed code). It also warns about the race condition for disk-bound scripts, giving clear when-not-to-use guidance.

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

set_active_studioSet active StudioA
Idempotent

Chooses which connected Studio window every other tool targets by default. Use it after list_studios when several places are open, and again whenever the user says to switch to another place.

The choice persists until it is changed or that Studio disconnects. While several Studios are connected and none has been chosen, tools refuse with AMBIGUOUS_STUDIO rather than guessing.

The choice belongs to this MCP connection alone. Several agents can share one Studio, and each keeps its own target, so calling this never moves another client's — two editors, or two sessions, can work on two places at once.

SUBAGENTS SHARE THEIR PARENT'S CONNECTION, and therefore its target. A subagent calling this retargets its parent and every sibling, and the damage is silent: later calls that name no studioId still succeed, just against the wrong place — and if that place is a playtest, everything written there is discarded when it stops. Inside a subagent, pass studioId on each call instead of calling this.

ParametersJSON Schema
NameRequiredDescriptionDefault
studioIdYesA studioId from list_studios.

TDQS

A4.6/5.0
Behavior5/5

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

Although annotations already indicate non-read-only, non-destructive behavior, the description adds substantial beyond-schema context: persistence until changed or disconnected, AMBIGUOUS_STUDIO refusal when no choice exists, per-connection state isolation, and the silent subagent retargeting hazard. This is rich disclosure of consequences beyond any structured field.

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?

The description is longer than average, but it is front-loaded with the core purpose and usage, and every later paragraph covers a real behavioral consequence. The subagent warning is verbose but vital; a slight tightening would make it fully concise, so 4 rather than 5.

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?

For a stateful selector with connection-scoped side effects, the description covers the full lifecycle: when to invoke it, what happens while multiple studios are connected, how state persists, and how it interacts with subagents. No output schema is needed, and nothing required to call it correctly is missing.

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

Parameters3/5

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

Schema description coverage is 100%, and the only parameter, studioId, is documented in the schema as coming from list_studios. The description reinforces the source and warns subagents to pass studioId directly, but it does not add new format, range, or default semantics beyond what the schema already states. Baseline 3 is appropriate.

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 states a specific verb and resource: it 'Chooses which connected Studio window every other tool targets by default.' It is immediately distinguishable from siblings like list_studios and studio_status because it names the selection role and the effect on other tools.

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?

Usage is explicit: use after list_studios when several places are open, and again when the user asks to switch. It also gives a firm exclusion, telling subagents to pass studioId on each call instead of invoking this tool, which is exactly the kind of when-to-use vs. when-not-to-use guidance an agent needs.

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

studio_statusStudio statusA
Read-onlyIdempotent

One-call snapshot of the connected Roblox Studio: place name and id, whether it is in edit / run / play mode, the current selection, which scripts are open in the editor, and how big the data model is.

Call this FIRST in any Studio session, and again whenever a tool reports NO_STUDIO or TIMEOUT — it is the cheapest way to tell a disconnected plugin apart from a genuinely failing request. Also call it before and after playtest, because most tools behave differently in run mode.

openScripts is what the user is actually working on: for each open tab it gives the script's path, the cursor line, any selected text, and which lines are on screen. Use it whenever a request is deictic — 'this function', 'the script I'm in', 'fix this' — instead of searching the place or asking which file they mean. Studio exposes no focused-tab API, so with several open, prefer the one holding a selection and otherwise ask.

Returns JSON. Selection is capped at 50 entries and selected text at 400 characters; use find or script_read for more.

ParametersJSON Schema
NameRequiredDescriptionDefault
studioIdNoTarget a specific Studio instance. Omit to use the active one (see list_studios / set_active_studio).

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already mark it read-only and safe, and the description adds behavioral limits and caveats: selection is capped at 50 entries, selected text at 400 characters, no focused-tab API exists, and it returns JSON. It also positions the call as the cheapest diagnostic for disconnection, which helps the agent interpret failures.

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

Conciseness5/5

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

Three dense paragraphs front-load the tool's purpose in the first sentence and every subsequent sentence adds decision-relevant detail: sequencing, deictic interpretation, and truncation limits. No filler is present; the length is justified by the absence of an output schema.

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?

The description covers what the tool returns, when to use it, how to interpret openScripts without a focused-tab API, and the truncation behavior that affects agents needing more data. Combined with the read-only annotations and schema-documented studioId, an agent has everything needed to call and interpret this tool correctly.

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

Parameters3/5

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

The single optional studioId parameter is fully documented in the schema itself ('Omit to use the active one'), so the description need not repeat it. The description adds no additional parameter-level meaning, but with 100% schema coverage the baseline 3 is appropriate.

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 opens with 'One-call snapshot of the connected Roblox Studio' and enumerates the exact fields returned: place name/id, edit/run/play mode, selection, open scripts, and data model size. This clearly differentiates it from siblings like list_studios and find by scoping it to the connected Studio session.

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 explicitly instructs the agent to call this tool FIRST in any Studio session, on NO_STUDIO/TIMEOUT, and before/after playtest. It also gives a concrete alternative rule: for deictic requests, use openScripts data instead of searching the place or asking the user, and prefer tabs with a selection. This is the strongest possible usage guidance.

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

syncSync scripts with files on diskA
Destructive

Mirrors the place's scripts into a folder on disk, so you can work on code with your own file tools -- read a window, search, edit in place, diff -- and then send it back to Studio in one call. Studio stays where the game runs: use playtest, screenshot, console and input to check the result.

Layout mirrors the instance tree, Rojo-style: ServerScriptService/Main.server.luau is a Script, .client.luau a LocalScript, .luau a ModuleScript, and a script with scripts inside is a folder holding init.server.luau (or init.client.luau, init.luau). New files become new scripts, and a file moved or renamed moves the script itself, keeping its identity.

Ops: status shows what would change without changing anything. sync goes both ways, pull only Studio -> disk, push only disk -> Studio. watch keeps them in step until stop: edit files and Studio follows within a second, and edits in Studio land on disk.

Nothing is overwritten blind. The last sync is remembered per file, so a file changed on both sides is a conflict, reported and left alone -- settle it, or pass prefer. Deleting a file deletes the script (one Ctrl+Z in Studio); a script deleted in Studio moves its file to .rbx-sync/trash. Nothing is deleted on a first sync.

UI and other instance trees: export writes one as a build file (e.g. StarterGui/Shop.build.json, the same fields create takes, only non-default properties). Edit it, then build -- or any sync -- rebuilds the tree in one undo step, keeping the scripts inside it. Build files are two-way too: a tree edited in Studio is written back to its file, and edits on both sides are a conflict rather than one silently undoing the other.

Conflicts leave Studio's version in .rbx-sync/conflicts/. Merge into the file (or fix Studio) and sync again: whichever side changed since the conflict wins. While watch runs, new conflicts and errors are appended to your next tool reply.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'status': dry run. 'sync': both ways. 'pull': Studio -> disk. 'push': disk -> Studio. 'watch'/'stop': continuous two-way sync. 'export': instance trees -> build files. 'build': build files -> instance trees.
dirNoSync folder, relative to the working directory. Default "studio".
filesNobuild: build files to apply, relative to the folder. Default: those changed since last built.
pathsNoexport: instances to write as build files, e.g. ["StarterGui.Shop"].
rootsNoStudio paths to sync, e.g. ["ServerScriptService", "ReplicatedStorage.Shared"]. Default: every service scripts are authored in. Remembered for the folder once given.
preferNoSettle conflicts in favour of one side instead of reporting them.
rebindNoLet a folder synced with one place follow a different place. Almost never what you want.
studioIdNoTarget Studio; omit for the active one.
confirmDeletesNoAllow a run that deletes most of what the folder tracks. Check `status` first.

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already flag destructive=true, non-idempotent, openWorld; the description goes well beyond that by disclosing exact destruction semantics ('deleting a file deletes the script, one Ctrl+Z in Studio'), trash/conflict locations ('.rbx-sync/trash', '.rbx-sync/conflicts/'), the first-sync no-delete guarantee, and the conflict-wins resolution rule. This is unusually rich behavioral disclosure for a mutation tool.

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?

The purpose is front-loaded and paragraphs are organized by concern (mirror, layout, ops, safety, build files, conflicts). It is long — roughly 350 words — and the trailing conflict-resolution paragraph could be folded into the earlier safety paragraph, but for an 8-op tool the length is largely earned.

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?

With 9 parameters, 8 enum ops, no output schema, and destructive/open-world behavior, this tool has substantial complexity, and the description covers layout mapping, per-op semantics, deletion safety, conflict handling, and the export/build round trip. Nothing an agent must know before invoking it appears 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 description coverage is 100%, so the per-parameter baseline is 3, but the narrative adds meaning the enum text does not: it explains what `watch` does over time, how `prefer` interacts with conflicts, and the consequence of `rebind` ('almost never what you want'). It stops short of documenting `dir`/`studioId`/`files`/`paths` beyond what the schema already states.

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 states a concrete verb and resource ('mirrors the place's scripts into a folder on disk') and frames the whole workflow (edit locally, send back to Studio in one call). It is immediately distinguishable from siblings like script_read, script_edit, and modify, whose scope is single-script rather than folder-tree mirroring.

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

Usage Guidelines4/5

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

It explains which op to reach for (`status` before destructive runs, `sync`/`pull`/`push` directionality, `watch` until `stop`) and routes verification work to siblings ('use playtest, screenshot, console and input to check the result'). It stops short of saying when NOT to use this tool versus in-place editing tools like script_edit, so it is clear context rather than full alternative routing.

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

terrainBuild and edit terrainA
Destructive

Fills, repaints and clears Roblox terrain — hills, water, caves, roads.

Terrain is not made of instances, so none of the instance tools reach it: there is nothing to create, no path for find, and no property for modify. This is the only way to shape it short of writing FillBall calls by hand through execute_luau.

fill takes an ARRAY of solids and applies them as one undo step, which is how terrain is actually built: a hill is several overlapping balls, a road is a row of blocks. Shapes are block (needs size), ball (needs radius), cylinder (needs radius and height) and wedge (needs size).

To CARVE, fill with material Air. That is not a special mode — a cave is a ball of Air inside a hill, and a tunnel is a row of them.

replace swaps one material for another inside a region and leaves the shape alone, which is how you turn a grass hill to snow without rebuilding it. clear empties a region, or everything with confirm=true. stats says whether the place uses terrain at all -- call it first in an unfamiliar place. It cannot say WHERE the terrain is: Roblox exposes no bounding box for it. Take a screenshot to see the shape.

Positions are the centre of the solid, in studs, as "x, y, z". Terrain snaps to a 4-stud voxel grid, so small features come out blockier than the numbers suggest; nothing thinner than about 4 studs survives.

ParametersJSON Schema
NameRequiredDescriptionDefault
opNo'fill' adds solids (use material Air to carve), 'replace' swaps a material in place, 'clear' empties a region or everything, 'stats' reports what is there.stats
toNoreplace only: the material to write instead.
fromNoreplace only: the material to look for.
sizeNoreplace and clear: extent of the region in studs, e.g. "512, 256, 512".
shapesNofill only: the solids to apply, together, as one undo step.
confirmNoclear only: required to empty ALL terrain. Omit it and give `position`/`size` to clear one region instead.
positionNoreplace and clear: centre of the region, e.g. "0, 0, 0".
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.8/5.0
Behavior5/5

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

Beyond annotations (which already flag destructive/non-idempotent), the description discloses that `fill` applies all solids as a single undo step, that carving is done by filling with material Air (not a special mode), that `clear` on everything requires confirm=true, and that `stats` cannot report terrain location. It also warns about the 4-stud voxel quantization and that nothing thinner than ~4 studs survives — real behavioral constraints an agent cannot infer from the schema.

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?

Front-loaded with a one-line summary followed by op-specific paragraphs; nearly every sentence carries actionable information. It runs long and a few clauses (e.g. the FillBall aside) are conversational, but the length is justified by the tool's four-op complexity.

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?

With no output schema, the description steps in to cover return-relevant behavior (stats reports only whether terrain exists), the fallback for visualizing shape (screenshot), coordinate/units conventions, and the voxel-grid limitation. An agent has everything needed to choose an op and call it correctly.

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%, so the baseline is 3, but the description adds genuine meaning: the per-shape parameter requirements (block/wedge need size, ball needs radius, cylinder needs radius+height), positions as the centre of the solid in studs, and the Air-carve convention. Much of this is mirrored in the schema descriptions, so it is additive rather than essential.

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 opening line names specific verbs (fills, repaints, clears) and the exact resource (Roblox terrain), then enumerates concrete use cases (hills, water, caves, roads). It also explicitly separates itself from the instance-based siblings: 'none of the instance tools reach it: there is nothing to create, no path for find, and no property for modify.'

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?

Each op gets a when-to-use: `fill` for building, `replace` for swapping material while leaving shape intact, `clear` for emptying, and `stats` explicitly recommended as the first call in an unfamiliar place. It names the alternative route (`execute_luau` FillBall calls) and frames itself as the preferred path over it.

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

treeBrowse hierarchyA
Read-onlyIdempotent

Lists the instance hierarchy under a path, breadth-first to a given depth. Returns a flat array of paths — flat is both cheaper and easier to act on than nested JSON, since every entry is directly usable as a path.

Use this to orient yourself in an unfamiliar place. Use find instead when you already know what you are looking for; a deep tree over a whole place wastes context on instances you will never touch.

With path omitted it lists only the containers a place is authored in — Workspace, ReplicatedStorage, ServerScriptService and friends. Roblox exposes ~120 services at the root, almost all engine internals; those are hidden and the response says how many. Pass an explicit path to look inside one of them anyway.

ParametersJSON Schema
NameRequiredDescriptionDefault
pathNoDot-notation root, e.g. "Workspace.Map". Omit to list services from the root.
depthNoLevels below `path` to walk. Keep low; each level multiplies the result.
limitNoMaximum items to return (1-500).
cursorNoOpaque cursor from a previous call's `nextCursor`. Omit for the first page.
detailNoconcise: compact identity. standard: selected facts. full: all readable properties for inspect; tree/find use the same columns as standard.standard
studioIdNoTarget Studio; omit for the active one.
classNameNoOnly include instances of this class or a subclass, e.g. "BasePart".
nameContainsNoOnly include instances whose name contains this text (case-insensitive).

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description adds real behavioral context beyond that: the flat-array return format, the depth-multiplication cost warning, and the fact that ~120 engine-internal root services are hidden with a count reported. It stops short of covering pagination/error behavior, but that is a minor omission.

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?

Front-loaded with the core behavior, then guidance, then the omit-path edge case — a sensible progression. Three paragraphs is slightly long, and the 'flat is both cheaper and easier to act on' rationale is arguably more justification than an agent needs, but every sentence carries information.

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?

With no output schema, the description carries the burden of describing the return value, and it does (flat array of paths, hidden-service count). Combined with the sibling routing and the omit-path explanation, an agent has everything needed to call this correctly.

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%, so the schema itself documents all 8 parameters including the omitted-path behavior. The description still adds value on `path` (what the omitted case actually yields and why services are hidden) and on `depth` (cost implication), going modestly beyond the schema's own text.

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?

States a specific verb and resource: 'Lists the instance hierarchy under a path, breadth-first to a given depth.' It also states the return shape (flat array of paths) and explicitly distinguishes itself from the sibling `find`, so an agent can select it without opening either 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?

Gives explicit when-to-use ('orient yourself in an unfamiliar place') and when-not ('Use `find` instead when you already know what you are looking for'), plus the cost rationale for avoiding deep trees. It also explains the omit-path case, which selects a materially different behavior.

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

undoUndo and redoA
Destructive

Steps Studio's undo history backwards or forwards.

Every write this server makes is already wrapped in an undo recording, so this reverses your own work as cleanly as the user pressing Ctrl+Z — one tool call is one step. Use it when the user says an edit was wrong, instead of trying to reconstruct the previous state by hand, which is guesswork and usually incomplete.

It reports how many steps actually applied, which is not always what was asked: the stack runs out, and an undo that did nothing otherwise looks exactly like one that worked.

Studio's history covers the whole session, including the user's own edits — undoing more steps than you made will start reverting THEIR work. Undo only what you just did, and only when asked.

ParametersJSON Schema
NameRequiredDescriptionDefault
stepsNoHow many steps to take. Keep it to what you did yourself.
actionNo'status' reports what is available without changing anything.status
studioIdNoTarget Studio; omit for the active one.

TDQS

A4.8/5.0
Behavior5/5

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

The annotation `destructiveHint: true` is already declared, but the description meaningfully adds context: it discloses the partial-failure behavior ('the stack runs out, and an undo that did nothing otherwise looks exactly like one that worked'), clarifies that the server's own writes are pre-wrapped in undo recordings, and warns that the history 'covers the whole session, including the user's own edits.' These are important behavioral traits that annotations alone cannot convey. There is no contradiction between description and annotations.

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?

The description is moderately long, but every paragraph earns its place — it fronts the core statement of what it does, then explains when to use it, then the critical edge case, and finally the safety warning. Nothing is wasted, and for a destructive tool, the added length is fully justified. It could be tightened slightly, but the density of information is well-matched to the risk profile.

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?

For a tool with no output schema, the description's disclosure that 'It reports how many steps actually applied' is essential return-value context. The description covers the full picture — the mechanics, the failure modes (stack exhaustion), the risks (resetting user work), and the safety guardrail — while the parameters and annotations are all declared. The tool's complexity (3 params, a destructive flag, no nested objects) is thoroughly addressed. There is no meaningful gap an agent would need to resolve before calling this correctly.

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?

With 100% schema description coverage, the schema already documents all three parameters completely, so the baseline is 3. The description adds extra value by explaining the edge case relevant to the `steps` parameter — that over-requesting is possible and will silently return fewer steps, and by clarifying how the `action: 'status'` semantics let the caller inspect before mutating. It would have been a 5 with even more explicit per-parameter cross-referencing, but this exceeds the baseline.

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 clearly states the tool's purpose: 'Steps Studio's undo history backwards or forwards' — a specific verb with an explicit resource and scope. It differentiates this from other operations by explaining what it reverses and why ('as cleanly as the user pressing Ctrl+Z — one tool call is one step'). Even though it's named just 'undo', the title 'Undo and redo' plus the description make the full scope clear.

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?

The description provides explicit usage conditions: 'Use it when the user says an edit was wrong, instead of trying to reconstruct the previous state by hand, which is guesswork and usually incomplete.' It also sets clear boundaries with 'Undo only what you just did, and only when asked', and explains the danger case where undoing beyond your own edits will revert the user's work. This is exactly the kind of when-to/not-to guidance that an agent needs.

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

universeOperate the live gameA
Destructive

Acts on the PUBLISHED experience and the people in it — not on the place open in Studio.

restart rolls live servers onto the version you just published. Publishing on its own changes nothing for anyone already playing: they stay on their server, running the old code, until it empties. This is the step people forget. By default it bleeds off over 10 minutes — matchmaking stops and players finish what they are doing — rather than shutting servers down under them, which is what Roblox's own default does.

message publishes to MessagingService, reaching every live server at once. Only servers with a SubscribeAsync listener on that exact topic receive it, and nothing reports whether anything was listening, so success here does not mean delivery.

ban and unban set a player's game-join restriction. A ban with no durationSeconds is PERMANENT. displayReason is shown to the player; privateReason is for your records. Scope it to one place with placeId, or leave that out to cover the whole experience. bans lists who is currently restricted.

user looks up a user id — the name-to-id step most other calls need. inventory reports what someone owns: passes, badges, assets.

servers lists the place's live servers — players, uptime, frame rate, memory, version — and logs reads one server's errors and warnings by its jobId, with stack traces and structured-log context. That is where a player's bug report actually happened; Studio only shows your own test. Roblox keeps warnings and errors only, and they arrive about three minutes after they are written.

products lists the game's developer products and game passes with their ids and prices — the ids a purchase script needs. sell creates one, or changes one given itemId. Creating checks the name first, so a retried create cannot leave two "100 Coins" products.

Everything here needs an Open Cloud key and a universe id. The user sets both once with cloud in the Studio panel.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'restart' rolls servers onto the new version, 'message' publishes to MessagingService, 'ban'/'unban'/'bans' manage player access, 'user' and 'inventory' look someone up, 'servers' and 'logs' read live servers, 'products' and 'sell' manage products and passes.
kindNoproducts/sell: 'product' is a developer product (bought again and again: currency, boosts), 'pass' a game pass (bought once: VIP, perks). products lists both when omitted; sell needs it.
nameNosell only: the item's name. Required to create.
imageNosell only: path to a local .png/.jpg/.bmp/.tga icon.
jobIdNologs only: the server, as listed by `servers`.
limitNobans/inventory/servers/logs: how many rows to return.
priceNosell only: price in Robux.
topicNomessage only: the MessagingService topic.
filterNoinventory: an Open Cloud filter, e.g. `gamePassIds=123` or `assetIds=456`, to ask about specific items rather than listing everything. servers: a CEL filter over the server fields, e.g. `occupancy > 0`.
itemIdNosell only: the product or pass to change. Omit to create a new one.
searchNologs only: case-insensitive text to find in the message, stack trace or context.
userIdNoban/unban/user/inventory: the player's user id.
confirmNoRequired for restart, message, ban, unban and sell. Each of these is visible to players the moment it runs and none can be undone from here.
forSaleNosell only: whether players can buy it. Say it explicitly when creating.
messageNomessage only: the payload, as a string.
placeIdNoban/unban: restrict to this place only, instead of the whole experience. restart: only restart this place's servers. servers/logs: which place, defaulting to `cloud place`.
severityNologs only: just this level. Omit for both.
universeIdNoWhich game. Omit to use the one set with `cloud universe <id>`.
descriptionNosell only: the item's description.
displayReasonNoban only: shown to the player when they are turned away.
privateReasonNoban only: your own record. The player never sees it.
bleedOffMinutesNorestart only: minutes to let existing servers drain. 0 shuts them down immediately, moving players mid-game. Defaults to 10.
durationSecondsNoban only: how long, in seconds. OMIT THIS AND THE BAN IS PERMANENT — say so to the user before you do it.
excludeAltAccountsNoban only: if true, the ban applies to this account alone rather than to alts Roblox links to it. Defaults to false.

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and openWorldHint=true, yet the description still adds substantial non-obvious behavior: default 10-minute bleed-off vs. Roblox's hard shutdown, MessagingService topic matching with no delivery feedback, relative server versioning semantics, permanent-ban risk when durationSeconds is omitted, ~3-minute log latency and warnings/errors-only retention, and create-time name checking that prevents duplicate products. It also correctly labels confirm as required for the irreversible ops rather than contradicting the destructive hint.

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

Conciseness5/5

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

Long but fully earned: one paragraph per op group, backticked op names, front-loaded with the single most important distinction (live vs. Studio), and no repetition of schema text. Every sentence carries either a behavioral or routing fact.

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?

For an 11-op, 24-parameter tool with no output schema, the description covers return shape where it matters (servers lists players/uptime/frame rate/memory/version; logs carries stack traces and structured context; products lists ids and prices), plus the auth/setup requirement. Nothing an agent needs to call it correctly 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%, so the schema carries most parameter meaning and the baseline would be 3. The description still adds real semantics beyond it — placeId scoping ('scope it to one place... or leave that out to cover the whole experience'), the create-vs-change contract of itemId, and the confirm requirement for the externally visible ops — so it edges above baseline.

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?

Opens with a precise scope statement — 'Acts on the PUBLISHED experience and the people in it — not on the place open in Studio' — that immediately separates it from every studio-side sibling (execute_luau, playtest, viewport). Each of the 11 ops is then named with a concrete verb+resource, so an agent knows what this tool does 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?

Explicitly says when to use restart (after publish, because publishing alone changes nothing for live players), when to prefer it over Roblox's harsh default, when message delivery is not guaranteed, when logs are the right source ('where a player's bug report actually happened; Studio only shows your own test'), and the prerequisite (Open Cloud key + universe id set via `cloud`). Alternatives and exclusions are named, not implied.

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

viewportViewport and selectionA
Idempotent

Works with the 3D view and the Studio selection.

select sets, extends or shrinks what is highlighted in Studio. Select what you just built or changed — it shows the user the result, and puts the instance under Studio's own move and scale handles. studio_status reports the current selection; this sets it.

focus aims the Studio camera at an instance and frames it so the whole thing is on screen. This is what makes screenshot worth having: a picture of wherever the camera happened to be answers nothing, while a picture of the thing you just built answers 'does it look right', which no amount of reading properties can. Build, focus, screenshot.

The distance is computed from the subject's size and the camera's field of view, so a doorway and a whole map both arrive filling a similar share of the frame. from changes the angle you view it from, and padding how tightly it is framed.

camera sets or reads the camera directly, for shots framing cannot express — standing inside a room, or looking along a corridor.

raycast fires a ray through the world and reports the first thing it hits, with position, surface normal, distance and material. This answers 'what occupies this space', which the data model alone cannot: use it to find the ground under a spawn point, or check whether a gap is clear before placing something.

ui audits a whole interface for the faults that are invisible in the data model: elements off the side of the screen, elements covering each other, zero-size elements, text too small to read, and text that overflows its label. A button positioned off a phone screen has a perfectly correct Position and Size — nothing about the instance is wrong, it is just somewhere nobody can reach.

It measures against whatever device is currently emulating, so the way to use it is twice: once as-is, then device op="set" a phone and again. Layout is live in edit mode — no playtest needed.

textbounds measures how big a piece of text actually renders. Point it at a TextLabel, TextButton or TextBox with path and it reads that label's own text, font, size and width and answers whether the text fits inside it. Give text and size directly and it just measures. There is no other honest way to answer 'will this label overflow' — character counts ignore the font, and font size is not a width.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNofocus only: look at this point instead of an instance, e.g. "0, 10, 0".
opYes'focus' points the camera at something and frames it, 'camera' sets it explicitly, 'select' changes the Studio selection, 'textbounds' measures rendered text, 'raycast' queries the world.
fontNotextbounds only: an Enum.Font name, e.g. "GothamMedium". Defaults to the label's.
fromNofocus only: direction to view from, e.g. "0, 1, 0" for directly above or "1, 0, 0" from the side. Defaults to a raised three-quarter view.
modeNoselect only: replace the selection, extend it, or remove from it.set
pathNofocus only: the instance to look at. A model, part, or folder containing them.
textNotextbounds only: the string to measure. Defaults to the label's own text.
pathsNoselect only: instances to select. An empty array clears the selection.
ignoreNoraycast only: instances the ray passes through.
lookAtNocamera only: the point to aim at.
originNoraycast only: where the ray starts, e.g. "0, 50, 0".
paddingNofocus only: how much room to leave around the subject. 1 is tight.
positionNocamera only: where to put the camera, e.g. "0, 20, 30".
richTextNotextbounds only: treat the text as rich text. Defaults to the label's setting.
studioIdNoTarget Studio; omit for the active one.
textSizeNotextbounds only: font size in pixels. Defaults to the label's.
directionNoraycast only: which way it points, e.g. "0, -1, 0" for straight down.
wrapWidthNotextbounds only: wrap at this width. 0 means do not wrap. Defaults to the label's width.
fieldOfViewNocamera only: field of view in degrees. Lower is more zoomed in.
maxDistanceNoraycast only: how far to look, in studs.

TDQS

A4.5/5.0
Behavior4/5

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

Annotations cover the safety profile (readOnlyHint=false, destructiveHint=false, idempotentHint=true), and the description adds genuinely new behavioral context: layout is live in edit mode with no playtest needed, distance is computed from subject size and FOV, and each query op's return shape (position/normal/distance/material for raycast). It does not state which ops mutate Studio state vs. only read, which annotations leave fuzzy at the whole-tool level.

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?

Organized op-by-op with lead sentences per capability, so it is scannable despite its length. It is on the verbose side and includes editorializing ('which no amount of reading properties can', 'answers nothing'), which is justified for a broad multi-op tool but not uniformly earning its place.

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

Completeness4/5

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

For a 6-op, 20-param tool with no output schema, the description is thorough: it explains what raycast, ui, and textbounds return and what select/focus/camera change. The one gap is that select/camera return values are never characterized, but given the query ops are documented, completeness is strong.

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 description coverage is 100%, so the baseline is 3, but the prose adds conceptual meaning beyond the per-parameter strings: how focus computes distance and frames both a doorway and a whole map similarly, that `at` substitutes for an instance, that ui measures against the current `device`, and that textbounds falls back to the label's own text/font/size when fields are omitted.

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 names each of the six ops with a concrete verb+resource: 'select sets/extends/shrinks the Studio selection', 'focus aims the camera', 'raycast fires a ray', 'ui audits an interface', 'textbounds measures rendered text'. It explicitly distinguishes itself from siblings ('studio_status reports the current selection; this sets it'), so an agent can route 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?

Nearly every op carries a when-to-use: 'select what you just built or changed', 'build, focus, screenshot', 'use ui... twice: once as-is, then device op="set" a phone and again'. It names the related tools (screenshot, device, studio_status) and the condition that selects each, leaving little to inference.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 13 tool updatesv0.8.6
    • Changedaudio1 field changed
      • changedInput schema / properties / asset / description
        Previous value: -"graph only: the audio id, e.g. \"rbxassetid://1234\". Find one with `assets op=\"search\" kind=\"audio\"`. Leave it out to build the chain now and set the asset later."New value: +"graph only: the audio id, e.g. \"rbxassetid://1234\". Find one with `assets op=\"search\" category=\"audio\"`. Leave it out to build the chain now and set the asset later."
    • Changedcollision2 fields changed
      • changedInput schema / properties / radius / description
        Previous value: -"cast shape=\"sphere\" or overlap region=\"radius\": the radius."New value: +"cast shape=\"sphere\" or overlap region=\"radius\": the radius. Defaults to 1 for a cast and 4 for an overlap."
      • changedInput schema / properties / size / description
        Previous value: -"cast shape=\"block\" or overlap region=\"box\": the volume size."New value: +"cast shape=\"block\" or overlap region=\"box\": the volume size. Defaults to \"1, 1, 1\" for a cast and \"4, 4, 4\" for an overlap."
    • Changedconsole2 fields changed
      • addedInput schema / properties / group
        Added value: +{
        +  "default": false,
        +  "description": "Collapse identical lines into one row with a count and first/last times.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / mode
        Added value: +{
        +  "default": "tail",
        +  "description": "'tail': the newest matches, cursor at the end of the log. 'drain': the oldest unread matches, cursor at the first one not shown, so a loop reads every line once.",
        +  "enum": [
        +    "tail",
        +    "drain"
        +  ],
        +  "type": "string"
        +}
    • Changeddevice4 fields changed
      • changedInput schema / properties / loss / description
        Previous value: -"network only: percentage of packets thrown away, up to 50 — the engine's own ceiling. The field that finds real bugs: latency makes a game feel slow, loss makes it behave wrongly. 2-8% is a bad mobile connection."New value: +"network only: percentage of packets thrown away, up to 0.5 — Roblox caps it there so the simulation does not fight congestion control. Latency makes a game feel slow; loss makes unreliable remotes arrive out of order or not at all."
      • changedInput schema / properties / loss / maximum
        Previous value: -50New value: +0.5
      • changedInput schema / properties / memory / description
        Previous value: -"network only: pretend the machine has this many MB of memory. A cheap phone is a small screen AND little memory; this is the half that makes textures unload. 0 removes the cap."New value: +"network only: pretend the machine has this many MB of memory. A cheap phone is a small screen AND little memory; this is the half that makes textures unload. 0 removes the cap, restoring the real amount."
      • changedInput schema / properties / preset / description
        Previous value: -"network only: a whole connection in one word. clear=0ms (normal), wifi=15ms, 4g=60ms/0.5% loss, 3g=150ms/2% loss, poor=400ms/8% loss. Named fields below override whichever part you name."New value: +"network only: a whole connection in one word. clear=0ms (normal), wifi=15ms, 4g=60ms/0.1% loss, 3g=150ms/0.3% loss, poor=400ms/0.5% loss. Named fields below override whichever part you name."
    • Changedfind2 fields changed
      • changedInput schema / properties / detail / description
        Previous value: -"How much to return per item. 'concise' = name + class only, cheapest, use when scanning or counting. 'standard' = the properties that matter for most edits. 'full' = every readable property, expensive — use only after you have narrowed to a handful of instances."New value: +"concise: compact identity. standard: selected facts. full: all readable properties for inspect; tree/find use the same columns as standard."
      • addedInput schema / properties / properties
        Added value: +{
        +  "description": "Project just these properties on matching rows, avoiding a second inspect call. Unreadable names are reported.",
        +  "items": {
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "type": "array"
        +}
    • Changedgeometry2 fields changed
      • changedInput schema / properties / collisionFidelity / description
        Previous value: -"How exactly the result collides. Precise is expensive - raise it only for a surface players walk on."New value: +"How exactly the result collides. Precise is expensive - raise it only for a surface players walk on. Tunable picks a precision from the size and handles thin details better; adjust it afterwards with `modify` on CollisionPrecision."
      • changedInput schema / properties / collisionFidelity / enum
        Previous value: -[
        -  "Default",
        -  "Hull",
        -  "Box",
        -  "PreciseConvexDecomposition"
        -]New value: +[
        +  "Default",
        +  "Hull",
        +  "Box",
        +  "PreciseConvexDecomposition",
        +  "Tunable"
        +]
    • Changedinspect1 field changed
      • changedInput schema / properties / detail / description
        Previous value: -"How much to return per item. 'concise' = name + class only, cheapest, use when scanning or counting. 'standard' = the properties that matter for most edits. 'full' = every readable property, expensive — use only after you have narrowed to a handful of instances."New value: +"concise: compact identity. standard: selected facts. full: all readable properties for inspect; tree/find use the same columns as standard."
    • Changedplaytest4 fields changed
      • changedInput schema / properties / op / description
        Previous value: -"'play' starts a playtest with a character, 'run' runs scripts with no player, 'multiplayer' starts a several-player test, 'stop' ends it and discards its changes, 'state' only reports."New value: +"'play' starts a playtest with a character, 'run' runs scripts with no player, 'multiplayer' starts a several-player test, 'addPlayers' joins more to a running multiplayer test, 'stop' ends it and discards its changes, 'state' only reports."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "play",
        -  "run",
        -  "multiplayer",
        -  "stop",
        -  "state"
        -]New value: +[
        +  "play",
        +  "run",
        +  "multiplayer",
        +  "addPlayers",
        +  "stop",
        +  "state"
        +]
      • removedInput schema / properties / players / default
        Removed value: -2
      • changedInput schema / properties / players / description
        Previous value: -"multiplayer only: how many players to start."New value: +"multiplayer: how many players to start (default 2). addPlayers: how many to add (default 1)."
    • Changedscreenshot1 field changed
      • addedInput schema / properties / player
        Added value: +{
        +  "description": "Playtest only: whose screen to capture. Required when the test has several players.",
        +  "type": "string"
        +}
    • Changedscript_grep4 fields changed
      • addedInput schema / properties / mode
        Added value: +{
        +  "default": "lines",
        +  "description": "'lines': matching lines. 'files': one row per matching script. 'counts': matching-line counts per pattern.",
        +  "enum": [
        +    "lines",
        +    "files",
        +    "counts"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / pattern / minLength
        Added value: +1
      • addedInput schema / properties / patterns
        Added value: +{
        +  "description": "Several literal strings searched in one pass, instead of `pattern`.",
        +  "items": {
        +    "minLength": 1,
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "minItems": 1,
        +  "type": "array"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "pattern"
        -]
    • Addedsync
    • Changedtree1 field changed
      • changedInput schema / properties / detail / description
        Previous value: -"How much to return per item. 'concise' = name + class only, cheapest, use when scanning or counting. 'standard' = the properties that matter for most edits. 'full' = every readable property, expensive — use only after you have narrowed to a handful of instances."New value: +"concise: compact identity. standard: selected facts. full: all readable properties for inspect; tree/find use the same columns as standard."
    • Changeduniverse16 fields changed
      • changedInput schema / properties / confirm / description
        Previous value: -"Required for restart, message, ban and unban. Each of these is visible to players the moment it runs and none can be undone from here."New value: +"Required for restart, message, ban, unban and sell. Each of these is visible to players the moment it runs and none can be undone from here."
      • addedInput schema / properties / description
        Added value: +{
        +  "description": "sell only: the item's description.",
        +  "type": "string"
        +}
      • changedInput schema / properties / filter / description
        Previous value: -"inventory only: an Open Cloud filter, e.g. `gamePassIds=123` or `assetIds=456`, to ask about specific items rather than listing everything."New value: +"inventory: an Open Cloud filter, e.g. `gamePassIds=123` or `assetIds=456`, to ask about specific items rather than listing everything. servers: a CEL filter over the server fields, e.g. `occupancy > 0`."
      • addedInput schema / properties / forSale
        Added value: +{
        +  "description": "sell only: whether players can buy it. Say it explicitly when creating.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / image
        Added value: +{
        +  "description": "sell only: path to a local .png/.jpg/.bmp/.tga icon.",
        +  "type": "string"
        +}
      • addedInput schema / properties / itemId
        Added value: +{
        +  "description": "sell only: the product or pass to change. Omit to create a new one.",
        +  "type": "string"
        +}
      • addedInput schema / properties / jobId
        Added value: +{
        +  "description": "logs only: the server, as listed by `servers`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / kind
        Added value: +{
        +  "description": "products/sell: 'product' is a developer product (bought again and again: currency, boosts), 'pass' a game pass (bought once: VIP, perks). products lists both when omitted; sell needs it.",
        +  "enum": [
        +    "product",
        +    "pass"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / limit / description
        Previous value: -"bans/inventory: how many rows to return."New value: +"bans/inventory/servers/logs: how many rows to return."
      • addedInput schema / properties / name
        Added value: +{
        +  "description": "sell only: the item's name. Required to create.",
        +  "type": "string"
        +}
      • changedInput schema / properties / op / description
        Previous value: -"'restart' rolls servers onto the new version, 'message' publishes to MessagingService, 'ban'/'unban'/'bans' manage player access, 'user' and 'inventory' look someone up."New value: +"'restart' rolls servers onto the new version, 'message' publishes to MessagingService, 'ban'/'unban'/'bans' manage player access, 'user' and 'inventory' look someone up, 'servers' and 'logs' read live servers, 'products' and 'sell' manage products and passes."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "restart",
        -  "message",
        -  "ban",
        -  "unban",
        -  "bans",
        -  "user",
        -  "inventory"
        -]New value: +[
        +  "restart",
        +  "message",
        +  "ban",
        +  "unban",
        +  "bans",
        +  "user",
        +  "inventory",
        +  "servers",
        +  "logs",
        +  "products",
        +  "sell"
        +]
      • changedInput schema / properties / placeId / description
        Previous value: -"ban/unban: restrict to this place only, instead of the whole experience. restart: only restart this place's servers."New value: +"ban/unban: restrict to this place only, instead of the whole experience. restart: only restart this place's servers. servers/logs: which place, defaulting to `cloud place`."
      • addedInput schema / properties / price
        Added value: +{
        +  "description": "sell only: price in Robux.",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / search
        Added value: +{
        +  "description": "logs only: case-insensitive text to find in the message, stack trace or context.",
        +  "type": "string"
        +}
      • addedInput schema / properties / severity
        Added value: +{
        +  "description": "logs only: just this level. Omit for both.",
        +  "enum": [
        +    "error",
        +    "warning"
        +  ],
        +  "type": "string"
        +}
  2. 4 tool updatesv0.8.0
    • Removedanimation
    • Changedcreate1 field changed
      • changedInput schema / properties / instances / items / properties / children / description
        Previous value: -"Instances to create inside this one. Build a whole model in one call rather than creating a parent and then addressing it by a path you have to guess."New value: +"Instances to create inside this one. Each takes the same fields as this entry (className, name, properties, attributes, tags, children), nested as deep as needed. Build a whole model in one call rather than creating a parent and then addressing it by a path you have to guess."
    • Changedscreenshot3 fields changed
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "Zoom to this instance at full resolution: a GUI element, a part, a model, or a folder of parts. Edit session only; it must be on screen.",
        +  "type": "string"
        +}
      • addedInput schema / properties / rect
        Added value: +{
        +  "description": "Zoom to \"x, y, width, height\" in viewport pixels. Read them off an earlier screenshot using the scale its caption states.",
        +  "type": "string"
        +}
      • changedInput schema / properties / width / description
        Previous value: -"Width to scale the image down to, in pixels; height follows the viewport's aspect ratio. Larger is sharper and costs more — raise it only when you need to read small text."New value: +"Largest width of the image, in pixels; height follows the aspect ratio. Never scales up. To read small text, zoom with `path` or `rect` rather than raising this."
    • Changedscript_read1 field changed
      • changedInput schema / properties / list / description
        Previous value: -"live only: list what is under the first path instead of reading it. Pass an empty path list to see the top level."New value: +"live only: list what is under the first path instead of reading it. Pass `paths: [\"\"]` to see the top level."
  3. 2 tool updatesv0.7.8
    • Changedconsole3 fields changed
      • addedInput schema / properties / player
        Added value: +{
        +  "description": "Client only: player name, required when multiple players are present.",
        +  "type": "string"
        +}
      • addedInput schema / properties / since
        Added value: +{
        +  "description": "Opaque nextCursor from a previous console response; return only newer matching lines.",
        +  "type": "string"
        +}
      • addedInput schema / properties / target
        Added value: +{
        +  "default": "studio",
        +  "description": "Output source; client requires a running playtest server studioId.",
        +  "enum": [
        +    "studio",
        +    "client"
        +  ],
        +  "type": "string"
        +}
    • Changedcreate5 fields changed
      • removedInput schema / definitions
        Removed value: -{
        -  "__schema0": {
        -    "properties": {
        -      "attributes": {
        -        "additionalProperties": {
        -          "anyOf": [
        -            {
        -              "type": "string"
        -            },
        -            {
        -              "type": "number"
        -            },
        -            {
        -              "type": "boolean"
        -            },
        -            {
        -              "properties": {
        -                "type": {
        -                  "description": "Roblox type to store the attribute as. Needed for anything but a plain string, number or boolean — a bare string stays a string.",
        -                  "enum": [
        -                    "string",
        -                    "boolean",
        -                    "number",
        -                    "BrickColor",
        -                    "CFrame",
        -                    "Color3",
        -                    "ColorSequence",
        -                    "Font",
        -                    "NumberRange",
        -                    "NumberSequence",
        -                    "Rect",
        -                    "UDim",
        -                    "UDim2",
        -                    "Vector2",
        -                    "Vector3"
        -                  ],
        -                  "type": "string"
        -                },
        -                "value": {
        -                  "description": "The value, written as the Properties panel shows it: \"0, 5, 0\".",
        -                  "type": [
        -                    "string",
        -                    "number",
        -                    "boolean"
        -                  ]
        -                }
        -              },
        -              "required": [
        -                "type",
        -                "value"
        -              ],
        -              "type": "object"
        -            }
        -          ]
        -        },
        -        "description": "Attributes to set, as name → value. A bare string, number or boolean is stored as-is; for any other type pass { type, value }, e.g. { type: \"Vector3\", value: \"0, 5, 0\" }. An empty string removes an attribute.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "children": {
        -        "description": "Instances to create inside this one. Build a whole model in one call rather than creating a parent and then addressing it by a path you have to guess.",
        -        "items": {
        -          "$ref": "#/definitions/__schema0"
        -        },
        -        "type": "array"
        -      },
        -      "className": {
        -        "description": "Concrete class to create, e.g. \"Part\", \"Folder\", \"Model\", \"SpawnLocation\".",
        -        "type": "string"
        -      },
        -      "name": {
        -        "description": "Name for the new instance.",
        -        "type": "string"
        -      },
        -      "parent": {
        -        "description": "Where to put it, e.g. \"Workspace\". Required at the top level only.",
        -        "type": "string"
        -      },
        -      "properties": {
        -        "additionalProperties": {
        -          "type": [
        -            "string",
        -            "number",
        -            "boolean"
        -          ]
        -        },
        -        "description": "Properties to set, as name → value. Values are written the way Studio's Properties panel shows them: \"12, 0, 5\" for a Vector3, \"0.2, 0.6, 1\" for a Color3, \"Neon\" or \"Enum.Material.Neon\" for an enum, true/false for a bool.",
        -        "propertyNames": {
        -          "type": "string"
        -        },
        -        "type": "object"
        -      },
        -      "tags": {
        -        "description": "CollectionService tags to add or remove.",
        -        "properties": {
        -          "add": {
        -            "description": "CollectionService tags to add.",
        -            "items": {
        -              "type": "string"
        -            },
        -            "type": "array"
        -          },
        -          "remove": {
        -            "description": "Tags to remove.",
        -            "items": {
        -              "type": "string"
        -            },
        -            "type": "array"
        -          }
        -        },
        -        "type": "object"
        -      }
        -    },
        -    "required": [
        -      "className"
        -    ],
        -    "type": "object"
        -  }
        -}
      • removedInput schema / properties / instances / items / $ref
        Removed value: -"#/definitions/__schema0"
      • addedInput schema / properties / instances / items / properties
        Added value: +{
        +  "attributes": {
        +    "additionalProperties": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "number"
        +        },
        +        {
        +          "type": "boolean"
        +        },
        +        {
        +          "properties": {
        +            "type": {
        +              "description": "Roblox type to store the attribute as. Needed for anything but a plain string, number or boolean — a bare string stays a string.",
        +              "enum": [
        +                "string",
        +                "boolean",
        +                "number",
        +                "BrickColor",
        +                "CFrame",
        +                "Color3",
        +                "ColorSequence",
        +                "Font",
        +                "NumberRange",
        +                "NumberSequence",
        +                "Rect",
        +                "UDim",
        +                "UDim2",
        +                "Vector2",
        +                "Vector3"
        +              ],
        +              "type": "string"
        +            },
        +            "value": {
        +              "description": "The value, written as the Properties panel shows it: \"0, 5, 0\".",
        +              "type": [
        +                "string",
        +                "number",
        +                "boolean"
        +              ]
        +            }
        +          },
        +          "required": [
        +            "type",
        +            "value"
        +          ],
        +          "type": "object"
        +        }
        +      ]
        +    },
        +    "description": "Attributes to set, as name → value. A bare string, number or boolean is stored as-is; for any other type pass { type, value }, e.g. { type: \"Vector3\", value: \"0, 5, 0\" }. An empty string removes an attribute.",
        +    "propertyNames": {
        +      "type": "string"
        +    },
        +    "type": "object"
        +  },
        +  "children": {
        +    "description": "Instances to create inside this one. Build a whole model in one call rather than creating a parent and then addressing it by a path you have to guess.",
        +    "items": {
        +      "additionalProperties": {},
        +      "propertyNames": {
        +        "type": "string"
        +      },
        +      "type": "object"
        +    },
        +    "type": "array"
        +  },
        +  "className": {
        +    "description": "Concrete class to create, e.g. \"Part\", \"Folder\", \"Model\", \"SpawnLocation\".",
        +    "type": "string"
        +  },
        +  "name": {
        +    "description": "Name for the new instance.",
        +    "type": "string"
        +  },
        +  "parent": {
        +    "description": "Where to put it, e.g. \"Workspace\". Required at the top level only.",
        +    "type": "string"
        +  },
        +  "properties": {
        +    "additionalProperties": {
        +      "type": [
        +        "string",
        +        "number",
        +        "boolean"
        +      ]
        +    },
        +    "description": "Properties to set, as name → value. Values are written the way Studio's Properties panel shows them: \"12, 0, 5\" for a Vector3, \"0.2, 0.6, 1\" for a Color3, \"Neon\" or \"Enum.Material.Neon\" for an enum, true/false for a bool.",
        +    "propertyNames": {
        +      "type": "string"
        +    },
        +    "type": "object"
        +  },
        +  "tags": {
        +    "description": "CollectionService tags to add or remove.",
        +    "properties": {
        +      "add": {
        +        "description": "CollectionService tags to add.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      },
        +      "remove": {
        +        "description": "Tags to remove.",
        +        "items": {
        +          "type": "string"
        +        },
        +        "type": "array"
        +      }
        +    },
        +    "type": "object"
        +  }
        +}
      • addedInput schema / properties / instances / items / required
        Added value: +[
        +  "className"
        +]
      • addedInput schema / properties / instances / items / type
        Added value: +"object"
  4. 3 tool updatesv0.7.5
    • Changeddebug5 fields changed
      • changedInput schema / properties / op / description
        Previous value: -"'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors."New value: +"'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors, 'remotes' traces RemoteEvents."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "set",
        -  "clear",
        -  "snapshots",
        -  "exceptions"
        -]New value: +[
        +  "set",
        +  "clear",
        +  "snapshots",
        +  "exceptions",
        +  "remotes"
        +]
      • changedInput schema / properties / path / description
        Previous value: -"clear only: remove breakpoints from this script. Omit to clear everything."New value: +"clear: script to clear. remotes: remote or subtree path, default game. Narrow this if discovery is truncated."
      • addedInput schema / properties / player
        Added value: +{
        +  "description": "remotes only: player name; required with multiple players. Both directions are scoped to this player.",
        +  "type": "string"
        +}
      • addedInput schema / properties / seconds
        Added value: +{
        +  "description": "remotes only: capture seconds, default 5.",
        +  "maximum": 15,
        +  "minimum": 1,
        +  "type": "number"
        +}
    • Changedexecute_luau4 fields changed
      • addedInput schema / properties / player
        Added value: +{
        +  "description": "client only: player name; required with multiple players.",
        +  "type": "string"
        +}
      • changedInput schema / properties / target / description
        Previous value: -"'studio' runs in the connected Studio, with plugin permissions. 'live' runs on Roblox's servers against the published place — production, with no undo."New value: +"'studio' runs in the connected Studio, with plugin permissions. 'live' runs on Roblox's servers against the published place — production, with no undo. 'client' runs in a player's playtest client VM."
      • changedInput schema / properties / target / enum
        Previous value: -[
        -  "studio",
        -  "live"
        -]New value: +[
        +  "studio",
        +  "live",
        +  "client"
        +]
      • changedInput schema / properties / timeoutSeconds / description
        Previous value: -"live only: how long the script may run. Defaults to 30."New value: +"live/client only: timeout in seconds. Defaults to 30."
    • Changedinput1 field changed
      • addedInput schema / properties / steps / items / properties / target
        Added value: +{
        +  "description": "click/text only: client GUI path, e.g. PlayerGui.HUD.BuyButton. Clicks its centre; focuses TextBoxes before typing.",
        +  "minLength": 1,
        +  "type": "string"
        +}
  5. 1 tool updatev0.7.1
    • Changedinput1 field changed
      • changedInput schema / properties / steps / items / properties / key / description
        Previous value: -"key only: an Enum.KeyCode name — \"W\", \"Space\", \"E\", \"LeftShift\", \"Escape\"."New value: +"key only: an Enum.KeyCode name — \"W\", \"Space\", \"E\", \"LeftShift\"."
  6. 2 tool updatesv0.7.0
    • Changedgeometry4 fields changed
      • changedInput schema / properties / op / description
        Previous value: -"'union' merges, 'subtract' cuts `with` out of `path`, 'intersect' keeps only the overlap, 'fragment' shatters into debris, 'sweep' builds a motion volume, 'segment' cuts a mesh into named parts."New value: +"'union' merges, 'subtract' cuts `with` out of `path`, 'intersect' keeps only the overlap, 'fragment' shatters into debris, 'sweep' builds a motion volume, 'segment' cuts a mesh into named parts, 'mesh' reads triangle counts, 'mirror' flips instances across a plane."
      • changedInput schema / properties / path / description
        Previous value: -"The part being operated on - the one cut from, for subtract."New value: +"The part being operated on - the one cut from, for subtract. Required for every op except mesh and mirror, which take `paths`."
      • changedInput schema / properties / paths / description
        Previous value: -"mesh only: the MeshParts to read geometry from."New value: +"mesh and mirror: the instances to read or flip."
      • changedInput schema / required
        Previous value: -[
        -  "op",
        -  "path"
        -]New value: +[
        +  "op"
        +]
    • Changedscript_edit2 fields changed
      • changedInput schema / properties / edits / description
        Previous value: -"Edits to apply together as one undoable step."New value: +"Edits to apply together as one undoable step. Required unless target is \"live\". The result carries each script's new `rev`, so a follow-up edit needs no re-read."
      • removedInput schema / required
        Removed value: -[
        -  "edits"
        -]
  7. 9 tool updatesv0.6.8
    • Changedassets14 fields changed
      • 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"
        +}
    • Addedaudio
    • Changedcollision18 fields changed
      • changedInput schema / properties / action / description
        Previous value: -"'list' shows existing groups and changes nothing. 'remove' unregisters a group entirely — not the same as un-assigning parts from it."New value: +"Groups: 'list' shows them and changes nothing, then 'create', 'assign', 'collidable', 'remove' (which unregisters a group entirely — not the same as un-assigning parts). Queries: 'cast' fires a shape and reports the first hit, 'overlap' lists what is inside a volume."
      • changedInput schema / properties / action / enum
        Previous value: -[
        -  "list",
        -  "create",
        -  "assign",
        -  "collidable",
        -  "remove"
        -]New value: +[
        +  "list",
        +  "create",
        +  "assign",
        +  "collidable",
        +  "remove",
        +  "cast",
        +  "overlap"
        +]
      • addedInput schema / properties / at
        Added value: +{
        +  "description": "overlap only: the centre, for region \"box\" or \"radius\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / collisionGroup
        Added value: +{
        +  "description": "cast/overlap: run the query as if from a part in this group. Required for a truthful answer in any place that uses groups.",
        +  "type": "string"
        +}
      • addedInput schema / properties / direction
        Added value: +{
        +  "description": "cast only: which way to go, e.g. \"0, -1, 0\" for down. Used with `distance`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / distance
        Added value: +{
        +  "description": "cast only: how far along `direction`. Defaults to 100.",
        +  "type": "number"
        +}
      • addedInput schema / properties / from
        Added value: +{
        +  "description": "cast only: where the cast starts, e.g. \"12, 0, 5\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / ignore
        Added value: +{
        +  "description": "cast/overlap: skip these and their descendants. The usual case is the character doing the looking, which otherwise blocks its own cast at zero distance.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / ignoreWater
        Added value: +{
        +  "description": "cast only: pass through terrain water instead of hitting it.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / limit
        Added value: +{
        +  "description": "overlap only: how many parts to list. Defaults to 50.",
        +  "maximum": 500,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / only
        Added value: +{
        +  "description": "cast/overlap: consider ONLY these instances and their descendants.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "overlap region=\"part\" only: the part to test against.",
        +  "type": "string"
        +}
      • addedInput schema / properties / radius
        Added value: +{
        +  "description": "cast shape=\"sphere\" or overlap region=\"radius\": the radius.",
        +  "type": "number"
        +}
      • addedInput schema / properties / region
        Added value: +{
        +  "description": "overlap only: 'box' and 'radius' need `at`; 'part' takes `path` and reports what overlaps that part — the fastest way to find things clipping through each other. Defaults to 'box'.",
        +  "enum": [
        +    "box",
        +    "radius",
        +    "part"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / respectCanCollide
        Added value: +{
        +  "description": "cast/overlap: skip parts with CanCollide off. Off by default, matching the engine — leave it off to ask what is there, turn it on to ask what would stop a player.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / shape
        Added value: +{
        +  "description": "cast only: 'ray' is a line and the usual choice. 'block' and 'sphere' sweep a volume along the same path — use them when the thing moving has width, e.g. whether a character fits through a gap rather than whether a point does.",
        +  "enum": [
        +    "ray",
        +    "block",
        +    "sphere"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / size
        Added value: +{
        +  "description": "cast shape=\"block\" or overlap region=\"box\": the volume size.",
        +  "type": "string"
        +}
      • addedInput schema / properties / to
        Added value: +{
        +  "description": "cast only: a point to aim at. Use this for sightlines — it saves working out a direction vector, which is where sign errors live.",
        +  "type": "string"
        +}
    • Changeddatastore6 fields changed
      • addedInput schema / properties / amount
        Added value: +{
        +  "description": "live increment only: how much to add. Negative subtracts. Safer than get-then-set for currency, which loses whatever the player earned in between.",
        +  "type": "number"
        +}
      • addedInput schema / properties / create
        Added value: +{
        +  "description": "live set only: allow writing a key that does not exist yet. Off by default — Open Cloud separates create from update, and a typo'd key silently creating a second empty save beside the real one is exactly what looks like a player's data resetting.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / kind / enum
        Previous value: -[
        -  "data",
        -  "memory"
        -]New value: +[
        +  "data",
        +  "memory",
        +  "ordered"
        +]
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "list",
        -  "get",
        -  "versions",
        -  "set",
        -  "remove"
        -]New value: +[
        +  "list",
        +  "get",
        +  "versions",
        +  "set",
        +  "remove",
        +  "increment",
        +  "snapshot"
        +]
      • addedInput schema / properties / target
        Added value: +{
        +  "default": "studio",
        +  "description": "'studio' reads through the connected Studio — right while building. 'live' goes to Roblox over Open Cloud and sees what the published game's servers see — right for a bug report.",
        +  "enum": [
        +    "studio",
        +    "live"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / universeId
        Added value: +{
        +  "description": "live only: which game. Omit to use the one set with `cloud universe <id>` in the panel.",
        +  "type": "string"
        +}
    • Changedexecute_luau5 fields changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "description": "Required for target=\"live\". This runs against the game people are playing and nothing here can undo it.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / placeId
        Added value: +{
        +  "description": "live only: which place. Omit to use `cloud place`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / target
        Added value: +{
        +  "default": "studio",
        +  "description": "'studio' runs in the connected Studio, with plugin permissions. 'live' runs on Roblox's servers against the published place — production, with no undo.",
        +  "enum": [
        +    "studio",
        +    "live"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / timeoutSeconds
        Added value: +{
        +  "description": "live only: how long the script may run. Defaults to 30.",
        +  "maximum": 300,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / universeId
        Added value: +{
        +  "description": "live only: which game. Omit to use `cloud universe`.",
        +  "type": "string"
        +}
    • Changedgeometry4 fields changed
      • addedInput schema / properties / about
        Added value: +{
        +  "description": "mirror only: the plane position, e.g. \"0, 0, 0\". Defaults to the middle of what is being mirrored, which flips it in place.",
        +  "type": "string"
        +}
      • changedInput schema / properties / axis / description
        Previous value: -"sweep only: axis to spin around, e.g. \"0, 1, 0\". Defaults to up."New value: +"sweep: axis to spin around, e.g. \"0, 1, 0\" (defaults to up). mirror: which axis to flip across — \"X\", \"Y\" or \"Z\", defaulting to X."
      • addedInput schema / properties / copy
        Added value: +{
        +  "description": "mirror only: leave the originals and add mirrored copies. True by default — that is what builds a symmetrical structure from half of one. False flips the originals in place.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "union",
        -  "subtract",
        -  "intersect",
        -  "fragment",
        -  "sweep",
        -  "segment",
        -  "mesh"
        -]New value: +[
        +  "union",
        +  "subtract",
        +  "intersect",
        +  "fragment",
        +  "sweep",
        +  "segment",
        +  "mesh",
        +  "mirror"
        +]
    • Changedscript_edit7 fields changed
      • addedInput schema / properties / confirm
        Added value: +{
        +  "description": "Required for target=\"live\".",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / edits / minItems
        Removed value: -1
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "live only: the script, e.g. \"ServerScriptService.Main\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / placeId
        Added value: +{
        +  "description": "live only: omit to use `cloud place`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / source
        Added value: +{
        +  "description": "live only: the complete new source.",
        +  "type": "string"
        +}
      • addedInput schema / properties / target
        Added value: +{
        +  "default": "studio",
        +  "description": "'studio' edits the open place. 'live' rewrites a script in the published place over Open Cloud — one file, whole source, no undo.",
        +  "enum": [
        +    "studio",
        +    "live"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / universeId
        Added value: +{
        +  "description": "live only: omit to use `cloud universe`.",
        +  "type": "string"
        +}
    • Changedscript_read4 fields changed
      • addedInput schema / properties / list
        Added value: +{
        +  "description": "live only: list what is under the first path instead of reading it. Pass an empty path list to see the top level.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / placeId
        Added value: +{
        +  "description": "live only: omit to use `cloud place`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / target
        Added value: +{
        +  "default": "studio",
        +  "description": "'studio' reads the open place. 'live' reads the published place over Open Cloud, Folders and scripts only.",
        +  "enum": [
        +    "studio",
        +    "live"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / universeId
        Added value: +{
        +  "description": "live only: omit to use `cloud universe`.",
        +  "type": "string"
        +}
    • Addeduniverse
  8. 12 tool updatesv0.6.5
    • Addedanimation
    • Changedassets11 fields changed
      • 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"
        +}
    • Changedcharacter10 fields changed
      • addedInput schema / properties / agentHeight
        Added value: +{
        +  "description": "How tall the walker is. Defaults to 5, a standard character.",
        +  "maximum": 100,
        +  "minimum": 0.1,
        +  "type": "number"
        +}
      • addedInput schema / properties / agentRadius
        Added value: +{
        +  "description": "How wide the walker is, in studs. Defaults to 2 — a standard character. Raise it to ask whether a bigger NPC fits through the same gaps a player does.",
        +  "maximum": 50,
        +  "minimum": 0.1,
        +  "type": "number"
        +}
      • addedInput schema / properties / canClimb
        Added value: +{
        +  "description": "Whether it may climb truss. Off by default.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / costs
        Added value: +{
        +  "additionalProperties": {
        +    "type": "number"
        +  },
        +  "description": "Material or PathfindingModifier label → cost, e.g. { \"Water\": 20 } to avoid swimming. Higher is more avoided; the route chosen is the cheapest total, not the shortest.",
        +  "propertyNames": {
        +    "type": "string"
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / from
        Added value: +{
        +  "description": "path only: where the route starts, e.g. \"0, 5, 0\". Defaults to the character.",
        +  "type": "string"
        +}
      • addedInput schema / properties / fromPath
        Added value: +{
        +  "description": "path only: an instance to start from, e.g. \"Workspace.SpawnLocation\".",
        +  "type": "string"
        +}
      • changedInput schema / properties / op / description
        Previous value: -"'moveTo' walks somewhere, 'act' performs an action, 'state' only reports."New value: +"'moveTo' walks somewhere, 'path' checks a route without walking it, 'act' performs an action, 'state' only reports."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "moveTo",
        -  "act",
        -  "state"
        -]New value: +[
        +  "moveTo",
        +  "path",
        +  "act",
        +  "state"
        +]
      • addedInput schema / properties / spacing
        Added value: +{
        +  "description": "Studs between waypoints, default 4. Tighter follows the geometry more closely; wider is a coarser route.",
        +  "maximum": 100,
        +  "minimum": 0.1,
        +  "type": "number"
        +}
      • addedInput schema / properties / toPath
        Added value: +{
        +  "description": "path only: an instance to end at instead of `to`.",
        +  "type": "string"
        +}
    • Changedcollision1 field changed
      • addedInput schema / properties / worldModel
        Added value: +{
        +  "description": "Path to a WorldModel whose own collision groups this call is about, e.g. \"StarterGui.Preview.Viewport.WorldModel\". Omit for the Workspace, which is what you want unless the parts in question live inside a ViewportFrame.",
        +  "type": "string"
        +}
    • Addeddatastore
    • Changeddevice8 fields changed
      • addedInput schema / properties / direction
        Added value: +{
        +  "description": "network only: which way to degrade. 'in' is the player with a bad connection, 'out' is everyone else seeing that player late. Defaults to both.",
        +  "enum": [
        +    "in",
        +    "out",
        +    "both"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / jitter
        Added value: +{
        +  "description": "network only: how much the delay varies, in milliseconds. Jitter breaks things steady latency does not — it is what makes replicated motion stutter rather than simply lag.",
        +  "maximum": 1000,
        +  "minimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / latency
        Added value: +{
        +  "description": "network only: minimum delay in milliseconds, up to 1000 — the engine's own ceiling. 0 clears it.",
        +  "maximum": 1000,
        +  "minimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / loss
        Added value: +{
        +  "description": "network only: percentage of packets thrown away, up to 50 — the engine's own ceiling. The field that finds real bugs: latency makes a game feel slow, loss makes it behave wrongly. 2-8% is a bad mobile connection.",
        +  "maximum": 50,
        +  "minimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / memory
        Added value: +{
        +  "description": "network only: pretend the machine has this many MB of memory. A cheap phone is a small screen AND little memory; this is the half that makes textures unload. 0 removes the cap.",
        +  "maximum": 65536,
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • changedInput schema / properties / op / description
        Previous value: -"'list' shows the available devices, 'set' switches to one, 'stop' returns to the normal viewport, 'state' only reports."New value: +"'list' shows the available devices, 'set' switches to one, 'network' shapes the connection, 'stop' undoes both, 'state' only reports."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "list",
        -  "set",
        -  "stop",
        -  "state"
        -]New value: +[
        +  "list",
        +  "set",
        +  "network",
        +  "stop",
        +  "state"
        +]
      • addedInput schema / properties / preset
        Added value: +{
        +  "description": "network only: a whole connection in one word. clear=0ms (normal), wifi=15ms, 4g=60ms/0.5% loss, 3g=150ms/2% loss, poor=400ms/8% loss. Named fields below override whichever part you name.",
        +  "enum": [
        +    "clear",
        +    "wifi",
        +    "4g",
        +    "3g",
        +    "poor"
        +  ],
        +  "type": "string"
        +}
    • Changedfind2 fields changed
      • addedInput schema / properties / op
        Added value: +{
        +  "default": "find",
        +  "description": "'find' searches for instances. 'tags' lists which CollectionService tags exist in the place, with counts — use it when you do not know the tag names yet.",
        +  "enum": [
        +    "find",
        +    "tags"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / selector
        Added value: +{
        +  "description": "Engine query selector, matched inside Studio. Supports a class name (\"Part\", superclasses included), \"#ExactName\", \"[Anchored=true]\", either-or with \"Part, Model\", direct children with \"Model > Part\" and descendants with \"Model >> Part\". No substring names and no < > comparisons — use nameContains and propertyValue for those. Combines with the other filters.",
        +  "type": "string"
        +}
    • Changedgeometry2 fields changed
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "union",
        -  "subtract",
        -  "intersect",
        -  "fragment",
        -  "sweep",
        -  "segment"
        -]New value: +[
        +  "union",
        +  "subtract",
        +  "intersect",
        +  "fragment",
        +  "sweep",
        +  "segment",
        +  "mesh"
        +]
      • addedInput schema / properties / paths
        Added value: +{
        +  "description": "mesh only: the MeshParts to read geometry from.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 50,
        +  "type": "array"
        +}
    • Changedinspect1 field changed
      • addedInput schema / properties / physics
        Added value: +{
        +  "default": false,
        +  "description": "Also report mass, density, assembly root and centre of mass for any BasePart. Mass appears nowhere in Studio — it is computed from volume and material — so this is the only way to answer 'why does this fall over', 'why does it sink', or 'why did half the model stay behind when I moved it'.",
        +  "type": "boolean"
        +}
    • Changedperformance2 fields changed
      • changedInput schema / properties / op / description
        Previous value: -"'snapshot' reads counters now; 'profile' samples running scripts; 'coverage' reports which lines have executed; 'scene' breaks the place down by what it is made of."New value: +"'snapshot' reads counters now; 'profile' samples running scripts; 'coverage' reports which lines have executed; 'scene' breaks the place down by what it is made of; 'audit' finds broken asset references and other silent faults."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "snapshot",
        -  "profile",
        -  "coverage",
        -  "scene"
        -]New value: +[
        +  "snapshot",
        +  "profile",
        +  "coverage",
        +  "scene",
        +  "audit"
        +]
    • Changedscript_read2 fields changed
      • addedInput schema / properties / line
        Added value: +{
        +  "description": "open only: line to put the cursor on.",
        +  "maximum": 9007199254740991,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedInput schema / properties / op
        Added value: +{
        +  "default": "read",
        +  "description": "'read' returns source. 'open' opens the first path in the user's Studio editor at `line` and returns nothing to read.",
        +  "enum": [
        +    "read",
        +    "open"
        +  ],
        +  "type": "string"
        +}
    • Changedviewport1 field changed
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "select",
        -  "raycast",
        -  "focus",
        -  "camera",
        -  "textbounds"
        -]New value: +[
        +  "select",
        +  "raycast",
        +  "focus",
        +  "camera",
        +  "textbounds",
        +  "ui"
        +]
  9. 1 tool updatev0.5.6
    • Addedterrain
  10. 5 tool updatesv0.4.5
    • Changedassets3 fields changed
      • 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"
        +}
    • Addedgenerate
    • Changedgeometry19 fields changed
      • addedInput schema / properties / anchor
        Added value: +{
        +  "default": true,
        +  "description": "segment only: anchor every part.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / axis
        Added value: +{
        +  "description": "sweep only: axis to spin around, e.g. \"0, 1, 0\". Defaults to up.",
        +  "type": "string"
        +}
      • addedInput schema / properties / checkAgainst
        Added value: +{
        +  "description": "sweep only: report what the volume overlaps. An empty array checks against everything; a list checks only those.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 50,
        +  "type": "array"
        +}
      • changedInput schema / properties / collisionFidelity / description
        Previous value: -"How exactly the result collides. Precise is expensive — raise it only for a surface players walk on."New value: +"How exactly the result collides. Precise is expensive - raise it only for a surface players walk on."
      • addedInput schema / properties / groups
        Added value: +{
        +  "description": "segment only: the part names to cut into, e.g. [\"body\", \"lid\"]. Overrides `schema`.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 16,
        +  "type": "array"
        +}
      • addedInput schema / properties / keep
        Added value: +{
        +  "default": true,
        +  "description": "sweep only: leave the volume as a part. Off measures and cleans up.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / keepOriginal
        Added value: +{
        +  "default": false,
        +  "description": "segment only: leave the source MeshPart in place instead of replacing it.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / op / description
        Previous value: -"'union' merges, 'subtract' cuts `with` out of `path`, 'intersect' keeps only the overlap, 'fragment' shatters `path` into pieces."New value: +"'union' merges, 'subtract' cuts `with` out of `path`, 'intersect' keeps only the overlap, 'fragment' shatters into debris, 'sweep' builds a motion volume, 'segment' cuts a mesh into named parts."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "union",
        -  "subtract",
        -  "intersect",
        -  "fragment"
        -]New value: +[
        +  "union",
        +  "subtract",
        +  "intersect",
        +  "fragment",
        +  "sweep",
        +  "segment"
        +]
      • changedInput schema / properties / path / description
        Previous value: -"The part being operated on — the one cut from, for subtract."New value: +"The part being operated on - the one cut from, for subtract."
      • addedInput schema / properties / pivot
        Added value: +{
        +  "description": "sweep only: the hinge point. Defaults to the part's own centre, which spins it in place - a door needs its hinge edge here.",
        +  "type": "string"
        +}
      • addedInput schema / properties / position
        Added value: +{
        +  "description": "segment only: where to place the result. Defaults to where the source was.",
        +  "type": "string"
        +}
      • addedInput schema / properties / positions
        Added value: +{
        +  "description": "sweep only: an explicit path of positions to sweep along.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "maxItems": 64,
        +  "type": "array"
        +}
      • addedInput schema / properties / scaleTo
        Added value: +{
        +  "description": "segment only: scale so the longest side is this many studs.",
        +  "exclusiveMinimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / schema
        Added value: +{
        +  "description": "segment only: a built-in split. 'Car5' gives a body and four wheels under fixed names; 'Body1' gives one mesh. Ignored when `groups` is set.",
        +  "enum": [
        +    "Body1",
        +    "Car5"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / spin
        Added value: +{
        +  "description": "sweep only: rotate this many degrees. Use with `pivot` for a hinge.",
        +  "type": "number"
        +}
      • addedInput schema / properties / steps
        Added value: +{
        +  "default": 12,
        +  "description": "sweep only: how many samples along the motion. Too few cuts corners off an arc.",
        +  "maximum": 64,
        +  "minimum": 2,
        +  "type": "integer"
        +}
      • addedInput schema / properties / to
        Added value: +{
        +  "description": "sweep only: slide to this position, e.g. \"0, 10, 0\".",
        +  "type": "string"
        +}
      • addedInput schema / properties / transparency
        Added value: +{
        +  "default": 0.5,
        +  "description": "sweep only: how see-through the volume is.",
        +  "maximum": 1,
        +  "minimum": 0,
        +  "type": "number"
        +}
    • Changedscript_edit1 field changed
      • addedInput schema / properties / edits / items / properties / revision
        Added value: +{
        +  "description": "The `rev` value script_read printed for this file. Pass it and the edit is refused if the script changed since you read it, instead of being applied to source you have not seen.",
        +  "type": "string"
        +}
    • Changedviewport7 fields changed
      • addedInput schema / properties / font
        Added value: +{
        +  "description": "textbounds only: an Enum.Font name, e.g. \"GothamMedium\". Defaults to the label's.",
        +  "type": "string"
        +}
      • changedInput schema / properties / op / description
        Previous value: -"'focus' points the camera at something and frames it, 'camera' sets it explicitly, 'select' changes the Studio selection, 'raycast' queries the world."New value: +"'focus' points the camera at something and frames it, 'camera' sets it explicitly, 'select' changes the Studio selection, 'textbounds' measures rendered text, 'raycast' queries the world."
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "select",
        -  "raycast",
        -  "focus",
        -  "camera"
        -]New value: +[
        +  "select",
        +  "raycast",
        +  "focus",
        +  "camera",
        +  "textbounds"
        +]
      • addedInput schema / properties / richText
        Added value: +{
        +  "description": "textbounds only: treat the text as rich text. Defaults to the label's setting.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / text
        Added value: +{
        +  "description": "textbounds only: the string to measure. Defaults to the label's own text.",
        +  "type": "string"
        +}
      • addedInput schema / properties / textSize
        Added value: +{
        +  "description": "textbounds only: font size in pixels. Defaults to the label's.",
        +  "maximum": 200,
        +  "minimum": 1,
        +  "type": "number"
        +}
      • addedInput schema / properties / wrapWidth
        Added value: +{
        +  "description": "textbounds only: wrap at this width. 0 means do not wrap. Defaults to the label's width.",
        +  "minimum": 0,
        +  "type": "number"
        +}
  11. 1 tool updatev0.3.7
    • Changedinput1 field changed
      • changedInput schema / properties / steps / items / properties / text / description
        Previous value: -"text only: the string to type."New value: +"text only: the string to type. Goes to the focused TextBox — click it first, in the same call."
  12. 2 tool updatesv0.3.5
    • Changedcreate3 fields changed
      • addedInput schema / definitions / __schema0 / properties / attributes / additionalProperties / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "properties": {
        +      "type": {
        +        "description": "Roblox type to store the attribute as. Needed for anything but a plain string, number or boolean — a bare string stays a string.",
        +        "enum": [
        +          "string",
        +          "boolean",
        +          "number",
        +          "BrickColor",
        +          "CFrame",
        +          "Color3",
        +          "ColorSequence",
        +          "Font",
        +          "NumberRange",
        +          "NumberSequence",
        +          "Rect",
        +          "UDim",
        +          "UDim2",
        +          "Vector2",
        +          "Vector3"
        +        ],
        +        "type": "string"
        +      },
        +      "value": {
        +        "description": "The value, written as the Properties panel shows it: \"0, 5, 0\".",
        +        "type": [
        +          "string",
        +          "number",
        +          "boolean"
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "value"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / definitions / __schema0 / properties / attributes / additionalProperties / type
        Removed value: -[
        -  "string",
        -  "number",
        -  "boolean"
        -]
      • changedInput schema / definitions / __schema0 / properties / attributes / description
        Previous value: -"Attributes to set, as name → value. An empty string removes one."New value: +"Attributes to set, as name → value. A bare string, number or boolean is stored as-is; for any other type pass { type, value }, e.g. { type: \"Vector3\", value: \"0, 5, 0\" }. An empty string removes an attribute."
    • Changedmodify3 fields changed
      • addedInput schema / properties / targets / items / properties / attributes / additionalProperties / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "number"
        +  },
        +  {
        +    "type": "boolean"
        +  },
        +  {
        +    "properties": {
        +      "type": {
        +        "description": "Roblox type to store the attribute as. Needed for anything but a plain string, number or boolean — a bare string stays a string.",
        +        "enum": [
        +          "string",
        +          "boolean",
        +          "number",
        +          "BrickColor",
        +          "CFrame",
        +          "Color3",
        +          "ColorSequence",
        +          "Font",
        +          "NumberRange",
        +          "NumberSequence",
        +          "Rect",
        +          "UDim",
        +          "UDim2",
        +          "Vector2",
        +          "Vector3"
        +        ],
        +        "type": "string"
        +      },
        +      "value": {
        +        "description": "The value, written as the Properties panel shows it: \"0, 5, 0\".",
        +        "type": [
        +          "string",
        +          "number",
        +          "boolean"
        +        ]
        +      }
        +    },
        +    "required": [
        +      "type",
        +      "value"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / targets / items / properties / attributes / additionalProperties / type
        Removed value: -[
        -  "string",
        -  "number",
        -  "boolean"
        -]
      • changedInput schema / properties / targets / items / properties / attributes / description
        Previous value: -"Attributes to set, as name → value. An empty string removes one."New value: +"Attributes to set, as name → value. A bare string, number or boolean is stored as-is; for any other type pass { type, value }, e.g. { type: \"Vector3\", value: \"0, 5, 0\" }. An empty string removes an attribute."
  13. 1 tool updatev0.3.0
    • Changedscript_read5 fields changed
      • changedInput schema / properties / endLine / description
        Previous value: -"Last line to return, inclusive. Omit to read to the end."New value: +"Default last line for entries without their own, inclusive. Omit to read to the end."
      • changedInput schema / properties / paths / description
        Previous value: -"Script paths, e.g. [\"ServerScriptService.Systems.Combat\"]."New value: +"Scripts to read, e.g. [\"ServerScriptService.Systems.Combat\"] or [{ path: \"...Combat\", startLine: 120, endLine: 180 }]."
      • addedInput schema / properties / paths / items / anyOf
        Added value: +[
        +  {
        +    "description": "A script path, read in full.",
        +    "type": "string"
        +  },
        +  {
        +    "properties": {
        +      "endLine": {
        +        "description": "Last line of the window for this script, inclusive.",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      },
        +      "path": {
        +        "description": "The script to read.",
        +        "type": "string"
        +      },
        +      "startLine": {
        +        "description": "First line of the window for this script, 1-based and inclusive.",
        +        "maximum": 9007199254740991,
        +        "minimum": 1,
        +        "type": "integer"
        +      }
        +    },
        +    "required": [
        +      "path"
        +    ],
        +    "type": "object"
        +  }
        +]
      • removedInput schema / properties / paths / items / type
        Removed value: -"string"
      • changedInput schema / properties / startLine / description
        Previous value: -"First line to return, 1-based and inclusive. Omit to start at the top."New value: +"Default first line for entries without their own, 1-based and inclusive. Omit to start at the top."
  14. 2 tool updatesv0.2.9
    • Changedcreate4 fields changed
      • removedInput schema / definitions / __schema0 / properties / attributes / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  }
        -]
      • addedInput schema / definitions / __schema0 / properties / attributes / additionalProperties / type
        Added value: +[
        +  "string",
        +  "number",
        +  "boolean"
        +]
      • removedInput schema / definitions / __schema0 / properties / properties / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  }
        -]
      • addedInput schema / definitions / __schema0 / properties / properties / additionalProperties / type
        Added value: +[
        +  "string",
        +  "number",
        +  "boolean"
        +]
    • Changedmodify4 fields changed
      • removedInput schema / properties / targets / items / properties / attributes / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  }
        -]
      • addedInput schema / properties / targets / items / properties / attributes / additionalProperties / type
        Added value: +[
        +  "string",
        +  "number",
        +  "boolean"
        +]
      • removedInput schema / properties / targets / items / properties / properties / additionalProperties / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "number"
        -  },
        -  {
        -    "type": "boolean"
        -  }
        -]
      • addedInput schema / properties / targets / items / properties / properties / additionalProperties / type
        Added value: +[
        +  "string",
        +  "number",
        +  "boolean"
        +]

TDQS

A4.2/5.0

Scored across 35 tools

Disambiguation4/5

Most tools have clearly distinct purposes, and the extensive descriptions explicitly guide when to use each (e.g., script_create vs create, character vs input). However, some overlap exists, such as raycasting in both viewport and collision tools, and the escape hatch execute_luau could be used for anything, though discouraged. The boundaries are mostly clear but not perfect.

Naming Consistency3/5

Tool names are consistently lowercase with snake_case for multi-word names, but the naming pattern mixes bare verbs (create, delete, modify), bare nouns (viewport, api, datastore), and verb_noun compounds (script_create, list_studios). This inconsistency in structure makes the set less predictable, though still readable.

Tool Count2/5

With 35 tools, the server exceeds the typical well-scoped range of 3-15 and falls into the 'too many' category (25+). While each tool may consolidate many operations, the sheer number increases cognitive load and misselection risk.

Completeness5/5

The toolset covers an impressive breadth of Roblox Studio development: instance manipulation, scripting, playtesting, performance profiling, debugging, asset management, terrain, data stores, universe operations, and more. No obvious major gaps in lifecycle or domain coverage are apparent.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables AI coding tools to control Roblox Studio for workspace exploration, instance manipulation, and script management. It provides tools for playtesting, scene rendering, and integration with the Roblox Creator Store.
    6
    8
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to control Roblox Studio by running Luau code, creating and editing instances, reading the scene tree, and managing scripts via an MCP server with a long-polling plugin bridge.
    MIT
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to interact with Roblox Studio via a token-efficient MCP server, live two-way script sync, and zero-friction plugin setup.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to explore, edit, and automate Roblox Studio sessions locally, including browsing instance hierarchies, reading and modifying scripts, manipulating properties, creating instances, building terrain, and running playtests.
    800 npm
    MIT