关于 Studio Sidecar
Studio Sidecar 是 Roblox Studio 内置 MCP 的补充服务,面向需要管理 Studio 进程、限制写入范围或操作 Open Cloud 资产的开发者。它把 PlaceId 写入保护、安全执行 Luau 与资产上传更新等能力集中为额外工具,不重复实现内置服务已有的编辑功能。
主要功能
- 01查看 Studio 进程与 MCP broker
- 02打开尚未打开的 place
- 03按 PlaceId 保护写入
- 04安全执行 Luau 并提取脚本
- 05通过 Open Cloud 上传、更新和归档资产
适用场景
- 01启动指定 Roblox place
- 02降低写入错误游戏的风险
- 03读取超过输出限制的脚本
- 04管理 Roblox Open Cloud 资产
MCP 相关
Studio Sidecar 本身是 MCP 服务,也会作为 MCP 客户端启动并连接 Roblox Studio 的内置 `StudioMCP`,借用其 `execute_luau` 能力。它为 MCP 客户端提供 11 个补充工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @gjlmotea/studio-sidecar-mcpROBLOX_API_KEY密钥Open Cloud API key with Asset read and write; only the four Open Cloud tools need itROBLOX_CREATOR_USER_IDRoblox user ID recorded as the creator of uploaded assetsROBLOX_UPLOAD_ROOTFolders that uploads may read from, joined with the platform path delimiter: ';' on Windows (C:\assets\models;D:\decals), ':' on macOS (/Users/you/models:/Volumes/art/decals). Uploads are refused when unsetROBLOX_STUDIO_PATHRoblox Studio executable; resolved automatically when unset本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Studio Sidecar — Roblox Studio 的配套 MCP 服务
English | 繁體中文

Studio Sidecar 用于弥补 Roblox Studio 内置 MCP 服务的不足,而非取而代之。
从 2026 年起,Roblox Studio 自带 MCP 服务(StudioMCP,随 Studio 安装,使用 stdio 传输),而独立的 Roblox/studio-rust-mcp-server 仓库已归档。内置服务提供第三方无法重新实现的工具:generate_mesh、generate_material 和 generate_procedural_model 使用 Roblox 云端 AI 并进行内容审核;search_asset、insert_asset 和 upload_image 使用你的登录账户库存权限;user_keyboard_input 和 user_mouse_input 则通过 CreateVirtualInput 执行。取而代之会失去所有这些功能。
因此,Studio Sidecar 只添加内置服务在结构上无法实现的功能,其余一切仍交由内置服务处理:
- 打开尚未打开的场景,并查看计算机上的所有 Studio 进程及 StudioMCP broker/stub。
- 按 PlaceId 防护写入操作,运行 Luau 并将运行时错误作为易读的值返回,且绝不截断输出;还可提取超过 100k 输出限制的脚本,并进行逐字节精确验证。
- 通过 Roblox Open Cloud 上传、更新和归档资源,并在更新被静默去重时明确给出判定。
无需 Studio 插件。共 11 个工具;Windows 已全面验证,macOS 部分验证(参见平台支持)。
目录
工具
| 工具 | 内置服务无法实现的原因 |
|---|---|
roblox_get_status | 显示是否已配置 Open Cloud,以及上传操作可能读取哪些文件夹 |
roblox_list_studios | 内置服务运行在单个 Studio 进程中;无法查看其他 Studio 进程或 StudioMCP broker/stub 结构 |
roblox_open_place | 打开尚未打开的场景属于操作系统任务:需要创建新的同级进程 |
roblox_cleanup_stubs | 原因相同;默认仅报告,只有设置 apply=true 时才会终止 stub,绝不会终止 broker |
roblox_place_guard | 内置的 multi_edit 按路径写入;错误的 studio_id 会静默覆盖其他游戏,且没有撤销或警告 |
roblox_luau_safe | 内置的 execute_luau 不检查 PlaceId,并会在输出超过 100k 个字符后静默截断 |
roblox_extract_place | 没有工具处理 100k 截断边界:分块、哨兵和逐文件字节检查都留给调用方处理;处理不当也不会报错 |
roblox_get_asset | 内置的 search_asset 将持有者报告为 creatorId,而非作者 |
roblox_upload_asset | 在 Studio 中调用 AssetService:CreateAssetAsync 目前总是抛出 not available yet |
roblox_update_asset | CreateAssetVersionAsync 也因相同原因不可用 |
roblox_archive_asset | 内置服务没有 Open Cloud 接口 |
刻意不包含:脚本读取和写入、场景查询、execute_luau、screen_capture、游戏测试。内置服务已提供这些功能,另行实现只会逐渐产生偏差。
Luau 在 Studio 端的运行方式
MCP 进程可以同时充当服务端和客户端。Studio Sidecar 会将 StudioMCP 作为独立子进程启动,并以 MCP 客户端的身份连接它,从而获得内置的 execute_luau。分块、哨兵和字节检查机制随后会被封装成单个工具。客户端正常关闭时,子进程也会随之退出,因此这条路径不会留下存根。
启动 StudioMCP 时,Studio Sidecar 使用的启动器与 Roblox 设置指南中的相同。在 Windows 上,它会通过 cmd.exe /c 运行 %LOCALAPPDATA%\Roblox\mcp.bat;如果找不到 mcp.bat,则会回退到 %LOCALAPPDATA%\Roblox\Versions\ 下最近修改的 StudioMCP.exe。在 macOS 上,它会使用 /Applications 或 ~/Applications 中 RobloxStudio.app 里的 StudioMCP。
快速开始
要求:已开启 Enable Studio as MCP server 的 Roblox Studio(在 Studio 中:Assistant → … → Manage MCP Servers),以及 Node.js 22 或更高版本。
将 Studio Sidecar 注册到你的 AI 客户端。Claude Code:
claude mcp add studio-sidecar --scope user \
-e ROBLOX_API_KEY="<your Open Cloud API key>" \
-e ROBLOX_CREATOR_USER_ID="<your Roblox user ID>" \
-e ROBLOX_UPLOAD_ROOT="<folder that uploads may read from>" \
-- npx -y @gjlmotea/studio-sidecar-mcp
读取 mcpServers JSON 配置的客户端(Claude Desktop、Cursor、Gemini CLI):
{
"mcpServers": {
"studio-sidecar": {
"command": "npx",
"args": ["-y", "@gjlmotea/studio-sidecar-mcp"],
"env": {
"ROBLOX_API_KEY": "<your Open Cloud API key>",
"ROBLOX_CREATOR_USER_ID": "<your Roblox user ID>",
"ROBLOX_UPLOAD_ROOT": "<folder that uploads may read from>"
}
}
}
}
VS Code 使用顶层 servers 键,并且每个服务都需要一个 type。输入变量可避免将密钥写入文件:服务首次启动时,VS Code 会询问密钥并安全地存储它。
{
"inputs": [
{
"type": "promptString",
"id": "roblox-api-key",
"description": "Roblox Open Cloud API key",
"password": true
}
],
"servers": {
"studio-sidecar": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@gjlmotea/studio-sidecar-mcp"],
"env": {
"ROBLOX_API_KEY": "${input:roblox-api-key}",
"ROBLOX_CREATOR_USER_ID": "<your Roblox user ID>",
"ROBLOX_UPLOAD_ROOT": "<folder that uploads may read from>"
}
}
}
}
各客户端的配置文件位置:
| 客户端 | 配置文件 |
|---|---|
| Claude Desktop | macOS:~/Library/Application Support/Claude/claude_desktop_config.json;Windows:%APPDATA%\Claude\claude_desktop_config.json。通过 Settings → Developer → Edit Config 打开 |
| Cursor | 每个项目的 ~/.cursor/mcp.json,或单个项目中的 .cursor/mcp.json |
| Gemini CLI | ~/.gemini/settings.json(用户级),.gemini/settings.json(项目级) |
| VS Code | 工作区中的 .vscode/mcp.json,或通过 MCP: Open User Configuration 命令打开的用户 mcp.json |
来源:Claude Desktop、Cursor、Gemini CLI、VS Code。
这三个变量都是可选的:未提供密钥时,四个 Open Cloud 工具会拒绝执行;未设置 ROBLOX_UPLOAD_ROOT 时,所有上传都会被拒绝;其他工具照常工作。请勿将密钥放入任何受版本控制追踪的配置文件中。
还需注册 Studio 的内置 MCP 服务;脚本编辑、截图和游戏测试功能都在其中。各平台的启动命令——macOS 上的 StudioMCP 和 Windows 上的 cmd.exe /c %LOCALAPPDATA%\Roblox\mcp.bat——来自 Roblox 的设置指南。
macOS:
claude mcp add roblox-studio --scope user -- /Applications/RobloxStudio.app/Contents/MacOS/StudioMCP
Windows:
claude mcp add roblox-studio --scope user -- cmd.exe /c "%LOCALAPPDATA%\Roblox\mcp.bat"
在 JSON 配置中,macOS 条目为 "command": "/Applications/RobloxStudio.app/Contents/MacOS/StudioMCP";Windows 条目为 "command": "cmd.exe",并使用 "args": ["/c", "%LOCALAPPDATA%\\Roblox\\mcp.bat"]。在 Windows 上应注册 mcp.bat,而不是 StudioMCP.exe:mcp.bat 的路径固定,而 StudioMCP.exe 位于 %LOCALAPPDATA%\Roblox\Versions\version-<hash>\ 中,该文件夹会随着 Studio 更新而变化。
注册后重启会话,然后调用 roblox_get_status,并检查 openCloudConfigured 和 allowedUploadRoots。
从 Finder 或“开始”菜单启动的桌面应用通常无法读取 shell 的 PATH;如果服务无法启动,请使用 npx 的绝对路径(或从源代码运行时使用 node 的绝对路径)。
从源代码运行
git clone https://github.com/gjlmotea/studio-sidecar-mcp.git
cd studio-sidecar-mcp
corepack pnpm install --frozen-lockfile
corepack pnpm run build
claude mcp add studio-sidecar --scope user -- "$(which node)" "$PWD/dist/index.js"
请像上文一样使用绝对路径注册,而不要手写指向项目文件夹的 .mcp.json。Claude Code 会在服务的环境中设置 CLAUDE_PROJECT_DIR,而不是在自身环境中设置,因此 .mcp.json 条目或 ~/.claude.json 中本地或用户范围条目的 command 或 args 中若引用 ${CLAUDE_PROJECT_DIR},就需要设置默认值,例如 ${CLAUDE_PROJECT_DIR:-.}。如果没有默认值,该条目仍会加载,claude mcp list 会显示缺少变量的警告,并且会原样使用未展开的 ${CLAUDE_PROJECT_DIR} 文本。.mcp.json 中项目范围的服务也需要审批:交互式会话会在使用前询问,而 claude -p 运行、Agent SDK 会话和云会话则会直接加载,不会询问。请参阅 Claude Code MCP 文档。
配置
| 变量 | 用途 |
|---|---|
ROBLOX_API_KEY | 具有资产读取和写入权限的 Open Cloud API 密钥(Creator Dashboard → Open Cloud API Keys) |
ROBLOX_CREATOR_USER_ID | 上传时记录在 creationContext 中的创建者 |
ROBLOX_UPLOAD_ROOT | 允许上传读取的文件夹。可以指定多个文件夹,并使用平台的路径分隔符连接:Windows 上为 ;(C:\assets\models;D:\decals),macOS 上为 :(/Users/you/models:/Volumes/art/decals)。未设置时,所有上传都会被拒绝 |
ROBLOX_STUDIO_PATH | Studio 可执行文件;未设置时,会根据当前安装自动解析 |
ROBLOX_UPLOAD_ROOT 是一项有意设置的安全防护:上传会将本地文件发送到外部服务,而对于 Models,此操作无法撤销,因此 MCP 客户端不能随意选择文件路径。比较之前,文件和允许的文件夹都会通过 realpath 解析,因此允许文件夹内的符号链接无法将上传指向其他位置。文件只会打开一次,并通过该打开句柄再次检查(仍在允许的文件夹内,且仍是同一个文件);发送的数据也从该句柄读取,因此检查后替换路径不会造成影响。存在多个硬链接的文件会被拒绝,因为允许文件夹内的硬链接可能指向同一卷上其他位置的文件;请改为上传副本。
这些工具所了解、但内置服务不会告知的内容
以下情况都在真实硬件上发现,并配有回归测试。
启动意图的引号处理会静默失败。 Studio 需要 -launchIntentString "{\"task\":\"EditPlace\",\"universeid\":\"…\",\"placeid\":\"…\"}"。未转义的引号会被 Windows 命令行解析器移除,Studio 收到损坏的 JSON 后会忽略该意图,并在没有报错的情况下打开空会话。唯一的线索是窗口标题显示 Roblox Studio,而不是 <place name> - Roblox Studio。Studio Sidecar 会将参数作为数组传递给 spawn,从而使 CommandLineToArgvW 规则可供测试。universeid 对应 scene/place.json 中的 gameId。
绝不要抢占窗口焦点。 调用 SetForegroundWindow 两秒后,Studio 中的一次意外按键关闭了刚刚加载的 place。roblox_open_place 只会轮询 broker 连接和进程标题。
不得终止 broker,且其身份会变化。 StudioMCP 由一个 broker 和每个客户端各自的一个 stub 组成;第一个 broker 在 127.0.0.1:13469 上监听,Studio 本身和每个 stub 都会连接到它。终止 broker 会断开所有连接,包括 Studio 的连接。broker 角色也会随时间转移到其他进程,因此始终通过“在 13469 端口上监听的进程”来识别 broker,而不是依赖已记录的 PID。无法识别 broker 时,roblox_cleanup_stubs 会放弃清理。由于某些客户端退出时不会回收 stub(参见 openai/codex#25893),stub 会不断累积;设置时长阈值可避免清理可能仍在运行的会话。
**更新是否成功取决于 revisionId,而不是 HTTP 状态。**使用 PATCH 更新资源时,如果内容的字节完全相同,会返回 HTTP 200、done: true 且没有错误,但 revisionId 不会变化:内容已被去重。roblox_update_asset 会比较更新前后的 revisionId,并报告 updated、deduplicated 或 indeterminate。即使 revisionId 增大,也不能保证 Studio 会看到新内容;Open Cloud 无法确认 Studio 端的缓存情况。要替换内容,请勿发送 updateMask(updateMask=fileContent 会因 Unknown field file_content 而失败);它仅用于元数据更改。
**100k 字符截断是 StudioMCP 本身造成的。**直接对 StudioMCP 进行测量:100,000 个字符的回复会完整返回;120,000 个字符的回复则会在 100,015 个字符处截断,并以 ... (truncated) 结尾。任何客户端都无法解除这一限制。因此,roblox_extract_place 使用了三项缺一不可的保障措施:
- 每个分块末尾都带有一个哨兵标记;没有该标记的分块会被视为不完整。仅凭长度无法判断回复是完整还是已截断。
- UTF-8 安全截断位置由 Lua 决定并返回,调用方从该位置继续,因此双方不会分别计算边界。
- 对每个文件进行字节数检查(使用
Buffer.byteLength,而不是String.length)。任何不匹配都会中止整个提取,因为部分正确的快照看起来像是成功了。
每次调用都会将数据暂存到自己的键下:shared.RBXEXTRACT_<32 hex digits>(仅存在于 Lua VM 内存中,绝不会写入 DataModel 或 .rbxl),完成后会清除,因此重叠的调用绝不会读取彼此的数据。如果清除失败,下一个连接到同一 Studio 的调用会再次清除,最多总共尝试三次。每个键还会记录上次使用时间;每个新键都会先清除闲置超过 15 分钟的任何键,因此,因释放失败、关闭或崩溃而遗留的键,会在下次调用该 Studio 时清除。关闭期间,服务端绝不会仅为清理而重新连接到 Studio。
实例名称几乎可以是任何内容,包括 ..、路径分隔符和 CON 或 NUL 等 Windows 设备名称,因此每个路径段都会经过清理。在所有平台上,设备名称都会在末尾加上 _(CON 会变成 CON_.server.luau),因此在 macOS 上生成的快照也能在 Windows 上打开;写入前还会检查最终路径是否位于输出文件夹内。
整个新快照首先会写入提取过程在输出文件夹内新建的目录(.studio-sidecar-staging-<random>)。只有所有文件都写入后,才会开始切换:将上一个快照的文件移到一旁,再通过硬链接将新文件放到位;如果文件名已被占用,硬链接操作会失败(对于不支持硬链接的文件系统,则使用排他创建)。如果切换期间发生任何错误,新文件会被移除,并将上一个快照移回,因此失败的运行会保留原先的快照。同一文件夹中的提取操作会依次运行。若运行中途被终止,可能会遗留 .studio-sidecar-staging-* 文件夹;其中只包含快照文件,可以安全删除。
绝不会覆盖任何内容。如果名称已被占用,包括文件系统视为相同的名称(不区分大小写的卷上的 Σ、ς 和 σ),脚本会使用下一个 ~n 后缀,而 scene/scripts.json 会记录实际写入的路径。重新提取到同一文件夹时,只会替换该文件夹先前的 scene/scripts.json 中列出的文件;如果文件夹中的 scene/ 文件并非由 Studio Sidecar 写入,则会拒绝操作。如果其中某个文件已变成硬链接,只会移除该名称,另一个名称下的内容保持不变。
Studio 桥接必须与服务具有相同的生命周期。 每次调用后都关闭它,会导致首次调用成功,之后的调用均失败,并提示“现在无法连接到 Roblox Studio”,让人误以为 Studio 已关闭。其实并非如此:关闭桥接会终止存根,下一次调用便会与代理程序发生竞争。同一条消息也会在冷启动期间出现——新的存根尚未连接到代理程序时就是如此。因此,桥接会在收到这条消息时重试获取 Studio 列表,但只会针对这条消息重试,最多等待 20 秒;每次尝试间隔增加 250 毫秒,最长为 1.5 秒。服务开始关闭后,桥接会拒绝新连接,因此仍在完成中的调用无法启动新的存根。
Open Cloud 支持的格式有限。 模型仅接受 .fbx;Decal 接受 bmp、jpeg、png 和 tga;Audio 接受 mp3 和 ogg,且只能创建,不能更新,同时受每月配额限制。格式错误只会在轮询操作后才导致失败,因此会在本地拒绝。模型和 Decal 一直不支持归档,roblox_archive_asset 会预先说明这一点。
平台支持
| Windows | macOS | |
|---|---|---|
| 打开指定的 place | ✅ 已验证 | ✅ 已实现,尚未在硬件上验证 |
| 进程和代理程序检查 | ✅ 已验证(PowerShell) | ✅ 已验证(ps + lsof) |
| 存根清理 | ✅ 已验证 | ✅ 已实现,尚未在硬件上验证 |
| 窗口标题 | ✅ | ❌ 始终为 undefined(需要辅助功能权限) |
| Open Cloud 工具 | ✅ | ✅(普通 HTTP) |
平台差异由 ports/process-inspector.ts 处理;代理程序检测、存根分类和清理逻辑则为共享实现。Linux 会被明确拒绝,而不是返回空快照,因为 Roblox Studio 不会在 Linux 上运行,返回空结果会被理解为“没有正在运行的 Studio”。
边界
- 不改变窗口焦点。 抢夺焦点可能导致意外按键关闭刚加载的 place。
roblox_luau_safe不是执行任意代码的新方式。execute_luau本来就掌握在客户端手中;此工具会在相同入口前增加强制的 PlaceId 检查、对整个代码块进行一次pcall,并对结果分块。pcall会捕获运行时错误,并将其作为可读值返回;错误之后的代码不会运行,错误发生前所做的更改也不会回滚。它不是沙盒。- 不对 13469 端口上的代理程序私有协议进行逆向工程。 像普通 MCP 客户端一样与
StudioMCP通信,就无需这么做。 - 不提供“从库存中移除”。 这需要通过
inventory.roblox.com使用已登录会话 Cookie 和 CSRF 令牌,而 Open Cloud API 密钥无法做到这一点。 - 已知限制:切换期间,输出文件夹中已有的文件夹可能被替换。 文件会写入新的暂存文件夹,但将其放到目标位置时,仍会按路径遍历输出文件夹中已有的子文件夹。每一级都会通过
realpath解析,并先检查是否位于输出文件夹内;但同一台机器上的其他程序仍可能在检查与移动之间将文件夹替换为符号链接(检查时与使用时之间的竞争)。移动操作只会创建新名称,因此最坏情况下,输出文件夹外会出现一个新文件;不会覆盖或删除任何外部内容。 - 已知限制:未释放的缓冲区会保留到下一次调用。 无法释放的 Luau 缓冲区会留在 Studio 的
shared表中,直到后续调用访问同一 Studio(对于空闲清理,也要等到空闲 15 分钟后),或直到 Studio 关闭。
开发
corepack pnpm install
corepack pnpm run verify # typecheck, tests, build, stdio smoke
corepack pnpm run verify:live # read-only checks against real Studio and a real account
corepack pnpm run verify:extract # end to end: open_place → place_guard → luau_safe → extract_place
verify:live 仅执行只读操作:不上传、不更新、不打开场景,也不终止进程。其 Open Cloud 部分需要 ROBLOX_API_KEY 和资源 ID(node scripts/verify-live.mjs <assetId>),否则会跳过。
verify:extract 需要 ROBLOX_VERIFY_PLACE_ID、ROBLOX_VERIFY_UNIVERSE_ID(一个你拥有的场景)和 ROBLOX_VERIFY_BASELINE(手动制作且经过字节验证的脚本快照)。它会打开一个 Studio 实例,并将提取的脚本与快照逐字节比较。特意将这些步骤串联起来,因为只有在连续调用多个工具时,桥接程序的生命周期漏洞才会显现。
许可证和商标
MIT。
Studio Sidecar 是一个独立的开源项目,与 Roblox Corporation 无关,也未获其认可。Roblox、Roblox Studio 和 Luau 是 Roblox Corporation 的商标。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。