Skip to main content
Glama
EL4CTEO

Roblox Studio MCP

Breakpoints and runtime inspection

debug

Set breakpoints in Roblox Studio scripts to capture call stacks and variable values, trace RemoteEvents, watch instances, and inspect collisions during playtests.

Instructions

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

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

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

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

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

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

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

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

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

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

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

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

collisions watches a part, or every part under a model, with the engine's collision summaries and returns one row per colliding pair, hardest impact first: contact point, surface normal, relative velocity, area, impact speed along the normal and total speed. Use it to tune impact FX, sound and damage from real numbers, or to find what a part keeps hitting. Needs physics running (a playtest); target=client reads the client's own simulation. Resting contact reports every frame, so set minSpeed to keep impacts only; it filters on impact speed, so sliding does not count.

Input Schema

NameRequiredDescriptionDefault
opYes'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors, 'remotes' traces RemoteEvents.
lineNoclear only: which line to remove.
modeNoexceptions only: break on every error, only unhandled ones, or never. Defaults to Unhandled.
pathNoclear: script to clear. remotes: remote or subtree path, default game. Narrow this if discovery is truncated. watch: instance. collisions: part, model or folder.
clearNosnapshots only: discard what is returned, so the next read starts fresh.
limitNosnapshots only: how many of the most recent to return.
playerNowatch client/remotes: player name; required with multiple players.
targetNoclient: read the actual player's playtest VM. Use the playtest server studioId.studio
secondsNowatch/remotes/collisions: bounded capture seconds, default 5. Pair watch with concurrent input to observe a reaction.
childrenNowatch: include direct child additions/removals.
minSpeedNocollisions: ignore contacts that hit softer than this, in studs/s along the contact normal.
studioIdNoTarget Studio; omit for the active one.
attributesNowatch: attribute names; omit for all, [] for none.
propertiesNowatch: properties to observe.
breakpointsNoset only: breakpoints to add.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changedv0.9.5
    • addedInput schema / properties / minSpeed
      Added value: +{
      +  "description": "collisions: ignore contacts that hit softer than this, in studs/s along the contact normal.",
      +  "minimum": 0,
      +  "type": "number"
      +}
    • changedInput schema / properties / op / enum
      Previous value: -[
      -  "set",
      -  "clear",
      -  "snapshots",
      -  "exceptions",
      -  "remotes",
      -  "watch"
      -]New value: +[
      +  "set",
      +  "clear",
      +  "snapshots",
      +  "exceptions",
      +  "remotes",
      +  "watch",
      +  "collisions"
      +]
    • changedInput schema / properties / path / description
      Previous value: -"clear: script to clear. remotes: remote or subtree path, default game. Narrow this if discovery is truncated."New value: +"clear: script to clear. remotes: remote or subtree path, default game. Narrow this if discovery is truncated. watch: instance. collisions: part, model or folder."
    • changedInput schema / properties / seconds / description
      Previous value: -"watch/remotes: bounded capture seconds, default 5. Pair watch with concurrent input to observe a reaction."New value: +"watch/remotes/collisions: bounded capture seconds, default 5. Pair watch with concurrent input to observe a reaction."
  2. Changed7 schema fields changedv0.9.1
    • addedInput schema / properties / attributes
      Added value: +{
      +  "description": "watch: attribute names; omit for all, [] for none.",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 16,
      +  "type": "array"
      +}
    • addedInput schema / properties / children
      Added value: +{
      +  "default": true,
      +  "description": "watch: include direct child additions/removals.",
      +  "type": "boolean"
      +}
    • changedInput schema / properties / op / enum
      Previous value: -[
      -  "set",
      -  "clear",
      -  "snapshots",
      -  "exceptions",
      -  "remotes"
      -]New value: +[
      +  "set",
      +  "clear",
      +  "snapshots",
      +  "exceptions",
      +  "remotes",
      +  "watch"
      +]
    • changedInput schema / properties / player / description
      Previous value: -"remotes only: player name; required with multiple players. Both directions are scoped to this player."New value: +"watch client/remotes: player name; required with multiple players."
    • addedInput schema / properties / properties
      Added value: +{
      +  "description": "watch: properties to observe.",
      +  "items": {
      +    "minLength": 1,
      +    "type": "string"
      +  },
      +  "maxItems": 16,
      +  "type": "array"
      +}
    • changedInput schema / properties / seconds / description
      Previous value: -"remotes only: capture seconds, default 5."New value: +"watch/remotes: bounded capture seconds, default 5. Pair watch with concurrent input to observe a reaction."
    • addedInput schema / properties / target
      Added value: +{
      +  "default": "studio",
      +  "description": "client: read the actual player's playtest VM. Use the playtest server studioId.",
      +  "enum": [
      +    "studio",
      +    "client"
      +  ],
      +  "type": "string"
      +}
  3. Changed5 schema fields changedv0.7.5
    • changedInput schema / properties / op / description
      Previous value: -"'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors."New value: +"'set' adds breakpoints, 'clear' removes one or all, 'snapshots' reads what has been captured, 'exceptions' controls breaking on errors, 'remotes' traces RemoteEvents."
    • changedInput schema / properties / op / enum
      Previous value: -[
      -  "set",
      -  "clear",
      -  "snapshots",
      -  "exceptions"
      -]New value: +[
      +  "set",
      +  "clear",
      +  "snapshots",
      +  "exceptions",
      +  "remotes"
      +]
    • changedInput schema / properties / path / description
      Previous value: -"clear only: remove breakpoints from this script. Omit to clear everything."New value: +"clear: script to clear. remotes: remote or subtree path, default game. Narrow this if discovery is truncated."
    • addedInput schema / properties / player
      Added value: +{
      +  "description": "remotes only: player name; required with multiple players. Both directions are scoped to this player.",
      +  "type": "string"
      +}
    • addedInput schema / properties / seconds
      Added value: +{
      +  "description": "remotes only: capture seconds, default 5.",
      +  "maximum": 15,
      +  "minimum": 1,
      +  "type": "number"
      +}
  4. First observedv0.1.8

TDQS

A4.7/5.0
Behavior5/5

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

With annotations only declaring readOnly=false/openWorld=true/non-idempotent, the description carries substantial extra behavioral load: breakpoints fire once per run, a log expression cannot see the loop control variable, a throwing log is reported in console rather than by this tool (so 'set' still returns Verified), one breakpoint per line, captures auto-resume without leaving a frozen Studio, and precise capture limits for remotes (5s default/max 15, 2000 events, 40 rows, 12 KB, truncation reporting). None of this is derivable from annotations or schema.

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

Conciseness4/5

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

Front-loaded with the core model (tracepoint vs step debugger) before the trade-offs, and most paragraphs earn their place by preventing a specific failure mode. It is long and slightly repetitive ('measured, not assumed' appears twice), and the remotes/collisions tail is dense enough that an agent skimming may miss it, but there is little pure 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?

For a 7-op tool with no output schema, the description covers set/clear/snapshots/remotes/collisions behavior thoroughly, including pitfalls an agent would otherwise hit. It is thin on the 'watch' and 'exceptions' ops, which are left to the schema enum alone, so an agent must consult the schema for those two modes.

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 description adds real semantics the schema does not: 'condition' and 'logMessage' are Luau expressions (logMessage explicitly not a template string, with a correct/incorrect example), values should be wrapped in tostring so nil prints rather than throwing, and minSpeed filters on impact speed so sliding does not count. The gap: the 'watch' and 'exceptions' ops get no parameter-level elaboration in the prose.

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 concrete verb+resource chain ('Sets breakpoints that record the stack and variables ... then reads back what they caught') and immediately disambiguates the tool type ('These are tracepoints, not a step debugger'). It also carves out the two secondary modes (remotes, collisions) with enough specificity that an agent knows what each op does without opening the schema.

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

Usage Guidelines5/5

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

Gives explicit when-to-use guidance for choosing between the two breakpoint kinds ('Reach for the log when you know what to watch, the capture when you do not') and explicit when-NOT-to-use guidance ('It is not a way to watch a value change inside a loop — ... have the code itself print and read that with console'). It also states prerequisites for each mode: set breakpoints before starting a playtest, physics must be running for collisions, playtest studioId needed for remotes.

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