Skip to main content
Glama
McpLogStream.cs6.56 kB
using System; using System.Collections.Generic; using UnityEngine; namespace LocalMcp.UnityServer { /// <summary> /// Manages Unity log streaming and history for MCP clients. /// Captures Debug.Log, Debug.LogWarning, and Debug.LogError messages. /// </summary> public class McpLogStream : IDisposable { private McpSession session; private List<LogEntry> logHistory = new List<LogEntry>(); private bool isStreaming = false; private const int MAX_LOG_HISTORY = 1000; private string levelFilter = "all"; public McpLogStream(McpSession mcpSession) { session = mcpSession; Application.logMessageReceived += HandleLog; } /// <summary> /// Enables or disables log streaming to the client. /// </summary> public string EnableStream(string paramsJson, object id) { try { var parameters = JsonUtility.FromJson<LogStreamParams>(paramsJson); isStreaming = parameters.enable; levelFilter = string.IsNullOrEmpty(parameters.level) ? "all" : parameters.level; string status = isStreaming ? "streaming" : "stopped"; string message = isStreaming ? "Log stream started" : "Log stream stopped"; var response = JsonRpcResponse.Success(new { status, message, level = levelFilter }, id); return response.ToJson(); } catch (Exception e) { return JsonRpcResponseHelper.ErrorMessage($"Failed to enable stream: {e.Message}", id); } } /// <summary> /// Returns log history filtered by level and count. /// </summary> public string GetHistory(string paramsJson, object id) { try { var parameters = JsonUtility.FromJson<LogHistoryParams>(paramsJson); int count = parameters.count > 0 ? Math.Min(parameters.count, MAX_LOG_HISTORY) : 50; string level = string.IsNullOrEmpty(parameters.level) ? "all" : parameters.level; List<LogEntry> filteredLogs = new List<LogEntry>(); lock (logHistory) { foreach (var log in logHistory) { if (ShouldIncludeLog(log.type, level)) { filteredLogs.Add(log); if (filteredLogs.Count >= count) { break; } } } } var response = JsonRpcResponse.Success(new { logs = filteredLogs, total = filteredLogs.Count }, id); return response.ToJson(); } catch (Exception e) { return JsonRpcResponseHelper.ErrorMessage($"Failed to get history: {e.Message}", id); } } /// <summary> /// Handles Unity log messages and streams them to clients. /// </summary> private void HandleLog(string message, string stackTrace, LogType type) { try { var entry = new LogEntry { timestamp = DateTime.UtcNow.ToString("o"), type = type, message = message, stackTrace = stackTrace }; // Add to history lock (logHistory) { logHistory.Insert(0, entry); // Insert at beginning for most recent first if (logHistory.Count > MAX_LOG_HISTORY) { logHistory.RemoveAt(logHistory.Count - 1); } } // Stream to client if enabled if (isStreaming && ShouldIncludeLog(type, levelFilter)) { SendLogNotification(entry); } } catch (Exception e) { Debug.LogError($"[MCP] Error handling log: {e.Message}"); } } /// <summary> /// Sends a log notification to the client. /// </summary> private void SendLogNotification(LogEntry entry) { try { // Create a notification (no id field for notifications in JSON-RPC) var notification = new { jsonrpc = "2.0", method = "unity.log.notify", @params = entry }; string json = JsonUtility.ToJson(notification); session.SendMessage(json); } catch (Exception e) { Debug.LogError($"[MCP] Error sending log notification: {e.Message}"); } } /// <summary> /// Determines if a log should be included based on level filter. /// </summary> private bool ShouldIncludeLog(LogType logType, string level) { if (level == "all") { return true; } else if (level == "warning") { return logType == LogType.Warning || logType == LogType.Error || logType == LogType.Assert || logType == LogType.Exception; } else if (level == "error") { return logType == LogType.Error || logType == LogType.Assert || logType == LogType.Exception; } return true; } /// <summary> /// Cleans up resources. /// </summary> public void Dispose() { Application.logMessageReceived -= HandleLog; isStreaming = false; logHistory.Clear(); } } /// <summary> /// Parameters for log stream enable/disable. /// </summary> [Serializable] public class LogStreamParams { public bool enable = true; public string level = "all"; // "all", "warning", "error" } /// <summary> /// Parameters for log history retrieval. /// </summary> [Serializable] public class LogHistoryParams { public int count = 50; public string level = "all"; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dsgarage/UniMCP4CC'

If you have feedback or need assistance with the MCP directory API, please join our Discord server