After starting a playtest, agents need observability into what the game is actually doing. Roblox Studio MCP provides layered observability tools: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.
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.
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").
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.Return only the last N entries after
since and filter are applied.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.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.
Breakpoint action:
"set"— set a breakpoint. Requiresscript_pathandline."remove"— remove a breakpoint. Requiresscript_pathandline."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.
Canonical path to a
LuaSourceContainer, for example game.ServerScriptService.Main or game.ServerScriptService[".dir"].ReproScript. Required for set and remove.1-based line number. Required for
set and remove.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".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.Optional Luau condition expression for
set. The breakpoint only fires when the condition evaluates to true.Whether the breakpoint is enabled when created (default
true).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.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.Which connected Studio place to target.
Requires the Studio Debugger Luau API beta feature to be enabled in Studio settings.
Log breakpoint agent workflow
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.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.Read breakpoint logs
Call
get_runtime_logs with filter="Breakpoint". The output includes the breakpoint location and all logged expressions.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).
Runtime peer to profile:
"server" (default) or "client-N". target="edit" is invalid because the Script Profiler captures running code, not the edit DataModel.Sample duration in milliseconds (default
1000, clamped to 100–15000). Keep captures short while the workload is active; longer captures are rarely more informative than repeated short ones.ScriptProfiler sampling frequency in samples per second (Hz). Default
1000, range 1–10000.Maximum number of
top_functions and debug_labels rows to return (default 20, clamped 1–100).Omit functions below this
TotalDuration threshold in microseconds after capture (default 0).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 Roblox frames in
top_functions (default false). Keep disabled to focus on game Luau.Include plugin frames in
top_functions (default false). The MCP capture implementation can add noise if enabled.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.
Which connected Studio place to target.
Reading the results
The response includestop_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 RobloxFunctionsarray (for cross-referencing withoutput_pathJSON).total_us— cumulative profilerTotalDurationfor this function in microseconds.source— the runtime script path as reported by Roblox. May need mapping back to editable source usinggrep_scriptsorsearch_files.
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:
capture_script_profiler with filter="Combat:" to isolate only those custom labels in top_functions and debug_labels.
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.
Runtime peer to profile:
"server" (default) or "client-N".MicroProfiler capture duration in milliseconds (default
1000, clamped 100–5000). Decoded event streams are much larger than Script Profiler output; shorter captures are recommended.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.Optional case-insensitive substring matched against timer name and group. For example,
"Heartbeat", "Simulation", "$Script", or "RbxTransport".Maximum
top_timers rows to return (default 20, range 1–100).Maximum
top_groups rows to return (default 20, range 1–100). Each group includes its own hot timers.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.Omit timers below this
inclusive_us threshold in microseconds after processing (default 0).Include Sleep/idle timers (default
false). Idle time usually hides actionable engine work.Include GPU thread events when LibMP exposes them (default
false).Maximum LibMP log events to walk (default
250000, range 10000–1000000). Raise for deeper captures.Analyze only the last N MicroProfiler frames from the snapshot (default
240, range 1–2000).Optional local path where the raw MicroProfiler snapshot bytes are written.
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.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.Optional inline prior
capture_micro_profiler summarized response to compare against. Prefer baseline_path for large captures.Label for the baseline side of
baseline_comparison, e.g. "empty_baseplate".Label for the current capture side, e.g.
"wave_spawn".Maximum delta rows per
baseline_comparison section (groups, timers, threads, call_edges). Default 20.Include the full compact
comparison_index in the normal response (default false). summary_output_path always saves it.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.
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.Optional
DeveloperMemoryTag whitelist. Unknown tag names return 0 and are listed in unknown_tags — cross-version tag drift does not cause errors.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.
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.
Peer to read from:
"edit", "server", "client-N", or "all" (default). "all" returns per-peer data; single-peer targets return that peer directly.Number of flattened top entries to include per mode (default
10, clamped 1–100).Include the full nested
SceneAnalysisService tree in each mode result (default false).Which connected Studio place to target.