Roblox Studio MCP
Provides tools to interact with Roblox Studio, including reading the instance tree, editing Luau scripts, setting properties, managing attributes and tags, creating objects, detecting drift, and syncing source files.
Click on "Install 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., "@Roblox Studio MCPlist all scripts in ServerScriptService"
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.
🎮 Roblox Studio MCP
Give your AI full access to Roblox Studio
Claude · Gemini · Codex · OpenCode · any MCP client
Quick Start · Studio CLI · Features · Tools · Client Setup · Docs
An MCP server that connects AI assistants directly to a running Roblox Studio session. Read the instance tree, edit Luau scripts, set properties, manage attributes & tags, create objects, detect drift, and sync source files — all over a 100% local connection that never leaves your machine.
Your AI MCP Server Studio Plugin
┌──────────┐ stdio ┌──────────────┐ HTTP ┌──────────────┐
│ Claude │◄──────────►│ Node.js │◄─────────►│ Luau │
│ Gemini │ │ port 3002 │ localhost │ polls every │
│ Codex │ │ │ │ 500ms │
└──────────┘ └──────┬───────┘ └──────────────┘
│
┌──────┴───────┐
│ Blueprint V1 │
│ Rojo sync │
└──────────────┘🤖 Using an AI Agent? (Claude Code, Cursor, etc.)
Let your AI agent set everything up for you!
Option 1: Copy-Paste This Prompt
Just copy and paste this to your AI agent:
Go to https://raw.githubusercontent.com/aaronaalmendarez/roblox-mcp/main/AGENT.md Read the entire file, then set up the Roblox Studio MCP on my machine. Follow all the installation steps in the "Complete Installation Guide" section.Your agent will handle cloning, building, configuring MCP, and setting up Blueprint V1 automatically.
Option 2: Manual
📋 View Raw (copy all)
Related MCP server: robloxstudio-mcp
🚀 Quick Start
1 → Install the Studio plugin (download .rbxmx) into your plugins folder
OS | Path |
Windows |
|
macOS |
|
2 → In Studio: Game Settings → Security → Allow HTTP Requests ✅
3 → Start the server:
# From this repo
npm install && npm run build
node dist/index.js4 → Configure your AI client (see Client Setup) — done!
npm run build:plugin
# Copy studio-plugin/MCPPlugin.rbxmx → plugins folder → restart Studio✨ Features
37+ MCP Tools
Category | What You Can Do | |
📂 | Instance Hierarchy | Browse game tree, search by name / class / content, list services |
📝 | Script Management | Read, write, line-edit Luau scripts with range support |
⚡ | Batch Editing | Atomic multi-op edits with SHA-256 hash checks + auto-rollback |
🔩 | Properties | Get/set any property, mass ops, formula & relative calculations |
🏗️ | Object Lifecycle | Create, delete, smart-duplicate with offset grids & variations |
🏷️ | Attributes & Tags | Full CRUD for attributes + CollectionService tags |
🩺 | Diagnostics | Drift detection, deprecated API lint, health endpoints, telemetry |
💾 | Snapshots | In-memory script snapshots with instant rollback |
IDE-First Sync
Blueprint V1 — Rojo-based multi-place source control
Bi-directional — push local files to Studio or pull Studio changes back
Conflict-safe — hash-based guards prevent accidental overwrites
Drift detection — know exactly when local and Studio have diverged
Built for Reliability
Optimistic concurrency via SHA-256 source hashes
Write idempotency — replay-safe with
X-Idempotency-KeyChunked script uploads for very large rewrites that exceed single MCP payload limits
Safe bridge fallback for script writes instead of
set_propertyonSourceFull-source reads for large scripts automatically avoid truncated plugin responses
Smart plugin polling: hot → active → idle intervals
Drift checks ignore formatting-only differences by default and report both raw and normalized hashes
Atomic apply → verify → rollback pipeline
🎨 The Studio CLI
One command to rule them all. A zero-dependency, cross-terminal orchestrator for your entire Roblox workflow.
____ ____ ____________ ______________ _____
/ __ \/ __ )/ ____/ __ \/ _/ ____/ __ \/ ___/
/ /_/ / __ / / / / / // // / / / / /\__ \
/ _, _/ /_/ / /___/ /_/ // // /___/ /_/ /___/ /
/_/ |_/_____/\____/_____/___/\____/_____//____/# One command starts everything
npm run studio -- dev
# Or pick your services
npm run studio -- mcp # MCP server only
npm run studio -- serve # Rojo server only
npm run studio -- dev --verbose # See all process outputWhat it does
Feature | Description |
Process Orchestration | Spawns MCP + Rojo + Watchers + Reverse Sync with a single command |
PID Tracking | Every process gets a PID file in |
Cross-Platform Kill |
|
Log Capture | Background processes write timestamped logs to |
Health Checks | Auto-verifies MCP (HTTP) and Rojo (TCP socket) before reporting "ready" |
Place Context | Auto-resolves active place, detected Studio place, or legacy fallback |
Beautiful UI | ANSI boxes, spinners, tables, and status indicators — works in any terminal |
Commands
studio dev # Full environment (MCP + Rojo + Watch + Reverse)
studio serve # Rojo server only
studio mcp # MCP server only
studio sync # Blueprint property sync once
studio watch # Property file watcher
studio build # Build .rbxl via Rojo
studio lint # Luau lint
studio place list # Places table with active marker
studio place status # Resolved context box
studio place use <key> # Switch active place
studio place detect # Auto-register current Studio place
studio status # System dashboard with health checks
studio stop [name] # Kill tracked process(es)
studio transcribe # Whisper transcription
studio doctor # Blueprint doctor
studio version # Version + logoGlobal Flags
--place <key> # Target place (slug / id / name)
--verbose # Show process output
--json # Machine-readable output
--dry-run # Preview changes without applying🆕 Recent Reliability Fixes
Large script reads are no longer silently truncated — full-source reads now return the complete script even when the plugin would otherwise cap the response to the first 1000 lines.
Formatting-only drift no longer shows up as content drift —
check_script_driftnow normalizes line endings, BOM, trailing whitespace, and trailing final newlines by default.Drift output is more explicit — diagnostics now include
comparisonMode,formattingOnly,formattingDifferences, raw hashes/lengths, and normalized hashes/lengths.Large script writes now have a safe transport — use the chunked upload tools or
scripts/push-script-fast.mjsfor large files; they commit through the plugin bridge andUpdateSourceAsyncinstead ofset_property.Sourcewrites no longer go through property tools —set_propertyandmass_set_propertynow reject theSourceproperty so escape sequences are not corrupted.Server and plugin defaults are aligned around port
3002— current builds start on3002first and keep58741only as a legacy fallback.
Example of the expected healthy case:
{
"status": "in-sync",
"comparisonMode": "canonical-text",
"formattingOnly": true,
"formattingDifferences": ["trailing-newline"],
"rawLocalLength": 74884,
"rawStudioLength": 74883,
"normalizedLocalLength": 74883,
"normalizedStudioLength": 74883
}This means the raw bytes differ, but the actual script content is the same.
A real healthy verification case now looks like this:
Full source read:
localLength: 74883,studioLength: 74883Raw bytes can still differ by one trailing newline:
rawLocalLength: 74884,rawStudioLength: 74883Normalized hashes then match, so the result is correctly reported as
in-syncThe result includes
comparisonMode,formattingOnly,formattingDifferences, and raw vs normalized hashes/lengths
🔧 Tool Reference
Tool | Description |
| Instance hierarchy as a tree |
| Search by name, class, or script content |
| List Roblox services and children |
| Find by name, class, or property |
| Full game hierarchy (configurable depth) |
| Children + class types |
| Properties/methods for any class |
| Place ID, name, game settings |
| Currently selected objects |
Tool | Description |
| Read source (optional line range, full reads safe for large scripts) |
| Source + SHA-256 hash with full-source recovery |
| Full rewrite (editor-safe; use chunked upload for very large files) |
| Start chunked upload session for large files |
| Append one chunk to an upload session |
| Commit an uploaded script through the plugin bridge |
| Discard an upload session without writing |
| Write only if hash matches |
| Fast write with safe bridge fallback |
| Gzip-compressed fast write |
| Replace line ranges |
| Insert at position |
| Delete line ranges |
| Atomic multi-edit + rollback |
| Apply → verify → rollback pipeline |
Tool | Description |
| In-memory rollback point |
| List session snapshots |
| Restore from snapshot |
| Cancel queued writes |
Tool | Description |
| All properties of an instance |
| Set any property except |
| Set on multiple instances except |
| Read from multiple instances |
| Find by property value |
| Formula-based property sets |
| Relative modifications |
| Create instance |
| Create with initial props |
| Batch create |
| Batch create with props |
| Delete instance |
| Smart dup with offsets & variations |
| Multiple smart dups at once |
Tool | Description |
| Read/write single attribute |
| All attributes on instance |
| Remove attribute |
| CollectionService tags |
| Add or remove tag |
| All instances with a tag |
Tool | Description |
| Write queue + bridge telemetry |
| Full diagnostic report |
| Local vs Studio drift check with formatting normalization and raw/normalized diagnostics |
| Deprecated API scanner |
🔌 Client Setup
All configs point to the local build. Replace the path with your actual install location.
claude mcp add robloxstudio -- node /path/to/roblox-mcp/dist/index.jsgemini mcp add robloxstudio node --trust -- /path/to/roblox-mcp/dist/index.js{
"mcpServers": {
"robloxstudio-mcp": {
"command": "node",
"args": ["/path/to/roblox-mcp/dist/index.js"]
}
}
}~/.codex/config.toml:
[mcp_servers.robloxstudio]
command = "node"
args = ["/path/to/roblox-mcp/dist/index.js"]~/.config/opencode/opencode.json:
{
"mcp": {
"robloxstudio": {
"type": "local",
"enabled": true,
"command": ["node", "/path/to/roblox-mcp/dist/index.js"]
}
}
}If using the published package instead of a local build:
npx -y @aaronalm19/roblox-mcp@latestFull reference with Windows fallbacks: docs/CLIENTS.md
📘 Blueprint V1
IDE-first source control built on Rojo with multi-place support.
blueprint-v1/
├── places/
│ ├── registry.json # Place ID → slug
│ ├── .active-place.json # Active context
│ └── <slug>/
│ ├── default.project.json
│ ├── src/ # Luau source
│ └── properties/
│ └── instances.json # Non-script props
└── src/ # Legacy fallbacknpm run place:detect # Auto-detect Studio place
npm run place:list # List registered places
npm run blueprint:sync # Property sync → Studio
npm run blueprint:watch # Continuous sync
npm run blueprint:reverse-sync # Pull Studio → local
npm run drift:check # Detect file divergence
npm run luau:lint # Static analysis (requires luau-lsp, see below)Luau Lint Setup (luau-lsp)
npm run luau:lint uses luau-lsp which ships full Roblox type stubs — Player, BasePart, Vector3, RemoteEvent, etc. all resolve correctly under --!strict.
One-time setup:
Option A — use the bundled binary (already in this repo, v1.63.0 Windows x64):
Expand-Archive tools\luau-lsp\luau-lsp-win64.zip -DestinationPath .tools\luau-lsp -ForceOption B — download the latest release for your platform:
Download
luau-lsp-win64.zip(Windows),luau-lsp-macos.zip(macOS), orluau-lsp-linux.zip(Linux)Extract
luau-lsp[.exe]→.tools/luau-lsp/luau-lsp.exe
Then generate the Rojo sourcemap:
rojo sourcemap blueprint-v1/places/<slug>/default.project.json --output sourcemap.jsonRun:
npm run luau:lint # findings=0 is the goal
npm run luau:lint:strict # exits non-zero if any findings (use in CI)Expected clean output:
[context] Place1 (125175608517936) [place1-2]
[luau-lint] files=4 analyzer=.tools/luau-lsp/luau-lsp.exe
[luau-lint] sourcemap=sourcemap.json
[luau-lint] findings=0Deep dive: docs/BLUEPRINT_V1.md
📋 Blueprint Operator Playbook
Everything below is the strict operational guide for working with Blueprint V1. Follow these steps exactly.
1. Canonical Windows Flow (copy-paste)
Open a terminal in the repo root and run each step in order:
# Step 1 — Detect the place open in Studio and register it
npm run place:detect
# Step 2 — Confirm resolved paths
npm run place:status
# Step 3 — Start Rojo against the resolved project
rojo serve blueprint-v1/places/<slug>/default.project.json
# Step 4 — Start continuous property sync (separate terminal)
npm run blueprint:watch
# Step 5 — Start reverse sync guard (separate terminal)
npm run blueprint:reverse-syncOr use the one-command launcher that does steps 3-5 automatically:
npm run studio -- dev --place <slug>Or the legacy orchestrator:
npm run dev:studio -- --place <slug>This resolves the existing place context, then spawns the MCP server, Rojo, property watcher, and reverse-sync in parallel. It does not run
place:detect— you must register the place first. PressCtrl+Cto stop all.
2. Required Tooling Install Matrix
Tool | Required | Install (Windows) |
Node.js ≥ 18 | ✅ Yes |
|
Rojo | ✅ Yes (for script sync) |
|
Luau CLI | Optional (for lint) |
|
Node.js: Download the
.msiinstaller from nodejs.org/en/downloadRojo: Download
rojo.exefrom GitHub releases, place in a folder on yourPATHLuau:
npm run luau:installhandles this — it downloads the correct binary for your OS into.tools/
3. Expected Success Output Per Step
npm run place:detect
✔ Detected place: Place2 (136131439760483)
✔ Registered slug: place2
✔ Set as active placenpm run place:status
Mode: place
Place: Place2 (136131439760483)
Slug: place2
Project: blueprint-v1/places/place2/default.project.json
Source: blueprint-v1/places/place2/src
Properties: blueprint-v1/places/place2/properties/instances.jsonrojo serve ...
Rojo server listening on port 34872http://localhost:3002/health
{
"pluginConnected": true,
"mcpServerActive": true,
"plugin": { "version": "1.10.0" }
}npm run blueprint:reverse-sync
Reverse sync active. Tracked scripts: 3
Polling every 2000ms...If any output differs from the above, stop and consult the Troubleshooting table.
4. Source of Truth Rules
Situation | Who Wins | Action |
You edited a | Local wins | Rojo pushes to Studio automatically |
You edited a script inside Studio | Studio wins | Run |
Both sides changed the same script | Neither — conflict | A conflict snapshot folder is written; you manually merge |
Non-script property changed in Studio | Studio wins | No automated pull — manually update |
Non-script property changed in | Local wins | Run |
You aren't sure what changed | Check first | Run |
Golden rule: Edit scripts in your IDE (Rojo syncs them). Edit non-script properties via instances.json. Only reverse-sync when you intentionally made Studio-side script changes.
5. File Naming & Path Mapping
Rojo uses file suffixes to determine the script type and instance name:
File Suffix | Script Type | Instance Name |
|
| Filename without suffix |
|
| Filename without suffix |
|
| Filename without suffix |
|
| Full filename |
Path resolution example:
File: blueprint-v1/places/place2/src/ServerScriptService/HorrorMain.server.luau
Instance: game.ServerScriptService.HorrorMain (Script)
File: blueprint-v1/places/place2/src/StarterPlayer/StarterPlayerScripts/HorrorClient.client.luau
Instance: game.StarterPlayer.StarterPlayerScripts.HorrorClient (LocalScript)
File: blueprint-v1/places/place2/src/ReplicatedStorage/HorrorConfig.module.luau
Instance: game.ReplicatedStorage.HorrorConfig (ModuleScript)The directory path under
src/maps directly to the Roblox service hierarchy. Thedefault.project.jsondefines which directories map to which services.
6. Conflict Handling
When reverse-sync detects both local and Studio changed the same script, it writes a conflict snapshot folder instead of overwriting:
blueprint-v1/places/<slug>/.reverse-sync-conflicts/
└── ServerScriptService/
└── HorrorMain.server.luau/
├── local.luau # Your local version at time of conflict
├── studio.luau # The Studio version that diverged
└── meta.json # Timestamps, hashes, instance pathRecovery workflow:
Open the conflict folder (e.g.
.reverse-sync-conflicts/ServerScriptService/HorrorMain.server.luau/)Compare
local.luau(your version) vsstudio.luau(Studio's version)Manually merge the changes into the original
.luaufile insrc/Delete the conflict folder
Run
npm run blueprint:reverse-syncagain — it will re-baseline from the merged file
State tracking: Each tracked script's hashes are stored in:
blueprint-v1/places/<slug>/.reverse-sync-state.jsonThis file contains lastLocalHash and lastStudioHash per script. If you need to force a full re-sync, delete this file and restart reverse-sync.
7. Common Failures & Fixes
Failure | Cause | Fix |
Place resolves wrong slug |
|
|
| Rojo not installed or not on PATH | Install via |
Module path mismatch | File in wrong | Match directory to Roblox service name exactly |
HTTP 403 from plugin | HTTP requests disabled in Studio | Game Settings → Security → Allow HTTP Requests |
Stale | Switched Studio places without re-detecting |
|
| MCP server not running |
|
Reverse-sync shows 0 tracked | No scripts match Rojo mappings | Verify files exist in resolved |
Rojo sync not updating Studio | Rojo serving wrong project file | Check |
Lint says "luau-analyze not found" | Luau CLI not installed |
|
| Server or plugin not connected | Start server, open Studio, enable plugin |
8. One-Command Dev Launcher
The Studio CLI is the recommended daily driver:
npm run studio -- dev --place place2Or use the legacy orchestrator:
npm run dev:studio -- --place place2Both start all four services in parallel:
Service | What It Does |
MCP server |
|
Rojo |
|
Property watcher | Continuous |
Reverse sync | Guarded Studio → local pull |
The CLI adds PID tracking, health checks, log capture, and a beautiful terminal UI:
✓ Resolved: Place2 [place2]
✓ MCP server listening on port 3002
✓ Rojo server listening on port 34872
✓ Property watcher active
✓ Reverse sync active
┌─────────────────────────────────────────────────────────────────────────┐
│ Dev Environment │
│ Project: blueprint-v1\places\place2\default.project.json │
│ Mode: place │
│ Studio: ● Press Ctrl+C to stop all │
└─────────────────────────────────────────────────────────────────────────┘CLI flags:
--no-rojo,--no-watch,--no-reverseto disable individual services.--verboseto see process output.
9. Blueprint Scope Boundaries
Blueprint separates concerns cleanly between two systems:
What | Managed By | Files |
Scripts (Luau code) | Rojo |
|
Non-script properties (Position, Size, Color, etc.) | Sync scripts |
|
Attributes | Sync scripts |
|
Tags | Sync scripts |
|
Instance creation / hierarchy | Rojo (via |
|
Do NOT:
Edit
.luaufiles throughinstances.json— Rojo handles scriptsCreate new services by adding directories without updating
default.project.jsonMix legacy
blueprint-v1/src/with place-specificblueprint-v1/places/<slug>/src/
10. Example: Horror Game (place2)
A complete real-world place from this repository:
blueprint-v1/places/place2/
├── default.project.json # Rojo project mapping 12 services
├── .reverse-sync-state.json # Tracks 3 scripts with SHA-256 hashes
├── .reverse-sync-conflicts/ # Empty (no conflicts currently)
├── src/
│ ├── ServerScriptService/
│ │ └── HorrorMain.server.luau # → game.ServerScriptService.HorrorMain (Script)
│ ├── ReplicatedStorage/
│ │ └── HorrorConfig.module.luau # → game.ReplicatedStorage.HorrorConfig (ModuleScript)
│ └── StarterPlayer/
│ └── StarterPlayerScripts/
│ └── HorrorClient.client.luau # → game.StarterPlayer.StarterPlayerScripts.HorrorClient (LocalScript)
└── properties/
├── instances.json # Non-script property manifest (empty for now)
└── schema.json # Property schema definitionsRegistry entry (blueprint-v1/places/registry.json):
{
"136131439760483": {
"placeId": 136131439760483,
"gameId": 9708597637,
"slug": "place2",
"displayName": "Place2"
}
}Full workflow for this place:
# One-time: detect and register
npm run place:detect
# → ✔ Detected place: Place2 (136131439760483), slug: place2
# Daily: start everything
npm run studio -- dev --place place2
# → MCP server, Rojo, property watcher, and reverse sync all running
# Or the legacy orchestrator:
npm run dev:studio -- --place place2
# Or manually:
rojo serve blueprint-v1/places/place2/default.project.json
npm run blueprint:watch
npm run blueprint:reverse-sync🛠️ Development
npm install # Dependencies
npm run build # TypeScript → dist/
npm run build:plugin # Build .rbxmx plugin
npm run dev # Dev server (tsx hot reload)
npm run typecheck # Type-check
npm test # Jest suite
npm run test:all # Jest + Luau E2EVerify Connection
curl http://localhost:3002/health
curl http://localhost:3002/diagnosticsProject Layout
├── src/ # TypeScript MCP server
│ ├── index.ts # Tool definitions + handler
│ ├── http-server.ts # Express bridge (:3002)
│ ├── bridge-service.ts # Plugin comms
│ └── tools/ # Tool implementations
├── studio-plugin/ # Luau Studio plugin
├── blueprint-v1/ # Rojo projects + sync state
├── scripts/ # 20+ CLI helpers
├── tests/ # Jest + Luau E2E
└── docs/ # Additional docs🔒 Security
Local-only | All traffic stays on |
No telemetry | Zero data collection — your projects are private |
Explicit | Tools only run when your AI invokes them |
Separated | Read and write operations are distinct |
❓ Troubleshooting
Problem | Fix |
Plugin missing |
|
HTTP 403 | Game Settings → Security → Allow HTTP Requests |
Disconnected | Start the MCP server — red is normal until then |
No tools | Restart MCP client + Studio, check |
Slow or large writes | Use chunked upload tools or |
Firewall | Allow |
📚 Docs
Setup for every MCP client | |
Multi-place sync deep dive | |
Detailed plugin setup |
🤝 Contributing
git clone https://github.com/aaronaalmendarez/roblox-mcp.git
cd roblox-mcp
npm install
npm run devIssues and PRs welcome on GitHub.
🙏 Acknowledgements
Original project: boshyxd/robloxstudio-mcp
This fork extends that foundation for multi-agent workflows, local blueprint-first development, and enhanced tooling.
MIT License © 2025
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/aaronaalmendarez/roblox-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server