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.
- package/bin/run.js +23 -18
- package/package.json +5 -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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
13
|
-
|
|
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
|
-
|
|
18
|
-
|
|
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
|
-
|
|
23
|
-
|
|
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
|
-
|
|
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.
|
|
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();
|