-
Notifications
You must be signed in to change notification settings - Fork 116
feat: Add search_console_logs tool for Unity log searching #50
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add search_console_logs tool for Unity log searching #50
Conversation
…ementation - Add ConsoleLogServiceType enum with EventBased and Unity6Enhanced options - Implement ConsoleLogsServiceUnity6 using internal LogEntries API for better reliability - Add command line argument support (-mcpConsoleLogService) for runtime switching - Update McpUnityServer to dynamically select service based on settings and Unity version - Add UI controls in McpUnityEditorWindow with warning dialogs for internal API usage - Default to safe EventBased implementation, Unity6Enhanced only when explicitly selected - Add clear startup logging to identify which implementation is active 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
…ered values - Create LogEntryModeFlags.cs with Unity's internal mode flag constants - Add support for observed mode values from debugging: * Compiler warnings: 266240 (0x41000) * Compiler errors: 272384 (0x42800) * Shader errors: 262212 (0x40044) * Runtime warnings: 8405504 (0x804200) * Runtime errors: 8405248 (0x804100) - Update Unity6InternalAPIReference.md with complete documentation - Add conditional debug logging for future mode value discovery - Improve error/warning classification accuracy in Unity 6 implementation This enables proper filtering of shader errors, compile errors, and runtime exceptions that were previously misclassified as "Log" type. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Removed GetEffectiveConsoleLogService() method - Console log service now only configurable via Unity Editor settings UI - Simplified configuration as command-line args are not practical for Unity Hub users 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
Keep file locally but stop tracking it in git 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
📝 WalkthroughWalkthroughThis update introduces a Unity 6-specific console log service that leverages internal Unity APIs for more reliable log retrieval, adds a settings UI for selecting the log service implementation, and provides supporting infrastructure including mode flag interpretation and documentation. The system dynamically selects the appropriate log service based on user settings and Unity version. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EditorWindow
participant Settings
participant McpUnityServer
participant ConsoleLogsServiceUnity6
participant ConsoleLogsService
User->>EditorWindow: Selects Console Log Service Type
EditorWindow->>Settings: Save selection (EventBased or Unity6Enhanced)
User->>McpUnityServer: (On server restart) InitializeServices()
McpUnityServer->>Settings: Read ConsoleLogServiceType
alt Unity6Enhanced and Unity 6+
McpUnityServer->>ConsoleLogsServiceUnity6: Instantiate and use
else Unity6Enhanced and not Unity 6+
McpUnityServer->>ConsoleLogsService: Instantiate fallback
else EventBased
McpUnityServer->>ConsoleLogsService: Instantiate and use
end
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate Unit Tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (6)
Editor/Services/LogEntryModeFlags.cs (2)
24-31
: Unused composite constants add noise
ObservedRuntimeWarning
andObservedRuntimeError
are declared but never referenced byGetLogTypeFromMode
. Either document their future use or remove them to avoid dead code.
57-57
: Magic fallback hides unknown modesSilently mapping every unrecognised mode to “Log” can mask future Unity additions. Prefer an explicit
"Unknown"
(or throwing) so callers decide how to handle unexpected data..gitignore (1)
124-126
: Good addition to ignore local Claude settingsYou might also ignore any file under
.claude/
to future-proof:-.claude/settings.local.json +.claude/Editor/Services/ConsoleLogsServiceUnity6.cs (2)
158-167
: Iterator walks the entire console on every request — consider early-exit for pagination.
for (int i = currentCount - 1; i >= 0; i--)
iterates every row to laterSkip(offset).Take(limit)
.
For huge logs this is O(n) per request; when clients page through data the cost repeats.A cheap optimisation: iterate until
collectedLogs.Count > offset + limit
and break, skipping work once enough items are gathered.
202-203
: Timestamp fabrication is misleading.
DateTime.Now.AddSeconds(-(currentCount - i))
produces synthetic, non-deterministic timestamps that change each call and bear no relation to when the log was emitted.If Unity’s internal API doesn’t expose time, omit the field or mark it
"unknown"
to avoid conveying inaccurate data.Editor/Services/Unity6InternalAPIReference.md (1)
8-14
: Minor Markdown-lint violations (blank lines around table).Insert a blank line before and after the table to silence MD058 and improve readability.
-### Fields -| Field Name | Type | Description | +### Fields + +| Field Name | Type | Description | ... -| callstackTextStartUTF16 | Int32 | UTF-16 character position where stack trace starts | +| callstackTextStartUTF16 | Int32 | UTF-16 character position where stack trace starts | +
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
.gitignore
(1 hunks)Editor/Services/ConsoleLogsServiceUnity6.cs
(1 hunks)Editor/Services/ConsoleLogsServiceUnity6.cs.meta
(1 hunks)Editor/Services/LogEntryModeFlags.cs
(1 hunks)Editor/Services/LogEntryModeFlags.cs.meta
(1 hunks)Editor/Services/Unity6InternalAPIReference.md
(1 hunks)Editor/Services/Unity6InternalAPIReference.md.meta
(1 hunks)Editor/UnityBridge/McpUnityEditorWindow.cs
(1 hunks)Editor/UnityBridge/McpUnityServer.cs
(2 hunks)Editor/UnityBridge/McpUnitySettings.cs
(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
Editor/UnityBridge/McpUnityEditorWindow.cs (1)
Editor/UnityBridge/McpUnitySettings.cs (1)
SaveSettings
(110-123)
Editor/Services/LogEntryModeFlags.cs (1)
Editor/Services/ConsoleLogsServiceUnity6.cs (1)
GetLogTypeFromMode
(348-352)
🪛 markdownlint-cli2 (0.17.2)
Editor/Services/Unity6InternalAPIReference.md
8-8: Tables should be surrounded by blank lines
null
(MD058, blanks-around-tables)
74-74: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🔇 Additional comments (6)
Editor/Services/LogEntryModeFlags.cs (1)
35-58
: Branch priority may mis-classify mixed-flag modesWhen multiple bits are set (e.g.,
kModeError | kModeWarning
) the first matching branch wins, which might hide a more severe flag. Consider checkingError/Exception
bits first irrespective of scripting/compiler special-cases, or compute severity via a priority table.Editor/Services/ConsoleLogsServiceUnity6.cs.meta (1)
1-2
: Meta file OK – Unity asset metadata only; nothing to review.Editor/Services/Unity6InternalAPIReference.md.meta (1)
1-7
: Meta file OK – documentation asset metadata only.Editor/Services/LogEntryModeFlags.cs.meta (1)
1-11
: Meta file OK – code asset metadata only.Editor/UnityBridge/McpUnitySettings.cs (1)
9-20
: Enum addition looks good – nothing blocking.The new
ConsoleLogServiceType
enum is straightforward and scoped correctly. No issues spotted here.Editor/UnityBridge/McpUnityServer.cs (1)
252-271
: Verify the pre-processor symbol for Unity 6 detection.The compilation guard uses
UNITY_6000_0_OR_NEWER
. Unity has historically exposed symbols such asUNITY_2020_1_OR_NEWER
, but early 6.0 alphas have shipped withUNITY_6000_OR_NEWER
(note the missing minor component). Double-check the exact symbol name to avoid the enhanced service getting stripped by the compiler even on Unity 6.No code change proposed—please confirm at build time.
public static string GetLogTypeFromMode(int mode) | ||
{ | ||
// Check for observed compiler/shader message patterns first | ||
if (mode == ObservedCompilerError) return "Error"; | ||
if (mode == ObservedCompilerWarning) return "Warning"; | ||
if (mode == ObservedShaderError) return "Error"; | ||
|
||
// Check for script compile errors/warnings | ||
if ((mode & kScriptCompileError) != 0) return "Error"; | ||
if ((mode & kScriptCompileWarning) != 0) return "Warning"; | ||
|
||
// Check for scripting errors/warnings | ||
if ((mode & kScriptingError) != 0) return "Error"; | ||
if ((mode & kScriptingWarning) != 0) return "Warning"; | ||
|
||
// Then check standard flags | ||
if ((mode & kModeError) != 0) return "Error"; | ||
if ((mode & kModeAssert) != 0) return "Assert"; | ||
if ((mode & kModeException) != 0) return "Exception"; | ||
if ((mode & kModeWarning) != 0) return "Warning"; | ||
if ((mode & kModeLog) != 0) return "Log"; | ||
|
||
return "Log"; // Default to Log instead of Unknown | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
GetLogTypeFromMode
should return LogType
enum instead of string
Returning a string sacrifices compile-time safety and invites typos downstream. Unity already defines UnityEngine.LogType
; re-using it would avoid an extra abstraction and makes switch statements exhaustively check all cases.
-public static string GetLogTypeFromMode(int mode)
+public static UnityEngine.LogType GetLogTypeFromMode(int mode)
Adjust the return
statements accordingly.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In Editor/Services/LogEntryModeFlags.cs between lines 35 and 58, the
GetLogTypeFromMode method currently returns string values representing log
types, which reduces type safety and risks typos. Modify the method to return
the UnityEngine.LogType enum instead of strings by replacing all string return
values with the corresponding LogType enum members. This change will improve
compile-time checking and allow exhaustive switch statements on the returned log
type.
// Basic log type flags (bits 0-4) | ||
public const int kModeError = 1 << 0; // 1 (0x1) | ||
public const int kModeAssert = 1 << 1; // 2 (0x2) | ||
public const int kModeLog = 1 << 2; // 4 (0x4) | ||
public const int kModeWarning = 1 << 3; // 8 (0x8) | ||
public const int kModeException = 1 << 4; // 16 (0x10) | ||
|
||
// Scripting related flags (bits 8-12) | ||
public const int kScriptingError = 1 << 8; // 256 (0x100) | ||
public const int kScriptingWarning = 1 << 9; // 512 (0x200) | ||
public const int kScriptingLog = 1 << 10; // 1024 (0x400) | ||
public const int kScriptCompileError = 1 << 11; // 2048 (0x800) | ||
public const int kScriptCompileWarning = 1 << 12; // 4096 (0x1000) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider using a [Flags]
enum instead of raw const int
values
Using an enum provides type-safety, self-documentation, and built-in bitwise helpers while still compiling to the same constants. Example:
-public const int kModeError = 1 << 0;
...
-public const int kScriptCompileWarning = 1 << 12;
+[Flags]
+public enum LogEntryMode
+{
+ Error = 1 << 0,
+ Assert = 1 << 1,
+ Log = 1 << 2,
+ Warning = 1 << 3,
+ Exception = 1 << 4,
+ ScriptingError = 1 << 8,
+ ScriptingWarning = 1 << 9,
+ ScriptingLog = 1 << 10,
+ ScriptCompileError = 1 << 11,
+ ScriptCompileWarning= 1 << 12
+}
This small refactor eliminates magic numbers elsewhere and prevents accidental mixing with unrelated bit-fields.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Basic log type flags (bits 0-4) | |
public const int kModeError = 1 << 0; // 1 (0x1) | |
public const int kModeAssert = 1 << 1; // 2 (0x2) | |
public const int kModeLog = 1 << 2; // 4 (0x4) | |
public const int kModeWarning = 1 << 3; // 8 (0x8) | |
public const int kModeException = 1 << 4; // 16 (0x10) | |
// Scripting related flags (bits 8-12) | |
public const int kScriptingError = 1 << 8; // 256 (0x100) | |
public const int kScriptingWarning = 1 << 9; // 512 (0x200) | |
public const int kScriptingLog = 1 << 10; // 1024 (0x400) | |
public const int kScriptCompileError = 1 << 11; // 2048 (0x800) | |
public const int kScriptCompileWarning = 1 << 12; // 4096 (0x1000) | |
// Basic log type flags (bits 0-4) | |
- public const int kModeError = 1 << 0; // 1 (0x1) | |
- public const int kModeAssert = 1 << 1; // 2 (0x2) | |
- public const int kModeLog = 1 << 2; // 4 (0x4) | |
- public const int kModeWarning = 1 << 3; // 8 (0x8) | |
- public const int kModeException = 1 << 4; // 16 (0x10) | |
- | |
- // Scripting related flags (bits 8-12) | |
- public const int kScriptingError = 1 << 8; // 256 (0x100) | |
- public const int kScriptingWarning = 1 << 9; // 512 (0x200) | |
- public const int kScriptingLog = 1 << 10; // 1024 (0x400) | |
- public const int kScriptCompileError = 1 << 11; // 2048 (0x800) | |
- public const int kScriptCompileWarning = 1 << 12; // 4096 (0x1000) | |
+ [Flags] | |
+ public enum LogEntryMode | |
+ { | |
+ Error = 1 << 0, | |
+ Assert = 1 << 1, | |
+ Log = 1 << 2, | |
+ Warning = 1 << 3, | |
+ Exception = 1 << 4, | |
+ ScriptingError = 1 << 8, | |
+ ScriptingWarning = 1 << 9, | |
+ ScriptingLog = 1 << 10, | |
+ ScriptCompileError = 1 << 11, | |
+ ScriptCompileWarning= 1 << 12 | |
+ } |
🤖 Prompt for AI Agents
In Editor/Services/LogEntryModeFlags.cs around lines 10 to 23, replace the raw
const int bit flags with a [Flags] enum to improve type safety and clarity.
Define an enum named LogEntryModeFlags with the same bit values as enum members,
applying the [Flags] attribute above it. This change will allow using the enum
type instead of ints for log mode flags, preventing accidental misuse and
enhancing code readability.
EditorGUILayout.Space(); | ||
|
||
// Console log service selection | ||
ConsoleLogServiceType newConsoleLogService = (ConsoleLogServiceType)EditorGUILayout.EnumPopup( | ||
new GUIContent("Console Log Service", "Select console log service implementation. EventBased is safe but may miss some logs. Unity6Enhanced uses internal APIs for better reliability but requires Unity 6+. Server restart required when changed."), | ||
settings.ConsoleLogService); | ||
if (newConsoleLogService != settings.ConsoleLogService) | ||
{ | ||
settings.ConsoleLogService = newConsoleLogService; | ||
settings.SaveSettings(); | ||
|
||
// Show warning for Unity6Enhanced | ||
if (newConsoleLogService == ConsoleLogServiceType.Unity6Enhanced) | ||
{ | ||
#if UNITY_6000_0_OR_NEWER | ||
EditorUtility.DisplayDialog("Console Log Service Changed", | ||
"Unity 6 enhanced console log service selected. This uses internal Unity APIs for better reliability but may break in future Unity versions.\n\nRestart the MCP server for changes to take effect.", "OK"); | ||
#else | ||
EditorUtility.DisplayDialog("Console Log Service Warning", | ||
$"Unity 6 enhanced console log service selected but current Unity version is {Application.unityVersion}. The service will fall back to event-based implementation.\n\nRestart the MCP server for changes to take effect.", "OK"); | ||
#endif | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Auto-restart the server after changing the log service for consistency.
When the user switches the console-log service, the dialog warns that a restart is required, yet the code does not replicate the automatic restart behaviour you already implement for the port change (lines 101-105).
Leaving the server running with the stale service instance means the UI and runtime behaviour diverge until the user manually restarts, which is easy to miss.
Consider restarting the server immediately after persisting the new value:
settings.ConsoleLogService = newConsoleLogService;
settings.SaveSettings();
+// Ensure the active server uses the new implementation
+if (mcpUnityServer.IsListening)
+{
+ mcpUnityServer.StopServer();
+ mcpUnityServer.StartServer();
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
EditorGUILayout.Space(); | |
// Console log service selection | |
ConsoleLogServiceType newConsoleLogService = (ConsoleLogServiceType)EditorGUILayout.EnumPopup( | |
new GUIContent("Console Log Service", "Select console log service implementation. EventBased is safe but may miss some logs. Unity6Enhanced uses internal APIs for better reliability but requires Unity 6+. Server restart required when changed."), | |
settings.ConsoleLogService); | |
if (newConsoleLogService != settings.ConsoleLogService) | |
{ | |
settings.ConsoleLogService = newConsoleLogService; | |
settings.SaveSettings(); | |
// Show warning for Unity6Enhanced | |
if (newConsoleLogService == ConsoleLogServiceType.Unity6Enhanced) | |
{ | |
#if UNITY_6000_0_OR_NEWER | |
EditorUtility.DisplayDialog("Console Log Service Changed", | |
"Unity 6 enhanced console log service selected. This uses internal Unity APIs for better reliability but may break in future Unity versions.\n\nRestart the MCP server for changes to take effect.", "OK"); | |
#else | |
EditorUtility.DisplayDialog("Console Log Service Warning", | |
$"Unity 6 enhanced console log service selected but current Unity version is {Application.unityVersion}. The service will fall back to event-based implementation.\n\nRestart the MCP server for changes to take effect.", "OK"); | |
#endif | |
} | |
} | |
EditorGUILayout.Space(); | |
// Console log service selection | |
ConsoleLogServiceType newConsoleLogService = (ConsoleLogServiceType)EditorGUILayout.EnumPopup( | |
new GUIContent("Console Log Service", "Select console log service implementation. EventBased is safe but may miss some logs. Unity6Enhanced uses internal APIs for better reliability but requires Unity 6+. Server restart required when changed."), | |
settings.ConsoleLogService); | |
if (newConsoleLogService != settings.ConsoleLogService) | |
{ | |
settings.ConsoleLogService = newConsoleLogService; | |
settings.SaveSettings(); | |
// Ensure the active server uses the new implementation | |
if (mcpUnityServer.IsListening) | |
{ | |
mcpUnityServer.StopServer(); | |
mcpUnityServer.StartServer(); | |
} | |
// Show warning for Unity6Enhanced | |
if (newConsoleLogService == ConsoleLogServiceType.Unity6Enhanced) | |
{ | |
#if UNITY_6000_0_OR_NEWER | |
EditorUtility.DisplayDialog("Console Log Service Changed", | |
"Unity 6 enhanced console log service selected. This uses internal Unity APIs for better reliability but may break in future Unity versions.\n\nRestart the MCP server for changes to take effect.", "OK"); | |
#else | |
EditorUtility.DisplayDialog("Console Log Service Warning", | |
$"Unity 6 enhanced console log service selected but current Unity version is {Application.unityVersion}. The service will fall back to event-based implementation.\n\nRestart the MCP server for changes to take effect.", "OK"); | |
#endif | |
} | |
} |
🤖 Prompt for AI Agents
In Editor/UnityBridge/McpUnityEditorWindow.cs between lines 146 and 169, after
changing and saving the ConsoleLogService setting, the code shows a dialog
warning that a server restart is needed but does not actually restart the server
automatically. To fix this, add code to trigger the server restart immediately
after saving the new ConsoleLogService value, similar to the restart logic used
for port changes around lines 101-105, ensuring the runtime uses the updated
service without requiring manual intervention.
if (_logEntriesType == null || _getCountMethod == null || _getEntryInternalMethod == null) | ||
{ | ||
return new JObject | ||
{ | ||
["logs"] = new JArray(), | ||
["message"] = "LogEntries API not available", | ||
["success"] = false | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Null-check misses _logEntryType
and field handles – can lead to NREs.
GetLogsAsJson
bails out only if _logEntriesType
, _getCountMethod
, or _getEntryInternalMethod
are null.
If _logEntryType
or any cached FieldInfo
is null but the first three are present, the subsequent reflection access (lines 169-175) will throw.
-if (_logEntriesType == null || _getCountMethod == null || _getEntryInternalMethod == null)
+if (_logEntriesType == null || _logEntryType == null ||
+ _getCountMethod == null || _getEntryInternalMethod == null ||
+ _messageField == null || _modeField == null)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
if (_logEntriesType == null || _getCountMethod == null || _getEntryInternalMethod == null) | |
{ | |
return new JObject | |
{ | |
["logs"] = new JArray(), | |
["message"] = "LogEntries API not available", | |
["success"] = false | |
}; | |
} | |
if (_logEntriesType == null || _logEntryType == null || | |
_getCountMethod == null || _getEntryInternalMethod == null || | |
_messageField == null || _modeField == null) | |
{ | |
return new JObject | |
{ | |
["logs"] = new JArray(), | |
["message"] = "LogEntries API not available", | |
["success"] = false | |
}; | |
} |
🤖 Prompt for AI Agents
In Editor/Services/ConsoleLogsServiceUnity6.cs around lines 118 to 126, the
null-check in GetLogsAsJson only verifies _logEntriesType, _getCountMethod, and
_getEntryInternalMethod, but misses checking _logEntryType and any cached
FieldInfo fields. To fix this, extend the null-check condition to include
_logEntryType and all relevant FieldInfo fields to prevent potential null
reference exceptions during reflection access later in the method.
Summary
Add comprehensive Unity console log search functionality as an MCP tool, providing powerful search capabilities for Unity developers using Claude Code and other MCP clients.
🔍 Features Added
Core Search Capabilities
Implementation Details
Enhanced Console Log Service
ConsoleLogServiceType
enum withEventBased
(default) andUnity6Enhanced
options🧪 Testing Results
All search functionality has been thoroughly tested:
shader
,texture
,Player
GameObject.*not found
,^\[MCP\].*
EventBased
andUnity6Enhanced
implementations📋 Usage Examples
🎯 Benefits
This tool significantly enhances the Unity development experience when using Claude Code for debugging and log analysis.
🤖 Generated with Claude Code
Created with Palmier
Summary by CodeRabbit