robloxstudio-mcp 2.7.0-next.5 → 2.7.0-next.6

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/dist/index.js CHANGED
@@ -2499,17 +2499,28 @@ ${code}`
2499
2499
  }]
2500
2500
  };
2501
2501
  }
2502
+ // Decal asset IDs are the wrapper asset; ImageLabel.Image needs the underlying image
2503
+ // content ID. The only reliable cross-auth way to resolve this is InsertService:LoadAsset
2504
+ // via the connected Studio plugin — the unauthenticated economy endpoint returns 401.
2502
2505
  async resolveImageId(decalAssetId) {
2506
+ const code = `
2507
+ local InsertService = game:GetService("InsertService")
2508
+ local ok, result = pcall(function() return InsertService:LoadAsset(${decalAssetId}) end)
2509
+ if not ok then return nil end
2510
+ local decal = result:FindFirstChildWhichIsA("Decal", true)
2511
+ local id = decal and decal.Texture:match("(%d+)") or nil
2512
+ result:Destroy()
2513
+ return id
2514
+ `;
2503
2515
  try {
2504
- const resp = await fetch(`https://economy.roblox.com/v2/assets/${decalAssetId}/details`);
2505
- if (!resp.ok)
2506
- return decalAssetId;
2507
- const details = await resp.json();
2508
- if (details.TextureId)
2509
- return String(details.TextureId);
2516
+ const response = await this.client.request("/api/execute-luau", { code }, "edit");
2517
+ const returnValue = response?.returnValue;
2518
+ if (returnValue !== void 0 && returnValue !== null && /^\d+$/.test(String(returnValue))) {
2519
+ return String(returnValue);
2520
+ }
2510
2521
  } catch {
2511
2522
  }
2512
- return decalAssetId;
2523
+ return null;
2513
2524
  }
2514
2525
  async uploadDecal(filePath, displayName, description, userId, groupId) {
2515
2526
  if (!fs.existsSync(filePath)) {
@@ -2533,12 +2544,13 @@ ${code}`
2533
2544
  creationContext: { creator }
2534
2545
  }, fileContent, fileName);
2535
2546
  const decalId = result.response?.assetId;
2536
- const imageId = decalId ? await this.resolveImageId(decalId) : void 0;
2547
+ const imageId = decalId ? await this.resolveImageId(decalId) : null;
2537
2548
  return {
2538
2549
  content: [{
2539
2550
  type: "text",
2540
2551
  text: JSON.stringify({
2541
2552
  ...result,
2553
+ decalId: decalId ?? null,
2542
2554
  imageId
2543
2555
  })
2544
2556
  }]
@@ -2555,7 +2567,7 @@ ${code}`
2555
2567
  assetId: String(result.assetId),
2556
2568
  displayName,
2557
2569
  assetType: "Decal",
2558
- backingAssetId: String(result.backingAssetId),
2570
+ decalId: String(result.assetId),
2559
2571
  imageId: String(result.backingAssetId)
2560
2572
  }
2561
2573
  })
@@ -2581,7 +2593,8 @@ ${code}`
2581
2593
  assetId: String(result2.assetId),
2582
2594
  displayName,
2583
2595
  assetType,
2584
- backingAssetId: String(result2.backingAssetId)
2596
+ decalId: String(result2.assetId),
2597
+ imageId: String(result2.backingAssetId)
2585
2598
  }
2586
2599
  })
2587
2600
  }]
@@ -2608,6 +2621,20 @@ ${code}`
2608
2621
  description: description || "",
2609
2622
  creationContext: { creator }
2610
2623
  }, fileContent, fileName);
2624
+ if (assetType === "Decal") {
2625
+ const decalId = result.response?.assetId;
2626
+ const imageId = decalId ? await this.resolveImageId(decalId) : null;
2627
+ return {
2628
+ content: [{
2629
+ type: "text",
2630
+ text: JSON.stringify({
2631
+ ...result,
2632
+ decalId: decalId ?? null,
2633
+ imageId
2634
+ })
2635
+ }]
2636
+ };
2637
+ }
2611
2638
  return {
2612
2639
  content: [{
2613
2640
  type: "text",
@@ -4573,7 +4600,7 @@ part(0,2,0,2,1,1,"b")`,
4573
4600
  {
4574
4601
  name: "upload_decal",
4575
4602
  category: "write",
4576
- description: "Upload an image file as a Decal asset to Roblox. Supports ROBLOSECURITY cookie auth (recommended, simpler) or ROBLOX_OPEN_CLOUD_API_KEY (needs asset:write scope + creator ID). Cookie auth is used automatically when ROBLOSECURITY is set.",
4603
+ description: "Upload an image file as a Decal asset to Roblox. Supports ROBLOSECURITY cookie auth (recommended, simpler) or ROBLOX_OPEN_CLOUD_API_KEY (needs asset:write scope + creator ID). Cookie auth is used automatically when ROBLOSECURITY is set. Response includes both decalId (Decal wrapper asset ID) and imageId (underlying image content ID \u2014 use this for ImageLabel.Image). For Open Cloud uploads, imageId is resolved via the connected Studio plugin (InsertService:LoadAsset); if the plugin is not connected, imageId is null.",
4577
4604
  inputSchema: {
4578
4605
  type: "object",
4579
4606
  properties: {
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
- {
2
- "name": "robloxstudio-mcp",
3
- "version": "2.7.0-next.5",
4
- "description": "MCP Server for Roblox Studio Integration - Access Studio data, scripts, and objects through AI tools",
5
- "main": "dist/index.js",
6
- "type": "module",
7
- "bin": {
8
- "robloxstudio-mcp": "dist/index.js"
9
- },
10
- "files": [
11
- "dist/**/*",
12
- "studio-plugin/**/*"
13
- ],
14
- "scripts": {
15
- "build": "tsup",
16
- "prepack": "node ../../scripts/prepack.mjs",
17
- "postpack": "node ../../scripts/postpack.mjs"
18
- },
19
- "keywords": [
20
- "mcp",
21
- "roblox",
22
- "studio",
23
- "ai",
24
- "model-context-protocol",
25
- "game-development"
26
- ],
27
- "author": "",
28
- "license": "MIT",
29
- "repository": {
30
- "type": "git",
31
- "url": "https://github.com/boshyxd/robloxstudio-mcp.git"
32
- },
33
- "homepage": "https://github.com/boshyxd/robloxstudio-mcp#readme",
34
- "bugs": {
35
- "url": "https://github.com/boshyxd/robloxstudio-mcp/issues"
36
- },
37
- "dependencies": {
38
- "@modelcontextprotocol/sdk": "^1.27.1",
39
- "cors": "^2.8.5",
40
- "express": "^4.18.2",
41
- "node-fetch": "^3.3.2",
42
- "uuid": "^9.0.1",
43
- "ws": "^8.14.2"
44
- },
45
- "devDependencies": {
46
- "@robloxstudio-mcp/core": "*"
47
- }
48
- }
1
+ {
2
+ "name": "robloxstudio-mcp",
3
+ "version": "2.7.0-next.6",
4
+ "description": "MCP Server for Roblox Studio Integration - Access Studio data, scripts, and objects through AI tools",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "robloxstudio-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/**/*",
12
+ "studio-plugin/**/*"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsup",
16
+ "prepack": "node ../../scripts/prepack.mjs",
17
+ "postpack": "node ../../scripts/postpack.mjs"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "roblox",
22
+ "studio",
23
+ "ai",
24
+ "model-context-protocol",
25
+ "game-development"
26
+ ],
27
+ "author": "",
28
+ "license": "MIT",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/boshyxd/robloxstudio-mcp.git"
32
+ },
33
+ "homepage": "https://github.com/boshyxd/robloxstudio-mcp#readme",
34
+ "bugs": {
35
+ "url": "https://github.com/boshyxd/robloxstudio-mcp/issues"
36
+ },
37
+ "dependencies": {
38
+ "@modelcontextprotocol/sdk": "^1.27.1",
39
+ "cors": "^2.8.5",
40
+ "express": "^4.18.2",
41
+ "node-fetch": "^3.3.2",
42
+ "uuid": "^9.0.1",
43
+ "ws": "^8.14.2"
44
+ },
45
+ "devDependencies": {
46
+ "@robloxstudio-mcp/core": "*"
47
+ }
48
+ }