Skip to main content
Glama
twodoorsdev
by twodoorsdev

readConsoleLogsFromApp

Fetch and monitor console logs from a connected React Native app via WebSocket debugger to streamline debugging and issue tracking.

Instructions

Reads console logs from a connected React Native app through the debugger WebSocket

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
appYesThe app object as returned by getConnectedApps
maxLogsNoMaximum number of logs to return (default: 100)

Implementation Reference

  • Core handler function that connects to the app's WebSocket debugger URL, enables the Runtime domain, listens for 'Runtime.consoleAPICalled' events, extracts log text from arguments, filters unsupported messages, collects logs with timestamps up to maxLogs, handles errors and timeouts.
    export const readConsoleLogsFromApp = async ( app: { id: string; description: string; webSocketDebuggerUrl: string }, maxLogs = 100, ): Promise<ConsoleMessage[]> => { return new Promise((resolve, reject) => { const ws = new WebSocket(app.webSocketDebuggerUrl); const logs: ConsoleMessage[] = []; let messageId = 1; ws.on('open', () => { // Enable runtime const enableRuntimeMessage = { id: messageId++, method: 'Runtime.enable', }; ws.send(JSON.stringify(enableRuntimeMessage)); }); ws.on('message', (data: string) => { try { const message = JSON.parse(data); // Handle console messages if (message.method === 'Runtime.consoleAPICalled') { const args = message.params.args || []; // biome-ignore lint/suspicious/noExplicitAny: <explanation> const text = args.map((arg: any) => arg.value || '').join(' '); // Skip the unsupported client message if (text.includes(UNSUPPORTED_CLIENT_MESSAGE)) { return; } const logMessage: ConsoleMessage = { type: message.params.type || 'log', text, level: message.params.type || 'log', timestamp: Date.now(), }; logs.push(logMessage); // Close connection when we have enough logs if (logs.length >= maxLogs) { ws.close(); } } } catch (error) { // @TODO Handle this better // console.error('Error parsing WebSocket message:', error); } }); ws.on('close', () => { resolve(logs); }); ws.on('error', (error) => { reject(error); }); // Set a timeout to close the connection if it takes too long setTimeout(() => { if (ws.readyState === WebSocket.OPEN) { ws.close(); } resolve(logs); }, 5000); }); };
  • Zod schema defining the input parameters: 'app' object with id, description, webSocketDebuggerUrl (from getConnectedApps), and optional 'maxLogs' number (default 100).
    export const readConsoleLogsFromAppSchema = z.object({ app: z .object({ id: z.string().describe('The Metro application ID'), description: z.string().describe(`The Metro application's bundle ID`), webSocketDebuggerUrl: z .string() .describe('The websocket debugger URL for the application'), }) .describe('The app object as returned by getConnectedApps'), maxLogs: z .number() .optional() .describe('Maximum number of logs to return (default: 100)'), }); export type ReadConsoleLogsFromAppSchema = z.infer< typeof readConsoleLogsFromAppSchema >;
  • ToolRegistration export defining the tool's name, description, input schema, and handler that validates inputs with the schema, calls the core readConsoleLogsFromApp function, returns formatted JSON logs or error message.
    export const readConsoleLogsFromAppTool: ToolRegistration<ReadConsoleLogsFromAppSchema> = { name: 'readConsoleLogsFromApp', description: 'Reads console logs from a connected React Native app through the debugger WebSocket', inputSchema: makeJsonSchema(readConsoleLogsFromAppSchema), handler: async ({ app, maxLogs }: ReadConsoleLogsFromAppSchema) => { try { const parsedArgs = readConsoleLogsFromAppSchema.parse({ app, maxLogs }); const logs = await readConsoleLogsFromApp( parsedArgs.app, parsedArgs.maxLogs, ); return { content: [ { type: 'text', text: JSON.stringify(logs, null, 2), }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error: ${(error as Error).message}`, }, ], isError: true, }; } }, };
  • Central registration in createTools() array (with handler wrapper) and static tools array export including readConsoleLogsFromAppTool.
    export const createTools = (): ToolRegistration<any>[] => { return [ { ...getConnectedAppsTool, // biome-ignore lint/suspicious/noExplicitAny: All tools validate their input schemas, so any is fine. handler: (args: any) => getConnectedAppsTool.handler(args), }, { ...readConsoleLogsFromAppTool, // biome-ignore lint/suspicious/noExplicitAny: All tools validate their input schemas, so any is fine. handler: (args: any) => readConsoleLogsFromAppTool.handler(args), }, ]; }; export const tools = [ readConsoleLogsFromAppTool, getConnectedAppsTool, ] as const;

Other Tools

Related 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/twodoorsdev/react-native-debugger-mcp'

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