Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit cbfecd4

Browse filesBrowse files
Merge pull request #35 from SamyNarrainen/env_port_fix
Env port fix
2 parents 4d0680b + 63622d8 commit cbfecd4
Copy full SHA for cbfecd4

File tree

Expand file treeCollapse file tree

7 files changed

+92
-113
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+92
-113
lines changed

‎Editor/UnityBridge/McpUnitySettings.cs

Copy file name to clipboardExpand all lines: Editor/UnityBridge/McpUnitySettings.cs
+6-20Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public class McpUnitySettings
1919

2020
private const string EnvUnityPort = "UNITY_PORT";
2121
private const string EnvUnityRequestTimeout = "UNITY_REQUEST_TIMEOUT";
22+
/// <remarks>
23+
/// This file path is also read by the MCP server. Changes here will require updates to it. See mcpUnity.ts
24+
/// </remarks>
2225
private const string SettingsPath = "ProjectSettings/McpUnitySettings.json";
2326

2427
private static McpUnitySettings _instance;
@@ -72,18 +75,6 @@ public void LoadSettings()
7275
string json = File.ReadAllText(SettingsPath);
7376
JsonUtility.FromJsonOverwrite(json, this);
7477
}
75-
76-
// Check for environment variable PORT
77-
string envPort = System.Environment.GetEnvironmentVariable(EnvUnityPort);
78-
if (!string.IsNullOrEmpty(envPort) && int.TryParse(envPort, out int port))
79-
{
80-
Port = port;
81-
}
82-
string envTimeout = System.Environment.GetEnvironmentVariable(EnvUnityRequestTimeout);
83-
if (!string.IsNullOrEmpty(envTimeout) && int.TryParse(envTimeout, out int timeout))
84-
{
85-
RequestTimeoutSeconds = timeout;
86-
}
8778
}
8879
catch (Exception ex)
8980
{
@@ -95,21 +86,16 @@ public void LoadSettings()
9586
/// <summary>
9687
/// Save settings to disk
9788
/// </summary>
89+
/// <remarks>
90+
/// WARNING: This file is also read by the MCP server. Changes here will require updates to it. See mcpUnity.ts
91+
/// </remarks>
9892
public void SaveSettings()
9993
{
10094
try
10195
{
10296
// Save settings to McpUnitySettings.json
10397
string json = JsonUtility.ToJson(this, true);
10498
File.WriteAllText(SettingsPath, json);
105-
106-
// Set environment variable PORT for the Node.js process
107-
// EnvironmentVariableTarget.User and EnvironmentVariableTarget.Machine should be used on .NET implementations running on Windows systems only.
108-
// For non-Windows systems, User and Machine are treated as Process.
109-
// Using Process target for broader compatibility.
110-
// see: https://learn.microsoft.com/en-us/dotnet/api/system.environmentvariabletarget?view=net-8.0#remarks
111-
Environment.SetEnvironmentVariable(EnvUnityPort, Port.ToString(), EnvironmentVariableTarget.Process);
112-
Environment.SetEnvironmentVariable(EnvUnityRequestTimeout, RequestTimeoutSeconds.ToString(), EnvironmentVariableTarget.Process);
11399
}
114100
catch (Exception ex)
115101
{

‎Editor/Utils/McpConfigUtils.cs

Copy file name to clipboardExpand all lines: Editor/Utils/McpConfigUtils.cs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public static string GenerateMcpConfigJson(bool useTabsIndentation)
6060
}
6161

6262
/// <summary>
63-
/// Gets the absolute path to the Server directory containing package.json
63+
/// Gets the absolute path to the Server directory containing package.json (root server dir).
6464
/// Works whether MCP Unity is installed via Package Manager or directly in the Assets folder
6565
/// </summary>
6666
public static string GetServerPath()

‎Server~/build/unity/mcpUnity.d.ts

Copy file name to clipboardExpand all lines: Server~/build/unity/mcpUnity.d.ts
+8-9Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,18 @@ export declare class McpUnity {
99
private port;
1010
private ws;
1111
private pendingRequests;
12-
private readonly REQUEST_TIMEOUT;
12+
private requestTimeout;
1313
private retryDelay;
1414
constructor(logger: Logger);
1515
/**
1616
* Start the Unity connection
1717
* @param clientName Optional name of the MCP client connecting to Unity
1818
*/
1919
start(clientName?: string): Promise<void>;
20+
/**
21+
* Reads our configuration file and sets parameters of the server based on them.
22+
*/
23+
private parseAndSetConfig;
2024
/**
2125
* Connect to the Unity WebSocket
2226
* @param clientName Optional name of the MCP client connecting to Unity
@@ -48,14 +52,9 @@ export declare class McpUnity {
4852
*/
4953
get isConnected(): boolean;
5054
/**
51-
* Retrieves the UNITY_PORT value from the Windows registry (HKCU\Environment)
52-
* @returns The port value as a string if found, otherwise an empty string
53-
*/
54-
private getUnityPortFromWindowsRegistry;
55-
/**
56-
* Retrieves the UNITY_PORT value from Unix-like system environment variables
57-
* @returns The port value as a string if found, otherwise an empty string
55+
* Read the McpUnitySettings.json file and return its contents as a JSON object.
56+
* @returns a JSON object with the contents of the McpUnitySettings.json file.
5857
*/
59-
private getUnityPortFromUnixRegistry;
58+
private readConfigFileAsJson;
6059
}
6160
export {};

‎Server~/build/unity/mcpUnity.js

Copy file name to clipboardExpand all lines: Server~/build/unity/mcpUnity.js
+36-39Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,26 @@
11
import WebSocket from 'ws';
22
import { v4 as uuidv4 } from 'uuid';
33
import { McpUnityError, ErrorType } from '../utils/errors.js';
4-
import { execSync } from 'child_process';
5-
import { default as winreg } from 'winreg';
4+
import { promises as fs } from 'fs';
5+
import path from 'path';
66
export class McpUnity {
77
logger;
8-
port;
8+
port = null;
99
ws = null;
1010
pendingRequests = new Map();
11-
REQUEST_TIMEOUT;
11+
requestTimeout = 10000;
1212
retryDelay = 1000;
1313
constructor(logger) {
1414
this.logger = logger;
15-
// Initialize port from environment variable or use default
16-
const envRegistry = process.platform === 'win32'
17-
? this.getUnityPortFromWindowsRegistry()
18-
: this.getUnityPortFromUnixRegistry();
19-
const envPort = process.env.UNITY_PORT || envRegistry;
20-
this.port = envPort ? parseInt(envPort, 10) : 8090;
21-
this.logger.info(`Using port: ${this.port} for Unity WebSocket connection`);
22-
// Initialize timeout from environment variable (in seconds; it is the same as Cline) or use default (10 seconds)
23-
const envTimeout = process.env.UNITY_REQUEST_TIMEOUT;
24-
this.REQUEST_TIMEOUT = envTimeout ? parseInt(envTimeout, 10) * 1000 : 10000;
25-
this.logger.info(`Using request timeout: ${this.REQUEST_TIMEOUT / 1000} seconds`);
2615
}
2716
/**
2817
* Start the Unity connection
2918
* @param clientName Optional name of the MCP client connecting to Unity
3019
*/
3120
async start(clientName) {
3221
try {
22+
this.logger.info('Attempting to read startup parameters...');
23+
await this.parseAndSetConfig();
3324
this.logger.info('Attempting to connect to Unity WebSocket...');
3425
await this.connect(clientName); // Pass client name to connect
3526
this.logger.info('Successfully connected to Unity WebSocket');
@@ -45,6 +36,19 @@ export class McpUnity {
4536
}
4637
return Promise.resolve();
4738
}
39+
/**
40+
* Reads our configuration file and sets parameters of the server based on them.
41+
*/
42+
async parseAndSetConfig() {
43+
const config = await this.readConfigFileAsJson();
44+
const configPort = config.Port;
45+
this.port = configPort ? parseInt(configPort, 10) : 8090;
46+
this.logger.info(`Using port: ${this.port} for Unity WebSocket connection`);
47+
// Initialize timeout from environment variable (in seconds; it is the same as Cline) or use default (10 seconds)
48+
const configTimeout = config.RequestTimeoutSeconds;
49+
this.requestTimeout = configTimeout ? parseInt(configTimeout, 10) * 1000 : 10000;
50+
this.logger.info(`Using request timeout: ${this.requestTimeout / 1000} seconds`);
51+
}
4852
/**
4953
* Connect to the Unity WebSocket
5054
* @param clientName Optional name of the MCP client connecting to Unity
@@ -74,7 +78,7 @@ export class McpUnity {
7478
this.disconnect();
7579
reject(new McpUnityError(ErrorType.CONNECTION, 'Connection timeout'));
7680
}
77-
}, this.REQUEST_TIMEOUT);
81+
}, this.requestTimeout);
7882
this.ws.onopen = () => {
7983
clearTimeout(connectionTimeout);
8084
this.logger.debug('WebSocket connected');
@@ -193,12 +197,12 @@ export class McpUnity {
193197
// Create timeout for the request
194198
const timeout = setTimeout(() => {
195199
if (this.pendingRequests.has(requestId)) {
196-
this.logger.error(`Request ${requestId} timed out after ${this.REQUEST_TIMEOUT}ms`);
200+
this.logger.error(`Request ${requestId} timed out after ${this.requestTimeout}ms`);
197201
this.pendingRequests.delete(requestId);
198202
reject(new McpUnityError(ErrorType.TIMEOUT, 'Request timed out'));
199203
}
200204
this.reconnect();
201-
}, this.REQUEST_TIMEOUT);
205+
}, this.requestTimeout);
202206
// Store pending request
203207
this.pendingRequests.set(requestId, {
204208
resolve,
@@ -225,27 +229,20 @@ export class McpUnity {
225229
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
226230
}
227231
/**
228-
* Retrieves the UNITY_PORT value from the Windows registry (HKCU\Environment)
229-
* @returns The port value as a string if found, otherwise an empty string
230-
*/
231-
getUnityPortFromWindowsRegistry() {
232-
const regKey = new winreg({ hive: winreg.HKCU, key: '\\Environment' });
233-
let result = '';
234-
regKey.get('UNITY_PORT', (err, item) => {
235-
if (err) {
236-
this.logger.error(`Error getting registry value: ${err.message}`);
237-
}
238-
else {
239-
result = item.value;
240-
}
241-
});
242-
return result;
243-
}
244-
/**
245-
* Retrieves the UNITY_PORT value from Unix-like system environment variables
246-
* @returns The port value as a string if found, otherwise an empty string
232+
* Read the McpUnitySettings.json file and return its contents as a JSON object.
233+
* @returns a JSON object with the contents of the McpUnitySettings.json file.
247234
*/
248-
getUnityPortFromUnixRegistry() {
249-
return execSync('printenv UNITY_PORT', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
235+
async readConfigFileAsJson() {
236+
const configPath = path.resolve(process.cwd(), '../ProjectSettings/McpUnitySettings.json');
237+
this.logger.debug(`Reading McpUnitySettings.json from ${configPath}`);
238+
try {
239+
const content = await fs.readFile(configPath, 'utf-8');
240+
const json = JSON.parse(content);
241+
return json;
242+
}
243+
catch (err) {
244+
this.logger.debug(`McpUnitySettings.json not found or unreadable: ${err instanceof Error ? err.message : String(err)}`);
245+
return {};
246+
}
250247
}
251248
}

‎Server~/build/utils/errors.js

Copy file name to clipboardExpand all lines: Server~/build/utils/errors.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export var ErrorType;
66
ErrorType["VALIDATION"] = "validation_error";
77
ErrorType["INTERNAL"] = "internal_error";
88
ErrorType["TIMEOUT"] = "timeout_error";
9-
})(ErrorType || (ErrorType = {}));
9+
})(ErrorType = ErrorType || (ErrorType = {}));
1010
export class McpUnityError extends Error {
1111
type;
1212
details;

‎Server~/build/utils/logger.js

Copy file name to clipboardExpand all lines: Server~/build/utils/logger.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export var LogLevel;
55
LogLevel[LogLevel["INFO"] = 1] = "INFO";
66
LogLevel[LogLevel["WARN"] = 2] = "WARN";
77
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
8-
})(LogLevel || (LogLevel = {}));
8+
})(LogLevel = LogLevel || (LogLevel = {}));
99
// Check environment variable for logging
1010
const isLoggingEnabled = process.env.LOGGING === 'true';
1111
// Check environment variable for logging in a file

‎Server~/src/unity/mcpUnity.ts

Copy file name to clipboardExpand all lines: Server~/src/unity/mcpUnity.ts
+39-42Lines changed: 39 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import WebSocket from 'ws';
22
import { v4 as uuidv4 } from 'uuid';
33
import { Logger } from '../utils/logger.js';
44
import { McpUnityError, ErrorType } from '../utils/errors.js';
5-
import { execSync } from 'child_process';
6-
import { default as winreg } from 'winreg';
5+
import { promises as fs } from 'fs';
6+
import path from 'path';
77

88
interface PendingRequest {
99
resolve: (value: any) => void;
@@ -30,28 +30,14 @@ interface UnityResponse {
3030

3131
export class McpUnity {
3232
private logger: Logger;
33-
private port: number;
33+
private port: number | null = null;
3434
private ws: WebSocket | null = null;
3535
private pendingRequests: Map<string, PendingRequest> = new Map<string, PendingRequest>();
36-
private readonly REQUEST_TIMEOUT: number;
36+
private requestTimeout = 10000;
3737
private retryDelay = 1000;
3838

3939
constructor(logger: Logger) {
4040
this.logger = logger;
41-
42-
// Initialize port from environment variable or use default
43-
const envRegistry = process.platform === 'win32'
44-
? this.getUnityPortFromWindowsRegistry()
45-
: this.getUnityPortFromUnixRegistry();
46-
47-
const envPort = process.env.UNITY_PORT || envRegistry;
48-
this.port = envPort ? parseInt(envPort, 10) : 8090;
49-
this.logger.info(`Using port: ${this.port} for Unity WebSocket connection`);
50-
51-
// Initialize timeout from environment variable (in seconds; it is the same as Cline) or use default (10 seconds)
52-
const envTimeout = process.env.UNITY_REQUEST_TIMEOUT;
53-
this.REQUEST_TIMEOUT = envTimeout ? parseInt(envTimeout, 10) * 1000 : 10000;
54-
this.logger.info(`Using request timeout: ${this.REQUEST_TIMEOUT / 1000} seconds`);
5541
}
5642

5743
/**
@@ -60,6 +46,9 @@ export class McpUnity {
6046
*/
6147
public async start(clientName?: string): Promise<void> {
6248
try {
49+
this.logger.info('Attempting to read startup parameters...');
50+
await this.parseAndSetConfig();
51+
6352
this.logger.info('Attempting to connect to Unity WebSocket...');
6453
await this.connect(clientName); // Pass client name to connect
6554
this.logger.info('Successfully connected to Unity WebSocket');
@@ -77,6 +66,22 @@ export class McpUnity {
7766

7867
return Promise.resolve();
7968
}
69+
70+
/**
71+
* Reads our configuration file and sets parameters of the server based on them.
72+
*/
73+
private async parseAndSetConfig() {
74+
const config = await this.readConfigFileAsJson();
75+
76+
const configPort = config.Port;
77+
this.port = configPort ? parseInt(configPort, 10) : 8090;
78+
this.logger.info(`Using port: ${this.port} for Unity WebSocket connection`);
79+
80+
// Initialize timeout from environment variable (in seconds; it is the same as Cline) or use default (10 seconds)
81+
const configTimeout = config.RequestTimeoutSeconds;
82+
this.requestTimeout = configTimeout ? parseInt(configTimeout, 10) * 1000 : 10000;
83+
this.logger.info(`Using request timeout: ${this.requestTimeout / 1000} seconds`);
84+
}
8085

8186
/**
8287
* Connect to the Unity WebSocket
@@ -112,7 +117,7 @@ export class McpUnity {
112117
this.disconnect();
113118
reject(new McpUnityError(ErrorType.CONNECTION, 'Connection timeout'));
114119
}
115-
}, this.REQUEST_TIMEOUT);
120+
}, this.requestTimeout);
116121

117122
this.ws.onopen = () => {
118123
clearTimeout(connectionTimeout);
@@ -249,12 +254,12 @@ export class McpUnity {
249254
// Create timeout for the request
250255
const timeout = setTimeout(() => {
251256
if (this.pendingRequests.has(requestId)) {
252-
this.logger.error(`Request ${requestId} timed out after ${this.REQUEST_TIMEOUT}ms`);
257+
this.logger.error(`Request ${requestId} timed out after ${this.requestTimeout}ms`);
253258
this.pendingRequests.delete(requestId);
254259
reject(new McpUnityError(ErrorType.TIMEOUT, 'Request timed out'));
255260
}
256261
this.reconnect();
257-
}, this.REQUEST_TIMEOUT);
262+
}, this.requestTimeout);
258263

259264
// Store pending request
260265
this.pendingRequests.set(requestId, {
@@ -282,29 +287,21 @@ export class McpUnity {
282287
// Basic WebSocket connection check
283288
return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
284289
}
285-
286-
/**
287-
* Retrieves the UNITY_PORT value from the Windows registry (HKCU\Environment)
288-
* @returns The port value as a string if found, otherwise an empty string
289-
*/
290-
private getUnityPortFromWindowsRegistry(): string {
291-
const regKey = new winreg({hive: winreg.HKCU, key: '\\Environment'});
292-
let result = '';
293-
regKey.get('UNITY_PORT', (err: Error | null, item: any) => {
294-
if (err) {
295-
this.logger.error(`Error getting registry value: ${err.message}`);
296-
} else {
297-
result = item.value;
298-
}
299-
});
300-
return result;
301-
}
302290

303291
/**
304-
* Retrieves the UNITY_PORT value from Unix-like system environment variables
305-
* @returns The port value as a string if found, otherwise an empty string
292+
* Read the McpUnitySettings.json file and return its contents as a JSON object.
293+
* @returns a JSON object with the contents of the McpUnitySettings.json file.
306294
*/
307-
private getUnityPortFromUnixRegistry(): string {
308-
return execSync('printenv UNITY_PORT', { stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
295+
private async readConfigFileAsJson(): Promise<any> {
296+
const configPath = path.resolve(process.cwd(), '../ProjectSettings/McpUnitySettings.json');
297+
this.logger.debug(`Reading McpUnitySettings.json from ${configPath}`);
298+
try {
299+
const content = await fs.readFile(configPath, 'utf-8');
300+
const json = JSON.parse(content);
301+
return json;
302+
} catch (err) {
303+
this.logger.debug(`McpUnitySettings.json not found or unreadable: ${err instanceof Error ? err.message : String(err)}`);
304+
return {};
305+
}
309306
}
310307
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.