Skip to main content
RbxGenie is a bridge between AI coding assistants (Claude, Cursor, OpenCode) and Roblox Studio, enabling automated manipulation of Roblox game objects, scripts, and properties through a tool-based API.

System Architecture

RbxGenie consists of three main components that work together to enable AI-driven Roblox Studio automation:

MCP Server

Model Context Protocol adapter for AI assistants

Node.js Daemon

HTTP server with event-driven polling bridge

Studio Plugin

Roblox Lua plugin with tool executors

Data Flow

The complete request-response cycle follows this path:
1

AI Tool Call

AI assistant (Claude/Cursor) calls a tool like get_file_tree or set_property through the MCP protocol
2

MCP Translation

MCP server (mcp.ts) receives the tool call, validates arguments with Zod schemas, and forwards to the daemon via HTTP POST to http://127.0.0.1:7766/tool/{name}
3

Command Queueing

HTTP daemon (server.ts) receives the request, generates a UUID, and enqueues the command in the bridge (bridge.ts) with a 120-second timeout
4

Long Polling

Studio plugin polls GET /poll endpoint (15-second long poll). When a command is available, it’s dequeued and returned to the plugin
5

Tool Execution

Plugin’s Executor.lua dispatches the tool to the appropriate tool module (InstanceTools, PropertyTools, etc.) and executes it against the Roblox DataModel
6

Result Submission

Plugin posts the result or error back to POST /result with the command ID
7

Response Chain

Bridge resolves the promise, daemon returns JSON response, MCP server formats it for the AI assistant

Component Communication

HTTP Endpoints

The daemon exposes these endpoints on http://127.0.0.1:7766:
EndpointMethodPurposeUsed By
/healthGETHealth check and connection statusPlugin (connection loop)
/tool/:namePOSTSubmit a tool execution requestMCP server
/pollGETLong-poll for pending commands (15s timeout)Plugin (Bridge.lua)
/resultPOSTSubmit command result or errorPlugin (Bridge.lua)

Event-Driven Bridge

The bridge (bridge.ts:1) maintains an in-memory queue of pending commands:
interface PendingCommand {
  id: string;              // UUID
  tool: string;            // Tool name
  args: Record<string, unknown>;
  resolve: (value: unknown) => void;  // Promise resolver
  reject: (reason: any) => void;      // Promise rejector
  timer: NodeJS.Timeout;   // 120s timeout
  _dispatched?: boolean;   // Dequeue marker
}
The bridge uses an EventEmitter pattern with a "enqueued" event to wake up long-polling requests immediately when a new command arrives, avoiding the full 15-second wait.

Timeout Handling

RbxGenie implements a multi-layer timeout strategy:
120 seconds — Commands timeout if not completed within 2 minutesLocation: bridge.ts:15
const COMMAND_TIMEOUT_MS = 120_000;

Undo/Redo Support

Write operations (non-read-only tools) are automatically wrapped in Roblox ChangeHistoryService recordings:
-- bridge.ts:106-116
local recording = nil
if not READ_ONLY_TOOLS[tool] then
  recording = ChangeHistoryService:TryBeginRecording("RbxGenie: " .. tool)
end

local result, err = Executor.dispatch(tool, args)

if recording then
  ChangeHistoryService:FinishRecording(recording, Enum.FinishRecordingOperation.Commit)
end
All property changes, object creation, script edits, and other mutations can be undone with Ctrl+Z in Roblox Studio.

Error Handling

Errors are propagated through the entire chain:
  1. Tool execution error → Lua pcall catches it → Posted to /result with error field
  2. Path resolution error → Returned as structured error from PathResolver.resolve
  3. HTTP error → Daemon returns 500 with ok: false and error message
  4. Timeout → Bridge rejects promise with { error, timeout: true, timeoutMs }
  5. MCP error → Returned as { isError: true } response to AI

Performance Characteristics

Request Latency

Typical: 50-200ms for simple queries
Complex operations: 500ms-2s
Worst case: 120s (timeout)

Concurrency

Single-threaded command execution
One command at a time in Studio
Queue size: Unlimited (memory-bound)
The plugin executes commands sequentially. Multiple simultaneous tool calls from the AI will queue up and execute one at a time. The bridge’s in-memory queue is not persistent—restarting the daemon loses pending commands.

Security Model

  • Local-only: Daemon binds to 127.0.0.1 only (server.ts:108)
  • No authentication: Assumes single-user local development environment
  • Studio HttpService: Plugin requires HttpService enabled in Studio settings
  • Execution sandbox: Lua code runs in Studio’s edit-mode environment with full API access
The execute_luau tool can run arbitrary Lua code in Roblox Studio. Only use RbxGenie in trusted AI sessions. Do not expose the daemon to network access.

Next Steps

Node.js Daemon

Learn about the HTTP server and bridge implementation

Studio Plugin

Explore the Lua plugin architecture and tool executors

MCP Server

Understand the Model Context Protocol adapter

Build docs developers (and LLMs) love