Manage ADB Logcat
manage-logcatRead Android logcat logs, capture crash dumps, check ANR traces, and clear log buffers with filters for package, PID, tag, priority, and line count.
Instructions
Unified tool to read logs, capture crashes, check ANRs, and clear buffers.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | Action to perform: read logs, get crash buffer, check ANR, or clear buffer. | read |
| packageName | No | Android package name; resolves pid via adb shell pidof | |
| pid | No | Explicit process id for logcat --pid | |
| tag | No | Logcat tag to include (uses -s tag) | |
| priority | No | Minimum priority (e.g. D for debug). | V |
| maxLines | No | Tail line count (logcat -t). | |
| timeoutMs | No | Timeout per adb call in milliseconds |
Implementation Reference
- src/tools/logcatTool.js:61-109 (handler)The main handler function for the 'manage-logcat' tool. Executes the tool logic: clear logcat buffers, check ANR state, capture crash buffer, or read logs based on the 'action' parameter. Resolves PID from packageName if needed.
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/tools/logcatTool.js:12-20 (schema)Input schema for the 'manage-logcat' tool defined with Zod. Validates/describes parameters: action (enum: read/crash/anr/clear), packageName, pid, tag, priority, maxLines, and timeoutMs.
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') }); - src/tools/logcatTool.js:53-110 (registration)The 'registerLogcatTool' function registers the 'manage-logcat' tool with the MCP server, including its metadata (title, description, inputSchema) and handler.
function registerLogcatTool(server) { 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:27-29 (registration)The top-level registration of the logcat tool in the MCP server entry point. Calls registerLogcatTool(server) to wire up the tool.
registerSvgTool(server); registerLogcatTool(server); registerTextLengthTool(server); - src/tools/logcatTool.js:43-51 (helper)Helper function 'resolvePid' that resolves an Android package name to a PID using 'adb shell pidof -s'. Returns null if not found.
async function resolvePid(packageName, timeoutMs) { try { const output = await runAdbCommand(['shell', 'pidof', '-s', packageName], timeoutMs); const pid = output.split(/\s+/).find(Boolean); return pid || null; } catch (e) { return null; // Return null if pidof failed or not found } }