Skip to main content
Glama

tauri_read_logs

Read-only

Read logs from Tauri applications to debug issues by accessing console, Android, iOS, or system log sources with filtering and timestamp options.

Instructions

[Tauri Apps Only] Read logs from various sources: "console" for webview JS logs, "android" for logcat, "ios" for simulator logs, "system" for desktop logs. Requires active tauri_driver_session for console logs. Use for debugging Tauri app issues at any level.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sourceYesLog source: "console" for webview JS logs, "android" for logcat, "ios" for simulator, "system" for desktop
linesNo
filterNoRegex or keyword to filter logs
sinceNoISO timestamp to filter logs since (e.g. 2023-10-27T10:00:00Z)
windowIdNoWindow label for console logs (defaults to "main")
appIdentifierNoApp port or bundle ID for console logs. Defaults to the only connected app or the default app if multiple are connected.

Implementation Reference

  • Main handler function for tauri_read_logs tool. Handles different log sources (console, android, ios, system), fetches logs using platform-specific commands, applies filters and limits.
    export async function readLogs(options: ReadLogsOptions): Promise<string> {
       const { source, lines = 50, filter, since, windowId, appIdentifier } = options;
    
       try {
          let output = '';
    
          // Handle console logs (webview JS logs)
          if (source === 'console') {
             return await getConsoleLogs({ filter, since, windowId, appIdentifier });
          }
    
          if (source === 'android') {
             const adbPath = findAdbPath();
    
             const args = [ 'logcat', '-d' ];
    
             if (since) {
                // adb logcat -T expects "MM-DD HH:MM:SS.mmm"
                const date = new Date(since);
    
                const month = (date.getMonth() + 1).toString().padStart(2, '0');
    
                const day = date.getDate().toString().padStart(2, '0');
    
                const hours = date.getHours().toString().padStart(2, '0');
    
                const minutes = date.getMinutes().toString().padStart(2, '0');
    
                const seconds = date.getSeconds().toString().padStart(2, '0');
    
                const ms = date.getMilliseconds().toString().padStart(3, '0');
    
                const adbTime = `${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;
    
                args.push('-T', adbTime);
             } else {
                args.push('-t', lines.toString());
             }
    
             const { stdout } = await execa(adbPath, args, { timeout: 10000 });
    
             output = stdout;
          } else if (source === 'ios') {
          // iOS / macOS
             const args = [ 'log', 'show', '--style', 'syslog' ];
    
             if (source === 'ios') {
                args.unshift('xcrun', 'simctl', 'spawn', 'booted');
             }
    
             if (since) {
                // log show --start "YYYY-MM-DD HH:MM:SS"
                // It accepts ISO-like formats too usually, but let's be safe with
                // local time format if possible
                // Actually 'log show' on macOS is picky. ISO 8601 works in recent versions.
                args.push('--start', since);
             } else {
                // Default to last 1m if no since provided, as 'lines' isn't
                // directly supported by log show time window
                args.push('--last', '1m');
             }
    
             try {
                const { stdout } = await execa(args[0], args.slice(1));
    
                // We still apply line limit manually if we didn't use -t (adb)
                let outLines = stdout.split('\n');
    
                if (!since) {
                   outLines = outLines.slice(-lines);
                }
                output = outLines.join('\n');
             } catch(e) {
                return `Error reading logs: ${e}`;
             }
          } else {
             // System (same as iOS essentially but local)
             const args = [ 'log', 'show', '--style', 'syslog' ];
    
             if (since) {
                args.push('--start', since);
             } else {
                args.push('--last', '1m');
             }
    
             try {
                const { stdout } = await execa('log', args.slice(1)); // 'log' is the command
    
                let outLines = stdout.split('\n');
    
                if (!since) {
                   outLines = outLines.slice(-lines);
                }
                output = outLines.join('\n');
             } catch(e) {
                return `Error reading system logs: ${e}`;
             }
          }
    
          if (filter) {
             try {
                const regex = new RegExp(filter, 'i');
    
                return output.split('\n').filter((line) => { return regex.test(line); }).join('\n');
             } catch(e) {
                return `Invalid filter regex: ${e}`;
             }
          }
          return output;
       } catch(error) {
          return `Error reading logs: ${error}`;
       }
    }
  • Zod schema for validating inputs to the tauri_read_logs tool, defining parameters like source, lines, filter, etc.
    export const ReadLogsSchema = z.object({
       source: z.enum([ 'console', 'android', 'ios', 'system' ])
          .describe('Log source: "console" for webview JS logs, "android" for logcat, "ios" for simulator, "system" for desktop'),
       lines: z.number().default(50),
       filter: z.string().optional().describe('Regex or keyword to filter logs'),
       since: z.string().optional().describe('ISO timestamp to filter logs since (e.g. 2023-10-27T10:00:00Z)'),
       windowId: z.string().optional().describe('Window label for console logs (defaults to "main")'),
       appIdentifier: z.union([ z.string(), z.number() ]).optional().describe(
          'App port or bundle ID for console logs. Defaults to the only connected app or the default app if multiple are connected.'
       ),
    });
  • Tool registration in the central tools registry, defining metadata, schema reference, and inline handler that delegates to readLogs function.
    {
       name: 'tauri_read_logs',
       description:
          '[Tauri Apps Only] Read logs from various sources: "console" for webview JS logs, ' +
          '"android" for logcat, "ios" for simulator logs, "system" for desktop logs. ' +
          'Requires active tauri_driver_session for console logs. ' +
          'Use for debugging Tauri app issues at any level.',
       category: TOOL_CATEGORIES.UI_AUTOMATION,
       schema: ReadLogsSchema,
       annotations: {
          title: 'Read Logs',
          readOnlyHint: true,
          openWorldHint: false,
       },
       handler: async (args) => {
          const parsed = ReadLogsSchema.parse(args);
    
          return await readLogs(parsed);
       },
    },
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, indicating a safe, bounded operation. The description adds useful context about the prerequisite for console logs and the debugging purpose, but does not disclose additional behavioral traits like rate limits, pagination behavior, or error conditions beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized with three sentences that are front-loaded with key information (audience, sources, prerequisite, purpose). Every sentence adds value, though the second sentence could be slightly more structured for clarity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (6 parameters, 1 required), good schema coverage (83%), and annotations providing safety context, the description is reasonably complete. It covers purpose, audience, sources, prerequisite, and usage context. The main gap is the lack of output schema, but the description compensates adequately for a read operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is high (83%), so the schema already documents most parameters well. The description adds some value by listing the four source options with brief explanations, but does not provide additional semantic context beyond what's in the schema descriptions for parameters like filter, since, or windowId.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states the verb 'Read' and resource 'logs', specifies the target audience '[Tauri Apps Only]', and lists the four distinct log sources with their specific purposes. This clearly distinguishes it from sibling tools like tauri_driver_session or tauri_webview_execute_js, which have different functions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool ('for debugging Tauri app issues at any level') and mentions a prerequisite ('Requires active tauri_driver_session for console logs'). However, it does not explicitly state when not to use it or name specific alternatives among the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/hypothesi/mcp-server-tauri'

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