inspect_logs
Analyze Android logcat or iOS unified logs to debug mobile applications by filtering logs based on app, log level, tags, patterns, and time range.
Instructions
Inspect device logs (Android logcat or iOS unified logs). Can filter by app, log level, tags, patterns, and time range.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| platform | Yes | Target platform | |
| appId | No | App package name (Android) or bundle ID (iOS) to filter logs | |
| deviceId | No | Device ID (optional, uses first available) | |
| minLevel | No | Minimum log level to include | |
| tags | No | Tags to include (Android logcat) | |
| excludeTags | No | Tags to exclude from results | |
| pattern | No | Search pattern (regex) to filter messages | |
| ignoreCase | No | Case insensitive pattern matching (default: true) | |
| subsystem | No | Subsystem filter (iOS only) | |
| category | No | Category filter (iOS only) | |
| maxEntries | No | Maximum log entries to return (default: 200) | |
| lastSeconds | No | Time range - logs from last N seconds (iOS, default: 300) | |
| clear | No | Clear log buffer before capture (Android only) | |
| includeCrashes | No | Include crash/fault logs (default: true) | |
| timeoutMs | No | Timeout in milliseconds (default: 30000) |
Implementation Reference
- Core handler function that validates input arguments, determines platform (Android/iOS), captures logs using platform-specific helpers, applies filters, and returns a structured LogInspectionResult including entries, filters applied, and duration.export async function inspectLogs(args: InspectLogsArgs): Promise<LogInspectionResult> { const { platform, appId, deviceId, minLevel, tags, excludeTags, pattern, ignoreCase = true, subsystem, category, maxEntries = 200, lastSeconds = 300, clear = false, includeCrashes = true, timeoutMs = 30000, } = args; const startTime = Date.now(); // Validate platform if (!isPlatform(platform)) { throw Errors.invalidArguments(`Invalid platform: ${platform}. Must be 'android' or 'ios'`); } // Validate log level if provided if (minLevel && !isValidLogLevel(minLevel)) { throw Errors.invalidArguments( `Invalid log level: ${minLevel}. Must be one of: verbose, debug, info, warning, error, fatal` ); } try { let entries: LogEntry[]; // Build filter const filter: LogFilter = {}; if (minLevel) { filter.minLevel = minLevel as LogLevel; } if (tags && tags.length > 0) { filter.tags = tags; } if (excludeTags && excludeTags.length > 0) { filter.excludeTags = excludeTags; } if (pattern) { filter.pattern = pattern; filter.ignoreCase = ignoreCase; } if (maxEntries > 0) { filter.limit = maxEntries; } // Capture logs based on platform if (platform === 'android') { entries = await captureAndroidLogs({ deviceId, appId, tags, maxEntries, clear, includeCrashes, timeoutMs, filter: Object.keys(filter).length > 0 ? filter : undefined, }); } else { entries = await captureIOSLogs({ deviceId, appId, subsystem, category, maxEntries, lastSeconds, timeoutMs, filter: Object.keys(filter).length > 0 ? filter : undefined, }); } return { success: true, platform, appId, deviceId, entries, totalEntries: entries.length, appliedFilters: Object.keys(filter).length > 0 ? filter : undefined, durationMs: Date.now() - startTime, }; } catch (error) { return { success: false, platform, appId, deviceId, entries: [], error: String(error), durationMs: Date.now() - startTime, }; } }
- TypeScript interface InspectLogsArgs defining all input parameters for the inspect_logs tool, including platform, appId, filters, patterns, timeouts, etc.export interface InspectLogsArgs { /** Target platform */ platform: string; /** App package/bundle ID (optional) */ appId?: string; /** Device ID */ deviceId?: string; /** Minimum log level to include */ minLevel?: string; /** Tags to include (Android) */ tags?: string[]; /** Tags to exclude */ excludeTags?: string[]; /** Search pattern (regex) */ pattern?: string; /** Case insensitive search */ ignoreCase?: boolean; /** Subsystem filter (iOS) */ subsystem?: string; /** Category filter (iOS) */ category?: string; /** Maximum entries to return */ maxEntries?: number; /** Time range - last N seconds */ lastSeconds?: number; /** Clear log buffer before capture (Android) */ clear?: boolean; /** Include crash/fault logs */ includeCrashes?: boolean; /** Timeout in milliseconds */ timeoutMs?: number; }
- src/tools/observability/inspect-logs.ts:265-350 (registration)registerInspectLogsTool function that registers the 'inspect_logs' tool with the global ToolRegistry. Defines tool description, creates detailed JSON inputSchema, and provides the async execution handler which calls inspectLogs and appends formattedOutput.export function registerInspectLogsTool(): void { getToolRegistry().register( 'inspect_logs', { description: 'Inspect device logs (Android logcat or iOS unified logs). ' + 'Can filter by app, log level, tags, patterns, and time range.', inputSchema: createInputSchema( { platform: { type: 'string', enum: ['android', 'ios'], description: 'Target platform', }, appId: { type: 'string', description: 'App package name (Android) or bundle ID (iOS) to filter logs', }, deviceId: { type: 'string', description: 'Device ID (optional, uses first available)', }, minLevel: { type: 'string', enum: ['verbose', 'debug', 'info', 'warning', 'error', 'fatal'], description: 'Minimum log level to include', }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags to include (Android logcat)', }, excludeTags: { type: 'array', items: { type: 'string' }, description: 'Tags to exclude from results', }, pattern: { type: 'string', description: 'Search pattern (regex) to filter messages', }, ignoreCase: { type: 'boolean', description: 'Case insensitive pattern matching (default: true)', }, subsystem: { type: 'string', description: 'Subsystem filter (iOS only)', }, category: { type: 'string', description: 'Category filter (iOS only)', }, maxEntries: { type: 'number', description: 'Maximum log entries to return (default: 200)', }, lastSeconds: { type: 'number', description: 'Time range - logs from last N seconds (iOS, default: 300)', }, clear: { type: 'boolean', description: 'Clear log buffer before capture (Android only)', }, includeCrashes: { type: 'boolean', description: 'Include crash/fault logs (default: true)', }, timeoutMs: { type: 'number', description: 'Timeout in milliseconds (default: 30000)', }, }, ['platform'] ), }, async (args) => { const result = await inspectLogs(args as unknown as InspectLogsArgs); return { ...result, formattedOutput: formatLogResult(result), }; } ); }
- src/tools/register.ts:167-170 (registration)Invocation of registerInspectLogsTool() during server startup in registerAllTools(), ensuring the tool is registered when the MCP server initializes.const { registerInspectLogsTool } = await import('./observability/inspect-logs.js'); registerInspectAppStateTool(); registerInspectLogsTool();
- formatLogResult helper that generates a markdown-formatted summary of log inspection results for AI consumption, used in the registered tool handler.export function formatLogResult(result: LogInspectionResult): string { if (!result.success) { const lines = [ `## Log Inspection: Failed`, ``, `**Error**: ${result.error}`, ]; return lines.join('\n'); } return generateLogSummary(result); }