@usergenerated/rbx-iris 0.3.124

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 ADDED
@@ -0,0 +1,61 @@
1
+ [![CI](https://github.com/UserGeneratedLLC/rbx-iris/actions/workflows/ci.yml/badge.svg)](https://github.com/UserGeneratedLLC/rbx-iris/actions/workflows/ci.yml)
2
+ [![Release](https://github.com/UserGeneratedLLC/rbx-iris/actions/workflows/release.yml/badge.svg)](https://github.com/UserGeneratedLLC/rbx-iris/actions/workflows/release.yml)
3
+ [![npm](https://img.shields.io/npm/v/@usergenerated/rbx-iris)](https://www.npmjs.com/package/@usergenerated/rbx-iris)
4
+ [![crates.io](https://img.shields.io/crates/v/rbx-iris)](https://crates.io/crates/rbx-iris)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](https://github.com/UserGeneratedLLC/rbx-iris/blob/main/LICENSE)
6
+
7
+ # @usergenerated/rbx-iris
8
+
9
+ npm wrapper for [Iris](https://github.com/UserGeneratedLLC/rbx-iris). Automatically downloads the correct pre-built binary for your platform from GitHub Releases.
10
+
11
+ 74 tools across scripting, instances, properties, attributes, transforms, camera, spatial queries, selections, history, collision groups, screenshots, execution, logging, and studio management — all over msgpack/WebSocket with multi-studio session routing.
12
+
13
+ ## Quick Setup
14
+
15
+ Requires [Node.js](https://nodejs.org/) 18+ and [Roblox Studio](https://create.roblox.com/).
16
+
17
+ ### Cursor (`.cursor/mcp.json`)
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "Iris": {
23
+ "command": "npx",
24
+ "args": ["-y", "--prefer-online", "@usergenerated/rbx-iris@latest", "--stdio", "--unsafe-reads", "--unsafe-writes"]
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ ### Claude Desktop (`claude_desktop_config.json`)
31
+
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "Iris": {
36
+ "command": "npx",
37
+ "args": ["-y", "--prefer-online", "@usergenerated/rbx-iris@latest", "--stdio", "--unsafe-reads", "--unsafe-writes"]
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ### Claude Code
44
+
45
+ ```sh
46
+ claude mcp add --transport stdio Iris -- npx -y --prefer-online @usergenerated/rbx-iris@latest --stdio --unsafe-reads --unsafe-writes
47
+ ```
48
+
49
+ Restart your MCP client and Roblox Studio after setup.
50
+
51
+ ## Supported Platforms
52
+
53
+ | OS | Architecture |
54
+ |---|---|
55
+ | Windows | x64, ARM64 |
56
+ | macOS | x64, ARM64 |
57
+ | Linux | x64, ARM64 |
58
+
59
+ ## License
60
+
61
+ [MIT](https://github.com/UserGeneratedLLC/rbx-iris/blob/main/LICENSE)
package/bin/cli.js ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const path = require("path");
5
+ const { spawn } = require("child_process");
6
+
7
+ const BIN_NAME = "rbx-iris";
8
+ const exe =
9
+ process.platform === "win32" ? `${BIN_NAME}.exe` : BIN_NAME;
10
+ const binPath = path.join(__dirname, exe);
11
+
12
+ const child = spawn(binPath, process.argv.slice(2), {
13
+ stdio: "inherit",
14
+ });
15
+
16
+ child.on("error", (err) => {
17
+ if (err.code === "ENOENT") {
18
+ console.error(
19
+ `${BIN_NAME} binary not found at ${binPath}\n` +
20
+ "Run 'npm install' or reinstall the package to download it."
21
+ );
22
+ } else {
23
+ console.error(`Failed to start ${BIN_NAME}: ${err.message}`);
24
+ }
25
+ process.exit(1);
26
+ });
27
+
28
+ child.on("exit", (code) => {
29
+ process.exit(code ?? 1);
30
+ });
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@usergenerated/rbx-iris",
3
+ "version": "0.3.124",
4
+ "description": "Iris — Roblox Studio MCP server, auto-downloads the correct platform binary from GitHub releases",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/UserGeneratedLLC/rbx-iris"
9
+ },
10
+ "bin": {
11
+ "rbx-iris": "bin/cli.js"
12
+ },
13
+ "scripts": {
14
+ "postinstall": "node postinstall.js"
15
+ },
16
+ "files": [
17
+ "bin/cli.js",
18
+ "postinstall.js",
19
+ "README.md"
20
+ ],
21
+ "engines": {
22
+ "node": ">=18"
23
+ }
24
+ }
package/postinstall.js ADDED
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ const https = require("https");
5
+ const fs = require("fs");
6
+ const path = require("path");
7
+ const { execSync } = require("child_process");
8
+ const os = require("os");
9
+
10
+ const REPO = "UserGeneratedLLC/rbx-iris";
11
+ const BIN_NAME = "rbx-iris";
12
+
13
+ const PLATFORM_MAP = {
14
+ "darwin-arm64": "macos-aarch64",
15
+ "darwin-x64": "macos-x86_64",
16
+ "linux-arm64": "linux-aarch64",
17
+ "linux-x64": "linux-x86_64",
18
+ "win32-arm64": "windows-aarch64",
19
+ "win32-x64": "windows-x86_64",
20
+ };
21
+
22
+ function getBinPath() {
23
+ const exe = process.platform === "win32" ? `${BIN_NAME}.exe` : BIN_NAME;
24
+ return path.join(__dirname, "bin", exe);
25
+ }
26
+
27
+ function getPlatformLabel() {
28
+ const key = `${process.platform}-${process.arch}`;
29
+ const label = PLATFORM_MAP[key];
30
+ if (!label) {
31
+ throw new Error(
32
+ `Unsupported platform: ${process.platform} ${process.arch}\n` +
33
+ `Supported: ${Object.keys(PLATFORM_MAP).join(", ")}`
34
+ );
35
+ }
36
+ return label;
37
+ }
38
+
39
+ function getVersion() {
40
+ const pkg = JSON.parse(
41
+ fs.readFileSync(path.join(__dirname, "package.json"), "utf8")
42
+ );
43
+ return pkg.version;
44
+ }
45
+
46
+ function httpsGet(url) {
47
+ return new Promise((resolve, reject) => {
48
+ https
49
+ .get(url, { headers: { "User-Agent": "rbx-iris-npm" } }, (res) => {
50
+ if (res.statusCode === 302 || res.statusCode === 301) {
51
+ httpsGet(res.headers.location).then(resolve, reject);
52
+ return;
53
+ }
54
+ if (res.statusCode !== 200) {
55
+ reject(
56
+ new Error(`Download failed: HTTP ${res.statusCode} from ${url}`)
57
+ );
58
+ return;
59
+ }
60
+ const chunks = [];
61
+ res.on("data", (chunk) => chunks.push(chunk));
62
+ res.on("end", () => resolve(Buffer.concat(chunks)));
63
+ res.on("error", reject);
64
+ })
65
+ .on("error", reject);
66
+ });
67
+ }
68
+
69
+ function extract(zipPath, destDir) {
70
+ try {
71
+ execSync(`tar -xf "${zipPath}" -C "${destDir}"`, { stdio: "pipe" });
72
+ return;
73
+ } catch (_) {
74
+ // tar failed, try fallback
75
+ }
76
+
77
+ if (process.platform === "win32") {
78
+ try {
79
+ execSync(
80
+ `powershell -NoProfile -Command "Expand-Archive -Force -Path '${zipPath}' -DestinationPath '${destDir}'"`,
81
+ { stdio: "pipe" }
82
+ );
83
+ return;
84
+ } catch (_) {
85
+ // fallback also failed
86
+ }
87
+ }
88
+
89
+ throw new Error(
90
+ "Extraction failed: neither tar nor PowerShell could extract the archive"
91
+ );
92
+ }
93
+
94
+ async function main() {
95
+ const binPath = getBinPath();
96
+
97
+ if (fs.existsSync(binPath)) {
98
+ console.log(`Binary already exists at ${binPath}, skipping download.`);
99
+ return;
100
+ }
101
+
102
+ const version = getVersion();
103
+ const label = getPlatformLabel();
104
+ const assetName = `${BIN_NAME}-${version}-${label}.zip`;
105
+ const url = `https://github.com/${REPO}/releases/download/v${version}/${assetName}`;
106
+
107
+ console.log(`Downloading ${BIN_NAME} v${version} for ${label}...`);
108
+
109
+ const zipBuffer = await httpsGet(url);
110
+
111
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "rbx-iris-"));
112
+ const zipPath = path.join(tmpDir, assetName);
113
+ const binDir = path.join(__dirname, "bin");
114
+
115
+ try {
116
+ fs.writeFileSync(zipPath, zipBuffer);
117
+ fs.mkdirSync(binDir, { recursive: true });
118
+ extract(zipPath, binDir);
119
+
120
+ if (process.platform !== "win32") {
121
+ fs.chmodSync(binPath, 0o755);
122
+ }
123
+
124
+ if (!fs.existsSync(binPath)) {
125
+ throw new Error(
126
+ `Extraction succeeded but binary not found at ${binPath}`
127
+ );
128
+ }
129
+
130
+ console.log(`Installed ${BIN_NAME} v${version} to ${binPath}`);
131
+ } finally {
132
+ fs.rmSync(tmpDir, { recursive: true, force: true });
133
+ }
134
+ }
135
+
136
+ main().catch((err) => {
137
+ console.error(`Failed to install ${BIN_NAME}: ${err.message}`);
138
+ process.exit(1);
139
+ });