@adiholick/nvstudio-mcp 2.0.1 → 2.0.2
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/README.md +43 -15
- package/dist/build-plugin.js +15 -9
- package/package.json +2 -2
- package/studio-plugin/Main.server.lua +9 -1
- package/studio-plugin/nvstudio_mcp.rbxmx +14 -9
- package/studio-plugin/ui_manager.lua +2 -2
package/README.md
CHANGED
|
@@ -8,9 +8,14 @@ Sistem ini didesain menggunakan **Hybrid Architecture** yang memisahkan logika E
|
|
|
8
8
|
|
|
9
9
|
## 📥 Instalasi
|
|
10
10
|
|
|
11
|
-
Langkah
|
|
11
|
+
Langkah instalasi dirancang **sangat mudah dan otomatis!**
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
> 💡 **Apakah perlu install plugin Roblox secara manual?**
|
|
14
|
+
> **TIDAK PERLU.** Jika Anda menjalankan skrip installer di bawah (Langkah 1), installer akan **secara otomatis menyalin plugin (`nvstudio_mcp.rbxmx`)** langsung ke folder plugin Roblox Studio di sistem operasi Anda.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
### Langkah 1: Jalankan Installer (Otomatis & Direkomendasikan)
|
|
14
19
|
|
|
15
20
|
Pilih perintah sesuai terminal yang Anda gunakan:
|
|
16
21
|
|
|
@@ -24,25 +29,40 @@ irm https://raw.githubusercontent.com/Adiholick/nvstudio-mcp/main/install.ps1 |
|
|
|
24
29
|
curl -fsSL https://raw.githubusercontent.com/Adiholick/nvstudio-mcp/main/install.sh | bash
|
|
25
30
|
```
|
|
26
31
|
|
|
32
|
+
**Apa saja yang dilakukan installer ini secara otomatis?**
|
|
33
|
+
1. 📦 Mengunduh source code, memasang dependensi Node.js, dan mengkompilasi TypeScript (*Bridge Server*).
|
|
34
|
+
2. 🧩 **Memasang Plugin Roblox Studio (`nvstudio_mcp.rbxmx`) otomatis** ke folder sistem Roblox Studio Anda (`%LOCALAPPDATA%\Roblox\Plugins` di Windows atau `~/Documents/ROBLOX/Plugins` di macOS).
|
|
35
|
+
3. 🤖 Mengintegrasikan *AI Agent Skills* anti-halusinasi langsung ke **Antigravity IDE** (`~/.gemini/config/plugins/nvstudio-mcp`).
|
|
36
|
+
4. ⚙️ Melakukan auto-konfigurasi jika mendeteksi editor **Cursor** (`.cursor/mcp.json`).
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
- Memasang dependensi Node.js dan melakukan kompilasi TypeScript (*Bridge Server*).
|
|
30
|
-
- Menyalin file plugin `nvstudio_mcp.rbxmx` ke dalam sistem Plugin Roblox Studio di OS Anda (Windows/macOS/WSL) secara otomatis.
|
|
31
|
-
- Mengintegrasikan *AI Agent Skills* langsung ke **Antigravity IDE** (`~/.gemini/config/plugins/nvstudio-mcp`).
|
|
32
|
-
- Melakukan auto-konfigurasi JSON jika Anda menggunakan **Cursor Editor**.
|
|
38
|
+
---
|
|
33
39
|
|
|
34
|
-
### 2
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
### Langkah 2: Mengaktifkan Izin di Roblox Studio (Wajib)
|
|
41
|
+
|
|
42
|
+
Karena pembatasan keamanan bawaan Roblox Studio, akses HTTP harus diizinkan sekali per place/game:
|
|
43
|
+
1. Buka game/place Anda di **Roblox Studio**.
|
|
44
|
+
2. Di toolbar atas, buka tab **Home** ➔ **Game Settings** ➔ pilih menu **Security**.
|
|
45
|
+
3. Centang (aktifkan) **`Allow HTTP Requests`**, lalu klik **Save**.
|
|
46
|
+
4. **Auto-Detect Aktif!** Plugin Roblox Studio kini memiliki heartbeat pintar yang akan otomatis terhubung (*Auto-Connect*) segera setelah MCP server aktif — Anda tidak perlu lagi repot menekan tombol connect secara manual.
|
|
38
47
|
|
|
39
48
|
---
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
### 📂 Alternatif: Instalasi Plugin Secara Manual (Opsional)
|
|
51
|
+
|
|
52
|
+
Jika Anda **tidak** menggunakan skrip installer otomatis di atas (misalnya hanya menambahkan server via `npx` di klien AI), pasang file plugin Roblox Studio secara manual:
|
|
53
|
+
1. Ambil file `nvstudio_mcp.rbxmx` dari folder [studio-plugin/nvstudio_mcp.rbxmx](file:///studio-plugin/nvstudio_mcp.rbxmx).
|
|
54
|
+
2. Pindahkan/salin file tersebut ke direktori plugin Roblox di komputer Anda:
|
|
55
|
+
- **Windows:** `%LOCALAPPDATA%\Roblox\Plugins` (atau `C:\Users\<Username>\AppData\Local\Roblox\Plugins`)
|
|
56
|
+
- **macOS:** `~/Documents/ROBLOX/Plugins`
|
|
57
|
+
3. Restart atau buka kembali Roblox Studio. Plugin akan muncul di tab **Plugins**.
|
|
42
58
|
|
|
43
|
-
|
|
59
|
+
---
|
|
44
60
|
|
|
45
|
-
|
|
61
|
+
## 🔌 Cara Menggunakan (Konfigurasi MCP Klien AI)
|
|
62
|
+
|
|
63
|
+
Jika Anda menggunakan AI Client lain seperti **Claude Desktop**, **Windsurf**, atau ingin menambahkan konfigurasi secara manual:
|
|
64
|
+
|
|
65
|
+
Tambahkan konfigurasi berikut ke file `mcp.json` Anda:
|
|
46
66
|
```json
|
|
47
67
|
{
|
|
48
68
|
"mcpServers": {
|
|
@@ -56,7 +76,15 @@ Salin konfigurasi ini:
|
|
|
56
76
|
}
|
|
57
77
|
}
|
|
58
78
|
```
|
|
59
|
-
*(
|
|
79
|
+
*(AI Anda akan selalu menjalankan versi terbaru dari server Bridge langsung dari NPM!)*
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 🖥️ Dashboard Visual & Fitur Pintar v2.0
|
|
84
|
+
|
|
85
|
+
- **Visual Dashboard Real-time:** Buka [http://localhost:3055](http://localhost:3055) di browser Anda untuk melihat monitor antrean perintah, log aktivitas AI, status koneksi Studio, dan statistik eksekusi secara visual.
|
|
86
|
+
- **Auto-Detect & Auto-Connect:** Plugin Roblox Studio otomatis menyambung ke server saat aktif dan kembali menunggu (*Waiting*) saat server mati tanpa interupsi manual.
|
|
87
|
+
- **Anti-Zombie Port Handling:** Tidak perlu khawatir error `EADDRINUSE`. Jika port `3055` tertahan oleh proses zombie akibat restart editor/IDE, server akan otomatis membersihkan port tersebut secara aman.
|
|
60
88
|
|
|
61
89
|
---
|
|
62
90
|
|
package/dist/build-plugin.js
CHANGED
|
@@ -39,7 +39,7 @@ function buildRbxmx() {
|
|
|
39
39
|
xml += `\t\t\t<bool name="DefinesCapabilities">false</bool>\n`;
|
|
40
40
|
xml += `\t\t\t<string name="Name">nvstudio_mcp</string>\n`;
|
|
41
41
|
xml += `\t\t\t<int64 name="SourceAssetId">-1</int64>\n`;
|
|
42
|
-
xml += `\t\t\t<SharedString name="Tags"
|
|
42
|
+
xml += `\t\t\t<SharedString name="Tags"></SharedString>\n`;
|
|
43
43
|
xml += `\t\t</Properties>\n`;
|
|
44
44
|
// Process files
|
|
45
45
|
for (const file of files) {
|
|
@@ -49,8 +49,9 @@ function buildRbxmx() {
|
|
|
49
49
|
// Main.server.lua is a Script, others are ModuleScripts
|
|
50
50
|
const isMain = name === 'Main.server';
|
|
51
51
|
const className = isMain ? 'Script' : 'ModuleScript';
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const scriptName = isMain ? 'Main' : name;
|
|
53
|
+
// Use a clean referent
|
|
54
|
+
const referent = `RBX_${scriptName.replace(/[^a-zA-Z0-9]/g, '_')}`;
|
|
54
55
|
xml += `\t\t<Item class="${className}" referent="${referent}">\n`;
|
|
55
56
|
xml += `\t\t\t<Properties>\n`;
|
|
56
57
|
xml += `\t\t\t\t<BinaryString name="AttributesSerialize"></BinaryString>\n`;
|
|
@@ -58,7 +59,7 @@ function buildRbxmx() {
|
|
|
58
59
|
xml += `\t\t\t\t<bool name="DefinesCapabilities">false</bool>\n`;
|
|
59
60
|
xml += `\t\t\t\t<bool name="Disabled">false</bool>\n`;
|
|
60
61
|
xml += `\t\t\t\t<Content name="LinkedSource"><null></null></Content>\n`;
|
|
61
|
-
xml += `\t\t\t\t<string name="Name">${
|
|
62
|
+
xml += `\t\t\t\t<string name="Name">${scriptName}</string>\n`;
|
|
62
63
|
xml += `\t\t\t\t<int64 name="SourceAssetId">-1</int64>\n`;
|
|
63
64
|
xml += `\t\t\t\t<SharedString name="Tags"></SharedString>\n`;
|
|
64
65
|
if (isMain) {
|
|
@@ -73,11 +74,7 @@ function buildRbxmx() {
|
|
|
73
74
|
}
|
|
74
75
|
// Close Folder
|
|
75
76
|
xml += `\t</Item>\n`;
|
|
76
|
-
//
|
|
77
|
-
xml += `\t<SharedStrings>\n`;
|
|
78
|
-
xml += `\t\t<SharedString md5="yuZpQdnvvUBOTYh1jqZ2cA=="></SharedString>\n`;
|
|
79
|
-
xml += `\t</SharedStrings>\n`;
|
|
80
|
-
// Close Roblox
|
|
77
|
+
// Close Roblox root (No SharedStrings block needed when all Tags are empty)
|
|
81
78
|
xml += `</roblox>\n`;
|
|
82
79
|
fs_1.default.writeFileSync(OUTPUT_FILE, xml, 'utf-8');
|
|
83
80
|
console.log(`[Build] Berhasil membuat ${OUTPUT_FILE}`);
|
|
@@ -111,5 +108,14 @@ function copyToRobloxPlugins() {
|
|
|
111
108
|
else {
|
|
112
109
|
console.log(`[Build] Platform ${process.platform} tidak didukung untuk auto-copy plugin.`);
|
|
113
110
|
}
|
|
111
|
+
// Also update ~/.nvstudio-mcp/studio-plugin/nvstudio_mcp.rbxmx if present
|
|
112
|
+
const homeClonePlugin = path_1.default.join(os_1.default.homedir(), '.nvstudio-mcp', 'studio-plugin', 'nvstudio_mcp.rbxmx');
|
|
113
|
+
if (fs_1.default.existsSync(path_1.default.dirname(homeClonePlugin))) {
|
|
114
|
+
try {
|
|
115
|
+
fs_1.default.copyFileSync(OUTPUT_FILE, homeClonePlugin);
|
|
116
|
+
console.log(`[Build] ✅ Berhasil memperbarui ${homeClonePlugin}`);
|
|
117
|
+
}
|
|
118
|
+
catch { }
|
|
119
|
+
}
|
|
114
120
|
}
|
|
115
121
|
buildRbxmx();
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adiholick/nvstudio-mcp",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Local Bridge Server MCP for Roblox Studio",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"nvstudio-mcp": "
|
|
7
|
+
"nvstudio-mcp": "dist/index.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
@@ -13,7 +13,7 @@ local ui = nil
|
|
|
13
13
|
|
|
14
14
|
-- Membangun Tombol Toolbar (Toggle)
|
|
15
15
|
local toolbar = plugin:CreateToolbar("NVStudio MCP")
|
|
16
|
-
local toggleBtn = toolbar:CreateButton("Dashboard", "Buka Dashboard NVStudio MCP", "rbxassetid://82696893597722")
|
|
16
|
+
local toggleBtn = toolbar:CreateButton("Dashboard", "Buka Dashboard NVStudio MCP", "rbxassetid://82696893597722", "NVStudio")
|
|
17
17
|
|
|
18
18
|
-- Global State & Context AI
|
|
19
19
|
local ctx = {
|
|
@@ -41,6 +41,14 @@ if uiModule then
|
|
|
41
41
|
ui:setAutoConnectState(autoConnect)
|
|
42
42
|
ui:setStatus("disconnected")
|
|
43
43
|
|
|
44
|
+
-- Sync state tombol toolbar dengan status widget
|
|
45
|
+
if ui.widget then
|
|
46
|
+
toggleBtn:SetActive(ui.widget.Enabled)
|
|
47
|
+
ui.widget:GetPropertyChangedSignal("Enabled"):Connect(function()
|
|
48
|
+
toggleBtn:SetActive(ui.widget.Enabled)
|
|
49
|
+
end)
|
|
50
|
+
end
|
|
51
|
+
|
|
44
52
|
-- Event Toggle GUI Panel
|
|
45
53
|
toggleBtn.Click:Connect(function()
|
|
46
54
|
ui:toggleVisibility()
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<bool name="DefinesCapabilities">false</bool>
|
|
9
9
|
<string name="Name">nvstudio_mcp</string>
|
|
10
10
|
<int64 name="SourceAssetId">-1</int64>
|
|
11
|
-
<SharedString name="Tags"
|
|
11
|
+
<SharedString name="Tags"></SharedString>
|
|
12
12
|
</Properties>
|
|
13
13
|
<Item class="ModuleScript" referent="RBX_create_instance">
|
|
14
14
|
<Properties>
|
|
@@ -367,14 +367,14 @@ end
|
|
|
367
367
|
]]></ProtectedString>
|
|
368
368
|
</Properties>
|
|
369
369
|
</Item>
|
|
370
|
-
<Item class="Script" referent="
|
|
370
|
+
<Item class="Script" referent="RBX_Main">
|
|
371
371
|
<Properties>
|
|
372
372
|
<BinaryString name="AttributesSerialize"></BinaryString>
|
|
373
373
|
<SecurityCapabilities name="Capabilities">0</SecurityCapabilities>
|
|
374
374
|
<bool name="DefinesCapabilities">false</bool>
|
|
375
375
|
<bool name="Disabled">false</bool>
|
|
376
376
|
<Content name="LinkedSource"><null></null></Content>
|
|
377
|
-
<string name="Name">Main
|
|
377
|
+
<string name="Name">Main</string>
|
|
378
378
|
<int64 name="SourceAssetId">-1</int64>
|
|
379
379
|
<SharedString name="Tags"></SharedString>
|
|
380
380
|
<token name="RunContext">0</token>
|
|
@@ -393,7 +393,7 @@ local ui = nil
|
|
|
393
393
|
|
|
394
394
|
-- Membangun Tombol Toolbar (Toggle)
|
|
395
395
|
local toolbar = plugin:CreateToolbar("NVStudio MCP")
|
|
396
|
-
local toggleBtn = toolbar:CreateButton("Dashboard", "Buka Dashboard NVStudio MCP", "rbxassetid://82696893597722")
|
|
396
|
+
local toggleBtn = toolbar:CreateButton("Dashboard", "Buka Dashboard NVStudio MCP", "rbxassetid://82696893597722", "NVStudio")
|
|
397
397
|
|
|
398
398
|
-- Global State & Context AI
|
|
399
399
|
local ctx = {
|
|
@@ -421,6 +421,14 @@ if uiModule then
|
|
|
421
421
|
ui:setAutoConnectState(autoConnect)
|
|
422
422
|
ui:setStatus("disconnected")
|
|
423
423
|
|
|
424
|
+
-- Sync state tombol toolbar dengan status widget
|
|
425
|
+
if ui.widget then
|
|
426
|
+
toggleBtn:SetActive(ui.widget.Enabled)
|
|
427
|
+
ui.widget:GetPropertyChangedSignal("Enabled"):Connect(function()
|
|
428
|
+
toggleBtn:SetActive(ui.widget.Enabled)
|
|
429
|
+
end)
|
|
430
|
+
end
|
|
431
|
+
|
|
424
432
|
-- Event Toggle GUI Panel
|
|
425
433
|
toggleBtn.Click:Connect(function()
|
|
426
434
|
ui:toggleVisibility()
|
|
@@ -945,8 +953,8 @@ function UIManager.init(pluginInstance, studioId)
|
|
|
945
953
|
-- Membuat Widget Panel yang bisa di-dock (menempel)
|
|
946
954
|
local widgetInfo = DockWidgetPluginGuiInfo.new(
|
|
947
955
|
Enum.InitialDockState.Right,
|
|
948
|
-
|
|
949
|
-
false, --
|
|
956
|
+
true, -- Initially visible on first install so user immediately sees the dashboard
|
|
957
|
+
false, -- Don't override user's saved state on subsequent launches
|
|
950
958
|
380, -- Default width
|
|
951
959
|
520, -- Default height
|
|
952
960
|
280, -- Min width
|
|
@@ -1414,7 +1422,4 @@ end
|
|
|
1414
1422
|
</Properties>
|
|
1415
1423
|
</Item>
|
|
1416
1424
|
</Item>
|
|
1417
|
-
<SharedStrings>
|
|
1418
|
-
<SharedString md5="yuZpQdnvvUBOTYh1jqZ2cA=="></SharedString>
|
|
1419
|
-
</SharedStrings>
|
|
1420
1425
|
</roblox>
|
|
@@ -5,8 +5,8 @@ function UIManager.init(pluginInstance, studioId)
|
|
|
5
5
|
-- Membuat Widget Panel yang bisa di-dock (menempel)
|
|
6
6
|
local widgetInfo = DockWidgetPluginGuiInfo.new(
|
|
7
7
|
Enum.InitialDockState.Right,
|
|
8
|
-
|
|
9
|
-
false, --
|
|
8
|
+
true, -- Initially visible on first install so user immediately sees the dashboard
|
|
9
|
+
false, -- Don't override user's saved state on subsequent launches
|
|
10
10
|
380, -- Default width
|
|
11
11
|
520, -- Default height
|
|
12
12
|
280, -- Min width
|