Skip to main content
Glama

capture_console

Capture console output from web pages by providing a URL, optionally executing JavaScript commands, and specifying capture duration to monitor browser console messages.

Instructions

Capture console output from a web page. Accepts a URL, optional JS command to run, and duration to wait (default 4 seconds). Returns all console messages during that time.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlYesHTTP/HTTPS URL to capture console from
jsCommandNoOptional JavaScript command to execute on the page
durationNoDuration to capture console output in seconds
waitUntilNoWait until event: load, domcontentloaded, networkidle0, networkidle2domcontentloaded

Implementation Reference

  • Main handler function for the 'capture_console' tool. Launches a Puppeteer browser, navigates to the provided URL, sets up listeners for console messages and page errors, optionally executes a JavaScript command, waits for the specified duration (default 4s), collects all messages, and returns them structured as ConsoleCaptureResult.
    export async function captureConsole( options: ConsoleCaptureOptions ): Promise<ConsoleCaptureResult> { logger.info('captureConsole called with options:', { url: options.url, jsCommand: options.jsCommand, duration: options.duration, waitUntil: options.waitUntil, }); // Update activity time when console capture is requested updateActivityTime(); const messages: ConsoleMessage[] = []; const startTime = new Date(); const duration = options.duration || 4; // Default 4 seconds let browser: Browser | null = null; let page: Page | null = null; try { // Get browser instance browser = await getBrowser(); page = await setupPage(browser); // Set up console message listener page.on('console', msg => { const type = msg.type() as ConsoleMessage['type']; const text = msg.text(); const timestamp = new Date(); // Try to get the actual arguments const args: any[] = []; msg.args().forEach(arg => { args.push(arg.toString()); }); messages.push({ type, text, timestamp, args: args.length > 0 ? args : undefined, }); logger.debug(`Console ${type}: ${text}`); }); // Set up page error listener page.on('pageerror', error => { messages.push({ type: 'error', text: error.toString(), timestamp: new Date(), }); logger.debug(`Page error: ${error}`); }); logger.info(`Starting console capture for ${options.url}`); // Navigate to the page await page.goto(options.url, { waitUntil: options.waitUntil || 'domcontentloaded', timeout: 60000, }); // Execute JS command if provided if (options.jsCommand) { logger.info(`Executing JS command: ${options.jsCommand}`); try { await page.evaluate(options.jsCommand); logger.debug('JS command executed successfully'); } catch (error) { logger.error('Failed to execute JS command:', error); messages.push({ type: 'error', text: `Failed to execute JS command: ${error}`, timestamp: new Date(), }); } } // Wait for the specified duration logger.info(`Capturing console for ${duration} seconds...`); await new Promise(resolve => setTimeout(resolve, duration * 1000)); const endTime = new Date(); const result: ConsoleCaptureResult = { url: options.url, messages, startTime, endTime, duration, executedCommand: options.jsCommand, }; logger.info( `Console capture completed: ${messages.length} messages captured` ); // Clean up the page after successful capture if (page && !page.isClosed()) { await page.close().catch(() => {}); } return result; } catch (error: any) { logger.error('Error capturing console:', error); // Clean up the page if (page && !page.isClosed()) { await page.close().catch(() => {}); } throw error; } }
  • src/serve.ts:214-224 (registration)
    Registers the 'capture_console' tool by including CONSOLE_CAPTURE_TOOL in the list returned by ListToolsRequestHandler.
    server.setRequestHandler(ListToolsRequestSchema, async () => { logger.debug('Received ListTools request'); const response = { tools: [SCREENSHOT_TOOL, SCREENCAST_TOOL, CONSOLE_CAPTURE_TOOL], }; logger.debug( 'Returning tools:', response.tools.map(t => t.name) ); return response; });
  • Defines the Tool object for 'capture_console' including name, description, inputSchema (JSON Schema for parameters), and annotations.
    const CONSOLE_CAPTURE_TOOL: Tool = { name: 'capture_console', description: 'Capture console output from a web page. Accepts a URL, optional JS command to run, and duration to wait (default 4 seconds). Returns all console messages during that time.', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'HTTP/HTTPS URL to capture console from', }, jsCommand: { type: 'string', description: 'Optional JavaScript command to execute on the page', }, duration: { type: 'number', description: 'Duration to capture console output in seconds', default: 4, }, waitUntil: { type: 'string', description: 'Wait until event: load, domcontentloaded, networkidle0, networkidle2', default: 'domcontentloaded', }, }, required: ['url'], }, annotations: { title: 'Capture Console Output', readOnlyHint: true, // Console capture doesn't modify anything destructiveHint: false, idempotentHint: false, // Each call captures fresh content openWorldHint: true, // Interacts with external websites }, };
  • TypeScript interfaces defining input (ConsoleCaptureOptions), output (ConsoleCaptureResult), and message structure (ConsoleMessage) for the capture_console tool.
    export interface ConsoleMessage { type: 'log' | 'error' | 'warn' | 'info' | 'debug'; text: string; timestamp: Date; args?: any[]; } export interface ConsoleCaptureOptions { url: string; jsCommand?: string; duration?: number; // Duration in seconds, default 4 waitUntil?: 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'; } export interface ConsoleCaptureResult { url: string; messages: ConsoleMessage[]; startTime: Date; endTime: Date; duration: number; executedCommand?: string; }
  • MCP server request handler that dispatches 'capture_console' tool calls: loads the screenshot module, maps arguments, calls captureConsole, formats the result messages, and returns MCP-formatted content.
    } else if (request.params.name === 'capture_console') { // Lazy load the module on first use if (!screenshotModule) { logger.debug('Loading screenshot module...'); screenshotModule = await import( './internal/screenshotCapture.js' ); logger.info('Screenshot module loaded successfully'); } const args = request.params.arguments as any; logger.info( `Processing console capture request for URL: ${args.url}` ); logger.debug('Console capture parameters:', { url: args.url, jsCommand: args.jsCommand, duration: args.duration, waitUntil: args.waitUntil, }); logger.debug('Calling captureConsole...'); const result = await screenshotModule.captureConsole({ url: args.url, jsCommand: args.jsCommand, duration: args.duration, waitUntil: args.waitUntil, }); logger.info('Console capture completed successfully'); logger.debug(`Captured ${result.messages.length} console messages`); // Format the console messages for output const formattedMessages = result.messages .map((msg: any) => { const timestamp = msg.timestamp.toISOString(); return `[${timestamp}] [${msg.type.toUpperCase()}] ${msg.text}`; }) .join('\n'); return { content: [ { type: 'text', text: `✅ Console capture completed for ${result.url} Duration: ${result.duration} seconds Messages captured: ${result.messages.length} ${result.executedCommand ? `JS Command executed: ${result.executedCommand}` : 'No JS command executed'} Console Output: ${formattedMessages || '(No console messages captured)'}`, }, ], }; } else {

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/just-every/mcp-screenshot-website-fast'

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