Studio Live
Integrates with Roblox Open Cloud to access the open place, enabling cloud operations through the cloud tool.
Provides real-time interaction with a running Roblox Studio instance over a WebSocket, enabling AI agents to execute Luau programs, observe DataModels, run playtests, hot-patch scripts, push instances, and manage controllers.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Studio LiveFix the coin collection script and hot-patch it into the live playtest"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Studio Live
Real-time Roblox Studio for AI agents. One MCP server, nine tools, an agent runtime that lives inside Studio.
Install · Quick start · Tools · Works with · Docs · Security
Studio Live connects an AI coding agent to a running Roblox Studio over a single WebSocket. Instead of one tool call per property, the agent ships whole Luau programs against a resident API, gets errors and assertions pushed into its context, keeps playtests alive while it hot-patches code, reaches Open Cloud for the open place, and asks a vision sidecar visual questions that come back as text.
Fast where it matters — 16 ms round trip (one Heartbeat frame), a hot-patch in a live playtest in ~17 ms, screenshots in ~30 ms even while Studio is minimised. Every number is measured; see Why it feels fast.
One undo step per program — an edit-DataModel
runis one Ctrl+Z for the human and rolls back on error.Push, not poll — errors, assertions, milestones, playtest, peer and job events arrive as they happen.
Playtests stay up — install controllers that run at Heartbeat in-engine, hot-patch scripts, push instances,
run_untila predicate — no stop/start per change.Multi-agent, multi-Studio — several agents share one Studio with FIFO writes; several Studio windows (server + N clients) form a multiplayer playtest.
Geometry is enforced — overlapping parts and "parts in parts" are detected on every edit and can be rejected outright.
Any MCP client — Claude Code, Codex CLI, Cursor, Claude Desktop, or a plain shell.
The design record is in docs/architecture.md, the wire contract in docs/protocol.md, the engine measurements it rests on in docs/live-measurements.md. Agents should read docs/agent-guide.md; the cloud and look tools have their own pages, docs/cloud.md and docs/vision.md.
Works with any MCP client
It is a plain stdio MCP server. Nothing in the plugin, the protocol or the tools is tied to one client; only the way pushed events reach the model differs.
Client | Tool calls | Push events |
|
Claude Code | stdio MCP ( | its | Anthropic API credential, or your Claude Code login |
Codex CLI · Cursor · Claude Desktop · any MCP client | stdio MCP | the | Anthropic API credential, or a |
Shell, scripts, other agents |
|
| same |
Several clients can run at once — the first bridge owns Studio, later ones proxy through it automatically. look is the one tool with a model behind it and today it only speaks to Anthropic models (the backend is the VisionProvider interface in bridge/src/vision/types.ts). Everything else works with no AI-vendor credential at all.
Related MCP server: roblox-studio-mcp
Why it feels fast
Every number below was measured on one machine (Studio 0.738, Windows 11); see docs/live-measurements.md.
Cost | Existing connectors | Studio Live | Measured |
Transport wait per hop | community plugin polls every 0.5 s: mean 250 ms, worst 500 ms, 2 req/s dispatch | one persistent WebSocket, push both ways | echo RTT p50 16.5 ms, max 17.7 ms (= one Heartbeat frame); 200 requests fired in one frame all answered in the next |
Changing code in a playtest | stop → edit → start ≈ 2.7 s plus two LLM turns | the playtest stays up; | hot-injected Script/LocalScript ran within 16.6 / 16.9 ms |
Screenshot | in-engine | Win32 | 28–44 ms for 1734×1399, works while occluded; ≈100 ms round trip including bicubic resize to 1024 px and JPEG |
Structured observation | one tree read or screenshot per LLM turn | pushed events + | full 2 381-instance snapshot: walk 2.6 ms + JSON 0.55 ms = 114 KB |
LLM turns per task | 2–10 s per micro-tool, ten tools for "walk to the door and try it" | one turn ships a Luau program or a controller that runs at Heartbeat in-engine | the turn itself cannot be removed, only the count |
The turn is the real cost, so the design (1) moves closed loops into Studio (controllers, run_until predicates, in-engine assertions), (2) makes each turn do more (programs against a resident S API, saved skills), and (3) streams observations to the agent instead of making it ask.
Requirements
Windows 10/11. The bridge and the plugin are platform-neutral Node and Luau, but the screenshot worker is Win32 (
PrintWindow) andinstall/twinlook up Windows paths, so macOS is not supported yet.Node.js ≥ 20.
Roblox Studio with Load User Plugins In Run Modes on (File → Studio Settings → Studio).
Optional: an Anthropic credential or a Claude Code login for
look; a Roblox Open Cloud API key forcloud.
Install
Full walkthrough with the reasons behind each step: docs/install.md.
git clone https://github.com/gurmyd/roblox-studio-live.git
cd roblox-studio-live
npm install
npm run build # tsc + copy worker.ps1 into dist + pack plugin/bootstrap.luau -> dist/StudioLive.rbxmx
npm run install:studio # copies the plugin into %LOCALAPPDATA%\Roblox\Plugins and prints the next stepsThen, once: restart Roblox Studio. The edit DataModel loads plugin files only at start; after that the runtime is pushed by the bridge on every connect, so updating this package never needs another restart.
Claude Code
The install step prints the exact line with the absolute path:
claude mcp add studio -- node "<absolute path>\dist\bridge\cli.js" serveRecommended .claude/settings.json, so tool calls and the push monitor run without prompts:
{ "permissions": { "allow": ["mcp__studio__*", "Monitor"] } }Codex CLI
~/.codex/config.toml:
[mcp_servers.studio]
command = "node"
args = ["C:\\path\\to\\roblox-studio-live\\dist\\bridge\\cli.js", "serve"]
# tool calls longer than Codex's tool timeout return a job handle; use job { action: "wait" }Cursor / Claude Desktop / other JSON-configured clients
{ "mcpServers": { "studio": { "command": "node", "args": ["C:\\path\\to\\roblox-studio-live\\dist\\bridge\\cli.js", "serve"] } } }Quick start
In a Claude Code session with Studio open on a place:
Arm push once — events then arrive in context without asking:
Monitor({ ws: { url: 'ws://127.0.0.1:47800/events' }, persistent: true })(other clients: callevents { since: 0, timeout_ms: 25000 }when you want a batch)observe { what: "status" }— confirms the hub is connected, which DataModels are alive, capabilities.run { dm: "edit", undo_label: "agent: first part", code: "return S.path(S.part{ Name='Hello', Size=Vector3.new(4,1,4), CFrame=CFrame.new(0,3,0) })" }— one undo step the human can Ctrl+Z.playtest { action: "start", mode: "play" }, thenplaytest { action: "install", dm: "client:1", name: "walker", code: "<controller>" }— the controller plays and reports assertions as events while you keep editing.
Worked examples for every acceptance test (T1–T4) are in docs/agent-guide.md. A record of six agents building a playable game concurrently through the bridge is in docs/multi-agent-build-report.md.
Tools
Tool | Purpose |
| Execute a Luau program against the resident |
| Read-only: |
|
|
| Human-like input sequences in the play client (keys, clicks, move, look, text, wait, focus; no scroll — an engine limit) through |
| Long-poll backfill of the event journal ( |
| Luau program library on disk: |
|
|
| Roblox Open Cloud for the open place: |
| Vision sidecar: |
observe, events and look are annotated read-only so Claude Code runs them in parallel with other calls; job is not (cancel rolls back an edit-DM recording). cloud and look are the only tools that leave the machine (openWorldHint: Open Cloud, the Claude API). With two Studio windows connected, write tools require session and reads carry a session_note.
look reaches its vision model one of two ways. With an Anthropic API credential in the bridge's environment (ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN, or an ant auth login profile) it calls the Claude API directly — about 2 s per look. Without one, a logged-in Claude Code install is enough: when claude is on the bridge's PATH the sidecar runs claude -p --output-format json per frame on your subscription (~10–15 s per look, watch interval at least 15 s, usage counted against your plan's limits rather than an API bill). STUDIO_LIVE_VISION_PROVIDER = auto | api | claude-cli chooses (default auto: the API when a credential resolves, else the CLI), and every answer and vision event names the provider that served it — see docs/vision.md.
Programs in play DataModels get the same S API plus S.ensure(path, class, props?) (create-if-missing for roots shared between agents), S.script.get(path, {from, to}) line ranges, and in controllers ctx.pathTo(pos, timeout) (PathfindingService) next to the straight-line ctx.moveTo. Several agents can share one Studio: edit-DM writes queue FIFO (no busy until 500 are waiting; measured live with 30 and 100 concurrent programs), and docs/agent-guide.md has the multi-agent contract they follow.
Geometry is enforced ("parts in parts"): every edit-DM run checks the parts it added or moved through S for intersections with other parts (touching faces are fine) and for Parts parented under Parts, and reports them as geometry + warnings; geometry_policy: "reject" (or STUDIO_LIVE_GEOMETRY_POLICY=reject) rolls such a run back with geometry_violation, observe { what: "geometry" } audits any subtree, and S.placeOn / S.fits / S.overlaps make correct placement one line — see the agent guide's "Geometry rules (enforced)".
Command line
Everything the tools do is also reachable from a shell through the running bridge (POST /rpc):
studio-live serve # the bridge + MCP server on stdio (what Claude Code launches)
studio-live install # install the bootstrap plugin (STUDIO_LIVE_PORT baked in)
studio-live status # GET /status of the running bridge (sessions, journal, jobs)
studio-live call <tool> [json | -] [--raw] [--port N] [--timeout ms]
studio-live call run --code-file .\build.luau --args-file .\build.args.json
studio-live call playtest '{"action":"hotpatch","dm":"server","path":"ServerScriptService.Main"}' --source-file .\Main.server.luau
studio-live call playtest '{"action":"run_until","dm":"server"}' --predicate-file .\ready.luau
studio-live sync <dir> [--pull] [--once] [--no-hotpatch] [--port N]
studio-live twin <place.rbxl> [--port N] [--timeout ms] [--exe C:\...\RobloxStudioBeta.exe]callperforms one tool call and prints the tool's text (--raw: the whole MCP result JSON); exit code 1 when the resultisErroror no bridge answers.--args-file <json>supplies the whole argument object;--code-file,--source-file,--predicate-fileread a Luau file (UTF-8, BOM stripped) intocode/source/predicate— the supported way to hand Luau to the tools from scripts and subagents, because shell heredocs turn\ninside Luau strings into real newlines (the resultingMalformed stringerror says so).syncmirrors a folder of.luaufiles into the open place (or the place into the folder with--pull) — docs/sync.md.twinlaunches a second Roblox Studio on a local place file (the newestRobloxStudioBeta.exeunder%LOCALAPPDATA%\Roblox\Versions\version-*\, then a per-machine install under%ProgramFiles(x86)%\Roblox\Versions;--exe <path>orSTUDIO_LIVE_STUDIO_EXEskips the scan; spawned detached with the.rbxlas its argument), waits up to 90 s (--timeout ms) for the new session to show up inGET /status, and prints its session id and place. A Studio that cannot start, or exits before connecting, is reported immediately (exit 1). **Multiple sessions:** each Studio process is its own session; while more than one is connected, passsession: "<guid or unique prefix>"on tool calls — reads default to the active session and say so (session_note), writes (run,playtest,input,skills run) refuse to guess. Naming a session once makes it the active one.
Troubleshooting
Screenshot fails with minimized. PrintWindow cannot render a minimized window (Studio suspends its render loop). By default the bridge un-minimizes it without taking focus (ShowWindow(SW_SHOWNOACTIVATE) and a SetWindowPos to the bottom of the Z-order) and waits 400 ms; pass restore: false to refuse instead. A window that was maximized before being minimized comes back at its normal size — that is a Win32 limit of non-activating restores. Occluded windows capture fine; you do not need Studio in front.
Screenshot fails with no_window. No visible top-level window of a RobloxStudioBeta process has "Roblox Studio" in its title: Studio is not running, is still on the splash screen, or title_match did not match (the message lists the titles it saw). With several Studio processes the foreground one wins, else the topmost in Z-order; within a process the largest window wins (the main window over floating docks). observe { what: "windows" } lists them; pass hwnd from that list to pin one. The first screenshot after a bridge start can take a few seconds while the PowerShell worker compiles its Win32 shim; the bridge warms it up in the background and does not count that time against the 10 s capture timeout.
playtest start says no_peer. The play server/client DataModels never said hello. Open File → Studio Settings → Studio and turn Load User Plugins In Run Modes on (Faster Play Solo disables user plugins in test mode by default), and check that StudioLive.rbxmx is installed and Studio was restarted after installing it. observe status shows peers once they connect.
Port 47800 is in use. The bridge listens on 127.0.0.1:47800 (STUDIO_LIVE_PORT overrides; Studio connects to the literal 127.0.0.1). A second MCP process on the same machine must not fight for the socket: it detects the primary and runs in proxy mode, forwarding tool calls over POST /rpc to the primary, which owns the single Studio connection; when the primary exits it first waits for jobs the proxy started, and the proxy then takes the port over on its next call. If the port is held by something else entirely, either free it or pick another: the plugin reads no settings, so set STUDIO_LIVE_PORT in the environment, run npm run install:studio again (it bakes the port into StudioLive.rbxmx), restart Studio once, and register the MCP server with --env STUDIO_LIVE_PORT=<port> (the install output prints the exact line).
syntax_error: Malformed string on code that is valid Luau. The program reached Studio with a real newline inside a quoted string: a shell heredoc or a JSON layer collapsed \\n to \n before the bridge saw it (the bridge itself is escape-clean — its selftest compiles "\n" and "[^\n]+" inside Luau strings). The error message appends the hint "your transport turned \n into a newline — pass code from a file (code_file)" when that is what happened. Write the program to a file and pass code_file / source_file / predicate_file (or studio-live call --code-file); never work around it with string.char(10).
Persisted controllers vanished after a restart / playtest list shows none. Persistence lives in the bridge (<STUDIO_LIVE_HOME>/persist/<placeId>.json, default home ~/.studio-live), not in Studio: plugin:GetSetting returns nil for every key on Studio 0.738. The bridge re-sends the list to the hub on every hello, so entries return when the bridge that stored them (or one sharing its home directory) is running; an entry is removed by uninstall or by a later install of the same name without persist. An unsaved place (placeId 0) has no file: its entries are memory-only and gone after a bridge restart. persist_note instead of persist_file on an install means the bridge could not write the file (read-only home, disk full) — the entry lives in memory for that bridge process only. Two Studios on the same placeId (a twin) share the file, which holds the union of both sessions' lists.
Monitor is unavailable (Claude Code). Monitor is gated off when DISABLE_TELEMETRY / CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC is set, on Bedrock/Vertex/Foundry, in non-interactive runs, and in some clients. Use the events tool instead: events { since: <last seq>, timeout_ms: 25000 } long-polls the same journal, and a PostToolBatch hook can attach "events since cursor" to every tool round trip. Also call events whenever a pushed frame shows dropped > 0 or a seq gap.
Nothing happens after editing plugin/bootstrap.luau. Studio does not load a newly written plugin file while running. Only the bootstrap lives on disk; iterate on runtime code through the bridge (pushed on connect) and restart Studio only when the bootstrap itself changes.
Development
npm run typecheck # tsc --noEmit
npm test # vitest (tests/**/*.test.ts); capture tests use a fake worker, no Studio needed
npm run build # dist/bridge/*.js + worker.ps1 + dist/StudioLive.rbxmx + dist/StudioLive.lua
npm run selftest # offline end-to-end: real bridge on a random port + scripts/fake-hub.mjs, PASS/FAIL per protocol check
npm run luau:check # parse/type-check plugin/**/*.luau with luau-lsp (fetches Roblox definitions once)
npm run fake-hub -- --port 47800 # pretend to be Studio against a running bridge (handshake, events, canned answers)
node scripts/capture-smoke.mjs # lists Studio windows and captures two frames with timings (Studio must be open)Layout: bridge/src (Node bridge: MCP server, sessions, journal, jobs, skills, capture/ worker, cloud/, vision/, sync/), plugin/bootstrap.luau (the only code installed into Studio) and plugin/runtime/** (the hub/agent runtime the bridge pushes on connect; see docs/luau-runtime.md), skills/builtin (Luau programs shipped with the bridge), scripts/ (build, packaging, selftest, smoke), docs/, tests/.
The bridge's stdout is the MCP stdio transport; every log line goes to stderr. Screenshots land in %TEMP%\studio-live\frames (newest 200 kept). The rules that keep the live system working (the bootstrap is frozen, tests never bind 47800, keys are never printed) are in AGENTS.md.
Documentation
Page | What it covers |
How an agent should work with the tools: working style, worked examples, the multi-agent contract, geometry rules, | |
The design record: what was built and why | |
The wire contract between bridge and plugin: bootstrap, ops, events, the | |
The in-Studio runtime that the bridge pushes on every connect | |
Install walkthrough with the reason behind each step | |
The | |
The | |
| |
Engine measurements on Studio 0.738 the design rests on | |
Acceptance-test results against a live Studio, defects found and fixed | |
Six agents building a playable game concurrently through the bridge | |
The architecture brief that preceded the build: what a connector can and cannot make fast |
Security
The bridge listens on 127.0.0.1 only and has no authentication: any process on your machine can drive Studio through it, and the plugin runs whatever bundle the bridge sends it. Only look (a screenshot to the Anthropic API) and cloud (your request to Open Cloud) leave the machine. API keys are read from the environment or ~/.studio-live, never returned by a tool, and masked in logs. Nothing saves or publishes a place on its own.
License
MIT. Not affiliated with Roblox Corporation.
This server cannot be deployed
Maintenance
Related MCP Connectors
Live browser debugging for AI assistants — DOM, console, network via MCP.
The OpenRouter MCP server plugs OpenRouter into the AI tools you already use. Once connected, your assistant can pull live OpenRouter data (models, prices, your credits, rankings, and docs) and send quick test messages, all without leaving your editor.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
- DazbenchOAuthapp.dazbench
Task management your AI agents can actually run. One line becomes a context-ready task over MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA production MCP integration that lets AI agents control Roblox Studio to autonomously build, test, and debug Roblox games. Provides 39 tools for explorer control, script management, terrain generation, and autonomous testing.1MIT
- AlicenseNot gradedqualityAmaintenanceEnables 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
- FlicenseNot gradedqualityAmaintenanceEnables AI agents to interact with Roblox Studio via a token-efficient MCP server, live two-way script sync, and zero-friction plugin setup.-
- AlicenseNot gradedqualityCmaintenanceAn MCP bridge that lets AI assistants control Roblox Studio 2021 in real time, offering tools for workspace inspection, instance creation, and Lua execution.12 npm1MIT