Skip to main content
Glama
Nam0101

android-mcp-toolkit

manage-logcat

Read Android device logs, capture crash buffers, check ANR reports, and clear log buffers through unified ADB logcat commands for debugging and monitoring.

Instructions

Unified tool to read logs, capture crashes, check ANRs, and clear buffers.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionNoAction to perform: read logs, get crash buffer, check ANR, or clear buffer.read
packageNameNoAndroid package name; resolves pid via adb shell pidof
pidNoExplicit process id for logcat --pid
tagNoLogcat tag to include (uses -s tag)
priorityNoMinimum priority (e.g. D for debug).V
maxLinesNoTail line count (logcat -t).
timeoutMsNoTimeout per adb call in milliseconds

Implementation Reference

  • The core handler function that implements the logic for the 'manage-logcat' tool, dispatching to different ADB logcat commands based on the 'action' parameter (read, crash, anr, clear).
    async (params) => { const { action, timeoutMs } = params; if (action === 'clear') { await runAdbCommand(['logcat', '-c'], timeoutMs); return { content: [{ type: 'text', text: 'Cleared logcat buffers.' }] }; } // Resolve PID if packageName is provided let pid = params.pid; if (!pid && params.packageName) { pid = await resolvePid(params.packageName, timeoutMs); } // 1. ANR Check if (action === 'anr') { const sections = []; try { const logArgs = ['logcat', '-d', '-t', String(params.maxLines), 'ActivityManager:E', '*:S']; const amLogs = await runAdbCommand(logArgs, timeoutMs); sections.push('ActivityManager (recent):\n' + (amLogs || 'No entries.')); } catch (e) { sections.push('ActivityManager error: ' + e.message); } try { const tail = await runAdbCommand(['shell', 'tail', '-n', '200', '/data/anr/traces.txt'], timeoutMs); sections.push('traces.txt tail (200 lines):\n' + (tail || 'Empty.')); } catch (e) { sections.push('traces.txt error: ' + e.message); } return { content: [{ type: 'text', text: sections.join('\n\n') }] }; } // 2. Crash Buffer if (action === 'crash') { const args = ['logcat', '-b', 'crash', '-d', '-t', String(params.maxLines)]; if (pid) args.push(`--pid=${pid}`); const output = await runAdbCommand(args, timeoutMs); return { content: [{ type: 'text', text: output || 'No crash entries found.' }] }; } // 3. Normal Read (Default) const args = ['logcat', '-d', '-t', String(params.maxLines)]; if (pid) args.push(`--pid=${pid}`); if (params.tag) { args.push('-s', `${params.tag}:${params.priority}`); } const output = await runAdbCommand(args, timeoutMs); return { content: [{ type: 'text', text: output || 'Logcat returned no lines.' }] }; }
  • Zod schema defining the input parameters and validation for the manage-logcat tool.
    const manageLogcatSchema = z.object({ action: z.enum(['read', 'crash', 'anr', 'clear']).default('read').describe('Action to perform: read logs, get crash buffer, check ANR, or clear buffer.'), packageName: z.string().min(1).describe('Android package name; resolves pid via adb shell pidof').optional(), pid: z.string().min(1).describe('Explicit process id for logcat --pid').optional(), tag: z.string().min(1).describe('Logcat tag to include (uses -s tag)').optional(), priority: z.enum(['V', 'D', 'I', 'W', 'E', 'F', 'S']).default('V').describe('Minimum priority (e.g. D for debug).'), maxLines: z.number().int().min(1).max(2000).default(200).describe('Tail line count (logcat -t).'), timeoutMs: z.number().int().min(1000).max(15000).default(5000).describe('Timeout per adb call in milliseconds') });
  • Direct registration of the 'manage-logcat' tool with the MCP server, specifying name, metadata, schema, and inline handler.
    server.registerTool( 'manage-logcat', { title: 'Manage ADB Logcat', description: 'Unified tool to read logs, capture crashes, check ANRs, and clear buffers.', inputSchema: manageLogcatSchema }, async (params) => { const { action, timeoutMs } = params; if (action === 'clear') { await runAdbCommand(['logcat', '-c'], timeoutMs); return { content: [{ type: 'text', text: 'Cleared logcat buffers.' }] }; } // Resolve PID if packageName is provided let pid = params.pid; if (!pid && params.packageName) { pid = await resolvePid(params.packageName, timeoutMs); } // 1. ANR Check if (action === 'anr') { const sections = []; try { const logArgs = ['logcat', '-d', '-t', String(params.maxLines), 'ActivityManager:E', '*:S']; const amLogs = await runAdbCommand(logArgs, timeoutMs); sections.push('ActivityManager (recent):\n' + (amLogs || 'No entries.')); } catch (e) { sections.push('ActivityManager error: ' + e.message); } try { const tail = await runAdbCommand(['shell', 'tail', '-n', '200', '/data/anr/traces.txt'], timeoutMs); sections.push('traces.txt tail (200 lines):\n' + (tail || 'Empty.')); } catch (e) { sections.push('traces.txt error: ' + e.message); } return { content: [{ type: 'text', text: sections.join('\n\n') }] }; } // 2. Crash Buffer if (action === 'crash') { const args = ['logcat', '-b', 'crash', '-d', '-t', String(params.maxLines)]; if (pid) args.push(`--pid=${pid}`); const output = await runAdbCommand(args, timeoutMs); return { content: [{ type: 'text', text: output || 'No crash entries found.' }] }; } // 3. Normal Read (Default) const args = ['logcat', '-d', '-t', String(params.maxLines)]; if (pid) args.push(`--pid=${pid}`); if (params.tag) { args.push('-s', `${params.tag}:${params.priority}`); } const output = await runAdbCommand(args, timeoutMs); return { content: [{ type: 'text', text: output || 'Logcat returned no lines.' }] }; } );
  • src/index.js:28-28 (registration)
    Invocation of registerLogcatTool which performs the server.registerTool for manage-logcat (and get-current-activity).
    registerLogcatTool(server);
  • Helper function to execute ADB shell commands with timeout handling and comprehensive error reporting, used extensively in the handler.
    async function runAdbCommand(args, timeoutMs) { try { const { stdout } = await execFileAsync('adb', args, { timeout: timeoutMs, maxBuffer: 5 * 1024 * 1024 }); return stdout.trimEnd(); } catch (error) { const stderr = error && typeof error.stderr === 'string' ? error.stderr.trim() : ''; const message = [`adb ${args.join(' ')} failed`, error.message].filter(Boolean).join(': '); if (stderr) { throw new Error(`${message} | stderr: ${stderr}`); } throw new Error(message); } }

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/Nam0101/android-mcp-toolkit'

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