unity-mcp-bridge 0.1.0 → 0.3.0

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.
Files changed (3) hide show
  1. package/bin/run.js +23 -18
  2. package/package.json +5 -3
  3. package/setup.js +190 -0
package/bin/run.js CHANGED
@@ -4,25 +4,30 @@ const { spawn } = require("child_process");
4
4
  const path = require("path");
5
5
  const fs = require("fs");
6
6
 
7
- const binDir = __dirname;
8
- const exeName = process.platform === "win32" ? "UnityMcpBridge.exe" : "UnityMcpBridge";
9
- const exePath = path.join(binDir, exeName);
7
+ // Check if this is a setup command
8
+ if (process.argv[2] === "setup") {
9
+ require(path.join(__dirname, "..", "setup.js"));
10
+ } else {
11
+ const binDir = __dirname;
12
+ const exeName = process.platform === "win32" ? "UnityMcpBridge.exe" : "UnityMcpBridge";
13
+ const exePath = path.join(binDir, exeName);
10
14
 
11
- if (!fs.existsSync(exePath)) {
12
- console.error("unity-mcp-bridge binary not found. Run 'npm install' to download it.");
13
- process.exit(1);
14
- }
15
+ if (!fs.existsSync(exePath)) {
16
+ console.error("unity-mcp-bridge binary not found. Run 'npm install' to download it.");
17
+ process.exit(1);
18
+ }
15
19
 
16
- const child = spawn(exePath, process.argv.slice(2), {
17
- stdio: "inherit",
18
- env: process.env,
19
- });
20
+ const child = spawn(exePath, process.argv.slice(2), {
21
+ stdio: "inherit",
22
+ env: process.env,
23
+ });
20
24
 
21
- child.on("error", (err) => {
22
- console.error(`Failed to start unity-mcp-bridge: ${err.message}`);
23
- process.exit(1);
24
- });
25
+ child.on("error", (err) => {
26
+ console.error(`Failed to start unity-mcp-bridge: ${err.message}`);
27
+ process.exit(1);
28
+ });
25
29
 
26
- child.on("exit", (code) => {
27
- process.exit(code ?? 0);
28
- });
30
+ child.on("exit", (code) => {
31
+ process.exit(code ?? 0);
32
+ });
33
+ }
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "unity-mcp-bridge",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "MCP (Model Context Protocol) Bridge for Unity Editor — connect AI agents to Unity Editor",
5
5
  "bin": {
6
- "unity-mcp-bridge": "./bin/run.js"
6
+ "unity-mcp-bridge": "./bin/run.js",
7
+ "unity-mcp-setup": "./setup.js"
7
8
  },
8
9
  "scripts": {
9
- "postinstall": "node install.js"
10
+ "postinstall": "node install.js",
11
+ "setup": "node setup.js"
10
12
  },
11
13
  "keywords": [
12
14
  "mcp",
package/setup.js ADDED
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const os = require("os");
6
+
7
+ const SUPPORTED_CLIENTS = ["claude-desktop", "cursor", "claude-code", "windsurf", "vscode"];
8
+
9
+ function getConfigPath(client) {
10
+ const home = os.homedir();
11
+ const platform = process.platform;
12
+
13
+ switch (client) {
14
+ case "claude-desktop":
15
+ if (platform === "win32") return path.join(home, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
16
+ if (platform === "darwin") return path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
17
+ return path.join(home, ".config", "Claude", "claude_desktop_config.json");
18
+
19
+ case "cursor":
20
+ if (platform === "win32") return path.join(home, "AppData", "Roaming", "Cursor", "User", "globalStorage", "cursor.mcp", "config.json");
21
+ if (platform === "darwin") return path.join(home, "Library", "Application Support", "Cursor", "User", "globalStorage", "cursor.mcp", "config.json");
22
+ return path.join(home, ".config", "Cursor", "User", "globalStorage", "cursor.mcp", "config.json");
23
+
24
+ case "claude-code":
25
+ return path.join(home, ".claude", "settings.json");
26
+
27
+ case "windsurf":
28
+ if (platform === "win32") return path.join(home, "AppData", "Roaming", "Windsurf", "User", "globalStorage", "windsurf.mcp", "config.json");
29
+ if (platform === "darwin") return path.join(home, "Library", "Application Support", "Windsurf", "User", "globalStorage", "windsurf.mcp", "config.json");
30
+ return path.join(home, ".config", "Windsurf", "User", "globalStorage", "windsurf.mcp", "config.json");
31
+
32
+ case "vscode":
33
+ if (platform === "win32") return path.join(home, "AppData", "Roaming", "Code", "User", "settings.json");
34
+ if (platform === "darwin") return path.join(home, "Library", "Application Support", "Code", "User", "settings.json");
35
+ return path.join(home, ".config", "Code", "User", "settings.json");
36
+
37
+ default:
38
+ return null;
39
+ }
40
+ }
41
+
42
+ function getBinaryPath() {
43
+ const binDir = path.join(__dirname, "bin");
44
+ const exeName = process.platform === "win32" ? "UnityMcpBridge.exe" : "UnityMcpBridge";
45
+ const exePath = path.join(binDir, exeName);
46
+
47
+ if (fs.existsSync(exePath)) {
48
+ return exePath;
49
+ }
50
+
51
+ return null;
52
+ }
53
+
54
+ function getMcpServerConfig(binaryPath) {
55
+ if (binaryPath) {
56
+ return {
57
+ command: binaryPath,
58
+ args: [],
59
+ env: {}
60
+ };
61
+ }
62
+
63
+ return {
64
+ command: "npx",
65
+ args: ["-y", "unity-mcp-bridge"],
66
+ env: {}
67
+ };
68
+ }
69
+
70
+ function readConfigSafe(configPath) {
71
+ if (!fs.existsSync(configPath)) {
72
+ return {};
73
+ }
74
+
75
+ try {
76
+ const raw = fs.readFileSync(configPath, "utf8");
77
+ return JSON.parse(raw);
78
+ } catch (err) {
79
+ console.warn(`Warning: existing config at ${configPath} is malformed. Existing content will be preserved as a backup.`);
80
+ const backupPath = configPath + ".backup";
81
+ try {
82
+ fs.copyFileSync(configPath, backupPath);
83
+ console.warn(` Backup saved to: ${backupPath}`);
84
+ } catch (_) {
85
+ // Ignore backup failure
86
+ }
87
+ return {};
88
+ }
89
+ }
90
+
91
+ function writeConfig(configPath, config) {
92
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
93
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
94
+ }
95
+
96
+ function setupVSCode(configPath, serverConfig) {
97
+ const config = readConfigSafe(configPath);
98
+
99
+ if (!config.mcp) config.mcp = {};
100
+ if (!config.mcp.servers) config.mcp.servers = {};
101
+ config.mcp.servers["unity-bridge"] = serverConfig;
102
+
103
+ writeConfig(configPath, config);
104
+ }
105
+
106
+ function setupStandardClient(configPath, serverConfig) {
107
+ const config = readConfigSafe(configPath);
108
+
109
+ if (!config.mcpServers) config.mcpServers = {};
110
+ config.mcpServers["unity-bridge"] = serverConfig;
111
+
112
+ writeConfig(configPath, config);
113
+ }
114
+
115
+ function main() {
116
+ const args = process.argv.slice(2);
117
+
118
+ // When invoked via run.js, argv will be [..., "setup", "<client>"]
119
+ // When invoked directly, argv will be [..., "<client>"] or [..., "setup", "<client>"]
120
+ // Filter out "setup" if it's the first arg
121
+ let filteredArgs = args;
122
+ if (filteredArgs[0] === "setup") {
123
+ filteredArgs = filteredArgs.slice(1);
124
+ }
125
+
126
+ if (filteredArgs.length === 0 || filteredArgs[0] === "--help" || filteredArgs[0] === "-h") {
127
+ console.log("Usage: unity-mcp-bridge setup <client>");
128
+ console.log("");
129
+ console.log("Supported clients:");
130
+ SUPPORTED_CLIENTS.forEach(c => console.log(" - " + c));
131
+ console.log("");
132
+ console.log("Examples:");
133
+ console.log(" npx unity-mcp-bridge setup claude-desktop");
134
+ console.log(" npx unity-mcp-bridge setup cursor");
135
+ console.log(" npx unity-mcp-bridge setup claude-code");
136
+ console.log(" npx unity-mcp-bridge setup windsurf");
137
+ console.log(" npx unity-mcp-bridge setup vscode");
138
+ process.exit(0);
139
+ }
140
+
141
+ const client = filteredArgs[0];
142
+
143
+ if (!SUPPORTED_CLIENTS.includes(client)) {
144
+ console.error("Unknown client: " + client);
145
+ console.error("Supported clients: " + SUPPORTED_CLIENTS.join(", "));
146
+ process.exit(1);
147
+ }
148
+
149
+ const configPath = getConfigPath(client);
150
+ if (!configPath) {
151
+ console.error("Cannot determine config path for " + client);
152
+ process.exit(1);
153
+ }
154
+
155
+ const binaryPath = getBinaryPath();
156
+ const serverConfig = getMcpServerConfig(binaryPath);
157
+
158
+ // Allow custom port via environment variable
159
+ const port = process.env.UNITY_TCP_PORT;
160
+ if (port) {
161
+ serverConfig.env.UNITY_TCP_PORT = port;
162
+ }
163
+
164
+ // Remove empty env object for cleaner config
165
+ if (Object.keys(serverConfig.env).length === 0) {
166
+ delete serverConfig.env;
167
+ }
168
+
169
+ try {
170
+ if (client === "vscode") {
171
+ setupVSCode(configPath, serverConfig);
172
+ } else {
173
+ setupStandardClient(configPath, serverConfig);
174
+ }
175
+
176
+ console.log("unity-mcp-bridge configured for " + client + ".");
177
+ console.log(" Config: " + configPath);
178
+ console.log(" Command: " + serverConfig.command + (serverConfig.args.length > 0 ? " " + serverConfig.args.join(" ") : ""));
179
+ if (binaryPath) {
180
+ console.log(" Binary: " + binaryPath);
181
+ }
182
+ console.log("");
183
+ console.log("Restart " + client + " to activate the MCP server.");
184
+ } catch (err) {
185
+ console.error("Failed to configure " + client + ": " + err.message);
186
+ process.exit(1);
187
+ }
188
+ }
189
+
190
+ main();