rbxstudio-mcp 2.2.3 → 2.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rbxstudio-mcp",
3
- "version": "2.2.3",
3
+ "version": "2.2.4",
4
4
  "description": "MCP Server for Roblox Studio Integration - Access Studio data, scripts, and objects through AI tools",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -219,11 +219,19 @@ local function injectTestCompanion(serverUrl, sessionId)
219
219
  local script = Instance.new("Script")
220
220
  script.Name = TEST_COMPANION_NAME
221
221
  script.Source = source
222
- -- Archivable=false so a stray companion never gets saved into the user's
223
- -- place file even if cleanup somehow misses it. The play-test mechanism
224
- -- still includes it in the test DataModel because it duplicates the live
225
- -- in-memory tree (not the saved file).
226
- script.Archivable = false
222
+ -- IMPORTANT: Archivable MUST stay true (the default).
223
+ -- ExecutePlayModeAsync builds the test DataModel by Clone()-ing the Edit
224
+ -- DataModel, and Instance:Clone() silently returns nil for any instance
225
+ -- with Archivable=false. We previously set this to false as a "safety"
226
+ -- against the companion getting saved into the user's place file — but
227
+ -- the side effect was that the companion never made it into the test
228
+ -- session at all. No companion → no log streaming and no way to receive
229
+ -- the "end" command, so stop_play would just time out.
230
+ --
231
+ -- We rely on the cleanup sweeps (on plugin activate, before each test,
232
+ -- after each test) to keep companions out of the saved file. The script
233
+ -- is also tagged with TEST_COMPANION_TAG so any orphan is easy to find.
234
+ script.Archivable = true
227
235
  script.Parent = game:GetService("ServerScriptService")
228
236
 
229
237
  pcall(function()
@@ -4563,6 +4571,34 @@ handlers.playSolo = function(requestData)
4563
4571
  }
4564
4572
  end
4565
4573
 
4574
+ -- HttpService.HttpEnabled preflight.
4575
+ --
4576
+ -- Plugins (this script) bypass HttpEnabled, but in-game scripts — and
4577
+ -- that includes our injected companion running inside the test
4578
+ -- DataModel — do not. Without HttpEnabled the companion can't reach
4579
+ -- the bridge to stream logs or receive the "end" command, so stop_play
4580
+ -- silently times out from the AI's perspective.
4581
+ --
4582
+ -- We can't fix this for the user: HttpEnabled is gated by
4583
+ -- LocalUserSecurity, which means a plugin literally cannot flip it
4584
+ -- from code. Best we can do is fail fast with an actionable error so
4585
+ -- the AI/user knows exactly what to toggle.
4586
+ local httpEnabledOk, httpEnabled = pcall(function()
4587
+ return HttpService.HttpEnabled
4588
+ end)
4589
+ if httpEnabledOk and httpEnabled == false then
4590
+ return {
4591
+ success = false,
4592
+ error = "HttpService.HttpEnabled is false. The injected test-session companion runs as an in-game script and needs HTTP access to stream logs and receive the stop command. Enable it in Studio: Game Settings → Security → Allow HTTP Requests (or Home → Game Settings → Security). A plugin cannot toggle this setting itself (LocalUserSecurity).",
4593
+ fixSteps = {
4594
+ "Open Game Settings (Home tab → Game Settings, or File → Game Settings)",
4595
+ "Go to the Security section",
4596
+ "Toggle 'Allow HTTP Requests' ON",
4597
+ "Click Save, then call play_solo again",
4598
+ },
4599
+ }
4600
+ end
4601
+
4566
4602
  -- If a previous test was somehow left running (e.g. plugin reloaded
4567
4603
  -- mid-test, user clicked Stop without us hearing), best-effort it.
4568
4604
  -- We can't detect Play mode from a plugin reliably, so we just do an