interceptor_browser_list_console
Retrieve buffered browser console messages (log, info, warning, error, debug) with optional filtering by type and text. Access historical console output from launched browsers.
Instructions
List console messages buffered since the browser was launched. Types: log, info, warning, error, debug, etc.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| target_id | Yes | Target ID from interceptor_browser_launch or interceptor_camoufox_launch | |
| types | No | Filter by console message types | |
| text_filter | No | Filter by text substring | |
| offset | No | Offset into results (default: 0) | |
| limit | No | Max messages to return (default: 50, max: 500) |
Implementation Reference
- src/tools/devtools.ts:205-238 (handler)The handler function for the interceptor_browser_list_console tool. Fetches console messages via getConsoleBufferForTarget, applies optional type/text filters, paginates with offset/limit, and returns the results.
async ({ target_id, types, text_filter, offset, limit }) => { try { let msgs = await getConsoleBufferForTarget(target_id); if (types && types.length > 0) { const set = new Set(types.map((t) => t.toLowerCase())); msgs = msgs.filter((m) => set.has(m.type.toLowerCase())); } if (text_filter) { const needle = text_filter.toLowerCase(); msgs = msgs.filter((m) => m.text.toLowerCase().includes(needle)); } const total = msgs.length; const o = normalizeOffset(offset); const l = normalizeLimit(limit); const page = msgs.slice(o, o + l); return { content: [{ type: "text", text: truncateResult({ status: "success", target_id, total, offset: o, limit: l, showing: page.length, messages: page, }), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: errorToString(e) }) }] }; } }, - src/tools/devtools.ts:196-204 (schema)The input schema for interceptor_browser_list_console: target_id (string), types (optional string array), text_filter (optional string), offset (number, default 0), limit (number, default 50, max 500).
"interceptor_browser_list_console", "List console messages buffered since the browser was launched. Types: log, info, warning, error, debug, etc.", { target_id: z.string().describe("Target ID from interceptor_browser_launch or interceptor_camoufox_launch"), types: z.array(z.string()).optional().describe("Filter by console message types"), text_filter: z.string().optional().describe("Filter by text substring"), offset: z.number().optional().default(0).describe("Offset into results (default: 0)"), limit: z.number().optional().default(DEFAULT_LIST_LIMIT).describe("Max messages to return (default: 50, max: 500)"), }, - src/tools/devtools.ts:111-239 (registration)Registration via server.tool() inside registerDevToolsTools(), which is called from src/index.ts at line 69.
export function registerDevToolsTools(server: McpServer): void { // ── snapshot ────────────────────────────────────────────────── server.tool( "interceptor_browser_snapshot", "Take an ARIA accessibility snapshot of the bound page (YAML-formatted role tree). " + "Great for LLM-driven page understanding without parsing HTML.", { target_id: z.string().describe("Target ID from interceptor_browser_launch or interceptor_camoufox_launch"), selector: z.string().optional().default("body").describe("Root selector to snapshot (default: 'body')"), mode: z.enum(["default", "ai"]).optional().default("default").describe("Snapshot mode — 'ai' adds ref attributes for locator reuse"), }, async ({ target_id, selector, mode }) => { try { const page = await getPageForTarget(target_id); const snapshot = await page.locator(selector).ariaSnapshot({ mode }); return { content: [{ type: "text", text: truncateResult({ status: "success", target_id, url: page.url(), title: await page.title().catch(() => ""), root: selector, snapshot, }), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: errorToString(e) }) }] }; } }, ); // ── screenshot ──────────────────────────────────────────────── server.tool( "interceptor_browser_screenshot", "Take a screenshot of the bound page. Saves to file_path if provided; otherwise reports byte count without embedding the image.", { target_id: z.string().describe("Target ID from interceptor_browser_launch or interceptor_camoufox_launch"), file_path: z.string().optional().describe("Optional path to save screenshot"), format: z.enum(["png", "jpeg"]).optional().default("png").describe("Image format (default: png)"), full_page: z.boolean().optional().default(false).describe("Capture the full scrollable page"), quality: z.number().optional().describe("JPEG quality 0-100 (ignored for png)"), }, async ({ target_id, file_path, format, full_page, quality }) => { try { const page = await getPageForTarget(target_id); const buffer = await page.screenshot({ type: format, fullPage: full_page, ...(format === "jpeg" && quality !== undefined ? { quality } : {}), }); let saved = false; if (file_path) { await mkdir(dirname(file_path), { recursive: true }); await writeFile(file_path, buffer); saved = true; } return { content: [{ type: "text", text: truncateResult({ status: "success", target_id, format, full_page, bytes: buffer.length, ...(file_path ? { file_path, saved } : {}), }), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: errorToString(e) }) }] }; } }, ); // ── console ─────────────────────────────────────────────────── server.tool( "interceptor_browser_list_console", "List console messages buffered since the browser was launched. Types: log, info, warning, error, debug, etc.", { target_id: z.string().describe("Target ID from interceptor_browser_launch or interceptor_camoufox_launch"), types: z.array(z.string()).optional().describe("Filter by console message types"), text_filter: z.string().optional().describe("Filter by text substring"), offset: z.number().optional().default(0).describe("Offset into results (default: 0)"), limit: z.number().optional().default(DEFAULT_LIST_LIMIT).describe("Max messages to return (default: 50, max: 500)"), }, async ({ target_id, types, text_filter, offset, limit }) => { try { let msgs = await getConsoleBufferForTarget(target_id); if (types && types.length > 0) { const set = new Set(types.map((t) => t.toLowerCase())); msgs = msgs.filter((m) => set.has(m.type.toLowerCase())); } if (text_filter) { const needle = text_filter.toLowerCase(); msgs = msgs.filter((m) => m.text.toLowerCase().includes(needle)); } const total = msgs.length; const o = normalizeOffset(offset); const l = normalizeLimit(limit); const page = msgs.slice(o, o + l); return { content: [{ type: "text", text: truncateResult({ status: "success", target_id, total, offset: o, limit: l, showing: page.length, messages: page, }), }], }; } catch (e) { return { content: [{ type: "text", text: JSON.stringify({ status: "error", error: errorToString(e) }) }] }; } }, ); - src/browser/session.ts:148-156 (helper)getConsoleBufferForTarget — helper that resolves the target entry and returns the console buffer. Handles both cloakbrowser (BrowserInterceptor) and camoufox targets.
export async function getConsoleBufferForTarget(targetId: string): Promise<ConsoleEntry[]> { const entry = getEntry(targetId); if (isCamoufoxTargetId(targetId)) { const camoufoxEntry = entry as CamoufoxEntryWithDriver; const page = await ensureCamoufoxPage(camoufoxEntry); return ensureConsoleBuffer(camoufoxEntry, page); } return (entry as BrowserTargetEntry).consoleBuffer; } - src/interceptors/browser.ts:15-28 (helper)ConsoleEntry interface definition — type, text, location, timestamp. Also BrowserTargetEntry interface which holds consoleBuffer.
export interface ConsoleEntry { type: string; text: string; location: string; timestamp: number; } export interface BrowserTargetEntry { target: ActiveTarget; browser: Browser; context: BrowserContext; page: Page; consoleBuffer: ConsoleEntry[]; }