Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Chrrxs/robloxstudio-mcp/llms.txt

Use this file to discover all available pages before exploring further.

After starting a playtest, agents need observability into what the game is actually doing. Roblox Studio MCP provides layered observability tools: get_runtime_logs reads the in-memory log buffers captured by each plugin peer; breakpoints lets agents instrument live scripts with log breakpoints — no pause, no stop, just automatic logging at a line — and then read those logs back; capture_script_profiler runs a short ScriptProfilerService capture and returns ranked Luau hotspots; capture_micro_profiler covers the engine side (render, physics, networking); and get_memory_breakdown / get_scene_analysis provide per-peer memory attribution. Together these tools let an agent move from “something is slow” to a specific line of Luau in a single agent loop.

get_runtime_logs

Reads the in-memory log buffers captured by Studio plugin peers. Each buffer captures approximately 64 KB of recent LogService output. Runtime peers seed from LogService:GetLogHistory() at plugin load so early startup logs emitted before the plugin finishes loading can still be returned, then continue capturing LogService.MessageOut entries. The oldest entries are dropped as the buffer fills.
target
string
Which capture buffer to read:
  • "all" (default) — merges all peer buffers and deduplicates same-message-and-level entries captured within a 2-second window across different buffers.
  • "edit" — edit DataModel peer buffer.
  • "server" — server peer buffer.
  • "client-N" — specific client peer buffer (e.g. "client-1", "client-2").
since
number
Return only entries with seq > since. Pass back the previous response’s nextSince (single target) or the matching perCaptureNextSince entry (target="all") for efficient incremental polling.
tail
number
Return only the last N entries after since and filter are applied.
filter
string
Plain substring matched against each entry’s message (no pattern semantics; literal text only). Applied after since, before tail. For example, filter="Breakpoint" isolates log breakpoint output.
instance_id
string
Which connected Studio place to target. Required when multiple places are connected; omit when only one is open. Use get_connected_instances to list available IDs.

Log attribution in solo vs. multiplayer sessions

Solo playtests (ordinary Play/Run sessions): LogService reflects logs across edit, server, and client peers — every peer sees every log. Script-origin peer attribution is not reliable, and entries omit the peer field. Use target="all" for convenience; capturedBy identifies which plugin buffer observed the entry, but not the originating script’s runtime context.StudioTestService multiplayer sessions only: Peer attribution IS reliable because each peer has a separate OS process. Entries include a peer field in multiplayer test responses.

breakpoints

Manages Studio debugger breakpoints through ScriptDebuggerService. For agent debugging, prefer log breakpoints: set a log breakpoint on a line, reproduce the behavior, then read get_runtime_logs filtered by "Breakpoint". This keeps the playtest running without any pause/resume ceremony.
action
string
required
Breakpoint action:
  • "set" — set a breakpoint. Requires script_path and line.
  • "remove" — remove a breakpoint. Requires script_path and line.
  • "clear" — remove MCP-managed breakpoints (default) or all Studio breakpoints (clear_all=true).
  • "list" — list breakpoints created through this MCP tool in the targeted DataModel.
script_path
string
Canonical path to a LuaSourceContainer, for example game.ServerScriptService.Main or game.ServerScriptService[".dir"].ReproScript. Required for set and remove.
line
number
1-based line number. Required for set and remove.
log_message
string
Studio breakpoint log expression for set. For example, "'health', health" (literal strings must be quoted as Luau strings). The tool automatically prefixes this with "Breakpoint" and script_path:line. After reproducing, read get_runtime_logs with filter="Breakpoint".
continue_execution
boolean
Whether the breakpoint logs and continues without pausing the playtest. Defaults to true when log_message is provided; otherwise false. Only set false when a ScriptDebuggerService.OnStopped handler is already installed that resumes breakpoint/non-exception stops with Enum.DebuggerResumeType.Resume.
condition
string
Optional Luau condition expression for set. The breakpoint only fires when the condition evaluates to true.
enabled
boolean
Whether the breakpoint is enabled when created (default true).
clear_all
boolean
Only applies to action="clear". Omit or set false to remove only MCP-managed breakpoints. Set true to call ScriptDebuggerService:ClearBreakpoints() and clear every Studio breakpoint in the targeted DataModel, including user-created ones.
target
string
Peer to target: "edit" (default), "server", or "client-N". Set edit-target breakpoints before a playtest starts; target "server" or "client-N" for already-running play DataModels.
instance_id
string
Which connected Studio place to target.
Do not set continue_execution=false unless you have already installed a ScriptDebuggerService.OnStopped handler on the same target that returns Enum.DebuggerResumeType.Resume for breakpoint/non-exception stops. Without that handler, the playtest will pause and MCP will lose its server/client peers.Minimal OnStopped handler:
local sds = game:GetService("ScriptDebuggerService")
sds.OnStopped = function(info)
    if info.Reason ~= Enum.ScriptStoppedReason.Exception then
        return Enum.DebuggerResumeType.Resume
    end
    print("EXCEPTION:", info.ExceptionText)
    return Enum.DebuggerResumeType.Resume
end
Requires the Studio Debugger Luau API beta feature to be enabled in Studio settings.

Log breakpoint agent workflow

1

Set a log breakpoint

Call breakpoints with action="set", a script_path, a line, and a log_message expression (e.g. "'damage', damage, 'source', source"). Leave continue_execution at its default true.
2

Reproduce the behavior

Use eval_server_runtime, eval_client_runtime, or simulate_mouse_input / simulate_keyboard_input to trigger the code path that hits the breakpoint.
3

Read breakpoint logs

Call get_runtime_logs with filter="Breakpoint". The output includes the breakpoint location and all logged expressions.
4

Clear breakpoints

Call breakpoints with action="clear" to remove all MCP-managed breakpoints. Omit clear_all to leave user breakpoints untouched.

capture_script_profiler

Captures one short ScriptProfilerService sample on a running server or client peer and returns a compact CPU summary. Use this for Luau/script optimization — not for render, physics, networking, or engine microprofiler lanes (use capture_micro_profiler for those).
target
string
Runtime peer to profile: "server" (default) or "client-N". target="edit" is invalid because the Script Profiler captures running code, not the edit DataModel.
duration_ms
number
Sample duration in milliseconds (default 1000, clamped to 10015000). Keep captures short while the workload is active; longer captures are rarely more informative than repeated short ones.
frequency
number
ScriptProfiler sampling frequency in samples per second (Hz). Default 1000, range 110000.
max_functions
number
Maximum number of top_functions and debug_labels rows to return (default 20, clamped 1100).
min_total_us
number
Omit functions below this TotalDuration threshold in microseconds after capture (default 0).
filter
string
Optional case-insensitive substring matched against function name and source path before top_functions are returned. Useful for focusing on one module or a debug.profilebegin label prefix (e.g. filter="Combat:").
include_native
boolean
Include native Roblox frames in top_functions (default false). Keep disabled to focus on game Luau.
include_plugin
boolean
Include plugin frames in top_functions (default false). The MCP capture implementation can add noise if enabled.
output_path
string
Optional local path where the MCP server writes the raw Roblox Script Profiler JSON for offline comparison or deeper analysis. When provided, the raw JSON is not inlined in the response.
instance_id
string
Which connected Studio place to target.

Reading the results

The response includes top_functions sorted by descending total_us (cumulative TotalDuration in microseconds). Each row includes:
  • rank — position in the sorted list.
  • function_index — the 1-based index into the raw Roblox Functions array (for cross-referencing with output_path JSON).
  • total_us — cumulative profiler TotalDuration for this function in microseconds.
  • source — the runtime script path as reported by Roblox. May need mapping back to editable source using grep_scripts or search_files.
Do not sum total_us rows as total CPU time. Nested labels and functions can overlap — a parent frame’s total_us includes the time spent in its children. The values are TotalDuration per function as defined by the Roblox Script Profiler JSON format.

Granular profiling with debug.profilebegin

For hotspot investigation inside a large module, instrument the suspected code with debug.profilebegin / debug.profileend and pass a matching filter:
-- Inside your server module (e.g. CombatSystem):
local function resolveDamage(attacker, target, weaponData)
    debug.profilebegin("Combat:ResolveDamage")

    -- ... damage calculation ...

    debug.profileend()
end
Then call capture_script_profiler with filter="Combat:" to isolate only those custom labels in top_functions and debug_labels.
Use a colon or other separator as a label prefix ("Combat:", "AI:", "Physics:") so filter can narrow results without false-positive matches against unrelated function names.

capture_micro_profiler

Captures one short Roblox MicroProfiler sample and returns structured CPU-time attribution across scripts, physics, render, networking, jobs, scheduler, GC, and engine timers. Use this when the performance question is “where is frame time going?” across engine subsystems, not just Luau.
target
string
Runtime peer to profile: "server" (default) or "client-N".
duration_ms
number
MicroProfiler capture duration in milliseconds (default 1000, clamped 1005000). Decoded event streams are much larger than Script Profiler output; shorter captures are recommended.
focus
string
Subsystem focus: "all" (default), "script", "physics", "render", "network", or "jobs". Use "all" first for unknown bottlenecks, then narrow focus after top_groups identifies the area.
filter
string
Optional case-insensitive substring matched against timer name and group. For example, "Heartbeat", "Simulation", "$Script", or "RbxTransport".
max_timers
number
Maximum top_timers rows to return (default 20, range 1100).
max_groups
number
Maximum top_groups rows to return (default 20, range 1100). Each group includes its own hot timers.
max_timers_per_group
number
Maximum nested top_timers inside each top_groups row (default 5). Use 0 to omit nested timers.
Maximum per-row parent, child, and thread context entries (default 3). Use 0 to omit relationship context.
min_total_us
number
Omit timers below this inclusive_us threshold in microseconds after processing (default 0).
include_idle
boolean
Include Sleep/idle timers (default false). Idle time usually hides actionable engine work.
include_gpu
boolean
Include GPU thread events when LibMP exposes them (default false).
max_events
number
Maximum LibMP log events to walk (default 250000, range 100001000000). Raise for deeper captures.
frame_window
number
Analyze only the last N MicroProfiler frames from the snapshot (default 240, range 12000).
output_path
string
Optional local path where the raw MicroProfiler snapshot bytes are written.
summary_output_path
string
Optional local path where the summarized JSON response (including a compact comparison_index) is written. Use this to save an empty-baseplate control capture for later baseline_path comparison.
baseline_path
string
Optional local path to a prior capture_micro_profiler summarized JSON. The tool adds a baseline_comparison field using current minus baseline, normalized by capture duration.
baseline
object
Optional inline prior capture_micro_profiler summarized response to compare against. Prefer baseline_path for large captures.
baseline_label
string
Label for the baseline side of baseline_comparison, e.g. "empty_baseplate".
current_label
string
Label for the current capture side, e.g. "wave_spawn".
max_comparison_rows
number
Maximum delta rows per baseline_comparison section (groups, timers, threads, call_edges). Default 20.
include_comparison_index
boolean
Include the full compact comparison_index in the normal response (default false). summary_output_path always saves it.
instance_id
string
Which connected Studio place to target.
inclusive_us values follow the same overlap caveat as Script Profiler total_us: nested timers accumulate their parent’s time. Do not sum inclusive_us rows as total frame time. pct_of_analyzed_wall can exceed 100% when work overlaps across threads.

get_memory_breakdown

Reads per-category memory usage by iterating Enum.DeveloperMemoryTag and calling Stats:GetMemoryUsageMbForTag per item, plus Stats:GetTotalMemoryUsageMb for the rollup. Returns a structured breakdown per peer.
target
string
Peer to read from: "edit", "server", "client-N", or "all" (default). "all" returns { peer: { total_mb, categories, timestamp } } for every connected peer except the edit proxy.
tags
array
Optional DeveloperMemoryTag whitelist. Unknown tag names return 0 and are listed in unknown_tags — cross-version tag drift does not cause errors.
instance_id
string
Which connected Studio place to target.
timestamp in the response is Unix milliseconds (DateTime.now().UnixTimestampMillis). If a peer has MemoryTrackingEnabled=false, that peer’s entry surfaces as { error } only; other peers in the "all" response are unaffected.

get_scene_analysis

Reads SceneAnalysisService data for attribution-focused performance analysis. Returns compact top-N entries for instance composition, script memory, unparented instances, triangle composition, animation memory, and audio memory. Complements get_memory_breakdown with DataModel-level attribution rather than raw tag totals.
mode
string
Scene analysis mode. One of:
  • "all" (default) — all modes.
  • "instance_composition" — top instances by child count / complexity.
  • "script_memory" — top scripts by memory usage.
  • "unparented_instances" — instances that are not in the DataModel tree.
  • "triangle_composition" — top meshes/parts by triangle count.
  • "animation_memory" — top animation assets by memory.
  • "audio_memory" — top audio assets by memory.
target
string
Peer to read from: "edit", "server", "client-N", or "all" (default). "all" returns per-peer data; single-peer targets return that peer directly.
topN
number
Number of flattened top entries to include per mode (default 10, clamped 1100).
raw
boolean
Include the full nested SceneAnalysisService tree in each mode result (default false).
instance_id
string
Which connected Studio place to target.
get_scene_analysis requires the Studio Scene Analysis beta feature to be enabled in Studio. If it is disabled, the tool returns scene_analysis_not_enabled with betaFeatureRequired=true.

Build docs developers (and LLMs) love