Skip to content

Commit d66a971

Browse files
committed
refactor: update console logging and resource handling for more accurate output
- Rename getConsoleLogResource to getConsoleLogsResource for consistency chore: remove the update pop up when changing the MCP port
1 parent 086a94c commit d66a971

File tree

8 files changed

+138
-90
lines changed

8 files changed

+138
-90
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ GvhProjectSettings.xml
114114
**/package-lock.json
115115
**/package-lock.json.meta
116116
.codeiumignore
117+
.windsurf
117118
Server/log.txt
118119
Server/log.txt.meta
119120
log.txt

Editor/Resources/GetConsoleLogsResource.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,36 @@ public class GetConsoleLogsResource : McpResourceBase
1313
public GetConsoleLogsResource(IConsoleLogsService consoleLogsService)
1414
{
1515
Name = "get_console_logs";
16-
Description = "Retrieves all logs from the Unity console";
17-
Uri = "unity://logs";
16+
Description = "Retrieves logs from the Unity console, optionally filtered by type (error, warning, info)";
17+
Uri = "unity://logs/{logType}";
1818

1919
_consoleLogsService = consoleLogsService;
2020
}
2121

2222
/// <summary>
23-
/// Fetch all logs from the Unity console
23+
/// Fetch logs from the Unity console, optionally filtered by type
2424
/// </summary>
25-
/// <param name="parameters">Resource parameters as a JObject (not used)</param>
25+
/// <param name="parameters">Resource parameters as a JObject (may include 'logType')</param>
2626
/// <returns>A JObject containing the list of logs</returns>
2727
public override JObject Fetch(JObject parameters)
2828
{
29-
// Get logs from the service
30-
JArray logsArray = _consoleLogsService.GetAllLogsAsJson();
31-
29+
string logType = null;
30+
if (parameters != null && parameters.ContainsKey("logType") && parameters["logType"] != null)
31+
{
32+
logType = parameters["logType"].ToString()?.ToLowerInvariant();
33+
if (string.IsNullOrWhiteSpace(logType))
34+
{
35+
logType = null;
36+
}
37+
}
38+
39+
JArray logsArray = _consoleLogsService.GetAllLogsAsJson(logType);
40+
3241
// Create the response
3342
return new JObject
3443
{
3544
["success"] = true,
36-
["message"] = $"Retrieved {logsArray.Count} log entries",
45+
["message"] = $"Retrieved {logsArray.Count} log entries" + (logType != null ? $" of type '{logType}'" : ""),
3746
["logs"] = logsArray
3847
};
3948
}

Editor/Services/ConsoleLogsService.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public ConsoleLogsService()
3838
public void StartListening()
3939
{
4040
// Register for log messages
41-
Application.logMessageReceived += OnLogMessageReceived;
41+
Application.logMessageReceivedThreaded += OnLogMessageReceived;
4242

4343
#if UNITY_6000_0_OR_NEWER
4444
// Unity 6 specific implementation
@@ -55,7 +55,7 @@ public void StartListening()
5555
public void StopListening()
5656
{
5757
// Unregister from log messages
58-
Application.logMessageReceived -= OnLogMessageReceived;
58+
Application.logMessageReceivedThreaded -= OnLogMessageReceived;
5959

6060
#if UNITY_6000_0_OR_NEWER
6161
// Unity 6 specific implementation
@@ -145,13 +145,16 @@ private void CheckConsoleClearViaReflection()
145145
private void OnLogMessageReceived(string logString, string stackTrace, LogType type)
146146
{
147147
// Add the log entry to our collection
148-
_logEntries.Add(new LogEntry
148+
lock (_logEntries)
149149
{
150-
Message = logString,
151-
StackTrace = stackTrace,
152-
Type = type,
153-
Timestamp = DateTime.Now
154-
});
150+
_logEntries.Add(new LogEntry
151+
{
152+
Message = logString,
153+
StackTrace = stackTrace,
154+
Type = type,
155+
Timestamp = DateTime.Now
156+
});
157+
}
155158
}
156159

157160
#if UNITY_6000_0_OR_NEWER

Editor/Tools/UpdateComponentTool.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ private GameObject FindGameObjectByPath(string path)
134134
{
135135
// Split the path by '/'
136136
string[] pathParts = path.Split('/');
137+
GameObject[] rootGameObjects = UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects();
137138

138139
// If the path is empty, return null
139140
if (pathParts.Length == 0)
@@ -142,7 +143,7 @@ private GameObject FindGameObjectByPath(string path)
142143
}
143144

144145
// Search through all root GameObjects in all scenes
145-
foreach (GameObject rootObj in UnityEngine.SceneManagement.SceneManager.GetActiveScene().GetRootGameObjects())
146+
foreach (GameObject rootObj in rootGameObjects)
146147
{
147148
if (rootObj.name == pathParts[0])
148149
{

Editor/UnityBridge/McpUnityEditorWindow.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,7 @@ private void DrawServerTab()
9999
settings.Port = newPort;
100100
settings.SaveSettings();
101101
mcpUnityServer.StopServer();
102-
EditorUtility.DisplayDialog("Restart MCP Client",
103-
"Please restart your MCP Client (Windsurf, Cursor, Calude Destktop, etc.) to apply the changes.",
104-
"OK");
102+
mcpUnityServer.StartServer(); // Restart the server.newPort
105103
}
106104
EditorGUILayout.EndHorizontal();
107105

@@ -261,6 +259,10 @@ private void DrawServerTab()
261259
{
262260
EditorUtility.DisplayDialog("Success", "The MCP configuration was successfully added to the Cursor config file.", "OK");
263261
}
262+
else
263+
{
264+
EditorUtility.DisplayDialog("Error", "The MCP configuration could not be added to the Cursor Desktop config file.", "OK");
265+
}
264266
}
265267

266268
EditorGUILayout.EndVertical();

Server~/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { registerSendConsoleLogTool } from './tools/sendConsoleLogTool.js';
1111
import { registerUpdateComponentTool } from './tools/updateComponentTool.js';
1212
import { registerAddAssetToSceneTool } from './tools/addAssetToSceneTool.js';
1313
import { registerGetMenuItemsResource } from './resources/getMenuItemResource.js';
14-
import { registerGetConsoleLogsResource } from './resources/getConsoleLogResource.js';
14+
import { registerGetConsoleLogsResource } from './resources/getConsoleLogsResource.js';
1515
import { registerGetHierarchyResource } from './resources/getHierarchyResource.js';
1616
import { registerGetPackagesResource } from './resources/getPackagesResource.js';
1717
import { registerGetAssetsResource } from './resources/getAssetsResource.js';

Server~/src/resources/getConsoleLogResource.ts

Lines changed: 0 additions & 69 deletions
This file was deleted.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { Logger } from '../utils/logger.js';
2+
import { ResourceTemplate, McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3+
import { ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
4+
import { McpUnity } from '../unity/mcpUnity.js';
5+
import { McpUnityError, ErrorType } from '../utils/errors.js';
6+
import { Variables } from '@modelcontextprotocol/sdk/shared/uriTemplate.js';
7+
8+
// Constants for the resource
9+
const resourceName = 'get_console_logs';
10+
const resourceMimeType = 'application/json';
11+
const resourceUri = 'unity://logs/{logType}';
12+
const resourceTemplate = new ResourceTemplate(resourceUri, {
13+
list: () => listLogTypes(resourceMimeType)
14+
});
15+
16+
function listLogTypes(resourceMimeType: string) {
17+
return {
18+
resources: [
19+
{
20+
uri: `unity://logs/`,
21+
name: "All logs",
22+
description: "Retrieve all Unity console logs",
23+
mimeType: resourceMimeType
24+
},
25+
{
26+
uri: `unity://logs/error`,
27+
name: "Error logs",
28+
description: "Retrieve only error logs from the Unity console",
29+
mimeType: resourceMimeType
30+
},
31+
{
32+
uri: `unity://logs/warning`,
33+
name: "Warning logs",
34+
description: "Retrieve only warning logs from the Unity console",
35+
mimeType: resourceMimeType
36+
},
37+
{
38+
uri: `unity://logs/info`,
39+
name: "Info logs",
40+
description: "Retrieve only info logs from the Unity console",
41+
mimeType: resourceMimeType
42+
}
43+
]
44+
};
45+
}
46+
47+
/**
48+
* Registers the get_console_logs resource with the MCP server
49+
*/
50+
export function registerGetConsoleLogsResource(server: McpServer, mcpUnity: McpUnity, logger: Logger) {
51+
logger.info(`Registering resource: ${resourceName}`);
52+
53+
server.resource(
54+
resourceName,
55+
resourceTemplate,
56+
{
57+
description: 'Retrieve Unity console logs by type',
58+
mimeType: resourceMimeType
59+
},
60+
async (uri, variables) => {
61+
try {
62+
return await resourceHandler(mcpUnity, uri, variables, logger);
63+
} catch (error) {
64+
logger.error(`Error handling resource ${resourceName}: ${error}`);
65+
throw error;
66+
}
67+
}
68+
);
69+
}
70+
71+
/**
72+
* Handles requests for Unity console logs by log type
73+
*/
74+
async function resourceHandler(mcpUnity: McpUnity, uri: URL, variables: Variables, logger: Logger): Promise<ReadResourceResult> {
75+
// Extract and convert the parameter from the template variables
76+
let logType = variables["logType"] ? decodeURIComponent(variables["logType"] as string) : undefined;
77+
if (logType === '') logType = undefined;
78+
79+
// Send request to Unity
80+
const response = await mcpUnity.sendRequest({
81+
method: resourceName,
82+
params: {
83+
logType: logType
84+
}
85+
});
86+
87+
if (!response.success) {
88+
throw new McpUnityError(
89+
ErrorType.RESOURCE_FETCH,
90+
response.message || 'Failed to fetch logs from Unity'
91+
);
92+
}
93+
94+
return {
95+
contents: [{
96+
uri: `unity://logs/${logType ?? ''}`,
97+
mimeType: resourceMimeType,
98+
text: JSON.stringify(response, null, 2)
99+
}]
100+
};
101+
}

0 commit comments

Comments
 (0)