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

Instances

create modify delete move

World

geometry terrain generate assets collision audio undo

Live game

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.

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

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.

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 type a sentence and a coding agent answers 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

agent [use <id>|new] stop

which agent runs your prompts

anything else

sent to that agent

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.

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, and requires a header a browser cannot set cross-origin. 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/.

Licence

MIT.

Available Tools

35 tools
animationRead and build animationsA

Reads an animation's actual keyframes, and builds new ones that play immediately in the open Studio.

Animations are the one part of a place no other tool can see. inspect on an Animation instance returns an asset id and stops there — the poses live on Roblox's servers. read downloads them, so you can answer 'how long is it', 'which joints does it move', and 'does it end where it started' without opening the Animation Editor and scrubbing.

read takes an asset id, an rbxassetid:// string, or the path of an Animation instance in the place — whichever you already have. It reports which RIG the animation was made for, which is the thing most worth knowing: an R15 animation on an R6 character does nothing at all — no error, no movement — and the asset id gives no hint either way.

build goes the other way: give it keyframes and it returns a content id you can put straight into an Animation's AnimationId. Nothing is uploaded and nothing is moderated — the id works in this Studio session and nowhere else, which makes it the right way to try an idea and the wrong way to ship one.

preview puts an animation ONTO a rig in the open place and freezes it at a chosen moment, so screenshot can show you the pose. It works in edit mode — no playtest. Ask for several moments in turn to compare poses across the animation; the rig stays posed until stop.

Poses are written the way a CFrame property is: "0, 1, 0" for a position, "0, 1, 0 | 0, 45, 0" to rotate as well.

The id build returns is a bare hash, not an rbxassetid:// URL. Use it exactly as given — prefixing it stops it working.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNopreview only: the moment to freeze on, in seconds. Ask for several in turn to compare poses across the animation.
opNo'read' downloads an existing animation, 'preview' poses a rig at one moment of it so you can screenshot it, 'build' makes a new one playable here, 'stop' clears a preview.read
rigNoThe model, e.g. "Workspace.Dummy". For preview/stop it is the rig to pose, and needs a Humanoid or an AnimationController inside it. For `build` it is optional and is read for its joint layout — pass it for anything that is not a standard R6 or R15 character (a custom rig, a weapon, a door, a Blender import), or the poses may be attached in the wrong order and the animation will move nothing.
holdNopreview only: freeze on that frame. Turn off to let it play, but then a screenshot catches whatever pose it happens to be in.
loopNobuild only: whether it repeats.
nameNobuild only: name for the sequence.
rootNobuild only: the rig part every pose hangs from. Defaults to "HumanoidRootPart", which is right for an R15 or R6 character.
assetIdNoread only: animation asset id (12345), "rbxassetid://12345", or the path of an Animation instance ("Workspace.Rig.Animate.run").
priorityNobuild only: which animations this one plays over.
studioIdNoTarget Studio; omit for the active one.
keyframesNobuild only: the keyframes, in any order — they are sorted by time.

TDQS

A4.7/5.0
Behavior5/5

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

Goes well beyond the annotations (readOnlyHint=false, openWorldHint=true). It discloses non-obvious behavior: built ids are session-local, unuploaded, unmoderated; rig mismatch fails silently with no error; the returned id is a bare hash that breaks if prefixed; preview freezes the rig until `stop`. This is exactly the context an agent needs to avoid failure modes.

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?

Five paragraphs, each carrying distinct operational info (read rationale, rig/R15-vs-R6 gotcha, build session-locality, preview mechanics, pose syntax, id format), so nothing is pure filler. Slightly long for a tool definition, but it is front-loaded with the core verb+resource statement and each later paragraph 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?

For an 11-param, no-output-schema, multi-op tool, the description covers op selection, the session-local id behavior, rig requirements, and pose formatting. Minor gaps remain: multi-studio targeting (`studioId`) and the `hold`/`loop`/`priority` interactions are left to the schema, but nothing critical to calling 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 baseline is 3, but the description adds real meaning: the pose string syntax ('0, 1, 0 | 0, 45, 0'), why `rig` matters for `build` (custom rigs, weapons, Blender imports may attach poses in the wrong order), and the accepted forms of `assetId`. It doesn't add much on `studioId` or the `keyframes` array beyond 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+resource statement ('Reads an animation's actual keyframes, and builds new ones') and explicitly carves out its territory against a named sibling: '`inspect` on an Animation instance returns an asset id and stops there'. An agent can distinguish this from inspect, generate, or assets 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?

It routes each op by intent: `read` for answering questions without scrubbing the editor, `preview` for posing a rig for `screenshot` in edit mode (no playtest), `build` to try an idea but explicitly 'the wrong way to ship one'. It names the alternative (`inspect`) and its limitation, and states the op-ordering (`preview` persists until `stop`).

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

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.

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

A5/5.0
Behavior5/5

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

Beyond the readOnlyHint and idempotentHint annotations, the description discloses several crucial behaviors: results come 'from the running binary rather than from a published dump', members return as signatures, deprecated members are 'never listed, only counted', and the `describe` vs `classes` operational split. These are non-obvious traits that directly affect how the tool should be called and interpreted, adding real value over the annotations alone.

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 paragraph earns its place. The first sentence states the core purpose, and subsequent paragraphs each cover a single behavioral aspect—freshness, return format, deprecation handling, and relationship to `inspect`—without redundancy. The ProximityPrompt example is illustrative, not 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 6-parameter tool with no output schema, the description fully covers what an agent needs to know: the return shape (signatures), default behaviors, deprecation semantics, and how to discover class names. There are no missing pieces that would leave an agent guessing how to invoke this correctly.

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 the schema covers 100% of parameters, the description adds substantial semantic context: it clarifies the two enum values of `op`, explains the `inherited` parameter's default and trade-off with a concrete example ('ProximityPrompt has 2 methods of its own and 42 inherited'), and specifies case-sensitivity of `className`. This goes well beyond what the JSON schema alone provides.

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: 'Lists the properties, methods and events of any Roblox class', and later explicitly differentiates from sibling `inspect` ('This is not the same as `inspect`. `inspect` reads the values on an instance...'). An agent can immediately tell what this tool does and how it differs from closely related 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?

Explicit when-to-use guidance is present: 'Use it before writing Luau against a class you are not certain of.' It also names when not to use it by contrasting with `inspect` ('this reads the shape of a class whether or not anything in the place is one'). This leaves no ambiguity for tool selection.

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

assetsCreator StoreA

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.9/5.0
Behavior5/5

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

The description goes far beyond the annotations by disclosing client-side filtering, silently ignored Roblox sort options, permanent grants with no revocation, publish API limitations that report success anyway, bake's data-model-session scoping, moderation and quota effects on uploads, and restart's 10-minute bleed-off behavior. No statement 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.

Conciseness4/5

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

The description is long and repeats some schema-level details such as `restart`, `audioType`, and `confirm`, but it is well organized by operation, front-loaded with the core purpose, and uses line breaks and warnings to keep the density navigable. It could be tightened, but the length is largely justified by eight operations and thirty parameters.

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 30 parameters, no output schema, and multiple mutating operations, the description is unusually complete. It covers return information, failure modes, authentication setup, safety hazards around scripts, upload moderation, quota checking, and the edit-mode/playtest distinction for baking. An agent has enough context to call the tool correctly and avoid the documented pitfalls.

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 real meaning to parameters: filters like `excludeScripts`, `maxTriangles`, `verifiedOnly`, `freeOnly`, and `minVotes` are applied locally, `audioType` defaults to SoundEffect because the engine's own default is Music, `confirm` is mandatory for permanent or live actions, and `file` omitted on upload checks credentials without sending anything.

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 sentence gives a specific verb and resource: 'Searches Roblox's Creator Store and inserts models into the place.' It then clearly enumerates all eight operations (search, peek, insert, bake, upload, grant, publish, quota) and explains what each does, so an agent can distinguish the tool's many modes and its boundaries.

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 repeatedly gives explicit when-to-use and when-not-to-use guidance: use `peek` whenever `hasScripts` is true, do not use `grant` for your own assets, do not use `bake` in edit mode expecting playtest persistence, and ask `op="quota"` instead of guessing. It also names exclusions like 'It does not help generate at all' and warns against speculative or repeated uploads.

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" kind="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.9/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, destructiveHint=true), it discloses a key non-obvious behavior: an otherwise valid graph is silent until wires connect named pins. It also explains that inspect surfaces Connected=false connections hidden in Explorer, and that graph is undoable. This adds real diagnostic value that annotations alone do not 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 longer than most but earns its length given 12 parameters and a non-obvious domain. It is front-loaded with the core mental model before enumerating operations, and every paragraph contributes. A little narrative is arguably unnecessary, so it is not quite 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?

For a complex tool with no output schema, it covers the main operations, common failure causes, edge cases (channel splitter pin, asset left out), and alternative tools. Nothing essential for selecting and invoking this tool 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%, so the baseline is 3, but the description adds meaning beyond the schema: it explains the failure mode behind toPin/fromPin, enumerates accepted effect classes, clarifies what omitting asset/path does, and distinguishes world versus ui placement. This makes parameter selection significantly safer.

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 specific domain (Roblox's modern audio graph) and a concrete set of operations (graph, wire, inspect) along with the instances involved. It explicitly contrasts with the old Sound instance and the sibling create tool, so an agent can distinguish this tool 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 routing: use graph for a complete chain, wire for joining existing instances, inspect for reading back and debugging silence-through-missing connections. It also states when NOT to use it ('old Sound ... use create for that') and when to prefer it (effects, per-listener mixing, multiple sources into one emitter).

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

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.
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.
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.6/5.0
Behavior4/5

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

The description discloses key behavioral traits beyond the annotations: groups are not undoable, not session-scoped, and removal unregisters the group entirely. It also explains world scoping (worldModel) and that assigning a Model assigns all parts inside. It does not contradict annotations (readOnlyHint false, destructiveHint false) and adds contextual details like the fact that a group with nothing assigned does nothing. It could mention rate limits or auth, but those are less relevant here.

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 well-structured, with clear sections for group management and queries. It front-loads the core purpose and differentiators, then explains ordering, scoping, and pitfalls. Every sentence adds value, though it could be slightly tightened. The structure makes it easy to scan for key facts.

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 23 parameters and no output schema, the description is remarkably complete. It covers the return values of casts and overlaps (part, hit point, normal, material, distance), explains the significance of hit: false, details the world scoping, and clarifies the operation ordering. It also addresses the common pitfall of running a cast with the wrong collisionGroup. Nothing essential seems missing 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?

Schema coverage is 100%, so the schema already documents parameters. The description adds meaning beyond the schema by explaining the purpose of collisionGroup ('Required for a truthful answer'), respectCanCollide ('matching the engine'), and the usual use case for ignore (the character doing the looking). It also clarifies the action enum's groups vs queries. This extra context helps an agent select and fill parameters correctly.

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 ('Controls which parts physically collide') and a resource ('which parts'), and explicitly differentiates from siblings by noting that it answers geometry queries (cast/overlap) that the Explorer and inspect cannot. The opening line is unambiguous about the tool's 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?

It provides explicit when-to-use guidance, contrasting with the alternative of turning CanCollide off, and identifies the specific question it answers that the Explorer cannot. It also gives a clear operation order (create, assign, collidable) and explains the difference between cast and overlap. This leaves no ambiguity about when to choose this tool.

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 the Studio Output window — 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.

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.

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 loaded is recoverable, and output from the playtest client is not reachable at all, because Studio forbids client sessions from making HTTP requests.

A quiet log is not proof nothing was said. Anything the playtest CLIENT printed is never here. 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
levelNoOnly this severity. Omit for everything.
limitNoMaximum items to return (1-500).
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 declare readOnly/idempotent/non-destructive, but the description adds substantial non-obvious behavior: per-session logs keyed to plugin load time, no pre-load history, client output unreachable due to HTTP restrictions, and Studio-emitted messages landing in the session that raised them. The warning about not treating a quiet log as an all-clear is exactly the kind of caveat an agent needs.

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 and well-structured, with the purpose in the first sentence. It is longer than strictly needed: the fact that client output is unreachable and the 'silence is not an all-clear' point are each stated twice, which costs some tightness.

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 model itself (up to 2000 lines held, newest last) and covers session scoping, filtering, and the key blind spots. An agent has everything needed to call it correctly and interpret empty results.

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 usage meaning beyond the schema: level to isolate errors, pattern to follow one subsystem's logging, and a rationale for using filters instead of a large limit. It doesn't add new syntax, but it does add selection guidance for the 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?

States a specific verb and resource ("Reads the Studio Output window") and enumerates what it contains (prints, warnings, runtime errors, newest last). It routes the agent to siblings explicitly — script_read to open a named script/line and list_studios to find a target session — so it is distinguishable from the rest of the toolset.

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 triggers ("after a playtest or an execute_luau call") and concrete when-not conditions (client output is never reachable; the editor log will not contain playtest prints). It names alternatives (list_studios, script_read, checking the Output window manually) and advises preferring a filter over a large limit.

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.9/5.0
Behavior5/5

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

Beyond the annotations, the description discloses that creation is a single undoable step, that property names are validated against the live Roblox API dump before transmission, and that typos return closest real names instead of engine errors. It also warns that an instance's path is unknowable until it exists and that same-named siblings make guessing unreliable. These are meaningful behavioral details not present in 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 four tight sentences with no filler. The core purpose is front-loaded in the first sentence, followed by nested usage rationale, validation behavior, and a sibling-routing instruction. Every sentence earns its place.

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 rich input schema, relevant annotations, and the absence of an output schema, the description covers what the agent needs: what the tool does, when to use an alternative, how to structure complex creates, and how errors are surfaced. Nothing critical for 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?

The input schema already provides 100% coverage with detailed parameter descriptions, so the baseline is 3. The description adds extra semantic value by explaining why children should be used for building models and how property validation handles typo'd names. It does not duplicate schema content but enhances conceptual understanding of 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 opens with a specific verb and resource: 'Creates instances with their properties, attributes and tags set at creation, as one undoable step.' It clearly differentiates from the sibling by explicitly directing Script, LocalScript, and ModuleScript creation to script_create. The purpose is unambiguous and not a tautology.

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: 'Use script_create for Script, LocalScript and ModuleScript — it takes source directly.' It also explains when nesting children is preferable and why, addressing the reliability of addressing newly created instances. This provides strong decision support for selecting between alternatives.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors.
lineNoclear only: which line to remove.
modeNoexceptions only: break on every error, only unhandled ones, or never. Defaults to Unhandled.
pathNoclear only: remove breakpoints from this script. Omit to clear everything.
clearNosnapshots only: discard what is returned, so the next read starts fresh.
limitNosnapshots only: how many of the most recent to return.
studioIdNoTarget Studio; omit for the active one.
breakpointsNoset only: breakpoints to add.

TDQS

A5/5.0
Behavior5/5

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

Beyond annotations, the description discloses critical non-obvious behaviors: breakpoints fire once per run, log expressions cannot see loop control variables, log errors surface in console rather than here, set returns Verified even when the expression fails to compile, and breakpoints never leave a thread stopped. This is exactly the kind of behavioral context annotations alone cannot 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 earns its length: every paragraph addresses a distinct operational risk or decision point, and the first sentence front-loads the core purpose. The structure moves from what it is, to non-obvious limitations, to cost tradeoffs, to practical placement advice, all without 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 complex tool with no output schema, the description is remarkably complete. It covers all four operations implicitly through parameter behavior, explains what snapshots return, warns about session scoping, and tells the agent to set breakpoints before playtesting. The only omitted details are the exact snapshot output format and exceptions behavior, both of which are partially covered by the schema and less critical than the behavioral warnings provided.

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 substantial meaning on top: condition must be a Luau expression evaluated in scope, logMessage is also Luau and not a template string, and line placement matters because certain lines can verify but never fire. These are value-add clarifications an agent could not infer from the schema 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 opening sentence states a specific action and resource: sets breakpoints that capture stack and variables, then reads back the captures. It goes further and explicitly distinguishes itself from a step debugger, making the tool's purpose crisp and differentiated from siblings like console, inspect, and playtest.

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 direct selection guidance: use the log form when you know what to watch, and the capture form when you do not. It also tells the agent when this tool is not appropriate (stepping through code) and directs log output to be read through the sibling console.

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 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.
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.
presetNonetwork 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.
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.8/5.0
Behavior5/5

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

Beyond the annotations (readOnlyHint=false, destructiveHint=false), the description discloses serious behavioral traits: that stop also clears network shaping, that a left-over device silently corrupts every later screenshot, that a lingering 400ms delay makes everything feel broken, and that nothing on screen explains why. This is exactly the side-effect and cleanup context the annotations cannot 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?

The core purpose is front-loaded and the paragraphs are cleanly separated by concern (motivation, workflow, list, network, stop). It is longer than average, with the 'Most Roblox players are on a phone' paragraph being expository, but the length is largely justified by 11 parameters and 5 operations.

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?

There is no output schema, and the description covers what an agent needs across all operations: set/list/network/stop behavior, cleanup requirements, and pairing with screenshot and playtest. The only op not explicitly narrated is 'state', which the schema itself defines as reporting-only.

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 field, making 3 the baseline. The description adds meaning on top: concrete device-id examples ('iphone_16', 'ipad_a16', 'samsung_galaxy_s25_ultra'), the framing of network shaping as deliberately degrading the connection, and the semantics of the presets and direction of degradation.

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: 'Resizes the Studio viewport to a real device, so you can see what a player on that device sees.' It further distinguishes itself from siblings by naming playtest and screenshot and clarifying that it operates on the editor viewport rather than a running game's HUD.

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 an explicit workflow ('set a device, screenshot, look'), states when to use it (finding device-specific UI breakage invisible in the data model), routes to alternatives ('Pair it with playtest to check a running game's HUD rather than the editor'), and states when to undo it ('stop... Do that when you are finished').

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

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="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
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.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 only: how long the script may run. Defaults to 30.

TDQS

A4.9/5.0
Behavior5/5

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

Goes well beyond the destructiveHint and openWorldHint annotations by disclosing that there is no timeout, infinite loops can hang Studio, changes may not be undoable as one step, live mode touches production with no undo, and playtest servers run code through a ModuleScript with plugin-only APIs unavailable. It also exposes the require module-cache pitfall explicitly.

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 for a high-risk, 7-parameter escape-hatch tool. Core behavior and return semantics are front-loaded, then safety, playtest, require, and live-mode caveats are organized into logical sections with no meaningful fluff.

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 and serious destructive potential, the description covers return values, output capture, timeout behavior, live-vs-studio differences, production safety, async execution, and known VM pitfalls. It provides everything an agent needs to decide whether and how to invoke the tool 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 documents all 7 parameters at 100% coverage, including live-only constraints and the confirm requirement, so the baseline is 3. The description adds meaningful operational semantics beyond the schema: source runs with plugin permissions, print/return are the output channels, studio scripts have no timeout, and live execution is queued asynchronously and returns a state.

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: 'Runs Luau in Studio's plugin context and returns whatever it printed, returned, or threw.' It also positions itself as the escape hatch when no dedicated sibling tool fits, clearly differentiating it from tools like create, modify, delete, move, script_edit, and find.

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 instructs to reach for it only when no dedicated tool fits and names the sibling tools that validate input, type values, and wrap writes in undo recording. It gives concrete good uses and also warns against using require to read live game state, 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.

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.
detailNoHow 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.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".
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.8/5.0
Behavior5/5

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

Annotations already declare readOnly/idempotent/non-destructive, yet the description still adds real behavioral insight: tag searches are served from CollectionService's index rather than a tree walk (hence fast on large places), TOO_BROAD is a possible outcome with a documented remedy, and `selector` executes matching in C++ so only survivors return. These are non-obvious performance and error behaviors 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 capability and an example before any caveats, and the paragraph breaks map cleanly to tags/selector concerns. It is somewhat long for a description, but nearly every sentence carries distinct routing or behavioral content rather than restating 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 12-parameter, 0-required, no-output-schema tool, the description covers the filter model, tag discovery workflow, subtree narrowing, and the selector escape hatch. Pagination and per-item detail are left to the schema, which documents them fully, so nothing an agent needs to invoke the tool 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 baseline is 3, but the prose meaningfully extends it: it explains the purpose of `op="tags"`, that every supplied filter must match, that `selector` 'combines with the other filters', and that `path` is the remedy for broad results. It stops short of covering paging (`limit`/`cursor`), which only the schema documents.

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 ('Searches the data model by name, class, property value and/or tag') and immediately distinguishes itself from siblings, naming `tree` and claiming to replace separate name/class/property/tag search tools. The concrete example ('anchored BaseParts under Workspace.Map whose name contains door') makes the scope unambiguous.

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 advice: 'Prefer it over `tree` whenever you know what you are looking for', 'Narrow with `path` if a search reports TOO_BROAD', and a full paragraph on when to call op="tags" before filtering by tag. It also states when to reach for `selector` (shape-of-tree questions or two-class queries). When-to-use, when-to-narrow, and alternatives are all present.

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.
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.
pathYesThe part being operated on - the one cut from, for subtract.
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 only: the MeshParts to read geometry from.
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.Default

TDQS

A5/5.0
Behavior5/5

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

Annotations already mark this as destructive and non-read-only, and the description goes far beyond them: it explains that subtract can succeed without cutting anything, intersect returns an error-style empty result, results lose Roblox's material/color/anchoring if not retained, mirror copies by default with a specific default plane, mesh only works on owned assets, segment is slow, and each call is one undo step. This is rich behavioral disclosure that materially changes how an agent should invoke and interpret the tool.

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 earns its length: every paragraph explains a distinct operation, a failure mode, or a practical caveat, and the bold section headers plus inline code formatting make it scannable. The title sentence front-loads the tool's purpose, and there is no filler or repetition of 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 28-parameter polymorphic tool with no output schema, this description is unusually complete. It covers per-operation semantics, parameter behavior, failure modes, ownership constraints, performance characteristics, undo behavior, and material retention. An agent has enough context to choose the right operation, set parameters correctly, and interpret surprising results.

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 substantial meaning to the core parameters: path as 'the one cut from, for subtract,' pivot as 'a door needs its hinge edge here,' steps as 'too few cuts corners off an arc,' checkAgainst as 'an empty array checks against everything,' and copy/about defaults for mirror. This goes well beyond the schema's field-by-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 scopes the tool precisely ('Every operation that reshapes solid geometry') and the description enumerates each operation with concrete verbs and resources: union, subtract, intersect, fragment, sweep, segment, mesh, mirror. This is unambiguous and clearly differentiated from sibling tools like create, modify, and move because it names the exact family of geometry-reshaping behaviors.

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 fragment for rubble and segment for articulation,' 'This is how to build a shape that is not a box without importing a mesh,' and calls sweep 'the only real answer' to collision questions. It also points to inspect as the verification step before subtract. This is strong when-to-use and alternative-routing guidance, both across the tool family and between operations within the tool.

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', 'does the menu close on Escape' — anything bound to input rather than to movement. Use character for going places and this for controls.

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

A4.8/5.0
Behavior5/5

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

Annotations mark it as a non-read-only, non-idempotent, open-world mutation; the description goes far beyond that by explaining the client-script parenting mechanism, that nothing is reported as sent until the client confirms, that missing confirmation yields an error not a success, and that cursor drawing is on by default. This is exactly the behavioural 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?

Front-loaded with the purpose and sibling routing, then escalates to mechanics. Nearly every sentence earns its place, but the window-resize anecdote ('435 to 952 pixels wide') is longer than the guidance it delivers and the block is dense enough to risk skimming.

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 4-param, one-required, mutation-style tool with no output schema and no structured annotation coverage of mechanics, the description covers coordinate semantics, the `landed` reply, emulated-device distortion, focus handling for text, failure/error behaviour, and prerequisites. Nothing needed to invoke 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 baseline is 3, but the description adds real meaning the schema lacks: the distinction between `hold` (how long a key stays down) and `after` (wait before the next step) with a concrete example, that `text` targets the FOCUSED TextBox and requires a click in the same call, and that coordinates are viewport pixels to be paired with `screenshot`.

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 ('Sends real keyboard and mouse input to a running playtest') and immediately distinguishes itself from the sibling `character` tool: movement vs. input-bound controls. An agent can pick between the two 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?

Explicitly routes: 'Use `character` for going places and this for controls', enumerates the test cases it is for (does pressing E open the door, sprint key, Escape closing menu), and states prerequisites — a running playtest addressed by the playtest's studioId from `list_studios`, 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"].
detailNoHow 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.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.6/5.0
Behavior5/5

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

Annotations already cover the read-only/idempotent/non-destructive profile, and the description adds real behavior beyond that: partial-failure semantics ('bad paths come back under failures' and do not abort the batch), per-detail cost/expense profiles, and the fact that property selection tracks the live API dump. This is exactly the kind of context an agent cannot get 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.

Conciseness5/5

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

Front-loaded with the core capability and the batching rationale, then a compact bulleted breakdown of detail levels, then the failure-handling note. Every sentence carries information; nothing is filler.

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, the description still covers parameters fully and discloses the key return-side behavior (the `failures` bucket), but it does not describe the overall response shape beyond that. Sufficient to invoke correctly, slightly short of complete for a read tool with no output schema.

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 class-specific meaning ('Part gets Size, Position, CFrame, Anchored, Material...') for the detail levels. Minor inconsistency: the description says concise returns 'class and child count only' while the schema says 'name + class only'.

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 properties, attributes, tags and children of one or more instances.' It is easy to distinguish from siblings such as tree (structure listing), find (search) and script_read (source). The scope (one or more instances, batched paths) is explicit.

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 clear operational guidance: batch all paths into one call, and reserve 'full' detail for one or two instances because it is expensive. It does not name a specific alternative sibling (e.g. when to prefer tree or find), but the when-to-use context for each detail level is unambiguous.

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. state reports without changing anything.

Pressing play adds a SECOND connected session for the playtest's server, and that is where the running game lives — console, performance and execute_luau must target its studioId, not the editor's. Call list_studios after starting and look for the entry whose context is a playtest.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
opYes'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.
argsNoValue handed to the test, readable inside it with `StudioTestService:GetTestArgs()`. Use it to tell a test which case to exercise.
playersNomultiplayer only: how many players to start.
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 declare openWorldHint=true and destructiveHint=false (though the tool stops/discards state). The description goes further: it states that play adds a second connected session hosting the game, that the call is non-blocking and reports the reached state, that stop discards changes exactly like pressing Stop, and that EndTest's value surfaces as lastResult. This is rich behavioral detail beyond the annotation flags, though it doesn't enumerate failure modes or edge cases (e.g., what happens if stop is called before any test).

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?

Dense but every sentence earns its place: op semantics up front, then async behavior, then studioId routing, then stop/EndTest contractholics. No filler, well-organized into scannable paragraphs.

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?

Comprehensive for a control tool. It explains non-blocking behavior, side effects of stopping, how to discover the right studio, and the return-value semantics. Minor gaps: no failure modes or preconditions (e.g., must be in edit mode for play), and no mention of auth, but the description is unusually complete for the domain.

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?

Even though the schema already documents all 4 parameters at 100% coverage, the description adds substantial semantic value: it explains the async nature of the reply ('returns the state reached'), how args is consumed inside the test, and the meaning of the state operation as a pure reporter. That goes beyond the schema's enumerations and helps an agent avoid misusing op as a blocking call.

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 uses specific verbs ('starts', 'stops', 'reports') tied to a clear resource ('playtests') and enumerates the five op values with distinct one-line meanings. It distinguishes the modes play/run/multiplayer and singles out state as read-only, so an agent can tell them apart 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 explains when to use play vs run vs multiplayer, warns that stop is the only way to end a test besides EndTest, and instructs calling list_studios after starting so console/performance/execute_luau target the playtest's studioId. This is actionable routing guidance with no ambiguity.

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
widthNoWidth 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.
studioIdNoTarget Studio; omit for the active one.

TDQS

A5/5.0
Behavior5/5

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

Annotations cover read-only and idempotent safety, and the description adds non-obvious context: it captures the user's current camera angle, behaves differently during playtest (slower, needs editor connection), and marks playtest captures with the caption `playtest client`. 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 action, then organized into when-to-use, camera behavior, and playtest caveats. Every sentence earns its place, including the illustrative wall/backwards/GUI examples that justify why a screenshot is needed.

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?

Even without an output schema, the description explains the return is an image, warns about playtest latency and editor connectivity, and names the required `viewport` sibling interaction. An agent has enough context to invoke it correctly in both normal and playtest scenarios.

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?

The schema already documents both parameters at 100% coverage, and the description adds beyond it: width guidance about sharpness versus cost, and studioId semantics for targeting a playtest client. This helps the agent choose parameter values, not just understand names.

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 ('Takes a picture of the Studio viewport') and immediately distinguishes itself from sibling tools that 'read the data model.' An agent can tell this is the visual-reality-check tool rather than a data query tool.

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 timing guidance: take a screenshot after building something visual and before reporting success. It also names the prerequisite `viewport op="focus"`, explains when to rely on data tools instead, and covers the playtest scenario with studioId targeting.

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".
editsYesEdits to apply together as one undoable step.
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

A4.8/5.0
Behavior5/5

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

The description goes far beyond the annotations. It discloses all-or-nothing batch semantics, the STALE_SCRIPT conditional write behavior, bottom-up line edit application, the fact that source replacement discards user changes, the live target's one-edit whole-source no-undo behavior, the fact that it changes the saved place not running servers, and the undo behavior via ScriptEditorService. This is exemplary behavioral disclosure. The annotations (destructiveHint=true, readOnlyHint=false) are consistent with the description's emphasis on destructive potential.

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 every section earns its place. It is front-loaded with the core purpose, then organized by edit mode, then revision semantics, then live target, then deployment caveats. It is dense but not redundant. It could arguably be tightened, but the complexity of the tool (three edit modes, two targets, revision safety) justifies the length. The structure with clear paragraphs and mode labels helps an agent parse it.

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 8 parameters, no output schema, and complex semantics, the description covers everything an agent needs to call it correctly: the three edit modes, the revision requirement, the live target's special constraints, the all-or-nothing batch behavior, and the post-edit restart guidance. The only thing not described is the return value, but there is no output schema and the description's focus on behavior is more important for correct invocation. The description is complete for the tool's complexity.

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 significant meaning beyond the schema: it explains the three edit modes (find/replace, startLine/endLine, source) and how they relate to the parameters, clarifies that find is literal not a pattern, explains the uniqueness requirement and replaceAll, explains the revision parameter's role in conditional writes, and clarifies the live-only parameters. It doesn't document every parameter individually, but the schema already does that. The description adds mode-level semantics that the schema lacks.

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: 'Edits Luau source through the Studio script editor' and immediately states it is the tool for any change to existing code. It distinguishes itself from siblings like script_create (creation) and script_read (reading) by framing itself as the editing tool for existing code.

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: 'This is the tool to use for any change to existing code.' It also provides clear alternatives and exclusions: it mentions script_read for reading, and contrasts with live target behavior. It explains when to use find/replace vs line ranges vs source replacement, and when to use target='live' with confirm:true. It even tells the agent to follow with universe op='restart' for live changes. This is comprehensive usage guidance.

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.

Matches come from the script editor's live buffer, so unsaved edits are searched too.

ParametersJSON Schema
NameRequiredDescriptionDefault
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.
patternYesLua pattern, or exact text when `literal` is set, e.g. "PlayerAdded".
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

A5/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, so the description doesn't need to repeat those safety attributes. The description adds valuable behavioral detail about the live buffer ('unsaved edits are searched too') and the return format (matching lines with paths and line numbers), enhancing transparency beyond 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 concise and well-structured: it opens with the core function, then explains when to use it, clarifies the pattern vs. literal distinction, and closes with the live buffer behavior. Each sentence contributes unique useful information without redundancy, and the flow is logical.

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 complexity (9 parameters, no output schema), the description covers all essential aspects: the return format, the search scope, the pattern semantics, and a key behavioral caveat (live buffer). Combined with the thorough schema descriptions, it provides enough context for an agent to correctly invoke the tool without missing critical details.

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?

The schema provides 100% coverage of parameters with descriptions, and the description supplements this by explaining the nuance of Lua patterns (e.g., `%` escaping), the behavior of `ignoreCase` when combined with pattern classes, and the recommendation to use `literal` for identifiers. This goes beyond simply restating 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 clearly states the tool's function: searching inside Luau source across the place and returning matching lines with paths and line numbers. It uses specific verbs (searches, returns) and specifies the resource (script source). It also implicitly differentiates from sibling tools like 'find' or 'inspect' by focusing on script source content.

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 the tool: 'find where something is defined or used before editing it' and contrasts it with reading whole scripts. It also provides practical guidance on using Lua patterns vs. literal search and the `literal` parameter for identifiers, which is actionable and clear.

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 an empty path list 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

A4.8/5.0
Behavior5/5

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

Annotations only say openWorldHint=true and destructiveHint=false, so the description carries the burden and exceeds it. It discloses that source comes from the live editor buffer, that file-bound scripts are a race with no failure reporting, that open rearranges the user's screen, that live mode has Instance API limitations (Folders/scripts only, GUID addressing, round-trip cost, seconds), and that list shows contents instead of reading. These are exactly the behavioral traits an agent needs to avoid incorrect calls.

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 every paragraph earns its place: buffer semantics, batching guidance, file-bound race, open behavior, live-mode limits, and list behavior. It is front-loaded with the core read action and line-number contract, then expands into mode-specific guidance. Slightly dense, but not padded.

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 10-parameter tool with no output schema, the description covers the critical context: what source is read, how to batch, how windows work, what open does, what live mode can and cannot do, and how to navigate with list. The only minor gap is not describing the result shape, but with no output schema and the description already explaining the flagged file-bound scripts, the agent has enough 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 the baseline is 3. The description adds meaning beyond the schema by explaining the top-level startLine/endLine act as defaults for entries without their own, that an entry may be a bare path or a window object, and that list:true with an empty path list shows the top level. It also clarifies the live-mode constraints on paths. This is meaningful added semantics, though the schema already documents each parameter well.

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 distinguishes itself from script_edit by noting line numbers are accepted back verbatim. It also covers the open variant and the live target, so an agent can tell exactly what this tool does versus siblings like script_grep or 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?

The description gives explicit when-to-use guidance: read the live buffer rather than saved property to avoid stale code, pass all scripts in one call, use open when pointing the user at something, and use target='live' to check the published place. It also names alternatives implicitly by explaining what open and list do instead of reading, and warns against editing file-bound scripts. This is rich routing 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.

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, only the fixed limit. 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

A5/5.0
Behavior5/5

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

Annotations already indicate destructiveHint=true and readOnlyHint=false, but the description adds extensive behavioral detail: terrain snaps to a 4-stud voxel grid, positions are the centre of the solid, fill applies multiple solids as one undo step, clear with confirm=true wipes everything, stats cannot report where terrain is because Roblox exposes no bounding box, and carving is done via Air material. These insights go far beyond the annotations and give the agent a realistic model of the tool's side effects and limitations.

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 carries essential information: the core purpose, the differentiation from instance tools, per-operation details, shape requirements, carving, position/grid behavior, and advice for usage. It is front-loaded with the most important fact (what it does) and then progresses logically. No filler or repetition; the length is 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?

Given the tool's complexity (multiple operations, shapes, carving, destructive potential) and the lack of an output schema, the description covers everything an agent needs: all operations and their semantics, parameter details, positional conventions, grid snapping, undo behavior, and strategic advice (call stats first, use screenshot). 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.

Parameters5/5

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

While schema coverage is 100%, the description enriches the parameters significantly. It explains that `fill` takes an array of solids and applies them as a single undo step, that `replace` swaps materials without changing shape, that `clear` can be scoped to a region or globally with confirm, and that `stats` only reports presence, not location. It also ties shape types to their required parameters (e.g., block needs size, ball needs radius) and explains the carving mechanic via Air. This is value beyond the schema's brief property 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 first sentence states exactly what the tool does: 'Fills, repaints and clears Roblox terrain — hills, water, caves, roads.' It uses specific verbs and a resource, and clearly distinguishes itself from instance tools by explaining that terrain is not made of instances and that this is the only way to shape it (besides hand-written FillBall calls). This unequivocally differentiates it from siblings like create, modify, and delete.

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 states when to use this tool: '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.' It also gives tactical advice, such as calling `stats` first in an unfamiliar place and taking a `screenshot` to see the shape. This covers both when to use and what alternatives exist (execute_luau), leaving nothing to inference.

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.
detailNoHow 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.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.7/5.0
Behavior5/5

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

Annotations establish readOnly/idempotent/not-destructive, so the safety profile is covered. The description then adds genuinely unexpected behavior an agent would never guess: the ~120 hidden root services, the fact that omitting path lists only authored containers, the hidden-services count appearing in the response, and the flat-over-nested design rationale. This is exactly the kind of domain gotcha the description is the only place to surface.

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 tight paragraphs with a clear job each: what it returns, when to use it, and the root/path edge behavior. The hidden-services admission—a place where most tools would hide a bug—earns its place in the final sentence. Everything is front-loaded (purpose first), with zero filler or ceremonial language.

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 read-only discovery tool with 100% schema coverage, no output schema, and 0 required parameters, the description covers every decision point an agent faces: what the response shape is, what surprising root behavior exists, how to avoid the find/tree ambiguity, and how cost scales with depth. The pagination and filter params are fully documented in the schema where they belong. The only thing an agent might want to know—the actual return shape—is explained ('flat array of paths'), and the response hint about the hidden-services count is disclosed. Nothing material 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?

At 100% schema description coverage, the schema carries the parameter-documentation burden, so the baseline of 3 applies. The description reinforces the cost model of `depth` and `detail` in prose, but that's complementary to, not a replacement for, the schema's work. No meaningful gap to compensate for.

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 specific verb and resource ('Lists the instance hierarchy under a path') plus the exact algorithm ('breadth-first to a given depth') and return type ('flat array of paths'). The explicit contrast with the sibling 'find' — 'Use `find` instead when you already know what you are looking for' — provides exactly the sibling differentiation the rubric rewards.

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?

States when to use it ('orient yourself in an unfamiliar place'), when not to use it ('when you already know what you are looking for'), names the alternative explicitly ('use `find` instead'), and gives a cost rationale for the boundary ('wastes context on instances you will never touch'). Textbook when/when-not/alternative coverage.

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.

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.
limitNobans/inventory: how many rows to return.
topicNomessage only: the MessagingService topic.
filterNoinventory only: an Open Cloud filter, e.g. `gamePassIds=123` or `assetIds=456`, to ask about specific items rather than listing everything.
userIdNoban/unban/user/inventory: the player's user id.
confirmNoRequired for restart, message, ban and unban. Each of these is visible to players the moment it runs and none can be undone from here.
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.
universeIdNoWhich game. Omit to use the one set with `cloud universe <id>`.
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.6/5.0
Behavior5/5

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

The description adds significant behavioral detail beyond annotations: restart bleeds off over 10 minutes rather than Roblox's default hard shutdown, message delivery is unacknowledged, bans without durationSeconds are permanent, and confirm is required because 'none can be undone from here.' This fully complements the destructiveHint and openWorldHint 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 organized by operation with a front-loaded key contrast, then per-op explanations, then shared auth context. It is long because the tool has 14 parameters and 7 operations, but every sentence contributes actionable information without padding.

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?

It covers auth setup, per-operation caveats, and rough return meanings for bans, user, and inventory. There is no output schema, and the description does not state precise response shapes for restart, message, ban, or unban, but an agent has enough context to invoke the tool correctly and interpret basic outcomes.

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 useful extra semantics: userId is 'the name-to-id step most other calls need,' bans scope via placeId, and inventory reports passes/badges/assets. It does not repeat every schema detail, but it adds meaning beyond the structured fields.

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 scope: 'Acts on the PUBLISHED experience and the people in it — not on the place open in Studio.' It then enumerates each operation with a distinct verb and target, so an agent can tell what the tool does and how it differs from Studio-side 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?

It gives concrete when-to-use guidance, especially for restart ('This is the step people forget') and message ('success here does not mean delivery'). It also states the auth prerequisite. It does not systematically name sibling alternatives or explicit when-not-to-use conditions, but the context is strong enough for operation selection.

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. 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
  2. 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"
        +]
  3. 1 tool updatev0.5.6
    • Addedterrain
  4. 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"
        +}
  5. 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."
  6. 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."
  7. 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."
  8. 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"
        +]
  9. 29 tool updatesv0.1.8
    • First observedapi
    • First observedassets
    • First observedcharacter
    • First observedcollision
    • First observedconsole
    • First observedcreate
    • First observeddebug
    • First observeddelete
    • First observeddevice
    • First observedexecute_luau
    • First observedfind
    • First observedgeometry
    • First observedinput
    • First observedinspect
    • First observedlist_studios
    • First observedmodify
    • First observedmove
    • First observedperformance
    • First observedplaytest
    • First observedscreenshot
    • First observedscript_create
    • First observedscript_edit
    • First observedscript_grep
    • First observedscript_read
    • First observedset_active_studio
    • First observedstudio_status
    • First observedtree
    • First observedundo
    • First observedviewport

TDQS

A4.4/5.0

Scored across 35 tools

Disambiguation5/5

Every tool addresses a clearly distinct concern: instance inspection, search, console output, performance, class API, scripting, assets, terrain, audio, input, etc. Overlapping areas are explicitly cross-referenced (e.g., `api` vs `inspect`, `character` vs `input`, `find` vs `tree`), so an agent can reliably select the right tool.

Naming Consistency3/5

Names are readable and mostly snake_case, but the convention is mixed: bare verbs (`inspect`, `create`, `move`), bare resource nouns (`console`, `terrain`, `character`), and multiword forms with different word orders (`script_read`, `list_studios`, `set_active_studio`, `execute_luau`). The `script_*` prefix gives one consistent subgroup, but overall no single predictable pattern is followed.

Tool Count4/5

35 tools is high, but the server's purpose is full Roblox Studio integration, and each tool maps to a substantial subsystem (scripts, animation, terrain, collision, datastores, universe, assets, debugging, playtest, etc.) rather than a trivial single action. The count feels slightly heavy but well justified by the breadth of the domain and the grouping of related operations into each tool.

Completeness4/5

The surface covers the main workflows: instance CRUD, script read/edit/search/create, playtesting, debugging, asset management, data stores, publishing, and specialized editors for terrain/animation/audio/geometry. There are minor gaps (e.g., no dedicated animation keyframe editor or game-settings tool), but the `execute_luau` escape hatch and op-level features compensate for most missing operations.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

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
    7
    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.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to directly manage Roblox Studio projects by creating, reading, updating, and deleting scripts, listing instances, executing Luau code, and inspecting properties. It works through natural language, making Studio operations accessible to AI.
    -