@akiojin/unity-mcp-server 2.42.2 → 2.42.4
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/bootstrap.js +38 -0
- package/package.json +3 -3
- package/src/core/config.js +4 -0
- package/src/core/unityConnection.js +19 -4
package/bin/bootstrap.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Bootstrap wrapper for unity-mcp-server
|
|
4
|
+
*
|
|
5
|
+
* This wrapper ensures:
|
|
6
|
+
* 1. Early stderr output before any module loading
|
|
7
|
+
* 2. Global exception handlers are registered first
|
|
8
|
+
* 3. Module load failures are caught and reported
|
|
9
|
+
*
|
|
10
|
+
* ESM static imports are hoisted, so we use dynamic import() to
|
|
11
|
+
* ensure our error handlers are set up before loading the main module.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Synchronous stderr write - this MUST appear before any module loading
|
|
15
|
+
process.stderr.write('[unity-mcp-server] Bootstrap starting...\n');
|
|
16
|
+
|
|
17
|
+
// Global exception handlers - catch any unhandled errors
|
|
18
|
+
process.on('uncaughtException', err => {
|
|
19
|
+
process.stderr.write(`[unity-mcp-server] FATAL: Uncaught exception: ${err.message}\n`);
|
|
20
|
+
process.stderr.write(`${err.stack}\n`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
process.on('unhandledRejection', (reason, _promise) => {
|
|
25
|
+
const msg = reason instanceof Error ? reason.message : String(reason);
|
|
26
|
+
const stack = reason instanceof Error ? reason.stack : '';
|
|
27
|
+
process.stderr.write(`[unity-mcp-server] FATAL: Unhandled rejection: ${msg}\n`);
|
|
28
|
+
if (stack) process.stderr.write(`${stack}\n`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Dynamic import to load the main module AFTER error handlers are set up
|
|
33
|
+
// This allows us to catch module load failures
|
|
34
|
+
import('./unity-mcp-server').catch(err => {
|
|
35
|
+
process.stderr.write(`[unity-mcp-server] FATAL: Module load failed: ${err.message}\n`);
|
|
36
|
+
process.stderr.write(`${err.stack}\n`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
});
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akiojin/unity-mcp-server",
|
|
3
|
-
"version": "2.42.
|
|
3
|
+
"version": "2.42.4",
|
|
4
4
|
"description": "MCP server and Unity Editor bridge — enables AI assistants to control Unity for AI-assisted workflows",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/core/server.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"unity-mcp-server": "./bin/
|
|
8
|
+
"unity-mcp-server": "./bin/bootstrap.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node src/core/server.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"prebuild:better-sqlite3": "node scripts/prebuild-better-sqlite3.mjs",
|
|
30
30
|
"prebuilt:manifest": "node scripts/generate-prebuilt-manifest.mjs",
|
|
31
31
|
"prepublishOnly": "npm run test:ci && npm run prebuilt:manifest",
|
|
32
|
-
"postinstall": "node scripts/ensure-better-sqlite3.mjs && chmod +x bin/unity-mcp-server || true",
|
|
32
|
+
"postinstall": "node scripts/ensure-better-sqlite3.mjs && chmod +x bin/bootstrap.js bin/unity-mcp-server || true",
|
|
33
33
|
"test:ci:unity": "timeout 60 node --test tests/unit/core/codeIndex.test.js tests/unit/core/config.test.js tests/unit/core/indexWatcher.test.js tests/unit/core/projectInfo.test.js tests/unit/core/server.test.js || exit 0",
|
|
34
34
|
"test:unity": "node tests/run-unity-integration.mjs",
|
|
35
35
|
"test:nounity": "npm run test:integration",
|
package/src/core/config.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import * as findUpPkg from 'find-up';
|
|
4
|
+
|
|
5
|
+
// Diagnostic log: confirm module loading reached this point
|
|
6
|
+
process.stderr.write('[unity-mcp-server] Config module loading...\n');
|
|
7
|
+
|
|
4
8
|
function findUpSyncCompat(matcher, options = {}) {
|
|
5
9
|
if (typeof matcher === 'function') {
|
|
6
10
|
let dir = options.cwd || process.cwd();
|
|
@@ -21,6 +21,7 @@ export class UnityConnection extends EventEmitter {
|
|
|
21
21
|
this.sendQueue = [];
|
|
22
22
|
this.inFlight = 0;
|
|
23
23
|
this.maxInFlight = 1; // process one command at a time by default
|
|
24
|
+
this.connectedAt = null; // Timestamp when connection was established
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
/**
|
|
@@ -77,8 +78,11 @@ export class UnityConnection extends EventEmitter {
|
|
|
77
78
|
|
|
78
79
|
// Set up event handlers
|
|
79
80
|
this.socket.on('connect', () => {
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
this.connectedAt = Date.now();
|
|
82
|
+
console.error(
|
|
83
|
+
`[unity-mcp-server] Unity TCP connected to ${targetHost}:${config.unity.port}`
|
|
84
|
+
);
|
|
85
|
+
logger.info(`Connected to Unity Editor at ${targetHost}:${config.unity.port}`);
|
|
82
86
|
this.connected = true;
|
|
83
87
|
this.reconnectAttempts = 0;
|
|
84
88
|
this.connectPromise = null;
|
|
@@ -88,6 +92,12 @@ export class UnityConnection extends EventEmitter {
|
|
|
88
92
|
});
|
|
89
93
|
|
|
90
94
|
this.socket.on('end', () => {
|
|
95
|
+
// Unity closed the connection (FIN received)
|
|
96
|
+
const duration = this.connectedAt ? Date.now() - this.connectedAt : 0;
|
|
97
|
+
console.error(
|
|
98
|
+
`[unity-mcp-server] Unity TCP connection ended by remote (FIN received, duration: ${duration}ms)`
|
|
99
|
+
);
|
|
100
|
+
logger.info(`Unity closed connection (FIN received) after ${duration}ms`);
|
|
91
101
|
// Treat end as close to trigger reconnection
|
|
92
102
|
this.socket.destroy();
|
|
93
103
|
});
|
|
@@ -130,9 +140,11 @@ export class UnityConnection extends EventEmitter {
|
|
|
130
140
|
return;
|
|
131
141
|
}
|
|
132
142
|
|
|
133
|
-
|
|
134
|
-
|
|
143
|
+
const duration = this.connectedAt ? Date.now() - this.connectedAt : 0;
|
|
144
|
+
console.error(`[unity-mcp-server] Unity TCP disconnected (duration: ${duration}ms)`);
|
|
145
|
+
logger.info(`Disconnected from Unity Editor after ${duration}ms`);
|
|
135
146
|
this.connected = false;
|
|
147
|
+
this.connectedAt = null;
|
|
136
148
|
this.socket = null;
|
|
137
149
|
|
|
138
150
|
// Clear message buffer
|
|
@@ -231,6 +243,9 @@ export class UnityConnection extends EventEmitter {
|
|
|
231
243
|
* @param {Buffer} data
|
|
232
244
|
*/
|
|
233
245
|
handleData(data) {
|
|
246
|
+
// Log received data size for debugging connection issues
|
|
247
|
+
console.error(`[unity-mcp-server] Received ${data.length} bytes from Unity`);
|
|
248
|
+
|
|
234
249
|
// Fast-path: accept single unframed JSON message (NDJSON style) from tests/clients
|
|
235
250
|
if (!this.messageBuffer.length) {
|
|
236
251
|
const asString = data.toString('utf8').trim();
|