mcp-scraper 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +4 -1
  2. package/dist/bin/api-server.cjs +2047 -831
  3. package/dist/bin/api-server.cjs.map +1 -1
  4. package/dist/bin/api-server.js +2 -2
  5. package/dist/bin/browser-agent-stdio-server.cjs +3 -3
  6. package/dist/bin/browser-agent-stdio-server.cjs.map +1 -1
  7. package/dist/bin/browser-agent-stdio-server.js +2 -2
  8. package/dist/bin/mcp-scraper-cli.cjs +1 -1
  9. package/dist/bin/mcp-scraper-cli.cjs.map +1 -1
  10. package/dist/bin/mcp-scraper-cli.js +1 -1
  11. package/dist/bin/mcp-scraper-combined-stdio-server.cjs +350 -5
  12. package/dist/bin/mcp-scraper-combined-stdio-server.cjs.map +1 -1
  13. package/dist/bin/mcp-scraper-combined-stdio-server.js +4 -4
  14. package/dist/bin/mcp-scraper-install.cjs +3 -3
  15. package/dist/bin/mcp-scraper-install.cjs.map +1 -1
  16. package/dist/bin/mcp-scraper-install.js +2 -2
  17. package/dist/bin/mcp-stdio-server.cjs +346 -1
  18. package/dist/bin/mcp-stdio-server.cjs.map +1 -1
  19. package/dist/bin/mcp-stdio-server.js +2 -2
  20. package/dist/bin/paa-harvest.cjs +3 -1
  21. package/dist/bin/paa-harvest.cjs.map +1 -1
  22. package/dist/bin/paa-harvest.js +1 -1
  23. package/dist/{chunk-SXTXMFEQ.js → chunk-AZ5PKU4F.js} +34 -1
  24. package/dist/chunk-AZ5PKU4F.js.map +1 -0
  25. package/dist/{chunk-Q4STSM63.js → chunk-C3FGVJWH.js} +3 -3
  26. package/dist/chunk-C3FGVJWH.js.map +1 -0
  27. package/dist/{chunk-DH4H3F6S.js → chunk-HRTCMLZB.js} +4 -4
  28. package/dist/chunk-HRTCMLZB.js.map +1 -0
  29. package/dist/{chunk-SIXJ6EVS.js → chunk-KO223PSJ.js} +347 -2
  30. package/dist/chunk-KO223PSJ.js.map +1 -0
  31. package/dist/{chunk-IPW4LFOT.js → chunk-UWSG3C5J.js} +4 -2
  32. package/dist/chunk-UWSG3C5J.js.map +1 -0
  33. package/dist/chunk-VB65G7PS.js +7 -0
  34. package/dist/chunk-VB65G7PS.js.map +1 -0
  35. package/dist/index.cjs +3 -1
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.js +1 -1
  38. package/dist/{server-MOP7NIUK.js → server-N5LM3PEO.js} +997 -253
  39. package/dist/server-N5LM3PEO.js.map +1 -0
  40. package/dist/{worker-SLQ375UG.js → worker-56IXWOQU.js} +3 -3
  41. package/docs/mcp-tool-craft-lint.generated.md +5 -2
  42. package/docs/mcp-tool-manifest.generated.json +85 -9
  43. package/package.json +1 -1
  44. package/dist/chunk-DH4H3F6S.js.map +0 -1
  45. package/dist/chunk-IPW4LFOT.js.map +0 -1
  46. package/dist/chunk-PGWJ2EJ3.js +0 -7
  47. package/dist/chunk-PGWJ2EJ3.js.map +0 -1
  48. package/dist/chunk-Q4STSM63.js.map +0 -1
  49. package/dist/chunk-SIXJ6EVS.js.map +0 -1
  50. package/dist/chunk-SXTXMFEQ.js.map +0 -1
  51. package/dist/server-MOP7NIUK.js.map +0 -1
  52. /package/dist/{worker-SLQ375UG.js.map → worker-56IXWOQU.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/browser-agent-stdio-server.ts","../../src/mcp/browser-agent-mcp-server.ts","../../src/lib/chrome-profiles.ts","../../src/lib/browser-service-env.ts","../../src/lib/local-browser-profiles.ts","../../src/services/browser-agent/local-browser-agent-service.ts","../../src/services/fanout/cdp-capture.ts","../../src/services/fanout/parse-helpers.ts","../../src/services/fanout/adapters/chatgpt.ts","../../src/services/fanout/adapters/claude.ts","../../src/services/fanout/adapters/index.ts","../../src/services/fanout/build.ts","../../src/services/fanout/classify.ts","../../src/services/fanout/export.ts","../../src/services/fanout/run-capture.ts","../../src/version.ts","../../src/mcp/browser-agent-tool-schemas.ts","../../src/mcp/replay-annotator.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { buildBrowserAgentMcpServer } from '../src/mcp/browser-agent-mcp-server.js'\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.MCP_SCRAPER_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.mcp-scraper-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n void 0\n }\n }\n return undefined\n}\n\nconst apiKey = (\n process.env.MCP_SCRAPER_API_KEY ??\n process.env.MCP_SCRAPER_KEY ??\n process.env.MCP_API_KEY ??\n readApiKeyFile()\n)?.trim()\nif (!apiKey) {\n process.stderr.write('MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\\n')\n process.exit(1)\n}\n\nconst baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || 'https://mcpscraper.dev'\nconst consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl\nconst server = buildBrowserAgentMcpServer({ baseUrl, apiKey, consoleBaseUrl })\nconst transport = new StdioServerTransport()\n\nasync function main() {\n await server.connect(transport)\n}\n\nmain().catch(err => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { listLocalChromeProfiles, type LocalChromeProfile } from '../lib/chrome-profiles.js'\nimport { browserServiceProfileName, browserServiceProfileSaveChanges } from '../lib/browser-service-env.js'\nimport { importChromeProfile, localBrowserModeEnabled, syncImportedChromeProfile } from '../lib/local-browser-profiles.js'\nimport { LocalBrowserAgentService } from '../services/browser-agent/local-browser-agent-service.js'\nimport { PACKAGE_VERSION } from '../version.js'\nimport {\n BrowserOpenInputSchema,\n BrowserProfileListInputSchema,\n BrowserProfileOnboardInputSchema,\n BrowserProfileImportInputSchema,\n BrowserProfileSyncInputSchema,\n BrowserCaptureFanoutInputSchema,\n BrowserCaptureFanoutOutputSchema,\n BrowserSessionInputSchema,\n BrowserLocateInputSchema,\n BrowserGotoInputSchema,\n BrowserClickInputSchema,\n BrowserTypeInputSchema,\n BrowserScrollInputSchema,\n BrowserPressInputSchema,\n BrowserReplayStopInputSchema,\n BrowserReplayDownloadInputSchema,\n BrowserReplayMarkInputSchema,\n BrowserReplayAnnotateInputSchema,\n BrowserListInputSchema,\n BrowserOpenOutputSchema,\n BrowserScreenshotOutputSchema,\n BrowserReadOutputSchema,\n BrowserLocateOutputSchema,\n BrowserActionOutputSchema,\n BrowserReplayStartOutputSchema,\n BrowserReplayStopOutputSchema,\n BrowserListReplaysOutputSchema,\n BrowserReplayDownloadOutputSchema,\n BrowserReplayMarkOutputSchema,\n BrowserReplayAnnotateOutputSchema,\n BrowserCloseOutputSchema,\n BrowserListSessionsOutputSchema,\n BrowserProfileListOutputSchema,\n BrowserProfileOnboardOutputSchema,\n BrowserProfileImportOutputSchema,\n BrowserProfileSyncOutputSchema,\n} from './browser-agent-tool-schemas.js'\nimport { annotateReplayVideo } from './replay-annotator.js'\n\nexport interface BrowserAgentHttpOptions {\n baseUrl: string\n apiKey: string\n consoleBaseUrl?: string\n timeoutMs?: number\n}\n\nfunction structuredResult(value: Record<string, unknown>, isError = false): CallToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(value) }],\n structuredContent: value,\n isError,\n }\n}\n\nfunction errorMessage(value: unknown): string {\n if (value && typeof value === 'object') {\n const data = value as Record<string, unknown>\n if (typeof data.error === 'string') return data.error\n if (typeof data.message === 'string') return data.message\n }\n return typeof value === 'string' ? value : 'Browser Agent request failed'\n}\n\nfunction errorResult(tool: string, value: unknown, sessionId: string | null = null, replayId: string | null = null): CallToolResult {\n return structuredResult({\n ok: false,\n tool,\n session_id: sessionId,\n ...(replayId !== null ? { replay_id: replayId } : {}),\n error: errorMessage(value),\n raw: value && typeof value === 'object' ? value as Record<string, unknown> : { value },\n }, true)\n}\n\nfunction actionResult(\n tool: string,\n sessionId: string,\n ok: boolean,\n data: unknown,\n nextRecommendedTool: string | null = 'browser_screenshot',\n): CallToolResult {\n if (!ok) return errorResult(tool, data, sessionId)\n return structuredResult({\n ok: true,\n tool,\n session_id: sessionId,\n result: data && typeof data === 'object' ? data as Record<string, unknown> : { value: data },\n nextRecommendedTool,\n })\n}\n\nfunction outputBaseDir(): string {\n return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction safeFilePart(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 120) || 'replay'\n}\n\nfunction replayFilePath(sessionId: string, replayId: string, filename?: string): string {\n const requested = filename?.trim()\n const stamp = new Date().toISOString().replace(/[:.]/g, '-')\n const name = requested\n ? safeFilePart(requested).replace(/\\.mp4$/i, '')\n : `${stamp}-${safeFilePart(sessionId)}-${safeFilePart(replayId)}`\n return join(outputBaseDir(), 'browser-replays', `${name}.mp4`)\n}\n\nfunction annotatedReplayFilePath(sessionId: string, replayId: string, filename?: string): string {\n const requested = filename?.trim()\n if (requested) return replayFilePath(sessionId, replayId, requested)\n const stamp = new Date().toISOString().replace(/[:.]/g, '-')\n return replayFilePath(sessionId, replayId, `${stamp}-${safeFilePart(sessionId)}-${safeFilePart(replayId)}-annotated`)\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction expandElementBounds(\n element: { left: number; top: number; width: number; height: number },\n viewport: { width?: number; height?: number } | undefined,\n padding: number,\n) {\n const sourceWidth = finiteNumber(viewport?.width) && viewport!.width > 0 ? viewport!.width : 1920\n const sourceHeight = finiteNumber(viewport?.height) && viewport!.height > 0 ? viewport!.height : 1080\n const left = Math.max(0, element.left - padding)\n const top = Math.max(0, element.top - padding)\n const right = Math.min(sourceWidth, element.left + element.width + padding)\n const bottom = Math.min(sourceHeight, element.top + element.height + padding)\n return {\n left,\n top,\n width: Math.max(1, right - left),\n height: Math.max(1, bottom - top),\n sourceWidth,\n sourceHeight,\n }\n}\n\nexport function buildBrowserAgentMcpServer(opts: BrowserAgentHttpOptions): McpServer {\n const server = new McpServer({ name: 'browser-agent', version: PACKAGE_VERSION })\n registerBrowserAgentMcpTools(server, opts)\n return server\n}\n\nexport function registerBrowserAgentMcpTools(server: McpServer, opts: BrowserAgentHttpOptions): void {\n const baseUrl = opts.baseUrl.replace(/\\/$/, '')\n const consoleBase = (opts.consoleBaseUrl ?? opts.baseUrl).replace(/\\/$/, '')\n const timeoutMs = opts.timeoutMs ?? 90_000\n const localBrowser = new LocalBrowserAgentService()\n\n async function req(method: string, path: string, body?: Record<string, unknown>): Promise<{ ok: boolean; data: any }> {\n try {\n const res = await fetch(`${baseUrl}${path}`, {\n method,\n headers: { 'Content-Type': 'application/json', 'x-api-key': opts.apiKey },\n body: body ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(timeoutMs),\n })\n const data = await res.json().catch(() => ({}))\n return { ok: res.ok, data }\n } catch (err) {\n return { ok: false, data: { error: err instanceof Error ? err.message : String(err) } }\n }\n }\n\n async function downloadReplay(\n sessionId: string,\n replayId: string,\n filename?: string,\n ): Promise<{ ok: boolean; data: any }> {\n const path = `/agent/sessions/${encodeURIComponent(sessionId)}/replays/${encodeURIComponent(replayId)}/download`\n try {\n const res = await fetch(`${baseUrl}${path}`, {\n method: 'GET',\n headers: { 'x-api-key': opts.apiKey },\n signal: AbortSignal.timeout(timeoutMs),\n })\n if (!res.ok) {\n const data = await res.json().catch(async () => ({ error: await res.text().catch(() => `HTTP ${res.status}`) }))\n return { ok: false, data }\n }\n const bytes = Buffer.from(await res.arrayBuffer())\n const filePath = replayFilePath(sessionId, replayId, filename)\n mkdirSync(join(outputBaseDir(), 'browser-replays'), { recursive: true })\n writeFileSync(filePath, bytes)\n return {\n ok: true,\n data: {\n replay_id: replayId,\n file_path: filePath,\n bytes: bytes.length,\n mime_type: res.headers.get('content-type') ?? 'video/mp4',\n download_url: `${baseUrl}${path}`,\n },\n }\n } catch (err) {\n return { ok: false, data: { error: err instanceof Error ? err.message : String(err) } }\n }\n }\n\n const annotations = (title: string, readOnly = false) => ({\n title,\n readOnlyHint: readOnly,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n })\n\n function selectChromeProfile(matches: LocalChromeProfile[], email?: string): LocalChromeProfile | null {\n const wanted = email?.trim().toLowerCase()\n if (!wanted) return matches[0] ?? null\n return matches.find(profile => profile.email.toLowerCase() === wanted) ?? matches[0] ?? null\n }\n\n function localReplayUnsupported(tool: string, sessionId: string | null = null, replayId: string | null = null): CallToolResult {\n return errorResult(tool, {\n error: 'Local browser mode does not support replay recording yet. Use hosted mode for browser_replay_* tools.',\n mode: 'local',\n }, sessionId, replayId)\n }\n\n server.registerTool(\n 'browser_profile_list',\n {\n title: 'List Local Chrome Profiles',\n description:\n 'List local Chrome profile metadata visible to this MCP server: account email, Chrome profile directory, local path, and a suggested managed browser profile name. This reads Chrome Local State only; it does not read cookies, passwords, browsing history, or copy local browser state. Use browser_profile_import when the user wants MCP Scraper to clone a local Chrome profile for local browser mode.',\n inputSchema: BrowserProfileListInputSchema,\n outputSchema: BrowserProfileListOutputSchema,\n annotations: annotations('List Local Chrome Profiles', true),\n },\n async input => {\n try {\n const profiles = await listLocalChromeProfiles(input.user_data_dir, input.email)\n return structuredResult({\n ok: true,\n tool: 'browser_profile_list',\n session_id: null,\n profiles,\n count: profiles.length,\n hint: 'Use browser_profile_import to clone one profile for local mode. Use browser_profile_onboard only for hosted Kernel profile setup.',\n })\n } catch (err) {\n return errorResult('browser_profile_list', { error: err instanceof Error ? err.message : String(err) })\n }\n },\n )\n\n server.registerTool(\n 'browser_profile_import',\n {\n title: 'Import Local Chrome Profile',\n description:\n 'Clone one local Chrome profile into MCP Scraper managed storage for local browser mode. This copies browser state files such as cookies, history, local storage, session storage, and password database metadata into ~/.mcp-scraper/browser-profiles by default; it skips cache and lock files and never prints cookie or password values. Use this when the user wants browser_open to run locally with their existing logged-in Chrome state.',\n inputSchema: BrowserProfileImportInputSchema,\n outputSchema: BrowserProfileImportOutputSchema,\n annotations: { title: 'Import Local Chrome Profile', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },\n },\n async input => {\n try {\n const result = await importChromeProfile({\n email: input.email,\n name: input.name,\n chromeProfileDirectory: input.chrome_profile_directory,\n sourceUserDataDir: input.user_data_dir,\n outputDir: input.output_dir,\n overwrite: input.overwrite,\n browserExecutablePath: input.browser_executable_path,\n })\n return structuredResult({\n ok: true,\n tool: 'browser_profile_import',\n session_id: null,\n profile: result.profile,\n source_profile: result.sourceProfile,\n next_steps: [\n `Set MCP_SCRAPER_BROWSER_MODE=local in the MCP server config.`,\n `Set MCP_SCRAPER_BROWSER_PROFILE=${result.profile.name}.`,\n 'Restart the MCP client so it starts the local browser mode process.',\n 'Call browser_open with the same MCP server; it will open a local Chrome window using the cloned profile.',\n ],\n hint: 'The clone is local to this machine. Re-run browser_profile_sync after logging into new sites in normal Chrome.',\n })\n } catch (err) {\n return errorResult('browser_profile_import', { error: err instanceof Error ? err.message : String(err) })\n }\n },\n )\n\n server.registerTool(\n 'browser_profile_sync',\n {\n title: 'Sync Local Chrome Profile',\n description:\n 'Refresh an existing MCP Scraper managed local browser profile from the source Chrome profile recorded in its manifest. This overwrites the managed clone, copies browser state files again, skips cache and lock files, and never prints cookie or password values.',\n inputSchema: BrowserProfileSyncInputSchema,\n outputSchema: BrowserProfileSyncOutputSchema,\n annotations: { title: 'Sync Local Chrome Profile', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },\n },\n async input => {\n try {\n const result = await syncImportedChromeProfile(input.name, {\n outputDir: input.output_dir,\n browserExecutablePath: input.browser_executable_path,\n })\n return structuredResult({\n ok: true,\n tool: 'browser_profile_sync',\n session_id: null,\n profile: result.profile,\n source_profile: result.sourceProfile,\n hint: `Refreshed ${result.profile.name}. Restart local browser sessions that were using this profile.`,\n })\n } catch (err) {\n return errorResult('browser_profile_sync', { error: err instanceof Error ? err.message : String(err) })\n }\n },\n )\n\n server.registerTool(\n 'browser_profile_onboard',\n {\n title: 'Onboard Hosted Browser Profile',\n description:\n 'Create or load a saved hosted Kernel browser profile and open a live setup browser with profile saving enabled. Use this only for hosted browser mode. If email is provided, the tool reads local Chrome profile metadata only to suggest the Kernel profile name; it does not import local cookies. For local browser mode with real Chrome state, use browser_profile_import instead.',\n inputSchema: BrowserProfileOnboardInputSchema,\n outputSchema: BrowserProfileOnboardOutputSchema,\n annotations: annotations('Onboard Hosted Browser Profile'),\n },\n async input => {\n let chromeProfile: LocalChromeProfile | null = null\n if (input.email) {\n try {\n chromeProfile = selectChromeProfile(await listLocalChromeProfiles(input.user_data_dir, input.email), input.email)\n } catch (err) {\n return errorResult('browser_profile_onboard', { error: err instanceof Error ? err.message : String(err) })\n }\n }\n const profile = input.profile?.trim() || chromeProfile?.recommendedKernelProfileName || browserServiceProfileName()\n if (!profile) {\n return errorResult('browser_profile_onboard', {\n error: 'profile is required when no email match or BROWSER_AGENT_PROFILE_NAME is available',\n })\n }\n const setupUrl = input.url ?? 'https://accounts.google.com/'\n const open = await req('POST', '/agent/sessions', {\n label: input.label ?? `Profile setup: ${profile}`,\n profile,\n save_profile_changes: true,\n timeout_seconds: input.timeout_seconds,\n })\n if (!open.ok) return errorResult('browser_profile_onboard', open.data)\n const session = open.data\n const goto = await req('POST', `/agent/sessions/${session.session_id}/goto`, { url: setupUrl })\n if (!goto.ok) return errorResult('browser_profile_onboard', goto.data, session.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_profile_onboard',\n session_id: session.session_id,\n watch_url: `${consoleBase}/console/${session.session_id}`,\n live_view_url: session.live_view_url ?? null,\n profile,\n setup_url: setupUrl,\n chrome_profile: chromeProfile,\n next_steps: [\n 'Open the watch_url and complete the login manually.',\n 'After login is complete, call browser_close with this session_id to persist cookies and local storage to the Kernel profile.',\n 'Use BROWSER_AGENT_PROFILE_NAME or browser_open.profile with this profile name for future authenticated sessions.',\n ],\n raw: session,\n })\n },\n )\n\n server.registerTool(\n 'browser_open',\n {\n title: 'Open Browser Session',\n description:\n 'Open a browser you can drive. By default this creates a hosted cloud browser with a watch_url; when MCP_SCRAPER_BROWSER_MODE=local it opens a local Google Chrome window against an imported MCP Scraper Chrome profile. Returns a session_id used by all other browser_* tools. In hosted mode, anti-bot stealth and automatic CAPTCHA/Cloudflare solving are on by default. Call browser_close when done.',\n inputSchema: BrowserOpenInputSchema,\n outputSchema: BrowserOpenOutputSchema,\n annotations: annotations('Open Browser Session'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const session = await localBrowser.open(input)\n return structuredResult({\n ok: true,\n tool: 'browser_open',\n session_id: session.session_id,\n watch_url: session.watch_url,\n live_view_url: null,\n url: input.url ?? null,\n hint: 'Local Chrome is open on this machine. Call browser_screenshot to see the page and click by x,y coordinates.',\n raw: session,\n })\n } catch (err) {\n return errorResult('browser_open', { error: err instanceof Error ? err.message : String(err), mode: 'local' })\n }\n }\n const profile = input.profile ?? browserServiceProfileName()\n const saveProfileChanges = input.save_profile_changes ?? browserServiceProfileSaveChanges()\n const open = await req('POST', '/agent/sessions', {\n label: input.label,\n ...(profile ? { profile } : {}),\n ...(profile && typeof saveProfileChanges === 'boolean' ? { save_profile_changes: saveProfileChanges } : {}),\n timeout_seconds: input.timeout_seconds,\n })\n if (!open.ok) return errorResult('browser_open', open.data)\n const session = open.data\n if (input.url) {\n await req('POST', `/agent/sessions/${session.session_id}/goto`, { url: input.url })\n }\n return structuredResult({\n ok: true,\n tool: 'browser_open',\n session_id: session.session_id,\n watch_url: `${consoleBase}/console/${session.session_id}`,\n live_view_url: session.live_view_url ?? null,\n url: input.url ?? null,\n hint: 'Call browser_screenshot to see the page. Click by the x,y of an element from the snapshot.',\n raw: session,\n })\n },\n )\n\n server.registerTool(\n 'browser_screenshot',\n {\n title: 'See Page (Screenshot + Elements)',\n description:\n 'Capture what the browser currently shows. Returns a screenshot image PLUS a text snapshot listing interactive elements with their center x,y coordinates, the page url and title, and visible text. This is your primary way to perceive the page. Click elements by their listed x,y. If a Cloudflare/CAPTCHA challenge is visible, wait and screenshot again rather than clicking it.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserScreenshotOutputSchema,\n annotations: annotations('See Page', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.screenshot(input.session_id)\n const content: CallToolResult['content'] = []\n if (res.image_base64) content.push({ type: 'image', data: res.image_base64, mimeType: res.mime_type })\n const structured = {\n ok: true,\n tool: 'browser_screenshot',\n session_id: input.session_id,\n url: res.url ?? null,\n title: res.title ?? null,\n text: res.text,\n elements: res.elements,\n screenshot: { mime_type: res.mime_type, inline: true },\n }\n content.push({ type: 'text', text: JSON.stringify(structured) })\n return { content, structuredContent: structured }\n } catch (err) {\n return errorResult('browser_screenshot', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/screenshot`)\n if (!res.ok) return errorResult('browser_screenshot', res.data, input.session_id)\n const { image_base64, mime_type, url, title, elements, text } = res.data\n const content: CallToolResult['content'] = []\n if (image_base64) content.push({ type: 'image', data: image_base64, mimeType: mime_type ?? 'image/png' })\n const structured = {\n ok: true,\n tool: 'browser_screenshot',\n session_id: input.session_id,\n url: url ?? null,\n title: title ?? null,\n text: typeof text === 'string' ? text : '',\n elements: Array.isArray(elements) ? elements : [],\n screenshot: image_base64 ? { mime_type: mime_type ?? 'image/png', inline: true } : null,\n }\n content.push({\n type: 'text',\n text: JSON.stringify(structured),\n })\n return { content, structuredContent: structured }\n },\n )\n\n server.registerTool(\n 'browser_read',\n {\n title: 'Read Page Text + Elements',\n description:\n 'Return the page url, title, visible text, and the list of interactive elements (with x,y) without an image. Cheaper than browser_screenshot when you only need to read content or find a target element to click.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserReadOutputSchema,\n annotations: annotations('Read Page', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.read(input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_read',\n session_id: input.session_id,\n url: res.url ?? null,\n title: res.title ?? null,\n text: res.text,\n elements: res.elements,\n raw: res,\n })\n } catch (err) {\n return errorResult('browser_read', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/read`)\n if (!res.ok) return errorResult('browser_read', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_read',\n session_id: input.session_id,\n url: res.data?.url ?? null,\n title: res.data?.title ?? null,\n text: typeof res.data?.text === 'string' ? res.data.text : '',\n elements: Array.isArray(res.data?.elements) ? res.data.elements : [],\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_locate',\n {\n title: 'Locate DOM Targets',\n description:\n 'Locate exact visible DOM elements or text ranges in the current browser viewport and return left/top/width/height bounds in screenshot pixels. Use this before drawing annotations or when a callout must literally circle, box, underline, or point to a real element. Prefer CSS selectors for exact UI elements; use text when selector is unknown. When a replay is actively recording, the result includes replay_elapsed_seconds for timing.',\n inputSchema: BrowserLocateInputSchema,\n outputSchema: BrowserLocateOutputSchema,\n annotations: annotations('Locate DOM Targets', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.locate(input.session_id, input.targets)\n return structuredResult({\n ok: true,\n tool: 'browser_locate',\n session_id: input.session_id,\n url: res.url ?? null,\n title: res.title ?? null,\n viewport: res.viewport ?? null,\n replay: null,\n targets: Array.isArray(res.targets) ? res.targets : [],\n raw: res,\n })\n } catch (err) {\n return errorResult('browser_locate', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/locate`, { targets: input.targets })\n if (!res.ok) return errorResult('browser_locate', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_locate',\n session_id: input.session_id,\n url: res.data?.url ?? null,\n title: res.data?.title ?? null,\n viewport: res.data?.viewport ?? null,\n replay: res.data?.replay ?? null,\n targets: Array.isArray(res.data?.targets) ? res.data.targets : [],\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_goto',\n {\n title: 'Navigate To URL',\n description: 'Navigate an existing browser session to a URL when the user asks you to go to another page or continue browsing in the same session. Use browser_open first if no session exists. Follow with browser_screenshot to see redirects, login walls, CAPTCHA/Cloudflare state, or the loaded page.',\n inputSchema: BrowserGotoInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Navigate To URL'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.goto(input.session_id, input.url)\n return actionResult('browser_goto', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_goto', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/goto`, { url: input.url })\n return actionResult('browser_goto', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_click',\n {\n title: 'Click',\n description: 'Click a visible page target using screenshot pixel coordinates. Use this when the user asks you to press a button, open a menu, choose a result, or activate a visible UI element. Use x/y only from the latest browser_screenshot, browser_read, or browser_locate result; do not guess coordinates. Follow with browser_screenshot when the click may change the page.',\n inputSchema: BrowserClickInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Click'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.click(input.session_id, input)\n return actionResult('browser_click', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_click', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/click`, {\n x: input.x,\n y: input.y,\n button: input.button,\n num_clicks: input.num_clicks,\n })\n return actionResult('browser_click', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_type',\n {\n title: 'Type Text',\n description: 'Type text into the currently focused browser field. Use this when the user asks you to fill a search box, form field, login field, or editable text area. Click or Tab to the field first if focus is uncertain. Use browser_press with [\"Return\"] to submit, and browser_screenshot afterward when page state matters.',\n inputSchema: BrowserTypeInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Type Text'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.type(input.session_id, input)\n return actionResult('browser_type', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_type', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/type`, { text: input.text, delay: input.delay })\n return actionResult('browser_type', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_scroll',\n {\n title: 'Scroll',\n description: 'Scroll the page to reveal more content before reading, clicking, or locating elements. Positive delta_y scrolls down; negative delta_y scrolls up. Follow with browser_screenshot or browser_read to inspect newly revealed content.',\n inputSchema: BrowserScrollInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Scroll'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.scroll(input.session_id, input)\n return actionResult('browser_scroll', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_scroll', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/scroll`, {\n delta_y: input.delta_y,\n delta_x: input.delta_x,\n x: input.x,\n y: input.y,\n })\n return actionResult('browser_scroll', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_press',\n {\n title: 'Press Keys',\n description: 'Press keyboard keys or combinations in the active browser session. Use this for submit, Escape, Tab navigation, select-all, or keyboard shortcuts. Examples: [\"Return\"], [\"Escape\"], [\"Tab\"], [\"Ctrl+a\"], [\"Ctrl+Shift+Tab\"]. Use browser_type for text entry and browser_screenshot after keypresses that may change the page.',\n inputSchema: BrowserPressInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Press Keys'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.press(input.session_id, input)\n return actionResult('browser_press', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_press', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/press`, { keys: input.keys })\n return actionResult('browser_press', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_replay_start',\n {\n title: 'Start Recording',\n description: 'Start recording an MP4 replay of the session. Returns replay_id, view_url when available, and a download_url. Use to capture a task for later review; stop with browser_replay_stop.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserReplayStartOutputSchema,\n annotations: annotations('Start Recording'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_start', input.session_id)\n const res = await req('POST', `/agent/sessions/${input.session_id}/replay/start`)\n if (!res.ok) return errorResult('browser_replay_start', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_replay_start',\n session_id: input.session_id,\n replay_id: res.data?.replay_id ?? res.data?.replayId ?? null,\n view_url: res.data?.view_url ?? res.data?.viewUrl ?? null,\n download_url: res.data?.download_url ?? res.data?.downloadUrl ?? null,\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_stop',\n {\n title: 'Stop Recording',\n description: 'Stop a replay recording and expose the final view_url and download_url. Use browser_replay_download to save the MP4 locally.',\n inputSchema: BrowserReplayStopInputSchema,\n outputSchema: BrowserReplayStopOutputSchema,\n annotations: annotations('Stop Recording'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_stop', input.session_id, input.replay_id)\n const res = await req('POST', `/agent/sessions/${input.session_id}/replay/stop`, { replay_id: input.replay_id })\n if (!res.ok) return errorResult('browser_replay_stop', res.data, input.session_id, input.replay_id)\n return structuredResult({\n ok: true,\n tool: 'browser_replay_stop',\n session_id: input.session_id,\n replay_id: res.data?.replay_id ?? res.data?.replayId ?? input.replay_id,\n view_url: res.data?.view_url ?? res.data?.viewUrl ?? null,\n download_url: res.data?.download_url ?? res.data?.downloadUrl ?? null,\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_list_replays',\n {\n title: 'List Replay Videos',\n description: 'List replay recordings for a browser session, including final view_url and authenticated download_url values when available.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserListReplaysOutputSchema,\n annotations: annotations('List Replay Videos', true),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_list_replays', input.session_id)\n const res = await req('GET', `/agent/sessions/${input.session_id}/replays`)\n if (!res.ok) return errorResult('browser_list_replays', res.data, input.session_id)\n const replays = Array.isArray(res.data?.replays) ? res.data.replays : []\n return structuredResult({\n ok: true,\n tool: 'browser_list_replays',\n session_id: input.session_id,\n replays,\n count: replays.length,\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_download',\n {\n title: 'Download Replay MP4',\n description: 'Download a replay recording through MCP Scraper and save the MP4 locally under MCP_SCRAPER_OUTPUT_DIR/browser-replays. Use after browser_replay_stop or browser_list_replays.',\n inputSchema: BrowserReplayDownloadInputSchema,\n outputSchema: BrowserReplayDownloadOutputSchema,\n annotations: annotations('Download Replay MP4'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_download', input.session_id, input.replay_id)\n const res = await downloadReplay(input.session_id, input.replay_id, input.filename)\n if (!res.ok) return errorResult('browser_replay_download', res.data, input.session_id, input.replay_id)\n return structuredResult({\n ok: true,\n tool: 'browser_replay_download',\n session_id: input.session_id,\n replay_id: input.replay_id,\n file_path: res.data?.file_path ?? null,\n bytes: typeof res.data?.bytes === 'number' ? res.data.bytes : null,\n mime_type: res.data?.mime_type ?? null,\n download_url: res.data?.download_url ?? null,\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_mark',\n {\n title: 'Mark Replay Annotation',\n description:\n 'While a replay is actively recording, locate one exact DOM target and return a ready-to-use annotation object with DOM bounds and replay-relative timing. Use this instead of guessing start_seconds or drawing rough rectangles. Workflow: start browser_replay_start, navigate until the target is visible and stable, call browser_replay_mark for each callout, then stop the replay and pass the returned annotations to browser_replay_annotate.',\n inputSchema: BrowserReplayMarkInputSchema,\n outputSchema: BrowserReplayMarkOutputSchema,\n annotations: annotations('Mark Replay Annotation', true),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_mark', input.session_id)\n const res = await req('POST', `/agent/sessions/${input.session_id}/locate`, { targets: [input.target] })\n if (!res.ok) return errorResult('browser_replay_mark', res.data, input.session_id)\n const target = res.data?.targets?.[0]\n const element = target?.element\n const elapsed = res.data?.replay?.replay_elapsed_seconds\n if (!target?.found || !element) {\n return errorResult('browser_replay_mark', { error: target?.error ?? 'target not found in current viewport', target }, input.session_id)\n }\n if (!finiteNumber(elapsed)) {\n return errorResult('browser_replay_mark', { error: 'no active replay clock found; call browser_replay_start before browser_replay_mark' }, input.session_id)\n }\n const padded = expandElementBounds(element, res.data?.viewport, input.padding ?? 8)\n const start = Math.max(0, elapsed + (input.start_offset_seconds ?? -0.25))\n const duration = input.duration_seconds ?? 4\n const annotation = {\n type: input.type ?? 'box',\n start_seconds: Number(start.toFixed(3)),\n end_seconds: Number((start + duration).toFixed(3)),\n left: Math.round(padded.left),\n top: Math.round(padded.top),\n width: Math.round(padded.width),\n height: Math.round(padded.height),\n ...(input.label ? { label: input.label } : {}),\n ...(input.color ? { color: input.color } : {}),\n ...(input.thickness ? { thickness: input.thickness } : {}),\n }\n return structuredResult({\n ok: true,\n tool: 'browser_replay_mark',\n session_id: input.session_id,\n replay_id: res.data?.replay?.replay_id ?? res.data?.replay?.replayId ?? null,\n annotation,\n source_width: padded.sourceWidth,\n source_height: padded.sourceHeight,\n replay: res.data.replay,\n target,\n hint: 'Append annotation to your annotations array. Use source_width/source_height with browser_replay_annotate.',\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_annotate',\n {\n title: 'Annotate Replay MP4',\n description:\n 'Download a browser replay MP4, render visual annotations over it, and save a new annotated MP4 locally. Use this after browser_replay_stop when the user wants proof videos with circles, boxes, arrows, underlines, or labels. For accurate timing and placement, prefer annotations returned by browser_replay_mark while the replay is recording; otherwise use exact left/top/width/height bounds from browser_locate. If the replay video size differs from the screenshot coordinate space, pass source_width and source_height.',\n inputSchema: BrowserReplayAnnotateInputSchema,\n outputSchema: BrowserReplayAnnotateOutputSchema,\n annotations: annotations('Annotate Replay MP4'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_annotate', input.session_id, input.replay_id)\n const sourceName = input.filename ? `${input.filename}-source` : undefined\n const downloaded = await downloadReplay(input.session_id, input.replay_id, sourceName)\n if (!downloaded.ok) return errorResult('browser_replay_annotate', downloaded.data, input.session_id, input.replay_id)\n try {\n const sourcePath = String(downloaded.data.file_path)\n const outputPath = annotatedReplayFilePath(input.session_id, input.replay_id, input.filename)\n mkdirSync(join(outputBaseDir(), 'browser-replays'), { recursive: true })\n const result = await annotateReplayVideo(sourcePath, outputPath, {\n annotations: input.annotations,\n sourceWidth: input.source_width,\n sourceHeight: input.source_height,\n sourceLeftOffset: input.source_left_offset,\n sourceTopOffset: input.source_top_offset,\n })\n return structuredResult({\n ok: true,\n tool: 'browser_replay_annotate',\n session_id: input.session_id,\n replay_id: input.replay_id,\n source_file_path: sourcePath,\n annotated_file_path: result.filePath,\n bytes: result.bytes,\n width: result.width,\n height: result.height,\n annotation_count: result.annotationCount,\n mime_type: 'video/mp4',\n })\n } catch (err) {\n return errorResult('browser_replay_annotate', { error: err instanceof Error ? err.message : String(err) }, input.session_id, input.replay_id)\n }\n },\n )\n\n server.registerTool(\n 'browser_close',\n {\n title: 'Close Browser Session',\n description: 'Close and release a browser session when the task is done, when the user asks to stop the browser, or when active browser billing should end. Use browser_list_sessions first if you need to recover the session_id.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserCloseOutputSchema,\n annotations: { title: 'Close Browser Session', readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.close(input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_close',\n session_id: input.session_id,\n closed: true,\n raw: res,\n })\n } catch (err) {\n return errorResult('browser_close', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('DELETE', `/agent/sessions/${input.session_id}`)\n if (!res.ok) return errorResult('browser_close', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_close',\n session_id: input.session_id,\n closed: true,\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_list_sessions',\n {\n title: 'List Browser Sessions',\n description: 'List browser sessions and their status, with a watch_url for each. Use this to recover a session_id, find an active browser, or decide which session to close. Use browser_open to create a new session.',\n inputSchema: BrowserListInputSchema,\n outputSchema: BrowserListSessionsOutputSchema,\n annotations: annotations('List Browser Sessions', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n const sessions = localBrowser.list(input.include_closed)\n return structuredResult({\n ok: true,\n tool: 'browser_list_sessions',\n session_id: null,\n sessions,\n count: sessions.length,\n })\n }\n const res = await req('GET', `/agent/sessions${input.include_closed ? '?all=1' : ''}`)\n if (!res.ok) return errorResult('browser_list_sessions', res.data)\n const sessions = (res.data.sessions ?? []).map((s: any) => ({ ...s, watch_url: `${consoleBase}/console/${s.session_id}` }))\n return structuredResult({\n ok: true,\n tool: 'browser_list_sessions',\n session_id: null,\n sessions,\n count: sessions.length,\n })\n },\n )\n\n server.registerTool(\n 'browser_capture_fanout',\n {\n title: 'Capture AI Search Fan-Out',\n description:\n 'Capture the query fan-out behind a ChatGPT or Claude web-search answer for Answer Engine Optimization (AEO) analysis: the exact sub-queries the model issued, every researched URL split into cited vs browsed-only with citation frequency and snippet, each source tagged by site category, plus top sourced sites and citation order. This tool returns the raw, structured fan-out data; YOU then analyze it — classify each sub-query by funnel stage (Problem/Solution/Decision-aware, Retention) and type (BoFu, Branded, Comparison, How-to, operator), identify which brands the model researched, and surface AEO insights. Requires MCP_SCRAPER_BROWSER_MODE=local with the user\\'s own logged-in Chrome profile (or a logged-in hosted profile); it reads the network stream the page receives and never leaves the machine. Open the session with browser_open and browser_goto to chatgpt.com or claude.ai first. Pass prompt to send and capture a new query, or omit it to capture a prompt the user just ran. Fan-out is only captured as it streams, so run the prompt with the session open.',\n inputSchema: BrowserCaptureFanoutInputSchema,\n outputSchema: BrowserCaptureFanoutOutputSchema,\n annotations: annotations('Capture AI Search Fan-Out', true),\n },\n async input => {\n const emit = (result: Record<string, unknown>, exports: unknown) => structuredResult({\n ok: true,\n tool: 'browser_capture_fanout',\n session_id: input.session_id,\n platform: result.platform,\n captured_at: result.capturedAt,\n prompt: result.prompt,\n meta: result.meta,\n queries: result.queries,\n browsed_urls: result.browsedUrls,\n cited_urls: result.citedUrls,\n browsed_only: result.browsedOnly,\n snippets: result.snippets,\n counts: result.counts,\n aggregates: result.aggregates,\n first_party_domain: result.firstPartyDomain,\n exports: exports ?? null,\n ...(result.debug ? { debug: result.debug } : {}),\n })\n if (localBrowserModeEnabled()) {\n try {\n const { result, exports } = await localBrowser.captureFanout(input.session_id, input)\n return emit(result as unknown as Record<string, unknown>, exports)\n } catch (err) {\n return errorResult('browser_capture_fanout', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/capture-fanout`, {\n prompt: input.prompt,\n wait_ms: input.wait_ms,\n first_party_domain: input.first_party_domain,\n export: false,\n })\n if (!res.ok) return errorResult('browser_capture_fanout', res.data, input.session_id)\n const hosted = (res.data?.result ?? res.data) as Record<string, unknown>\n return emit(hosted, res.data?.exports ?? null)\n },\n )\n\n}\n","import { readFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface LocalChromeProfile {\n email: string\n displayName: string\n chromeProfileDirectory: string\n chromeProfilePath: string\n recommendedKernelProfileName: string\n}\n\nexport function defaultChromeUserDataDir(): string {\n if (process.platform === 'darwin') return join(homedir(), 'Library', 'Application Support', 'Google', 'Chrome')\n if (process.platform === 'win32') {\n return join(process.env.LOCALAPPDATA ?? join(homedir(), 'AppData', 'Local'), 'Google', 'Chrome', 'User Data')\n }\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config'), 'google-chrome')\n}\n\nexport function recommendedKernelProfileName(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/@/g, '-')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 80) || 'browser-profile'\n}\n\nexport async function listLocalChromeProfiles(\n userDataDir = defaultChromeUserDataDir(),\n emailFilter?: string,\n): Promise<LocalChromeProfile[]> {\n const raw = await readFile(join(userDataDir, 'Local State'), 'utf8')\n const localState = JSON.parse(raw) as {\n profile?: {\n info_cache?: Record<string, {\n name?: string\n shortcut_name?: string\n user_name?: string\n gaia_name?: string\n }>\n }\n }\n const wanted = emailFilter?.trim().toLowerCase()\n return Object.entries(localState.profile?.info_cache ?? {})\n .map(([directory, info]) => {\n const email = (info.user_name ?? '').trim()\n const displayName = (info.name ?? info.shortcut_name ?? '').trim()\n const labelSource = email || displayName || directory\n return {\n email,\n displayName,\n chromeProfileDirectory: directory,\n chromeProfilePath: join(userDataDir, directory),\n recommendedKernelProfileName: recommendedKernelProfileName(labelSource),\n }\n })\n .filter(row => !wanted || row.email.toLowerCase() === wanted || row.displayName.toLowerCase().includes(wanted))\n}\n","export function browserServiceApiKey(): string | undefined {\n const value = (process.env.BROWSER_SERVICE_API_KEY ?? process.env.KERNEL_API_KEY)?.trim()\n return value || undefined\n}\n\nexport function browserServiceProxyId(): string | undefined {\n const value = (process.env.BROWSER_SERVICE_PROXY_ID ?? process.env.KERNEL_PROXY_ID)?.trim()\n return value || undefined\n}\n\nexport function browserServiceProfileName(): string | undefined {\n const value = (\n process.env.BROWSER_AGENT_PROFILE_NAME ??\n process.env.BROWSER_SERVICE_PROFILE_NAME ??\n process.env.KERNEL_BROWSER_PROFILE_NAME ??\n process.env.KERNEL_PROFILE_NAME\n )?.trim()\n return value || undefined\n}\n\nexport function browserServiceProfileSaveChanges(): boolean | undefined {\n const value = (\n process.env.BROWSER_AGENT_PROFILE_SAVE_CHANGES ??\n process.env.BROWSER_SERVICE_PROFILE_SAVE_CHANGES ??\n process.env.KERNEL_BROWSER_PROFILE_SAVE_CHANGES ??\n process.env.KERNEL_PROFILE_SAVE_CHANGES\n )?.trim().toLowerCase()\n if (!value) return undefined\n if (['1', 'true', 'yes', 'on'].includes(value)) return true\n if (['0', 'false', 'no', 'off'].includes(value)) return false\n return undefined\n}\n","import { existsSync } from 'node:fs'\nimport { cp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join, relative, sep } from 'node:path'\nimport {\n defaultChromeUserDataDir,\n listLocalChromeProfiles,\n recommendedKernelProfileName,\n type LocalChromeProfile,\n} from './chrome-profiles.js'\n\nexport interface ImportedBrowserProfileManifest {\n layoutVersion: 1\n name: string\n profileRoot: string\n userDataDir: string\n browserExecutablePath: string | null\n sourceUserDataDir: string\n sourceProfileDirectory: string\n sourceProfilePath: string\n email: string\n displayName: string\n createdAt: string\n updatedAt: string\n copyMode: 'chrome-profile-clone'\n}\n\nexport interface ImportChromeProfileOptions {\n email?: string\n name?: string\n chromeProfileDirectory?: string\n sourceUserDataDir?: string\n outputDir?: string\n overwrite?: boolean\n browserExecutablePath?: string\n}\n\nexport interface ImportChromeProfileResult {\n profile: ImportedBrowserProfileManifest\n sourceProfile: LocalChromeProfile\n excludedNames: string[]\n}\n\nconst EXCLUDED_PROFILE_NAMES = [\n 'Cache',\n 'Code Cache',\n 'Crashpad',\n 'DawnCache',\n 'DawnGraphiteCache',\n 'DawnWebGPUCache',\n 'GPUCache',\n 'GrShaderCache',\n 'ShaderCache',\n 'Shared Dictionary',\n]\n\nexport function defaultImportedBrowserProfilesDir(): string {\n return process.env.MCP_SCRAPER_BROWSER_PROFILE_BASE_DIR?.trim()\n || join(homedir(), '.mcp-scraper', 'browser-profiles')\n}\n\nexport function defaultChromeExecutablePath(): string | undefined {\n const envPath = process.env.MCP_SCRAPER_BROWSER_EXECUTABLE?.trim() || process.env.CHROME_PATH?.trim()\n if (envPath) return envPath\n\n const candidates = process.platform === 'darwin'\n ? ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome']\n : process.platform === 'win32'\n ? [\n join(process.env.PROGRAMFILES ?? 'C:\\\\Program Files', 'Google', 'Chrome', 'Application', 'chrome.exe'),\n join(process.env['PROGRAMFILES(X86)'] ?? 'C:\\\\Program Files (x86)', 'Google', 'Chrome', 'Application', 'chrome.exe'),\n ]\n : ['/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium-browser', '/usr/bin/chromium']\n\n return candidates.find(candidate => existsSync(candidate))\n}\n\nexport function localBrowserModeEnabled(): boolean {\n return process.env.MCP_SCRAPER_BROWSER_MODE?.trim().toLowerCase() === 'local'\n}\n\nexport function importedProfileName(value: string): string {\n return recommendedKernelProfileName(value)\n}\n\nexport function importedProfileRoot(name: string, outputDir = defaultImportedBrowserProfilesDir()): string {\n return join(outputDir, importedProfileName(name))\n}\n\nexport function importedProfileManifestPath(name: string, outputDir = defaultImportedBrowserProfilesDir()): string {\n return join(importedProfileRoot(name, outputDir), 'manifest.json')\n}\n\nexport function importedProfileUserDataDir(name: string, outputDir = defaultImportedBrowserProfilesDir()): string {\n return join(importedProfileRoot(name, outputDir), 'user-data')\n}\n\nasync function readExistingManifest(path: string): Promise<ImportedBrowserProfileManifest | null> {\n try {\n return JSON.parse(await readFile(path, 'utf8')) as ImportedBrowserProfileManifest\n } catch {\n return null\n }\n}\n\nfunction isExcludedProfilePath(sourceRoot: string, sourcePath: string): boolean {\n const rel = relative(sourceRoot, sourcePath)\n if (!rel) return false\n const parts = rel.split(sep).filter(Boolean)\n const last = parts[parts.length - 1] ?? ''\n if (last.startsWith('Singleton')) return true\n if (last === 'LOCK' || last.endsWith('.lock')) return true\n if (parts.some(part => EXCLUDED_PROFILE_NAMES.includes(part))) return true\n if (parts.includes('Service Worker') && parts.includes('CacheStorage')) return true\n return false\n}\n\nasync function copyProfileTree(sourceProfilePath: string, destinationProfilePath: string): Promise<void> {\n await cp(sourceProfilePath, destinationProfilePath, {\n recursive: true,\n force: true,\n errorOnExist: false,\n dereference: false,\n filter: source => !isExcludedProfilePath(sourceProfilePath, source),\n })\n}\n\nfunction selectProfile(profiles: LocalChromeProfile[], options: ImportChromeProfileOptions): LocalChromeProfile {\n const requestedDirectory = options.chromeProfileDirectory?.trim()\n const requestedEmail = options.email?.trim().toLowerCase()\n const exactDirectory = requestedDirectory\n ? profiles.find(profile => profile.chromeProfileDirectory === requestedDirectory)\n : undefined\n if (exactDirectory) return exactDirectory\n\n const exactEmail = requestedEmail\n ? profiles.find(profile => profile.email.toLowerCase() === requestedEmail)\n : undefined\n if (exactEmail) return exactEmail\n\n const first = profiles[0]\n if (first) return first\n\n const hint = requestedDirectory\n ? `Chrome profile directory \"${requestedDirectory}\"`\n : requestedEmail\n ? `Chrome account \"${requestedEmail}\"`\n : 'Chrome profile'\n throw new Error(`${hint} was not found in ${options.sourceUserDataDir ?? defaultChromeUserDataDir()}`)\n}\n\nasync function ensureProfilePathExists(profile: LocalChromeProfile): Promise<void> {\n const details = await stat(profile.chromeProfilePath).catch(() => null)\n if (!details?.isDirectory()) {\n throw new Error(`Chrome profile path does not exist or is not a directory: ${profile.chromeProfilePath}`)\n }\n}\n\nasync function writeNormalizedLocalState(\n sourceLocalStatePath: string,\n destinationLocalStatePath: string,\n sourceProfileDirectory: string,\n): Promise<void> {\n const raw = await readFile(sourceLocalStatePath, 'utf8')\n const localState = JSON.parse(raw) as {\n profile?: {\n info_cache?: Record<string, unknown>\n last_used?: string\n last_active_profiles?: string[]\n }\n }\n const selectedInfo = localState.profile?.info_cache?.[sourceProfileDirectory]\n ?? localState.profile?.info_cache?.Default\n ?? {}\n localState.profile = {\n ...(localState.profile ?? {}),\n info_cache: { Default: selectedInfo },\n last_used: 'Default',\n last_active_profiles: ['Default'],\n }\n await writeFile(destinationLocalStatePath, `${JSON.stringify(localState, null, 2)}\\n`)\n}\n\nexport async function importChromeProfile(options: ImportChromeProfileOptions = {}): Promise<ImportChromeProfileResult> {\n const sourceUserDataDir = options.sourceUserDataDir?.trim() || defaultChromeUserDataDir()\n const profiles = await listLocalChromeProfiles(sourceUserDataDir, options.email)\n const sourceProfile = selectProfile(profiles, { ...options, sourceUserDataDir })\n await ensureProfilePathExists(sourceProfile)\n\n const name = importedProfileName(options.name?.trim() || sourceProfile.recommendedKernelProfileName)\n const outputDir = options.outputDir?.trim() || defaultImportedBrowserProfilesDir()\n const profileRoot = importedProfileRoot(name, outputDir)\n const manifestPath = importedProfileManifestPath(name, outputDir)\n const userDataDir = importedProfileUserDataDir(name, outputDir)\n const existingManifest = await readExistingManifest(manifestPath)\n const existing = existsSync(profileRoot)\n\n if (existing && !options.overwrite) {\n throw new Error(`Imported browser profile \"${name}\" already exists at ${profileRoot}. Re-run with --overwrite to refresh it.`)\n }\n\n if (existing) await rm(profileRoot, { recursive: true, force: true })\n await mkdir(join(userDataDir, 'Default'), { recursive: true })\n await writeNormalizedLocalState(\n join(sourceUserDataDir, 'Local State'),\n join(userDataDir, 'Local State'),\n sourceProfile.chromeProfileDirectory,\n )\n await copyProfileTree(sourceProfile.chromeProfilePath, join(userDataDir, 'Default'))\n\n const now = new Date().toISOString()\n const manifest: ImportedBrowserProfileManifest = {\n layoutVersion: 1,\n name,\n profileRoot,\n userDataDir,\n browserExecutablePath: options.browserExecutablePath?.trim() || defaultChromeExecutablePath() || null,\n sourceUserDataDir,\n sourceProfileDirectory: sourceProfile.chromeProfileDirectory,\n sourceProfilePath: sourceProfile.chromeProfilePath,\n email: sourceProfile.email,\n displayName: sourceProfile.displayName,\n createdAt: existingManifest?.createdAt ?? now,\n updatedAt: now,\n copyMode: 'chrome-profile-clone',\n }\n await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`)\n\n return {\n profile: manifest,\n sourceProfile,\n excludedNames: EXCLUDED_PROFILE_NAMES,\n }\n}\n\nexport async function loadImportedBrowserProfile(\n name = process.env.MCP_SCRAPER_BROWSER_PROFILE?.trim() || 'default',\n outputDir = defaultImportedBrowserProfilesDir(),\n): Promise<ImportedBrowserProfileManifest> {\n const profileName = importedProfileName(name)\n const manifestPath = importedProfileManifestPath(profileName, outputDir)\n const manifest = await readExistingManifest(manifestPath)\n if (!manifest) {\n throw new Error(\n `Imported browser profile \"${profileName}\" was not found. Run: mcp-scraper-cli browser import-chrome --name ${profileName}`,\n )\n }\n return manifest\n}\n\nexport async function syncImportedChromeProfile(\n name: string,\n options: Pick<ImportChromeProfileOptions, 'outputDir' | 'browserExecutablePath'> = {},\n): Promise<ImportChromeProfileResult> {\n const outputDir = options.outputDir?.trim() || defaultImportedBrowserProfilesDir()\n const manifest = await loadImportedBrowserProfile(name, outputDir)\n return importChromeProfile({\n name: manifest.name,\n sourceUserDataDir: manifest.sourceUserDataDir,\n chromeProfileDirectory: manifest.sourceProfileDirectory,\n outputDir,\n overwrite: true,\n browserExecutablePath: options.browserExecutablePath ?? manifest.browserExecutablePath ?? undefined,\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { existsSync } from 'node:fs'\nimport { basename } from 'node:path'\nimport { chromium } from 'playwright-extra'\nimport StealthPlugin from 'puppeteer-extra-plugin-stealth'\nimport type { BrowserContext, Page } from 'playwright'\n\nchromium.use(StealthPlugin())\nimport {\n defaultChromeExecutablePath,\n loadImportedBrowserProfile,\n type ImportedBrowserProfileManifest,\n} from '../../lib/local-browser-profiles.js'\nimport type {\n BrowserCaptureFanoutInput,\n BrowserClickInput,\n BrowserLocateInput,\n BrowserOpenInput,\n BrowserPressInput,\n BrowserScrollInput,\n BrowserTypeInput,\n} from '../../mcp/browser-agent-tool-schemas.js'\nimport { runFanoutCapture, type FanoutCaptureOutput } from '../fanout/run-capture.js'\n\ninterface LocalBrowserContextState {\n key: string\n context: BrowserContext\n profile: ResolvedLocalBrowserProfile\n}\n\ninterface ResolvedLocalBrowserProfile {\n name: string\n userDataDir: string\n browserExecutablePath: string | null\n manifest: ImportedBrowserProfileManifest | null\n}\n\ninterface LocalBrowserSessionState {\n sessionId: string\n label: string | null\n page: Page\n contextKey: string\n profileName: string\n userDataDir: string\n createdAt: string\n lastActionAt: string\n closedAt: string | null\n status: 'open' | 'closed'\n timeout?: NodeJS.Timeout\n}\n\ntype ReadPageResult = {\n url: string\n title: string\n text: string\n elements: Array<Record<string, unknown>>\n viewport: Record<string, unknown>\n}\n\nfunction directProfileDir(): string | undefined {\n return process.env.MCP_SCRAPER_BROWSER_PROFILE_DIR?.trim() || undefined\n}\n\nfunction configuredProfileName(profile?: string): string {\n return profile?.trim()\n || process.env.MCP_SCRAPER_BROWSER_PROFILE?.trim()\n || (directProfileDir() ? basename(directProfileDir()!) : 'default')\n}\n\nfunction launchExecutablePath(profile: ResolvedLocalBrowserProfile): string | undefined {\n const configured = process.env.MCP_SCRAPER_BROWSER_EXECUTABLE?.trim()\n || profile.browserExecutablePath\n || defaultChromeExecutablePath()\n return configured && existsSync(configured) ? configured : undefined\n}\n\nfunction ignoreDefaultArgsFor(executablePath?: string): string[] | undefined {\n if (!executablePath) return undefined\n if (process.platform !== 'darwin') return undefined\n if (!/Google Chrome\\.app\\/Contents\\/MacOS\\/Google Chrome$/.test(executablePath)) return undefined\n return ['--password-store=basic', '--use-mock-keychain']\n}\n\nfunction normalizeKeyCombo(value: string): string {\n return value\n .split('+')\n .map(part => {\n const trimmed = part.trim()\n const lower = trimmed.toLowerCase()\n if (lower === 'ctrl' || lower === 'control') return 'Control'\n if (lower === 'cmd' || lower === 'command' || lower === 'meta') return 'Meta'\n if (lower === 'option' || lower === 'alt') return 'Alt'\n if (lower === 'return') return 'Enter'\n if (lower === 'esc') return 'Escape'\n if (trimmed.length === 1) return trimmed.toUpperCase()\n return trimmed\n })\n .join('+')\n}\n\nfunction sessionSummary(session: LocalBrowserSessionState): Record<string, unknown> {\n return {\n session_id: session.sessionId,\n status: session.status,\n label: session.label,\n profile: session.profileName,\n user_data_dir: session.userDataDir,\n created_at: session.createdAt,\n last_action_at: session.lastActionAt,\n closed_at: session.closedAt,\n watch_url: `local://browser-session/${session.sessionId}`,\n url: session.status === 'open' ? session.page.url() : null,\n }\n}\n\nexport class LocalBrowserAgentService {\n private readonly contexts = new Map<string, LocalBrowserContextState>()\n private readonly sessions = new Map<string, LocalBrowserSessionState>()\n\n async open(input: BrowserOpenInput): Promise<Record<string, unknown>> {\n const profile = await this.resolveProfile(input.profile)\n const contextState = await this.ensureContext(profile)\n const pages = contextState.context.pages()\n const page = pages.length === 1 && !this.hasOpenSessionForContext(contextState.key)\n ? pages[0]\n : await contextState.context.newPage()\n const now = new Date().toISOString()\n const sessionId = `lbs_${randomUUID().replace(/-/g, '').slice(0, 20)}`\n const session: LocalBrowserSessionState = {\n sessionId,\n label: input.label ?? null,\n page,\n contextKey: contextState.key,\n profileName: profile.name,\n userDataDir: profile.userDataDir,\n createdAt: now,\n lastActionAt: now,\n closedAt: null,\n status: 'open',\n }\n const timeoutSeconds = input.timeout_seconds ?? 600\n if (timeoutSeconds > 0) {\n session.timeout = setTimeout(() => {\n void this.close(sessionId)\n }, timeoutSeconds * 1000)\n session.timeout.unref()\n }\n this.sessions.set(sessionId, session)\n\n if (input.url) await this.goto(sessionId, input.url)\n\n return {\n session_id: sessionId,\n watch_url: `local://browser-session/${sessionId}`,\n live_view_url: null,\n profile: profile.name,\n user_data_dir: profile.userDataDir,\n url: input.url ?? null,\n mode: 'local',\n }\n }\n\n async screenshot(sessionId: string): Promise<ReadPageResult & { image_base64: string; mime_type: string }> {\n const session = this.requireOpenSession(sessionId)\n await this.waitForPage(session.page)\n const image = await session.page.screenshot({ type: 'png', fullPage: false })\n const page = await this.read(sessionId)\n return {\n ...page,\n image_base64: image.toString('base64'),\n mime_type: 'image/png',\n }\n }\n\n async read(sessionId: string): Promise<ReadPageResult> {\n const session = this.requireOpenSession(sessionId)\n await this.waitForPage(session.page)\n this.touch(session)\n const title = await session.page.title().catch(() => '')\n const snapshot = await session.page.evaluate(() => {\n const cssEscape = (value: string) => {\n const escapeFn = (globalThis as { CSS?: { escape?: (input: string) => string } }).CSS?.escape\n return escapeFn ? escapeFn(value) : value.replace(/[\"\\\\#.:>+~[\\]()]/g, '\\\\$&')\n }\n const textFor = (element: Element): string => {\n const html = element as HTMLInputElement & HTMLElement\n return (\n element.getAttribute('aria-label')\n || element.getAttribute('title')\n || html.placeholder\n || html.value\n || html.innerText\n || element.textContent\n || ''\n ).replace(/\\s+/g, ' ').trim()\n }\n const selectorFor = (element: Element): string => {\n const id = (element as HTMLElement).id\n if (id) return `#${cssEscape(id)}`\n const name = element.getAttribute('name')\n const tag = element.tagName.toLowerCase()\n if (name) return `${tag}[name=\"${name.replace(/\"/g, '\\\\\"')}\"]`\n const parts: string[] = []\n let current: Element | null = element\n while (current && current !== document.body && parts.length < 4) {\n const currentTag = current.tagName.toLowerCase()\n const parent: Element | null = current.parentElement\n if (!parent) {\n parts.unshift(currentTag)\n break\n }\n const children = Array.from(parent.children) as Element[]\n const siblings = children.filter((child: Element) => child.tagName === current!.tagName)\n const index = siblings.indexOf(current) + 1\n parts.unshift(siblings.length > 1 ? `${currentTag}:nth-of-type(${index})` : currentTag)\n current = parent\n }\n return parts.join(' > ') || tag\n }\n const candidates = Array.from(document.querySelectorAll<HTMLElement>(\n 'a, button, input, textarea, select, summary, [role], [contenteditable=\"true\"], [tabindex]:not([tabindex=\"-1\"])',\n ))\n const elements = candidates\n .map((element, index) => {\n const rect = element.getBoundingClientRect()\n const style = window.getComputedStyle(element)\n const visible = rect.width > 0\n && rect.height > 0\n && style.display !== 'none'\n && style.visibility !== 'hidden'\n && Number(style.opacity || '1') > 0\n if (!visible) return null\n const label = textFor(element)\n return {\n index,\n tag: element.tagName.toLowerCase(),\n role: element.getAttribute('role') || null,\n text: label.slice(0, 180),\n selector: selectorFor(element),\n x: Math.round(rect.left + rect.width / 2),\n y: Math.round(rect.top + rect.height / 2),\n left: Math.round(rect.left),\n top: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n }\n })\n .filter(Boolean)\n .slice(0, 120)\n\n return {\n text: (document.body?.innerText || '').replace(/\\n{3,}/g, '\\n\\n').slice(0, 30_000),\n elements,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n },\n }\n })\n\n return {\n url: session.page.url(),\n title,\n text: snapshot.text,\n elements: snapshot.elements as Array<Record<string, unknown>>,\n viewport: snapshot.viewport,\n }\n }\n\n async locate(sessionId: string, targets: BrowserLocateInput['targets']): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n const located = []\n for (const target of targets) {\n try {\n const locator = target.selector\n ? session.page.locator(target.selector)\n : session.page.getByText(target.text ?? '', { exact: target.match === 'exact' })\n const selected = locator.nth(target.index ?? 0)\n await selected.waitFor({ state: 'visible', timeout: 3000 }).catch(() => undefined)\n const box = await selected.boundingBox()\n const text = await selected.textContent({ timeout: 1000 }).catch(() => null)\n located.push({\n input: target,\n found: Boolean(box),\n element: box\n ? {\n left: Math.round(box.x),\n top: Math.round(box.y),\n width: Math.round(box.width),\n height: Math.round(box.height),\n x: Math.round(box.x + box.width / 2),\n y: Math.round(box.y + box.height / 2),\n text: (text ?? '').replace(/\\s+/g, ' ').trim().slice(0, 220),\n }\n : null,\n })\n } catch (err) {\n located.push({\n input: target,\n found: false,\n element: null,\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n const read = await this.read(sessionId)\n return {\n url: read.url,\n title: read.title,\n viewport: read.viewport,\n replay: null,\n targets: located,\n }\n }\n\n async goto(sessionId: string, url: string): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n const response = await session.page.goto(url, { waitUntil: 'domcontentloaded', timeout: 45_000 }).catch(err => {\n throw new Error(err instanceof Error ? err.message : String(err))\n })\n await this.waitForPage(session.page)\n return {\n ok: true,\n url: session.page.url(),\n status: response?.status() ?? null,\n mode: 'local',\n }\n }\n\n async click(sessionId: string, input: BrowserClickInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n await session.page.mouse.click(input.x, input.y, {\n button: input.button ?? 'left',\n clickCount: input.num_clicks ?? 1,\n })\n await this.waitForPage(session.page)\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async type(sessionId: string, input: BrowserTypeInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n await session.page.keyboard.type(input.text, { delay: input.delay })\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async scroll(sessionId: string, input: BrowserScrollInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n if (typeof input.x === 'number' && typeof input.y === 'number') {\n await session.page.mouse.move(input.x, input.y)\n }\n await session.page.mouse.wheel((input.delta_x ?? 0) * 120, (input.delta_y ?? 5) * 120)\n await session.page.waitForTimeout(150).catch(() => undefined)\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async press(sessionId: string, input: BrowserPressInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n for (const key of input.keys) {\n await session.page.keyboard.press(normalizeKeyCombo(key))\n }\n await this.waitForPage(session.page)\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async close(sessionId: string): Promise<Record<string, unknown>> {\n const session = this.sessions.get(sessionId)\n if (!session || session.status === 'closed') {\n return { ok: true, closed: true, already_closed: true, mode: 'local' }\n }\n if (session.timeout) clearTimeout(session.timeout)\n session.status = 'closed'\n session.closedAt = new Date().toISOString()\n await session.page.close().catch(() => undefined)\n await this.closeContextIfUnused(session.contextKey)\n return { ok: true, closed: true, mode: 'local' }\n }\n\n list(includeClosed = false): Record<string, unknown>[] {\n return Array.from(this.sessions.values())\n .filter(session => includeClosed || session.status === 'open')\n .map(sessionSummary)\n }\n\n async captureFanout(sessionId: string, input: BrowserCaptureFanoutInput): Promise<FanoutCaptureOutput> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n return runFanoutCapture(session.page, input)\n }\n\n async screenshotOnly(sessionId: string): Promise<string> {\n const session = this.requireOpenSession(sessionId)\n await this.waitForPage(session.page)\n const img = await session.page.screenshot({ type: 'png', fullPage: false })\n return img.toString('base64')\n }\n\n private async resolveProfile(profile?: string): Promise<ResolvedLocalBrowserProfile> {\n const directDir = directProfileDir()\n const requestedName = configuredProfileName(profile)\n if (directDir && (!profile || requestedName === process.env.MCP_SCRAPER_BROWSER_PROFILE?.trim())) {\n return {\n name: requestedName,\n userDataDir: directDir,\n browserExecutablePath: process.env.MCP_SCRAPER_BROWSER_EXECUTABLE?.trim() || defaultChromeExecutablePath() || null,\n manifest: null,\n }\n }\n const manifest = await loadImportedBrowserProfile(requestedName)\n return {\n name: manifest.name,\n userDataDir: manifest.userDataDir,\n browserExecutablePath: manifest.browserExecutablePath,\n manifest,\n }\n }\n\n private async ensureContext(profile: ResolvedLocalBrowserProfile): Promise<LocalBrowserContextState> {\n const existing = this.contexts.get(profile.userDataDir)\n if (existing) return existing\n const executablePath = launchExecutablePath(profile)\n const context = await chromium.launchPersistentContext(profile.userDataDir, {\n headless: false,\n viewport: { width: 1440, height: 900 },\n acceptDownloads: true,\n ...(executablePath ? { executablePath } : {}),\n ...(ignoreDefaultArgsFor(executablePath) ? { ignoreDefaultArgs: ignoreDefaultArgsFor(executablePath) } : {}),\n })\n const state = { key: profile.userDataDir, context, profile }\n context.on('close', () => {\n this.contexts.delete(profile.userDataDir)\n const closedAt = new Date().toISOString()\n for (const session of this.sessions.values()) {\n if (session.contextKey === profile.userDataDir && session.status === 'open') {\n session.status = 'closed'\n session.closedAt = closedAt\n if (session.timeout) clearTimeout(session.timeout)\n }\n }\n })\n this.contexts.set(profile.userDataDir, state)\n return state\n }\n\n private requireOpenSession(sessionId: string): LocalBrowserSessionState {\n const session = this.sessions.get(sessionId)\n if (!session || session.status !== 'open') throw new Error(`Local browser session not found or closed: ${sessionId}`)\n return session\n }\n\n private touch(session: LocalBrowserSessionState): void {\n session.lastActionAt = new Date().toISOString()\n }\n\n private hasOpenSessionForContext(contextKey: string): boolean {\n return Array.from(this.sessions.values()).some(session => session.contextKey === contextKey && session.status === 'open')\n }\n\n private async closeContextIfUnused(contextKey: string): Promise<void> {\n if (this.hasOpenSessionForContext(contextKey)) return\n const state = this.contexts.get(contextKey)\n if (!state) return\n this.contexts.delete(contextKey)\n await state.context.close().catch(() => undefined)\n }\n\n private async waitForPage(page: Page): Promise<void> {\n await page.waitForLoadState('domcontentloaded', { timeout: 5_000 }).catch(() => undefined)\n await page.waitForTimeout(200).catch(() => undefined)\n }\n}\n","import type { CDPSession, Page } from 'playwright'\n\nconst ANSWER_RE = /\\/backend-api\\/(f\\/)?conversation$|\\/chat_conversations\\/[^/]+\\/(completion|retry_completion)$|\\/completion$/i\n\ninterface AnswerBody {\n url: string\n ct: string\n text: string\n}\n\nexport class FanoutCdpCapture {\n private client: CDPSession | null = null\n private reqUrl = new Map<string, string>()\n private ctById = new Map<string, string>()\n private answerIds = new Set<string>()\n private bodies: AnswerBody[] = []\n private pending: Promise<void>[] = []\n private answerStreams = 0\n\n async attach(page: Page): Promise<void> {\n if (this.client) return\n const client = await page.context().newCDPSession(page)\n this.client = client\n await client.send('Network.enable', { maxTotalBufferSize: 200_000_000, maxResourceBufferSize: 200_000_000 } as never)\n client.on('Network.requestWillBeSent', (e: Record<string, unknown>) => {\n const id = e.requestId as string\n const req = e.request as Record<string, unknown> | undefined\n if (id) this.reqUrl.set(id, (req?.url as string) || '')\n })\n client.on('Network.responseReceived', (e: Record<string, unknown>) => {\n const id = e.requestId as string\n const res = e.response as Record<string, unknown> | undefined\n const url = (res?.url as string) || this.reqUrl.get(id) || ''\n const headers = (res?.headers as Record<string, string>) || {}\n const ct = String(headers['content-type'] || headers['Content-Type'] || '')\n if (id) this.ctById.set(id, ct)\n if (id && (this.isAnswerUrl(url) || /event-stream/i.test(ct))) this.answerIds.add(id)\n })\n client.on('Network.loadingFinished', (e: Record<string, unknown>) => this.grab(e.requestId as string))\n }\n\n reset(): void {\n this.bodies = []\n this.answerStreams = 0\n this.answerIds.clear()\n this.pending = []\n }\n\n answerStreamCount(): number {\n return this.answerStreams\n }\n\n async drain(): Promise<void> {\n await Promise.all(this.pending)\n }\n\n bestAnswerText(): string {\n const eventStreams = this.bodies.filter((b) => /event-stream/i.test(b.ct))\n const answerStreams = eventStreams.filter((b) => this.isAnswerUrl(b.url)).sort((a, b) => b.text.length - a.text.length)\n if (answerStreams.length) return answerStreams.map((b) => b.text).join('\\n')\n const answerJson = this.bodies.filter((b) => this.isAnswerUrl(b.url)).sort((a, b) => b.text.length - a.text.length)\n if (answerJson.length) return answerJson[0].text\n if (eventStreams.length) return eventStreams.sort((a, b) => b.text.length - a.text.length)[0].text\n return ''\n }\n\n async detach(): Promise<void> {\n try {\n await this.client?.detach()\n } catch {\n this.client = null\n }\n this.client = null\n }\n\n private isAnswerUrl(url: string): boolean {\n let path = ''\n try {\n path = new URL(url).pathname\n } catch {\n path = String(url || '').split('?')[0]\n }\n return ANSWER_RE.test(path)\n }\n\n private grab(requestId: string | undefined): void {\n if (!requestId || !this.client || !this.answerIds.has(requestId)) return\n const url = this.reqUrl.get(requestId) || ''\n const ct = this.ctById.get(requestId) || ''\n const client = this.client\n const p = client\n .send('Network.getResponseBody', { requestId } as never)\n .then((r: Record<string, unknown>) => {\n const text = r.base64Encoded ? Buffer.from(String(r.body), 'base64').toString('utf8') : String(r.body || '')\n if (text) {\n this.bodies.push({ url, ct, text })\n if (this.isAnswerUrl(url)) this.answerStreams++\n }\n })\n .catch(() => undefined)\n this.pending.push(p)\n }\n}\n","const INTERNAL = /chatgpt\\.com|openai\\.com|oaiusercontent|oaistatic|claude\\.ai|anthropic\\.com/i\nconst TRACK = /^(utm_|oai|fbclid|gclid|ref$|ref_|sa$|usg$|ved$|sca_esv$|sources$)/i\n\nexport function domainOf(u: string): string {\n try {\n return new URL(u).hostname.replace(/^www\\./, '')\n } catch {\n return ''\n }\n}\n\nexport function normUrl(u: string): string {\n try {\n const x = new URL(u)\n x.hash = ''\n for (const k of [...x.searchParams.keys()]) {\n if (TRACK.test(k)) x.searchParams.delete(k)\n }\n return x.toString().replace(/\\/$/, '').toLowerCase()\n } catch {\n return String(u || '').toLowerCase()\n }\n}\n\nexport function isExternal(u: string): boolean {\n const h = domainOf(u)\n return Boolean(h) && !INTERNAL.test(h)\n}\n\nexport function unesc(s: string): string {\n try {\n return JSON.parse('\"' + s + '\"')\n } catch {\n return String(s).replace(/\\\\(.)/g, '$1')\n }\n}\n\nexport function stripCitationMarkers(s: string): string {\n return String(s || '')\n .replace(/[-]/g, '')\n .replace(/cite(?:turn\\d+\\w+?\\d+)+/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\nexport function sliceBalanced(text: string, openIdx: number): string | null {\n const open = text[openIdx]\n const close = open === '[' ? ']' : '}'\n let depth = 0\n let inStr = false\n let esc = false\n for (let i = openIdx; i < text.length; i++) {\n const ch = text[i]\n if (inStr) {\n if (esc) esc = false\n else if (ch === '\\\\') esc = true\n else if (ch === '\"') inStr = false\n continue\n }\n if (ch === '\"') {\n inStr = true\n continue\n }\n if (ch === open) depth++\n else if (ch === close) {\n depth--\n if (depth === 0) return text.slice(openIdx, i + 1)\n }\n }\n return null\n}\n\nexport function findJsonValues(text: string, field: string): unknown[] {\n const out: unknown[] = []\n const re = new RegExp('\"' + field + '\"\\\\s*:\\\\s*(\\\\[|\\\\{)', 'g')\n let m: RegExpExecArray | null\n while ((m = re.exec(text))) {\n const openIdx = m.index + m[0].length - 1\n const slice = sliceBalanced(text, openIdx)\n if (slice) {\n try {\n out.push(JSON.parse(slice))\n } catch {\n continue\n }\n }\n }\n return out\n}\n\nexport function stringsInArrayBody(arrBody: string): string[] {\n const out: string[] = []\n const re = /\"((?:[^\"\\\\]|\\\\.){2,300}?)\"/g\n let m: RegExpExecArray | null\n while ((m = re.exec(arrBody))) out.push(unesc(m[1]))\n return out\n}\n\nexport function cleanQuery(q: string): string | null {\n const t = (q || '').trim()\n if (t.length < 2 || t.length > 300) return null\n return t\n}\n","import type { FanoutAdapter, FanoutSource, FanoutSnippet, ParsedFanout } from '../types.js'\nimport {\n cleanQuery,\n domainOf,\n findJsonValues,\n isExternal,\n normUrl,\n stringsInArrayBody,\n stripCitationMarkers,\n unesc,\n} from '../parse-helpers.js'\n\ninterface SourceAcc {\n url: string\n domain: string\n title: string\n cited: boolean\n timesCited: number\n firstOrder: number\n snippet: string\n round: number | null\n}\n\nfunction roundOf(refId: string | null): number | null {\n const m = /^turn(\\d+)/.exec(refId || '')\n return m ? Number(m[1]) : null\n}\n\nfunction normRef(r: unknown): string | null {\n if (typeof r === 'string') {\n const m = /turn(\\d+)(search|news|ref|video|image|product)(\\d+)/.exec(r)\n return m ? `turn${m[1]}${m[2]}${m[3]}` : null\n }\n if (r && typeof r === 'object') {\n const o = r as Record<string, unknown>\n if (o.turn_index != null) {\n return `turn${o.turn_index}${o.ref_type || 'search'}${o.ref_index != null ? o.ref_index : ''}`\n }\n }\n return null\n}\n\nfunction refsInText(s: string): string[] {\n return (String(s || '').match(/turn\\d+(?:search|news|ref|video|image|product)\\d+/g) || [])\n .map(normRef)\n .filter((x): x is string => Boolean(x))\n}\n\nfunction collectInto(arr: unknown[], v: unknown): void {\n if (Array.isArray(v)) arr.push(...v)\n else if (v && typeof v === 'object') arr.push(v)\n}\n\nfunction reconstructFromSsePatches(raw: string): string {\n const contentReferences: unknown[] = []\n const searchResultGroups: unknown[] = []\n const citations: unknown[] = []\n const citedUrls = new Set<string>()\n const state = { found: false }\n\n const handleOp = (op: unknown): void => {\n if (!op || typeof op !== 'object') return\n const o = op as Record<string, unknown>\n const v = o.v\n if (o.o === 'patch' && Array.isArray(v)) {\n state.found = true\n v.forEach(handleOp)\n return\n }\n const path = typeof o.p === 'string' ? o.p : ''\n if ((path === '' || path === '/message') && v && typeof v === 'object') {\n const root = v as Record<string, unknown>\n const msg = (root.message as Record<string, unknown>) || root\n const md = msg && (msg.metadata as Record<string, unknown>)\n if (md) {\n collectInto(contentReferences, md.content_references)\n collectInto(searchResultGroups, md.search_result_groups)\n collectInto(citations, md.citations)\n state.found = true\n }\n }\n if (!path) return\n if (/\\/safe_urls$/.test(path) && Array.isArray(v)) {\n for (const u of v) if (typeof u === 'string') citedUrls.add(u)\n state.found = true\n } else if (path.includes('content_references')) {\n collectInto(contentReferences, v)\n state.found = true\n } else if (path.includes('search_result_groups')) {\n collectInto(searchResultGroups, v)\n state.found = true\n } else if (path.includes('citations')) {\n collectInto(citations, v)\n state.found = true\n }\n }\n\n for (const line of raw.split('\\n')) {\n const s = (line.startsWith('data:') ? line.slice(5) : line).trim()\n if (!s || s === '[DONE]' || (s[0] !== '{' && s[0] !== '[')) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(s)\n } catch {\n continue\n }\n const ops = Array.isArray(parsed) ? parsed : [parsed]\n ops.forEach(handleOp)\n }\n\n if (!state.found) return raw\n const citedRefs = [...citedUrls].map((url) => ({ type: 'grouped_webpages', items: [{ url }] }))\n const synthetic = JSON.stringify({\n content_references: [...contentReferences, ...citedRefs],\n search_result_groups: searchResultGroups,\n citations,\n })\n return raw + '\\n' + synthetic\n}\n\nexport const chatgptAdapter: FanoutAdapter = {\n platform: 'ChatGPT',\n matchesHost(hostname) {\n return /(^|\\.)chatgpt\\.com$|(^|\\.)openai\\.com$/i.test(hostname)\n },\n parse(rawInput, prompt): ParsedFanout {\n const raw = reconstructFromSsePatches(rawInput)\n const sources = new Map<string, SourceAcc>()\n const snippets = new Map<string, FanoutSnippet>()\n const queries = new Set<string>()\n const unmapped = new Set<string>()\n const meta = { model: '', finishType: '', title: '', rounds: 0 }\n\n const ensure = (url: string): SourceAcc | null => {\n if (!isExternal(url)) return null\n const k = normUrl(url)\n let s = sources.get(k)\n if (!s) {\n s = { url, domain: domainOf(url), title: '', cited: false, timesCited: 0, firstOrder: Infinity, snippet: '', round: null }\n sources.set(k, s)\n }\n return s\n }\n const addSnippet = (url: string, title: string, text: string) => {\n const clean = stripCitationMarkers(text)\n if (!isExternal(url) || clean.length < 2) return\n snippets.set(normUrl(url), { url, domain: domainOf(url), title: title || domainOf(url), text: clean.slice(0, 400) })\n }\n\n for (const m of raw.matchAll(/\"([a-z_]*(?:quer|search)[a-z_]*)\"\\s*:/gi)) unmapped.add(m[1])\n\n for (const m of raw.matchAll(/\"search_model_queries\"\\s*:\\s*\\[([^\\]]*)\\]/g)) {\n for (const q of stringsInArrayBody(m[1])) {\n const c = cleanQuery(q)\n if (c) queries.add(c)\n }\n }\n for (const m of raw.matchAll(/\"(?:search_queries|queries|search_query)\"\\s*:\\s*\\[([^\\]]*)\\]/g)) {\n for (const q of stringsInArrayBody(m[1])) {\n const c = cleanQuery(q)\n if (c) queries.add(c)\n }\n }\n\n for (const v of findJsonValues(raw, 'search_result_groups')) {\n if (!Array.isArray(v)) continue\n for (const g of v) {\n const entries = (g && typeof g === 'object' && Array.isArray((g as Record<string, unknown>).entries))\n ? ((g as Record<string, unknown>).entries as Array<Record<string, unknown>>)\n : []\n for (const e of entries) {\n const url = typeof e.url === 'string' ? e.url : ''\n const s = ensure(url)\n if (!s) continue\n if (!s.title && typeof e.title === 'string') s.title = e.title.slice(0, 200)\n const ref = normRef(e.ref_id)\n if (ref && s.round == null) s.round = roundOf(ref)\n if (typeof e.snippet === 'string' && e.snippet) addSnippet(url, s.title, e.snippet)\n }\n }\n }\n\n for (const m of raw.matchAll(/\"url\"\\s*:\\s*\"(https?:\\/\\/[^\"\\\\]+)\"(?:[\\s\\S]{0,120}?\"(?:title|name)\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.){0,200})\")?/g)) {\n const s = ensure(m[1])\n if (s && !s.title && m[2]) s.title = unesc(m[2]).slice(0, 200)\n }\n\n let spanTotal = 0\n for (const cr of findJsonValues(raw, 'content_references')) {\n if (!Array.isArray(cr)) continue\n for (const ref of cr as Array<Record<string, unknown>>) {\n const type = typeof ref.type === 'string' ? ref.type : ''\n const isBundle = /sources_footnote|nav_list|alt_text/.test(type)\n const refs = refsInText(typeof ref.matched_text === 'string' ? ref.matched_text : '')\n if (!isBundle) spanTotal++\n const ord = typeof ref.start_idx === 'number' ? ref.start_idx : (isBundle ? Infinity : spanTotal)\n const items = Array.isArray(ref.items) ? (ref.items as Array<Record<string, unknown>>) : []\n items.forEach((it, idx) => {\n const refForItem = refs.length === items.length ? refs[idx] : refs[0]\n const urls = [it.url]\n .concat((Array.isArray(it.supporting_websites) ? it.supporting_websites : []).map((s) => (s as Record<string, unknown>)?.url))\n .filter((u): u is string => typeof u === 'string')\n for (const u of urls) {\n const s = ensure(u)\n if (!s) continue\n if (!isBundle) {\n s.cited = true\n s.timesCited++\n if (ord < s.firstOrder) s.firstOrder = ord\n } else if (!s.cited) {\n s.cited = true\n }\n if (refForItem && s.round == null) s.round = roundOf(refForItem)\n }\n if (typeof it.url === 'string' && typeof it.snippet === 'string') addSnippet(it.url, typeof it.title === 'string' ? it.title : '', it.snippet)\n })\n }\n }\n\n for (const v of findJsonValues(raw, 'citations')) {\n if (!Array.isArray(v)) continue\n v.forEach((c, i) => {\n const md = (c && typeof c === 'object' ? (c as Record<string, unknown>).metadata : null) as Record<string, unknown> | null\n if (!md || typeof md.url !== 'string') return\n const s = ensure(md.url)\n if (!s) return\n s.cited = true\n s.timesCited++\n const ord = typeof (c as Record<string, unknown>).start_ix === 'number' ? (c as Record<string, unknown>).start_ix as number : i\n if (ord < s.firstOrder) s.firstOrder = ord\n if (typeof md.text === 'string') addSnippet(md.url, typeof md.title === 'string' ? md.title : '', md.text)\n })\n }\n\n for (const m of raw.matchAll(/\"content_type\"\\s*:\\s*\"tether_quote\"([\\s\\S]{0,4000}?)\"text\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/g)) {\n const url = (m[1].match(/\"url\"\\s*:\\s*\"([^\"]+)\"/) || [])[1]\n const title = (m[1].match(/\"title\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/) || [])[1]\n if (url) {\n ensure(url)\n addSnippet(url, title ? unesc(title) : '', unesc(m[2]))\n }\n }\n\n const modelMatches = [...raw.matchAll(/\"resolved_model_slug\"\\s*:\\s*\"([^\"]+)\"/g)]\n const slugMatches = modelMatches.length ? modelMatches : [...raw.matchAll(/\"model_slug\"\\s*:\\s*\"([^\"]+)\"/g)]\n if (slugMatches.length) meta.model = slugMatches[slugMatches.length - 1][1]\n const finish = raw.match(/\"finish_details\"\\s*:\\s*\\{[^}]*\"type\"\\s*:\\s*\"([^\"]+)\"/)\n if (finish) meta.finishType = finish[1]\n\n const searchRounds = (raw.match(/\"recipient\"\\s*:\\s*\"(?:web|browser)\"[\\s\\S]{0,400}?\"content_type\"\\s*:\\s*\"code\"[\\s\\S]{0,200}?search\\(/g) || []).length\n const sourceRounds = new Set<number>()\n for (const s of sources.values()) if (s.round != null) sourceRounds.add(s.round)\n meta.rounds = Math.max(searchRounds, sourceRounds.size)\n\n const ordered: FanoutSource[] = [...sources.values()]\n .sort((a, b) => (a.cited === b.cited ? b.timesCited - a.timesCited || a.firstOrder - b.firstOrder : a.cited ? -1 : 1))\n .map((s) => ({\n url: s.url,\n domain: s.domain,\n title: s.title || s.domain,\n cited: s.cited,\n timesCited: s.timesCited,\n snippet: snippets.get(normUrl(s.url))?.text || '',\n round: s.round,\n }))\n\n return {\n subQueries: [...queries],\n sources: ordered,\n snippets: [...snippets.values()],\n meta,\n unmappedKeys: [...unmapped].slice(0, 50),\n }\n },\n}\n","import type { FanoutAdapter, FanoutSource, FanoutSnippet, ParsedFanout } from '../types.js'\nimport { cleanQuery, domainOf, isExternal, normUrl, unesc } from '../parse-helpers.js'\n\ninterface SourceAcc {\n url: string\n domain: string\n title: string\n cited: boolean\n timesCited: number\n snippet: string\n round: number | null\n}\n\nfunction isFavicon(u: string): boolean {\n return /\\/s2\\/favicons/i.test(u) || /favicon/i.test(u)\n}\n\nexport const claudeAdapter: FanoutAdapter = {\n platform: 'Claude',\n matchesHost(hostname) {\n return /(^|\\.)claude\\.ai$/i.test(hostname)\n },\n parse(raw, prompt): ParsedFanout {\n const sources = new Map<string, SourceAcc>()\n const snippets = new Map<string, FanoutSnippet>()\n const queries = new Set<string>()\n const unmapped = new Set<string>()\n const meta = { model: '', finishType: '', title: '', rounds: 0 }\n\n const ensure = (url: string): SourceAcc | null => {\n if (!url || !isExternal(url) || isFavicon(url)) return null\n const k = normUrl(url)\n let s = sources.get(k)\n if (!s) {\n s = { url, domain: domainOf(url), title: '', cited: false, timesCited: 0, snippet: '', round: null }\n sources.set(k, s)\n }\n return s\n }\n\n const toolInputs = new Map<number, { name: string; buf: string }>()\n const searchBlocks = new Set<number>()\n const finalizeTool = (index: number) => {\n const t = toolInputs.get(index)\n if (!t || !/web_search|web_fetch|search|browse/i.test(t.name)) return\n try {\n const input = JSON.parse(t.buf) as Record<string, unknown>\n if (typeof input.query === 'string') {\n const q = cleanQuery(input.query)\n if (q) queries.add(q)\n }\n } catch {\n const m = t.buf.match(/\"query\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/)\n if (m) {\n const q = cleanQuery(unesc(m[1]))\n if (q) queries.add(q)\n }\n }\n }\n\n for (const line of raw.split('\\n')) {\n const s = (line.startsWith('data:') ? line.slice(5) : line).trim()\n if (!s || (s[0] !== '{' && s[0] !== '[')) continue\n let ev: Record<string, unknown>\n try {\n ev = JSON.parse(s) as Record<string, unknown>\n } catch {\n continue\n }\n const type = ev.type\n if (type === 'content_block_start') {\n const cb = (ev.content_block as Record<string, unknown>) || {}\n const index = typeof ev.index === 'number' ? ev.index : -1\n if (cb.type === 'tool_use' && index >= 0) {\n const name = typeof cb.name === 'string' ? cb.name : ''\n toolInputs.set(index, { name, buf: '' })\n if (/web_search|web_fetch|search|browse/i.test(name)) searchBlocks.add(index)\n }\n } else if (type === 'content_block_delta') {\n const d = (ev.delta as Record<string, unknown>) || {}\n const index = typeof ev.index === 'number' ? ev.index : -1\n if (d.type === 'input_json_delta' && typeof d.partial_json === 'string') {\n const t = toolInputs.get(index)\n if (t) t.buf += d.partial_json\n } else if (d.type === 'citation_start_delta') {\n const c = (d.citation as Record<string, unknown>) || {}\n if (typeof c.url === 'string') {\n const src = ensure(c.url)\n if (src) {\n src.cited = true\n src.timesCited++\n if (!src.title && typeof c.title === 'string') src.title = c.title.slice(0, 200)\n if (typeof c.cited_text === 'string' && c.cited_text) {\n snippets.set(normUrl(c.url), { url: c.url, domain: domainOf(c.url), title: src.title, text: String(c.cited_text).slice(0, 400) })\n }\n }\n }\n }\n } else if (type === 'content_block_stop') {\n const index = typeof ev.index === 'number' ? ev.index : -1\n if (index >= 0) finalizeTool(index)\n } else if (type === 'message_delta' || type === 'message_stop' || type === 'message_start') {\n const d = (ev.delta as Record<string, unknown>) || (ev.message as Record<string, unknown>) || {}\n if (typeof d.stop_reason === 'string' && !meta.finishType) meta.finishType = d.stop_reason\n if (typeof d.model === 'string' && !meta.model) meta.model = d.model\n }\n }\n\n for (const index of searchBlocks) finalizeTool(index)\n\n for (const m of raw.matchAll(/\"title\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.){1,200})\"\\s*,\\s*\"url\"\\s*:\\s*\"(https?:\\/\\/[^\"\\\\]+)\"/g)) {\n const src = ensure(m[2])\n if (src && !src.title) src.title = unesc(m[1]).slice(0, 200)\n }\n for (const m of raw.matchAll(/\"url\"\\s*:\\s*\"(https?:\\/\\/[^\"\\\\]+)\"/g)) ensure(m[1])\n\n for (const m of raw.matchAll(/\\\\\"title\\\\\"\\s*:\\s*\\\\\"((?:[^\"\\\\]|\\\\.){1,160}?)\\\\\"[\\s\\S]{0,160}?\\\\\"url\\\\\"\\s*:\\s*\\\\\"(https?:[^\"\\\\]+)\\\\\"/g)) {\n const src = ensure(m[2])\n if (src && !src.title) src.title = unesc(unesc(m[1])).slice(0, 200)\n }\n for (const m of raw.matchAll(/\\\\\"url\\\\\"\\s*:\\s*\\\\\"(https?:[^\"\\\\]+)\\\\\"/g)) ensure(m[1])\n\n if (!meta.model) {\n const mm = raw.match(/\"model\"\\s*:\\s*\"(claude[^\"]+)\"/)\n if (mm) meta.model = mm[1]\n }\n meta.rounds = queries.size > 0 ? searchBlocks.size : 0\n\n for (const m of raw.matchAll(/\"([a-z_]*(?:quer|search)[a-z_]*)\"\\s*:/gi)) unmapped.add(m[1])\n\n const ordered: FanoutSource[] = [...sources.values()]\n .sort((a, b) => (a.cited === b.cited ? b.timesCited - a.timesCited : a.cited ? -1 : 1))\n .map((s) => ({\n url: s.url,\n domain: s.domain,\n title: s.title || s.domain,\n cited: s.cited,\n timesCited: s.timesCited,\n snippet: snippets.get(normUrl(s.url))?.text || '',\n round: s.round,\n }))\n\n return {\n subQueries: [...queries],\n sources: ordered,\n snippets: [...snippets.values()],\n meta,\n unmappedKeys: [...unmapped].slice(0, 50),\n }\n },\n}\n","import type { FanoutAdapter, FanoutPlatform } from '../types.js'\nimport { chatgptAdapter } from './chatgpt.js'\nimport { claudeAdapter } from './claude.js'\n\nexport const FANOUT_ADAPTERS: FanoutAdapter[] = [chatgptAdapter, claudeAdapter]\n\nexport function adapterForHost(hostname: string): FanoutAdapter | null {\n return FANOUT_ADAPTERS.find((a) => a.matchesHost(hostname)) ?? null\n}\n\nexport function adapterForPlatform(platform: FanoutPlatform): FanoutAdapter | null {\n return FANOUT_ADAPTERS.find((a) => a.platform === platform) ?? null\n}\n\nexport { chatgptAdapter, claudeAdapter }\n","import type { FanoutPlatform, FanoutResult, ParsedFanout } from './types.js'\n\nexport interface BuildContext {\n platform: FanoutPlatform\n parsed: ParsedFanout\n prompt: string\n ready: boolean\n rawBytes: number\n}\n\nexport function buildFanoutResult(ctx: BuildContext): FanoutResult {\n const { platform, parsed, ready, rawBytes } = ctx\n const browsedUrls = parsed.sources\n const citedUrls = browsedUrls.filter((s) => s.cited)\n const browsedOnly = browsedUrls.filter((s) => !s.cited)\n const prompt = ctx.prompt || parsed.meta.title || ''\n\n const result: FanoutResult = {\n platform,\n capturedAt: new Date().toISOString(),\n prompt,\n meta: parsed.meta,\n subQueries: parsed.subQueries,\n browsedUrls,\n citedUrls,\n browsedOnly,\n snippets: parsed.snippets,\n counts: {\n subQueries: parsed.subQueries.length,\n browsed: browsedUrls.length,\n cited: citedUrls.length,\n browsedOnly: browsedOnly.length,\n },\n }\n\n if (parsed.subQueries.length === 0 && browsedUrls.length === 0) {\n result.debug = {\n interceptorReady: ready,\n rawBytes,\n unmappedKeys: parsed.unmappedKeys,\n note: ready\n ? 'Capture hook is live but no fan-out was seen yet. Run a NEW prompt that triggers web search in this session, then call browser_capture_fanout again. Fan-out is only captured as it streams; past answers from before the session opened cannot be recovered.'\n : 'Capture hook not detected on this page. The session must be opened with MCP_SCRAPER_BROWSER_MODE=local and navigated to chatgpt.com or claude.ai after opening, so the hook installs before the site scripts run.',\n }\n }\n\n return result\n}\n","import type { FanoutResult, FanoutSource } from './types.js'\n\nexport type SiteType =\n | 'First-party/vendor'\n | 'News/media'\n | 'Reddit'\n | 'Social/video'\n | 'Encyclopedia'\n | 'Review site'\n | 'Docs'\n | 'Blog'\n\nexport interface ClassifiedSource extends FanoutSource {\n siteType: SiteType\n}\n\nexport interface FanoutAggregates {\n topSites: Array<{ domain: string; count: number; cited: boolean; timesCited: number; siteType: SiteType }>\n citationOrder: Array<{ rank: number; domain: string; url: string; timesCited: number }>\n byCategory: Record<SiteType, number>\n}\n\nexport interface EnrichedFanout {\n platform: FanoutResult['platform']\n capturedAt: string\n prompt: string\n meta: FanoutResult['meta']\n queries: string[]\n browsedUrls: ClassifiedSource[]\n citedUrls: ClassifiedSource[]\n browsedOnly: ClassifiedSource[]\n snippets: FanoutResult['snippets']\n counts: FanoutResult['counts']\n aggregates: FanoutAggregates\n firstPartyDomain: string | null\n debug?: FanoutResult['debug']\n}\n\nexport interface EnrichOptions {\n firstPartyDomain?: string\n}\n\nconst SOCIAL = /(^|\\.)(youtube\\.com|youtu\\.be|instagram\\.com|tiktok\\.com|facebook\\.com|fb\\.com|x\\.com|twitter\\.com|linkedin\\.com|pinterest\\.com|threads\\.net|vimeo\\.com)$/i\nconst ENCYCLOPEDIA = /(^|\\.)(wikipedia\\.org|wikimedia\\.org|britannica\\.com|merriam-webster\\.com|dictionary\\.com|fandom\\.com|investopedia\\.com)$/i\nconst REVIEW = /(^|\\.)(yelp\\.com|trustpilot\\.com|g2\\.com|capterra\\.com|angi\\.com|angieslist\\.com|bbb\\.org|consumeraffairs\\.com|bestcompany\\.com|sitejabber\\.com|clutch\\.co|bestpickreports\\.com|homeguide\\.com|porch\\.com|ontoplist\\.com|thumbtack\\.com)$/i\nconst NEWS = /(^|\\.)(reuters\\.com|apnews\\.com|nytimes\\.com|wsj\\.com|washingtonpost\\.com|bloomberg\\.com|cnbc\\.com|forbes\\.com|bbc\\.com|theguardian\\.com|cnn\\.com|npr\\.org|usatoday\\.com|expressnews\\.com|mysanantonio\\.com|beaumontenterprise\\.com)$/i\n\nexport function classifyDomain(domain: string, firstPartyDomain?: string): SiteType {\n const d = domain.toLowerCase().replace(/^www\\./, '')\n if (firstPartyDomain) {\n const fp = firstPartyDomain.toLowerCase().replace(/^www\\./, '')\n if (fp && (d === fp || d.endsWith('.' + fp))) return 'First-party/vendor'\n }\n if (/(^|\\.)reddit\\.com$/i.test(d)) return 'Reddit'\n if (SOCIAL.test(d)) return 'Social/video'\n if (ENCYCLOPEDIA.test(d)) return 'Encyclopedia'\n if (REVIEW.test(d)) return 'Review site'\n if (NEWS.test(d) || /(^|\\.)news\\./i.test(d)) return 'News/media'\n if (/^docs?\\.|^developer\\.|^developers\\.|readthedocs|\\.dev$/i.test(d)) return 'Docs'\n return 'Blog'\n}\n\nfunction emptyCategoryCounts(): Record<SiteType, number> {\n return { 'First-party/vendor': 0, 'News/media': 0, Reddit: 0, 'Social/video': 0, Encyclopedia: 0, 'Review site': 0, Docs: 0, Blog: 0 }\n}\n\nexport function enrichFanout(result: FanoutResult, opts: EnrichOptions = {}): EnrichedFanout {\n const addSiteType = (s: FanoutSource): ClassifiedSource => ({ ...s, siteType: classifyDomain(s.domain, opts.firstPartyDomain) })\n const browsedUrls = result.browsedUrls.map(addSiteType)\n const citedUrls = result.citedUrls.map(addSiteType)\n const browsedOnly = result.browsedOnly.map(addSiteType)\n\n const byCategory = emptyCategoryCounts()\n const domainAgg = new Map<string, { domain: string; count: number; cited: boolean; timesCited: number; siteType: SiteType }>()\n for (const s of browsedUrls) {\n byCategory[s.siteType]++\n const cur = domainAgg.get(s.domain)\n if (!cur) domainAgg.set(s.domain, { domain: s.domain, count: 1, cited: s.cited, timesCited: s.timesCited, siteType: s.siteType })\n else {\n cur.count++\n cur.cited = cur.cited || s.cited\n cur.timesCited += s.timesCited\n }\n }\n const topSites = [...domainAgg.values()].sort((a, b) => b.count - a.count || b.timesCited - a.timesCited)\n\n const citationOrder = citedUrls\n .slice()\n .sort((a, b) => b.timesCited - a.timesCited)\n .map((s, i) => ({ rank: i + 1, domain: s.domain, url: s.url, timesCited: s.timesCited }))\n\n return {\n platform: result.platform,\n capturedAt: result.capturedAt,\n prompt: result.prompt,\n meta: result.meta,\n queries: result.subQueries,\n browsedUrls,\n citedUrls,\n browsedOnly,\n snippets: result.snippets,\n counts: result.counts,\n aggregates: { topSites, citationOrder, byCategory },\n firstPartyDomain: opts.firstPartyDomain ? opts.firstPartyDomain.toLowerCase().replace(/^www\\./, '') : null,\n ...(result.debug ? { debug: result.debug } : {}),\n }\n}\n","import { mkdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport Papa from 'papaparse'\nimport type { EnrichedFanout } from './classify.js'\n\nexport interface FanoutExportPaths {\n dir: string\n json: string\n queriesCsv: string\n queriesTsv: string\n citationsCsv: string\n sourcesCsv: string\n domainsCsv: string\n report: string\n}\n\nfunction outputBaseDir(): string {\n return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction safe(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'capture'\n}\n\nfunction writeTable(path: string, rows: Array<Record<string, unknown>>, delimiter: ','): void\nfunction writeTable(path: string, rows: Array<Record<string, unknown>>, delimiter: '\\t'): void\nfunction writeTable(path: string, rows: Array<Record<string, unknown>>, delimiter: string): void {\n writeFileSync(path, Papa.unparse(rows.length ? rows : [{}], { delimiter }))\n}\n\nexport function exportFanout(enriched: EnrichedFanout): FanoutExportPaths {\n const stamp = safe(enriched.capturedAt.replace(/[:.]/g, '-'))\n const dir = join(outputBaseDir(), 'fanout', `${stamp}-${safe(enriched.platform)}`)\n mkdirSync(dir, { recursive: true })\n\n const queryRows = enriched.queries.map((q, i) => ({ index: i + 1, query: q }))\n const citationRows = enriched.aggregates.citationOrder.map((c) => {\n const src = enriched.citedUrls.find((s) => s.url === c.url)\n return { rank: c.rank, domain: c.domain, url: c.url, timesCited: c.timesCited, siteType: src?.siteType ?? '', title: src?.title ?? '' }\n })\n const sourceRows = enriched.browsedUrls.map((s) => ({ domain: s.domain, url: s.url, cited: s.cited, timesCited: s.timesCited, siteType: s.siteType, title: s.title, round: s.round ?? '' }))\n const domainRows = enriched.aggregates.topSites.map((d) => ({ domain: d.domain, count: d.count, cited: d.cited, timesCited: d.timesCited, siteType: d.siteType }))\n\n const paths: FanoutExportPaths = {\n dir,\n json: join(dir, 'fanout.json'),\n queriesCsv: join(dir, 'queries.csv'),\n queriesTsv: join(dir, 'queries.tsv'),\n citationsCsv: join(dir, 'citations.csv'),\n sourcesCsv: join(dir, 'sources.csv'),\n domainsCsv: join(dir, 'domains.csv'),\n report: join(dir, 'report.html'),\n }\n\n writeFileSync(paths.json, JSON.stringify(enriched, null, 2))\n writeTable(paths.queriesCsv, queryRows, ',')\n writeTable(paths.queriesTsv, queryRows, '\\t')\n writeTable(paths.citationsCsv, citationRows, ',')\n writeTable(paths.sourcesCsv, sourceRows, ',')\n writeTable(paths.domainsCsv, domainRows, ',')\n writeFileSync(paths.report, renderReportHtml(enriched))\n\n return paths\n}\n\nfunction esc(s: string): string {\n return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n\nexport function renderReportHtml(enriched: EnrichedFanout): string {\n const data = JSON.stringify(enriched).replace(/</g, '\\\\u003c')\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>AI Search Fan-Out — ${esc(enriched.platform)}</title>\n<style>\n:root{--bg:#0b0d12;--panel:#151922;--line:#252b38;--ink:#e8ecf3;--mut:#8b95a7;--acc:#5b9dff;--cite:#39d98a;--browse:#5a6677}\n*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}\n.wrap{max-width:980px;margin:0 auto;padding:28px 20px 80px}\nh1{font-size:20px;margin:0 0 2px}.sub{color:var(--mut);margin:0 0 20px;font-size:13px}\n.stat{font-size:30px;font-weight:700}.stat small{font-size:13px;font-weight:400;color:var(--mut)}\n.cards{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:18px 0}\n.card{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:12px 14px}\n.card b{font-size:22px;display:block}.card span{color:var(--mut);font-size:12px}\n.bars{margin:8px 0 22px}.bar{display:flex;align-items:center;gap:8px;margin:4px 0}\n.bar .lab{width:150px;color:var(--mut);font-size:12px;text-align:right}.bar .track{flex:1;background:#10141c;border-radius:5px;overflow:hidden}\n.bar .fill{background:var(--acc);height:16px}.bar .n{width:34px;font-size:12px;color:var(--mut)}\n.tabs{display:flex;gap:8px;margin:22px 0 12px}.tab{background:var(--panel);border:1px solid var(--line);color:var(--ink);padding:7px 14px;border-radius:8px;cursor:pointer}\n.tab.on{background:var(--acc);border-color:var(--acc);color:#04101f;font-weight:600}\n.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}\n.chip{background:var(--panel);border:1px solid var(--line);color:var(--mut);padding:4px 10px;border-radius:20px;cursor:pointer;font-size:12px}\n.chip.on{border-color:var(--acc);color:var(--ink)}.chip b{color:var(--ink)}\n.row{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:10px 12px;margin:6px 0;display:flex;gap:10px;align-items:flex-start}\n.row .idx{color:var(--mut);min-width:22px}.row .main{flex:1}\n.tag{font-size:11px;padding:2px 7px;border-radius:6px;border:1px solid var(--line);color:var(--mut);margin-right:5px}\n.dom{font-weight:600}.url{color:var(--mut);font-size:12px;word-break:break-all}\n.pill{font-size:11px;padding:2px 7px;border-radius:6px}.pill.cite{background:rgba(57,217,138,.15);color:var(--cite)}.pill.brow{background:rgba(90,102,119,.2);color:#aeb8c8}\n.copy{background:none;border:1px solid var(--line);color:var(--mut);border-radius:6px;cursor:pointer;font-size:11px;padding:2px 8px}\n.hide{display:none}\n</style>\n</head>\n<body><div class=\"wrap\">\n<h1>AI Search Fan-Out</h1>\n<p class=\"sub\" id=\"sub\"></p>\n<div class=\"stat\" id=\"stat\"></div>\n<div class=\"cards\" id=\"cards\"></div>\n<div id=\"charts\"></div>\n<div class=\"tabs\"><button class=\"tab on\" data-tab=\"q\">Queries</button><button class=\"tab\" data-tab=\"u\">URLs</button></div>\n<div class=\"chips\" id=\"chips\"></div>\n<div id=\"list\"></div>\n</div>\n<script>\nconst D=${data};\nconst el=(t,c,h)=>{const e=document.createElement(t);if(c)e.className=c;if(h!=null)e.innerHTML=h;return e};\ndocument.getElementById('sub').textContent=D.platform+' · '+(D.meta.model||'model n/a')+' · '+D.meta.rounds+' search round(s) · prompt: '+(D.prompt||'');\ndocument.getElementById('stat').innerHTML='Total Fan-Out: '+D.counts.subQueries+' <small>sub-queries · '+D.counts.browsed+' URLs researched · '+D.counts.cited+' cited</small>';\nconst cards=[['Sub-queries',D.counts.subQueries],['Researched',D.counts.browsed],['Cited',D.counts.cited],['Browsed-only',D.counts.browsedOnly]];\nconst cc=document.getElementById('cards');cards.forEach(([k,v])=>{const c=el('div','card');c.appendChild(el('b',null,v));c.appendChild(el('span',null,k));cc.appendChild(c)});\nfunction barChart(title,obj){const max=Math.max(1,...Object.values(obj));const box=el('div','bars');box.appendChild(el('div',null,'<b>'+title+'</b>'));Object.entries(obj).forEach(([k,v])=>{const r=el('div','bar');r.appendChild(el('div','lab',k));const t=el('div','track');const f=el('div','fill');f.style.width=(v/max*100)+'%';t.appendChild(f);r.appendChild(t);r.appendChild(el('div','n',v));box.appendChild(r)});return box}\nconst charts=document.getElementById('charts');\ncharts.appendChild(barChart('URL Categories',D.aggregates.byCategory));\nlet tab='q',filter=null;\nconst chips=document.getElementById('chips'),list=document.getElementById('list');\nfunction render(){\n chips.innerHTML='';list.innerHTML='';\n if(tab==='q'){\n D.queries.forEach((q,i)=>{const r=el('div','row');r.appendChild(el('div','idx',i+1));const m=el('div','main');m.appendChild(el('div',null,esc(q)));r.appendChild(m);const b=el('button','copy','copy');b.onclick=()=>navigator.clipboard.writeText(q);r.appendChild(b);list.appendChild(r)});\n } else {\n const counts={};D.browsedUrls.forEach(s=>{counts[s.siteType]=(counts[s.siteType]||0)+1});\n Object.entries(counts).forEach(([k,v])=>{const c=el('button','chip'+(filter===k?' on':''),k+' <b>'+v+'</b>');c.onclick=()=>{filter=filter===k?null:k;render()};chips.appendChild(c)});\n D.browsedUrls.forEach(s=>{if(filter&&s.siteType!==filter)return;const r=el('div','row');const m=el('div','main');m.appendChild(el('div',null,'<span class=\"dom\">'+esc(s.domain)+'</span> <span class=\"pill '+(s.cited?'cite':'brow')+'\">'+(s.cited?'cited '+s.timesCited+'×':'browsed')+'</span> <span class=\"tag\">'+s.siteType+'</span>'));m.appendChild(el('div','url',esc(s.url)));r.appendChild(m);list.appendChild(r)});\n }\n}\nfunction esc(s){return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}\ndocument.querySelectorAll('.tab').forEach(t=>t.onclick=()=>{document.querySelectorAll('.tab').forEach(x=>x.classList.remove('on'));t.classList.add('on');tab=t.dataset.tab;filter=null;render()});\nrender();\n</script>\n</body></html>`\n}\n","import type { Page } from 'playwright'\nimport { FanoutCdpCapture } from './cdp-capture.js'\nimport { adapterForHost } from './adapters/index.js'\nimport { buildFanoutResult } from './build.js'\nimport { enrichFanout, type EnrichedFanout } from './classify.js'\nimport { exportFanout, type FanoutExportPaths } from './export.js'\n\nexport interface FanoutCaptureInput {\n prompt?: string\n wait_ms?: number\n first_party_domain?: string\n reset?: boolean\n export?: boolean\n}\n\nexport interface FanoutCaptureOutput {\n result: EnrichedFanout\n exports: FanoutExportPaths | null\n}\n\nconst COMPOSER_SELECTORS = [\n '#prompt-textarea',\n 'div#prompt-textarea',\n 'textarea[data-testid=\"prompt-textarea\"]',\n 'div.ProseMirror[contenteditable=\"true\"]',\n 'div[contenteditable=\"true\"]',\n 'textarea',\n]\n\nasync function sendPrompt(page: Page, text: string): Promise<boolean> {\n for (const selector of COMPOSER_SELECTORS) {\n const locator = page.locator(selector).first()\n try {\n await locator.waitFor({ state: 'visible', timeout: 12_000 })\n } catch {\n continue\n }\n await locator.click({ timeout: 4_000 }).catch(() => undefined)\n await locator.focus().catch(() => undefined)\n await page.keyboard.type(text, { delay: 12 })\n await page.waitForTimeout(300).catch(() => undefined)\n await page.keyboard.press('Enter')\n return true\n }\n return false\n}\n\nasync function waitForAnswer(page: Page, cap: FanoutCdpCapture, baseline: number, waitMs: number): Promise<void> {\n const start = Date.now()\n while (Date.now() - start < waitMs && cap.answerStreamCount() <= baseline) {\n await page.waitForTimeout(400).catch(() => undefined)\n }\n await page.waitForTimeout(1_000).catch(() => undefined)\n}\n\nexport async function runFanoutCapture(page: Page, input: FanoutCaptureInput): Promise<FanoutCaptureOutput> {\n const cap = new FanoutCdpCapture()\n await cap.attach(page)\n try {\n const baseline = cap.answerStreamCount()\n if (input.prompt) await sendPrompt(page, input.prompt).catch(() => false)\n const waitMs = input.wait_ms ?? (input.prompt ? 90_000 : 8_000)\n await waitForAnswer(page, cap, baseline, waitMs)\n await cap.drain()\n\n let hostname = ''\n try {\n hostname = new URL(page.url()).hostname\n } catch {\n hostname = ''\n }\n const adapter = adapterForHost(hostname)\n if (!adapter) {\n throw new Error(`browser_capture_fanout supports chatgpt.com and claude.ai only; the session is on ${hostname || 'an unknown page'}. Navigate there first with browser_goto.`)\n }\n\n const text = cap.bestAnswerText()\n const parsed = adapter.parse(text, input.prompt || '')\n const result = buildFanoutResult({ platform: adapter.platform, parsed, prompt: input.prompt || '', ready: true, rawBytes: text.length })\n const enriched = enrichFanout(result, { firstPartyDomain: input.first_party_domain })\n const exports = input.export ? exportFanout(enriched) : null\n return { result: enriched, exports }\n } finally {\n await cap.detach().catch(() => undefined)\n }\n}\n","export const PACKAGE_VERSION = '0.3.0'\n","import { z } from 'zod'\n\nconst NullableString = z.string().nullable()\nconst BrowserRawObject = z.record(z.unknown())\n\nconst BrowserElementOutput = z.record(z.unknown())\n\nconst BrowserBaseOutput = {\n ok: z.boolean().describe('Whether the browser-agent action succeeded.'),\n tool: z.string().describe('Browser Agent MCP tool that produced this response.'),\n session_id: NullableString.describe('Browser session id when the response is scoped to a session.'),\n}\n\nconst BrowserReplayBaseOutput = {\n ...BrowserBaseOutput,\n replay_id: NullableString.describe('Replay id when the response is scoped to a replay.'),\n}\n\nexport const BrowserOpenInputSchema = {\n label: z.string().optional().describe('Optional human label for this session, shown in the watch console.'),\n url: z.string().url().optional().describe('Optional URL to navigate to immediately after opening.'),\n profile: z.string().optional().describe('Optional saved profile name to load a logged-in session for a site.'),\n save_profile_changes: z.boolean().optional().describe('Persist cookies and local storage back to the named profile when the session is closed. Use this for profile setup or intentional auth refreshes; avoid parallel sessions writing to the same profile.'),\n timeout_seconds: z.number().int().min(60).max(259200).optional().describe('How long the session may live before auto-termination. Defaults to 600. The browser idles into a zero-cost standby between actions, so a longer timeout is cheap.'),\n}\nexport type BrowserOpenInput = z.infer<ReturnType<typeof z.object<typeof BrowserOpenInputSchema>>>\n\nexport const BrowserProfileListInputSchema = {\n email: z.string().optional().describe('Optional Chrome account email or displayed profile name to filter for, for example seo@example.com.'),\n user_data_dir: z.string().optional().describe('Optional Chrome user data directory. Defaults to the current OS Chrome profile root.'),\n}\nexport type BrowserProfileListInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileListInputSchema>>>\n\nexport const BrowserProfileOnboardInputSchema = {\n email: z.string().optional().describe('Optional local Chrome account email to find and convert into a suggested Kernel profile name.'),\n profile: z.string().optional().describe('Optional Kernel browser profile name to create/load. If omitted, email is used to derive one.'),\n user_data_dir: z.string().optional().describe('Optional Chrome user data directory for email lookup. Defaults to the current OS Chrome profile root.'),\n url: z.string().url().optional().describe('Setup URL to open after creating the browser. Defaults to https://accounts.google.com/.'),\n label: z.string().optional().describe('Optional human label for this setup session.'),\n timeout_seconds: z.number().int().min(60).max(259200).optional().describe('How long the setup session may live before auto-termination. Defaults to 600.'),\n}\nexport type BrowserProfileOnboardInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileOnboardInputSchema>>>\n\nexport const BrowserProfileImportInputSchema = {\n email: z.string().optional().describe('Optional Chrome account email or displayed profile name to select from Chrome Local State.'),\n name: z.string().optional().describe('Name for the managed MCP Scraper browser profile. Defaults to a slug derived from the selected Chrome account.'),\n chrome_profile_directory: z.string().optional().describe('Optional Chrome profile directory to import, for example Default or Profile 1.'),\n user_data_dir: z.string().optional().describe('Optional source Chrome user data directory. Defaults to the current OS Chrome profile root.'),\n output_dir: z.string().optional().describe('Optional managed profile base directory. Defaults to ~/.mcp-scraper/browser-profiles.'),\n browser_executable_path: z.string().optional().describe('Optional Chrome executable path for local browser launches. Defaults to the installed Google Chrome path when found.'),\n overwrite: z.boolean().default(false).describe('Overwrite an existing managed profile clone with the same name.'),\n}\nexport type BrowserProfileImportInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileImportInputSchema>>>\n\nexport const BrowserProfileSyncInputSchema = {\n name: z.string().describe('Managed MCP Scraper browser profile name to refresh from its recorded source Chrome profile.'),\n output_dir: z.string().optional().describe('Optional managed profile base directory. Defaults to ~/.mcp-scraper/browser-profiles.'),\n browser_executable_path: z.string().optional().describe('Optional Chrome executable path to store in the refreshed profile manifest.'),\n}\nexport type BrowserProfileSyncInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileSyncInputSchema>>>\n\nexport const BrowserSessionInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n}\nexport type BrowserSessionInput = z.infer<ReturnType<typeof z.object<typeof BrowserSessionInputSchema>>>\n\nexport const BrowserLocateTargetSchema = z.object({\n name: z.string().optional().describe('Optional label for this target, echoed in the result.'),\n selector: z.string().optional().describe('CSS selector for the exact DOM element to locate, for example h1, input[name=\"q\"], or [data-testid=\"result\"].'),\n text: z.string().optional().describe('Visible text to locate when a selector is not known. The tool returns the text range bounds when possible.'),\n match: z.enum(['contains', 'exact']).default('contains').describe('How to match text targets. Defaults to contains.'),\n index: z.number().int().min(0).default(0).describe('Zero-based match index when multiple elements match.'),\n}).refine(value => Boolean(value.selector || value.text), {\n message: 'target requires selector or text',\n})\n\nexport const BrowserLocateInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n targets: z.array(BrowserLocateTargetSchema).min(1).max(20).describe('DOM targets to locate in the current viewport. Use selectors for exact elements, or text for visible text ranges.'),\n}\nexport type BrowserLocateInput = z.infer<ReturnType<typeof z.object<typeof BrowserLocateInputSchema>>>\n\nexport const BrowserGotoInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n url: z.string().url().describe('URL to navigate the browser to.'),\n}\nexport type BrowserGotoInput = z.infer<ReturnType<typeof z.object<typeof BrowserGotoInputSchema>>>\n\nexport const BrowserClickInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n x: z.number().describe('X coordinate to click, in screenshot pixels. Use only coordinates from the latest browser_screenshot, browser_read, or browser_locate result; do not guess.'),\n y: z.number().describe('Y coordinate to click, in screenshot pixels. Use only coordinates from the latest browser_screenshot, browser_read, or browser_locate result; do not guess.'),\n button: z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button.'),\n num_clicks: z.number().int().min(1).max(3).optional().describe('Number of clicks, e.g. 2 for double-click.'),\n}\nexport type BrowserClickInput = z.infer<ReturnType<typeof z.object<typeof BrowserClickInputSchema>>>\n\nexport const BrowserTypeInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n text: z.string().describe('Text to type at the current focus. Click a field first to focus it.'),\n delay: z.number().int().min(0).max(500).optional().describe('Optional per-keystroke delay in ms for human-like typing.'),\n}\nexport type BrowserTypeInput = z.infer<ReturnType<typeof z.object<typeof BrowserTypeInputSchema>>>\n\nexport const BrowserScrollInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n delta_y: z.number().default(5).describe('Vertical scroll in wheel units. Positive scrolls down, negative up.'),\n delta_x: z.number().default(0).describe('Horizontal scroll in wheel units.'),\n x: z.number().optional().describe('X position to scroll at. Defaults to screen center.'),\n y: z.number().optional().describe('Y position to scroll at. Defaults to screen center.'),\n}\nexport type BrowserScrollInput = z.infer<ReturnType<typeof z.object<typeof BrowserScrollInputSchema>>>\n\nexport const BrowserPressInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n keys: z.array(z.string()).min(1).describe('Keys or combinations to press, e.g. [\"Return\"], [\"Ctrl+a\"], [\"Ctrl+Shift+Tab\"].'),\n}\nexport type BrowserPressInput = z.infer<ReturnType<typeof z.object<typeof BrowserPressInputSchema>>>\n\nexport const BrowserReplayStopInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n replay_id: z.string().describe('The replay id returned by browser_replay_start or browser_list_replays. Use only a returned replay_id; do not construct one yourself.'),\n}\nexport type BrowserReplayStopInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayStopInputSchema>>>\n\nexport const BrowserReplayDownloadInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n replay_id: z.string().describe('The replay id returned by browser_replay_start or browser_list_replays. Use only a returned replay_id; do not construct one yourself.'),\n filename: z.string().optional().describe('Optional local MP4 filename. Defaults to a timestamped replay filename.'),\n}\nexport type BrowserReplayDownloadInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayDownloadInputSchema>>>\n\nexport const BrowserReplayAnnotationSchema = z.object({\n type: z.enum(['box', 'circle', 'underline', 'arrow', 'label']).default('box').describe('Annotation style to draw over the replay.'),\n start_seconds: z.number().min(0).default(0).describe('When the annotation should appear in the replay.'),\n end_seconds: z.number().min(0).optional().describe('When the annotation should disappear. Defaults to two seconds after start_seconds.'),\n left: z.number().optional().describe('Target left edge in browser screenshot pixels. Use element.left from browser_screenshot/browser_read.'),\n top: z.number().optional().describe('Target top edge in browser screenshot pixels. Use element.top from browser_screenshot/browser_read.'),\n width: z.number().positive().optional().describe('Target width in browser screenshot pixels. Use element.width from browser_screenshot/browser_read.'),\n height: z.number().positive().optional().describe('Target height in browser screenshot pixels. Use element.height from browser_screenshot/browser_read.'),\n x: z.number().optional().describe('Point target x coordinate in browser screenshot pixels when no box is available.'),\n y: z.number().optional().describe('Point target y coordinate in browser screenshot pixels when no box is available.'),\n from_x: z.number().optional().describe('Arrow start x coordinate in browser screenshot pixels. Defaults near the target.'),\n from_y: z.number().optional().describe('Arrow start y coordinate in browser screenshot pixels. Defaults near the target.'),\n to_x: z.number().optional().describe('Arrow target x coordinate in browser screenshot pixels. Defaults to the target box center.'),\n to_y: z.number().optional().describe('Arrow target y coordinate in browser screenshot pixels. Defaults to the target box center.'),\n label: z.string().max(120).optional().describe('Optional text callout to render near the annotation.'),\n color: z.string().regex(/^#?[0-9a-fA-F]{6}$/).optional().describe('Annotation color as hex, for example #ff3b30.'),\n thickness: z.number().min(1).max(24).optional().describe('Stroke thickness in pixels. Defaults to 5.'),\n})\n\nexport const BrowserReplayMarkInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself. A replay must already be recording.'),\n target: BrowserLocateTargetSchema.describe('The exact DOM element or text range to mark in the current viewport.'),\n type: z.enum(['box', 'circle', 'underline', 'arrow']).default('box').describe('Annotation style to generate. Labels are included on the returned annotation when label is provided.'),\n label: z.string().max(120).optional().describe('Optional callout text to render near the target.'),\n color: z.string().regex(/^#?[0-9a-fA-F]{6}$/).optional().describe('Annotation color as hex, for example #ff3b30.'),\n thickness: z.number().min(1).max(24).optional().describe('Stroke thickness in pixels. Defaults to 5.'),\n padding: z.number().min(0).max(80).default(8).describe('Pixels to expand the DOM bounds so the highlight does not touch the text edge.'),\n start_offset_seconds: z.number().min(-5).max(10).default(-0.25).describe('Offset from the current replay time. Negative values make the callout appear just before the mark action is captured.'),\n duration_seconds: z.number().min(0.5).max(30).default(4).describe('How long the generated annotation should remain visible.'),\n}\nexport type BrowserReplayMarkInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayMarkInputSchema>>>\n\nexport const BrowserReplayAnnotateInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n replay_id: z.string().describe('The replay id returned by browser_replay_start or browser_list_replays. Use only a returned replay_id; do not construct one yourself.'),\n annotations: z.array(BrowserReplayAnnotationSchema).min(1).max(50).describe('Timed overlay annotations to render on the replay. Prefer annotations returned by browser_replay_mark; otherwise use exact DOM bounds from browser_locate/browser_screenshot/browser_read.'),\n filename: z.string().optional().describe('Optional output MP4 filename. Defaults to a timestamped annotated replay filename.'),\n source_width: z.number().positive().optional().describe('Width of the screenshot coordinate space used for annotations. Defaults to the replay video width.'),\n source_height: z.number().positive().optional().describe('Height of the coordinate space used for annotations. When this is a page viewport height smaller than the replay video height, the annotator infers the browser chrome top offset.'),\n source_left_offset: z.number().min(0).optional().describe('Optional explicit X offset from annotation coordinates to replay video coordinates. Usually omitted.'),\n source_top_offset: z.number().min(0).optional().describe('Optional explicit Y offset from annotation coordinates to replay video coordinates. Usually omitted because browser chrome offset is inferred when source_height is a page viewport height.'),\n}\nexport type BrowserReplayAnnotateInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayAnnotateInputSchema>>>\n\nexport const BrowserListInputSchema = {\n include_closed: z.boolean().default(false).describe('Include closed sessions in the list.'),\n}\nexport type BrowserListInput = z.infer<ReturnType<typeof z.object<typeof BrowserListInputSchema>>>\n\nexport const BrowserCaptureFanoutInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. The session must be a local-mode session on chatgpt.com or claude.ai that is logged in. Use only a returned session_id; do not construct one yourself.'),\n prompt: z.string().optional().describe('Optional prompt to type into the chat composer and submit before capturing. Omit to passively capture the fan-out of a prompt the user just ran in the visible browser. The prompt must trigger web search for there to be a fan-out.'),\n wait_ms: z.number().int().min(0).max(180000).optional().describe('How long to wait for the answer stream to finish before parsing. Defaults to 90000 when a prompt is sent, 8000 for passive capture. Capture ends as soon as the answer stream finishes.'),\n first_party_domain: z.string().optional().describe('The brand/site being researched, for example example.com. Sources on this domain are tagged First-party/vendor. Set this when the prompt is about a specific business.'),\n reset: z.boolean().default(false).describe('Clear any previously buffered stream for this page before capturing. Use when re-running to avoid mixing turns.'),\n export: z.boolean().default(false).describe('When true, write JSON, CSV, TSV exports (queries, citations, sources, domains) and a self-contained HTML report to MCP_SCRAPER_OUTPUT_DIR/fanout and return their paths.'),\n}\nexport type BrowserCaptureFanoutInput = z.infer<ReturnType<typeof z.object<typeof BrowserCaptureFanoutInputSchema>>>\n\nconst FanoutSourceOutput = z.object({\n url: z.string(),\n domain: z.string(),\n title: z.string(),\n cited: z.boolean(),\n timesCited: z.number().int().min(0),\n snippet: z.string(),\n round: z.number().int().nullable(),\n siteType: z.string().describe('URL category: First-party/vendor, News/media, Reddit, Social/video, Encyclopedia, Review site, Docs, or Blog.'),\n})\n\nexport const BrowserCaptureFanoutOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_capture_fanout'),\n platform: z.enum(['ChatGPT', 'Claude']).describe('Which AI-search surface the fan-out was captured from.'),\n captured_at: z.string(),\n prompt: z.string().describe('The user prompt that triggered the captured fan-out, when recoverable.'),\n meta: z.object({\n model: z.string(),\n finishType: z.string(),\n title: z.string(),\n rounds: z.number().int().min(0),\n }),\n queries: z.array(z.string()).describe('Every web-search sub-query the model issued, in capture order. Classify these by funnel stage and type yourself from the text.'),\n browsed_urls: z.array(FanoutSourceOutput).describe('Every researched URL (cited and browsed-only), cited first.'),\n cited_urls: z.array(FanoutSourceOutput).describe('The subset of researched URLs actually cited in the final answer.'),\n browsed_only: z.array(FanoutSourceOutput).describe('Researched URLs the model pulled but did not cite.'),\n snippets: z.array(z.object({ url: z.string(), domain: z.string(), title: z.string(), text: z.string() })),\n counts: z.object({\n subQueries: z.number().int().min(0),\n browsed: z.number().int().min(0),\n cited: z.number().int().min(0),\n browsedOnly: z.number().int().min(0),\n }),\n aggregates: z.object({\n topSites: z.array(z.object({ domain: z.string(), count: z.number().int(), cited: z.boolean(), timesCited: z.number().int(), siteType: z.string() })),\n citationOrder: z.array(z.object({ rank: z.number().int(), domain: z.string(), url: z.string(), timesCited: z.number().int() })),\n byCategory: z.record(z.number().int()),\n }).describe('Objective aggregates: top sourced sites by frequency, citation order, and URL-category counts.'),\n first_party_domain: z.string().nullable(),\n exports: z.object({\n dir: z.string(),\n json: z.string(),\n queriesCsv: z.string(),\n queriesTsv: z.string(),\n citationsCsv: z.string(),\n sourcesCsv: z.string(),\n domainsCsv: z.string(),\n report: z.string(),\n }).nullable().describe('Local file paths when export=true, otherwise null.'),\n debug: z.object({\n interceptorReady: z.boolean(),\n rawBytes: z.number().int().min(0),\n unmappedKeys: z.array(z.string()),\n note: z.string(),\n }).optional(),\n}\n\nexport const BrowserOpenOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_open'),\n session_id: z.string().describe('Session id returned by browser_open. Use only this exact value in later browser_* calls; do not construct one yourself.'),\n watch_url: z.string().describe('Human watch/takeover URL for this browser session.'),\n live_view_url: NullableString.describe('Raw live-view URL from the browser service when available.'),\n url: NullableString.describe('Initial URL requested by the caller, when provided.'),\n hint: z.string(),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserProfileListOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_list'),\n session_id: z.null(),\n profiles: z.array(BrowserRawObject),\n count: z.number().int().min(0),\n hint: z.string(),\n}\n\nexport const BrowserProfileOnboardOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_onboard'),\n session_id: z.string(),\n watch_url: z.string(),\n live_view_url: NullableString,\n profile: z.string(),\n setup_url: z.string(),\n chrome_profile: BrowserRawObject.nullable(),\n next_steps: z.array(z.string()),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserProfileImportOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_import'),\n session_id: z.null(),\n profile: BrowserRawObject,\n source_profile: BrowserRawObject,\n next_steps: z.array(z.string()),\n hint: z.string(),\n}\n\nexport const BrowserProfileSyncOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_sync'),\n session_id: z.null(),\n profile: BrowserRawObject,\n source_profile: BrowserRawObject,\n hint: z.string(),\n}\n\nexport const BrowserScreenshotOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_screenshot'),\n url: NullableString,\n title: NullableString,\n text: z.string(),\n elements: z.array(BrowserElementOutput),\n screenshot: z.object({\n mime_type: z.string(),\n inline: z.boolean(),\n }).nullable(),\n}\n\nexport const BrowserReadOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_read'),\n url: NullableString,\n title: NullableString,\n text: z.string(),\n elements: z.array(BrowserElementOutput),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserLocateOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_locate'),\n url: NullableString,\n title: NullableString,\n viewport: BrowserRawObject.nullable(),\n replay: BrowserRawObject.nullable(),\n targets: z.array(BrowserRawObject),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserActionOutputSchema = {\n ...BrowserBaseOutput,\n result: BrowserRawObject.describe('Provider action result. Check ok and follow with browser_screenshot/browser_read when page state matters.'),\n nextRecommendedTool: z.string().nullable(),\n}\n\nexport const BrowserReplayStartOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_start'),\n view_url: NullableString,\n download_url: NullableString,\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserReplayStopOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_stop'),\n view_url: NullableString,\n download_url: NullableString,\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserListReplaysOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_list_replays'),\n replays: z.array(BrowserRawObject),\n count: z.number().int().min(0),\n}\n\nexport const BrowserReplayDownloadOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_download'),\n file_path: NullableString,\n bytes: z.number().int().min(0).nullable(),\n mime_type: NullableString,\n download_url: NullableString,\n}\n\nexport const BrowserReplayMarkOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_mark'),\n annotation: BrowserRawObject,\n source_width: z.number().nullable(),\n source_height: z.number().nullable(),\n target: BrowserRawObject.nullable(),\n hint: z.string(),\n}\n\nexport const BrowserReplayAnnotateOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_annotate'),\n source_file_path: NullableString,\n annotated_file_path: NullableString,\n bytes: z.number().int().min(0).nullable(),\n width: z.number().int().min(0).nullable(),\n height: z.number().int().min(0).nullable(),\n annotation_count: z.number().int().min(0).nullable(),\n mime_type: NullableString,\n}\n\nexport const BrowserCloseOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_close'),\n closed: z.boolean(),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserListSessionsOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_list_sessions'),\n session_id: z.null(),\n sessions: z.array(BrowserRawObject),\n count: z.number().int().min(0),\n}\n","import { execFile } from 'node:child_process'\nimport { mkdtemp, rm, stat, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport type ReplayAnnotationType = 'box' | 'circle' | 'underline' | 'arrow' | 'label'\n\nexport interface ReplayAnnotation {\n type?: ReplayAnnotationType\n start_seconds?: number\n end_seconds?: number\n left?: number\n top?: number\n width?: number\n height?: number\n x?: number\n y?: number\n from_x?: number\n from_y?: number\n to_x?: number\n to_y?: number\n label?: string\n color?: string\n thickness?: number\n}\n\nexport interface AnnotateReplayOptions {\n annotations: ReplayAnnotation[]\n sourceWidth?: number\n sourceHeight?: number\n sourceLeftOffset?: number\n sourceTopOffset?: number\n}\n\ninterface Size {\n width: number\n height: number\n}\n\ninterface Rect {\n left: number\n top: number\n width: number\n height: number\n}\n\ninterface CoordinateTransform {\n scaleX: number\n scaleY: number\n offsetX: number\n offsetY: number\n}\n\nexport interface AnnotatedReplayResult {\n filePath: string\n bytes: number\n width: number\n height: number\n annotationCount: number\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction formatAssTime(seconds: number): string {\n const safe = Math.max(0, seconds)\n const hours = Math.floor(safe / 3600)\n const minutes = Math.floor((safe % 3600) / 60)\n const wholeSeconds = Math.floor(safe % 60)\n const centiseconds = Math.floor((safe - Math.floor(safe)) * 100)\n return `${hours}:${String(minutes).padStart(2, '0')}:${String(wholeSeconds).padStart(2, '0')}.${String(centiseconds).padStart(2, '0')}`\n}\n\nfunction cssHexToAssColor(color?: string): string {\n const normalized = color?.trim().match(/^#?([0-9a-fA-F]{6})$/)?.[1] ?? 'ff3b30'\n const red = normalized.slice(0, 2)\n const green = normalized.slice(2, 4)\n const blue = normalized.slice(4, 6)\n return `&H${blue}${green}${red}&`\n}\n\nfunction escapeAssText(value: string): string {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\r?\\n/g, '\\\\N')\n}\n\nfunction resolveCoordinateTransform(video: Size, source: Size, options: AnnotateReplayOptions): CoordinateTransform {\n const explicitOffsetX = finiteNumber(options.sourceLeftOffset) ? options.sourceLeftOffset : null\n const explicitOffsetY = finiteNumber(options.sourceTopOffset) ? options.sourceTopOffset : null\n const inferredTopOffset =\n explicitOffsetY == null &&\n Math.round(source.width) === Math.round(video.width) &&\n source.height < video.height &&\n video.height - source.height <= 220\n ? video.height - source.height\n : 0\n const offsetX = explicitOffsetX ?? 0\n const offsetY = explicitOffsetY ?? inferredTopOffset\n return {\n scaleX: (video.width - offsetX) / source.width,\n scaleY: (video.height - offsetY) / source.height,\n offsetX,\n offsetY,\n }\n}\n\nfunction transformPoint(x: number, y: number, transform: CoordinateTransform): { x: number; y: number } {\n return {\n x: x * transform.scaleX + transform.offsetX,\n y: y * transform.scaleY + transform.offsetY,\n }\n}\n\nfunction scaleRect(annotation: ReplayAnnotation, transform: CoordinateTransform): Rect {\n if (\n finiteNumber(annotation.left) &&\n finiteNumber(annotation.top) &&\n finiteNumber(annotation.width) &&\n finiteNumber(annotation.height)\n ) {\n const origin = transformPoint(annotation.left, annotation.top, transform)\n return {\n left: origin.x,\n top: origin.y,\n width: annotation.width * transform.scaleX,\n height: annotation.height * transform.scaleY,\n }\n }\n if (finiteNumber(annotation.x) && finiteNumber(annotation.y)) {\n const radius = finiteNumber(annotation.width) ? annotation.width / 2 : 28\n const point = transformPoint(annotation.x, annotation.y, transform)\n return {\n left: point.x - radius * transform.scaleX,\n top: point.y - radius * transform.scaleY,\n width: radius * 2 * transform.scaleX,\n height: radius * 2 * transform.scaleY,\n }\n }\n throw new Error('annotation needs either left/top/width/height or x/y')\n}\n\nfunction rectPath(rect: Rect): string {\n const x1 = Math.round(rect.left)\n const y1 = Math.round(rect.top)\n const x2 = Math.round(rect.left + rect.width)\n const y2 = Math.round(rect.top + rect.height)\n return `m ${x1} ${y1} l ${x2} ${y1} l ${x2} ${y2} l ${x1} ${y2} l ${x1} ${y1}`\n}\n\nfunction ellipsePath(rect: Rect): string {\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const rx = Math.max(4, rect.width / 2)\n const ry = Math.max(4, rect.height / 2)\n const points: string[] = []\n for (let i = 0; i <= 32; i += 1) {\n const t = (Math.PI * 2 * i) / 32\n const x = Math.round(cx + Math.cos(t) * rx)\n const y = Math.round(cy + Math.sin(t) * ry)\n points.push(`${i === 0 ? 'm' : 'l'} ${x} ${y}`)\n }\n return points.join(' ')\n}\n\nfunction filledRectPath(left: number, top: number, width: number, height: number): string {\n return rectPath({ left, top, width, height })\n}\n\nfunction arrowPath(fromX: number, fromY: number, toX: number, toY: number, thickness: number): string {\n const dx = toX - fromX\n const dy = toY - fromY\n const length = Math.max(1, Math.hypot(dx, dy))\n const ux = dx / length\n const uy = dy / length\n const px = -uy\n const py = ux\n const half = thickness / 2\n const head = Math.max(14, thickness * 4)\n const baseX = toX - ux * head\n const baseY = toY - uy * head\n const p1x = Math.round(fromX + px * half)\n const p1y = Math.round(fromY + py * half)\n const p2x = Math.round(baseX + px * half)\n const p2y = Math.round(baseY + py * half)\n const p3x = Math.round(baseX + px * head * 0.55)\n const p3y = Math.round(baseY + py * head * 0.55)\n const p4x = Math.round(toX)\n const p4y = Math.round(toY)\n const p5x = Math.round(baseX - px * head * 0.55)\n const p5y = Math.round(baseY - py * head * 0.55)\n const p6x = Math.round(baseX - px * half)\n const p6y = Math.round(baseY - py * half)\n const p7x = Math.round(fromX - px * half)\n const p7y = Math.round(fromY - py * half)\n return `m ${p1x} ${p1y} l ${p2x} ${p2y} l ${p3x} ${p3y} l ${p4x} ${p4y} l ${p5x} ${p5y} l ${p6x} ${p6y} l ${p7x} ${p7y} l ${p1x} ${p1y}`\n}\n\nfunction eventLine(start: number, end: number, body: string): string {\n return `Dialogue: 0,${formatAssTime(start)},${formatAssTime(end)},Default,,0,0,0,,${body}`\n}\n\nfunction labelLine(start: number, end: number, x: number, y: number, label: string): string {\n const safeX = Math.round(x)\n const safeY = Math.round(y)\n return eventLine(\n start,\n end,\n `{\\\\an7\\\\pos(${safeX},${safeY})\\\\fs30\\\\bord4\\\\shad0\\\\c&HFFFFFF&\\\\3c&H000000&}${escapeAssText(label)}`,\n )\n}\n\nfunction shapeLine(start: number, end: number, path: string, color: string, thickness: number, filled = false): string {\n const fillAlpha = filled ? '&H00&' : '&HFF&'\n const border = filled ? 0 : thickness\n return eventLine(\n start,\n end,\n `{\\\\an7\\\\pos(0,0)\\\\p1\\\\bord${border}\\\\shad0\\\\1a${fillAlpha}\\\\1c${color}\\\\3c${color}}${path}`,\n )\n}\n\nexport function buildAssSubtitle(options: AnnotateReplayOptions, video: Size): string {\n const source = {\n width: options.sourceWidth && options.sourceWidth > 0 ? options.sourceWidth : video.width,\n height: options.sourceHeight && options.sourceHeight > 0 ? options.sourceHeight : video.height,\n }\n const transform = resolveCoordinateTransform(video, source, options)\n const lines: string[] = []\n for (const annotation of options.annotations) {\n const start = Math.max(0, annotation.start_seconds ?? 0)\n const end = annotation.end_seconds && annotation.end_seconds > start ? annotation.end_seconds : start + 2\n const type = annotation.type ?? 'box'\n const color = cssHexToAssColor(annotation.color)\n const thickness = Math.round(clamp(annotation.thickness ?? 5, 2, 24))\n if (type === 'label') {\n if (!annotation.label) throw new Error('label annotation needs label')\n const rect = scaleRect(annotation, transform)\n lines.push(labelLine(start, end, rect.left, Math.max(8, rect.top), annotation.label))\n continue\n }\n if (type === 'arrow') {\n const rect = finiteNumber(annotation.to_x) && finiteNumber(annotation.to_y)\n ? null\n : scaleRect(annotation, transform)\n const toPoint = finiteNumber(annotation.to_x) && finiteNumber(annotation.to_y)\n ? transformPoint(annotation.to_x, annotation.to_y, transform)\n : null\n const toX = toPoint ? toPoint.x : rect!.left + rect!.width / 2\n const toY = toPoint ? toPoint.y : rect!.top + rect!.height / 2\n const fromPoint = finiteNumber(annotation.from_x) && finiteNumber(annotation.from_y)\n ? transformPoint(annotation.from_x, annotation.from_y, transform)\n : null\n const fromX = fromPoint ? fromPoint.x : clamp(toX - 120, 12, video.width - 12)\n const fromY = fromPoint ? fromPoint.y : clamp(toY - 90, 12, video.height - 12)\n lines.push(shapeLine(start, end, arrowPath(fromX, fromY, toX, toY, thickness), color, thickness, true))\n if (annotation.label) lines.push(labelLine(start, end, fromX + 8, Math.max(96, fromY - 36), annotation.label))\n continue\n }\n const rect = scaleRect(annotation, transform)\n if (type === 'underline') {\n const underlineTop = rect.top + rect.height + thickness\n lines.push(shapeLine(start, end, filledRectPath(rect.left, underlineTop, rect.width, thickness), color, 0, true))\n } else if (type === 'circle') {\n lines.push(shapeLine(start, end, ellipsePath(rect), color, thickness))\n } else {\n lines.push(shapeLine(start, end, rectPath(rect), color, thickness))\n }\n if (annotation.label) lines.push(labelLine(start, end, rect.left, Math.max(8, rect.top - 38), annotation.label))\n }\n\n return [\n '[Script Info]',\n 'ScriptType: v4.00+',\n `PlayResX: ${Math.round(video.width)}`,\n `PlayResY: ${Math.round(video.height)}`,\n 'ScaledBorderAndShadow: yes',\n '',\n '[V4+ Styles]',\n 'Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding',\n 'Style: Default,Arial,30,&H00FFFFFF,&H000000FF,&H00000000,&H90000000,0,0,0,0,100,100,0,0,1,2,0,7,0,0,0,1',\n '',\n '[Events]',\n 'Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text',\n ...lines,\n '',\n ].join('\\n')\n}\n\nasync function videoSize(inputFilePath: string): Promise<Size> {\n const { stdout } = await execFileAsync('ffprobe', [\n '-v',\n 'error',\n '-select_streams',\n 'v:0',\n '-show_entries',\n 'stream=width,height',\n '-of',\n 'json',\n inputFilePath,\n ], { maxBuffer: 1024 * 1024 })\n const parsed = JSON.parse(stdout) as { streams?: Array<{ width?: number; height?: number }> }\n const stream = parsed.streams?.[0]\n if (!stream?.width || !stream.height) throw new Error('could not read replay video dimensions')\n return { width: stream.width, height: stream.height }\n}\n\nfunction ffmpegFilterPath(path: string): string {\n return path.replace(/\\\\/g, '\\\\\\\\').replace(/:/g, '\\\\:')\n}\n\nexport async function annotateReplayVideo(\n inputFilePath: string,\n outputFilePath: string,\n options: AnnotateReplayOptions,\n): Promise<AnnotatedReplayResult> {\n if (!options.annotations.length) throw new Error('annotations must include at least one item')\n const size = await videoSize(inputFilePath)\n const tmp = await mkdtemp(join(tmpdir(), 'mcp-scraper-ass-'))\n const assPath = join(tmp, 'annotations.ass')\n try {\n await writeFile(assPath, buildAssSubtitle(options, size), 'utf8')\n await execFileAsync('ffmpeg', [\n '-y',\n '-i',\n inputFilePath,\n '-vf',\n `ass=${ffmpegFilterPath(assPath)}`,\n '-c:v',\n 'libx264',\n '-pix_fmt',\n 'yuv420p',\n '-movflags',\n '+faststart',\n '-c:a',\n 'copy',\n outputFilePath,\n ], { maxBuffer: 1024 * 1024 * 20 })\n const out = await stat(outputFilePath)\n return {\n filePath: outputFilePath,\n bytes: out.size,\n width: size.width,\n height: size.height,\n annotationCount: options.annotations.length,\n }\n } finally {\n await rm(tmp, { recursive: true, force: true })\n }\n}\n"],"mappings":"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","names":["import_node_fs","import_node_os","import_node_path","import_node_fs","import_node_os","import_node_path","import_promises","import_node_os","import_node_path","import_node_fs","import_node_path","esc","import_node_fs","import_node_os","import_node_path","Papa","exports","StealthPlugin","import_promises","import_node_os","import_node_path","safe","rect","outputBaseDir","finiteNumber","server","baseUrl","session","res","content","structured","sessions","exports"]}
1
+ {"version":3,"sources":["../../bin/browser-agent-stdio-server.ts","../../src/mcp/browser-agent-mcp-server.ts","../../src/lib/chrome-profiles.ts","../../src/lib/browser-service-env.ts","../../src/lib/local-browser-profiles.ts","../../src/services/browser-agent/local-browser-agent-service.ts","../../src/services/fanout/cdp-capture.ts","../../src/services/fanout/parse-helpers.ts","../../src/services/fanout/adapters/chatgpt.ts","../../src/services/fanout/adapters/claude.ts","../../src/services/fanout/adapters/index.ts","../../src/services/fanout/build.ts","../../src/services/fanout/classify.ts","../../src/services/fanout/export.ts","../../src/services/fanout/run-capture.ts","../../src/version.ts","../../src/mcp/browser-agent-tool-schemas.ts","../../src/mcp/replay-annotator.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { buildBrowserAgentMcpServer } from '../src/mcp/browser-agent-mcp-server.js'\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.MCP_SCRAPER_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.mcp-scraper-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n void 0\n }\n }\n return undefined\n}\n\nconst apiKey = (\n process.env.MCP_SCRAPER_API_KEY ??\n process.env.MCP_SCRAPER_KEY ??\n process.env.MCP_API_KEY ??\n readApiKeyFile()\n)?.trim()\nif (!apiKey) {\n process.stderr.write('MCP_SCRAPER_API_KEY env var or ~/.mcp-scraper-key is required\\n')\n process.exit(1)\n}\n\nconst baseUrl = process.env.MCP_SCRAPER_BASE_URL?.trim() || process.env.MCP_BASE_URL?.trim() || 'https://mcpscraper.dev'\nconst consoleBaseUrl = process.env.BROWSER_AGENT_CONSOLE_URL?.trim() || baseUrl\nconst server = buildBrowserAgentMcpServer({ baseUrl, apiKey, consoleBaseUrl })\nconst transport = new StdioServerTransport()\n\nasync function main() {\n await server.connect(transport)\n}\n\nmain().catch(err => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport { mkdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { listLocalChromeProfiles, type LocalChromeProfile } from '../lib/chrome-profiles.js'\nimport { browserServiceProfileName, browserServiceProfileSaveChanges } from '../lib/browser-service-env.js'\nimport { importChromeProfile, localBrowserModeEnabled, syncImportedChromeProfile } from '../lib/local-browser-profiles.js'\nimport { LocalBrowserAgentService } from '../services/browser-agent/local-browser-agent-service.js'\nimport { PACKAGE_VERSION } from '../version.js'\nimport {\n BrowserOpenInputSchema,\n BrowserProfileListInputSchema,\n BrowserProfileOnboardInputSchema,\n BrowserProfileImportInputSchema,\n BrowserProfileSyncInputSchema,\n BrowserCaptureFanoutInputSchema,\n BrowserCaptureFanoutOutputSchema,\n BrowserSessionInputSchema,\n BrowserLocateInputSchema,\n BrowserGotoInputSchema,\n BrowserClickInputSchema,\n BrowserTypeInputSchema,\n BrowserScrollInputSchema,\n BrowserPressInputSchema,\n BrowserReplayStopInputSchema,\n BrowserReplayDownloadInputSchema,\n BrowserReplayMarkInputSchema,\n BrowserReplayAnnotateInputSchema,\n BrowserListInputSchema,\n BrowserOpenOutputSchema,\n BrowserScreenshotOutputSchema,\n BrowserReadOutputSchema,\n BrowserLocateOutputSchema,\n BrowserActionOutputSchema,\n BrowserReplayStartOutputSchema,\n BrowserReplayStopOutputSchema,\n BrowserListReplaysOutputSchema,\n BrowserReplayDownloadOutputSchema,\n BrowserReplayMarkOutputSchema,\n BrowserReplayAnnotateOutputSchema,\n BrowserCloseOutputSchema,\n BrowserListSessionsOutputSchema,\n BrowserProfileListOutputSchema,\n BrowserProfileOnboardOutputSchema,\n BrowserProfileImportOutputSchema,\n BrowserProfileSyncOutputSchema,\n} from './browser-agent-tool-schemas.js'\nimport { annotateReplayVideo } from './replay-annotator.js'\n\nexport interface BrowserAgentHttpOptions {\n baseUrl: string\n apiKey: string\n consoleBaseUrl?: string\n timeoutMs?: number\n}\n\nfunction structuredResult(value: Record<string, unknown>, isError = false): CallToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(value) }],\n structuredContent: value,\n isError,\n }\n}\n\nfunction errorMessage(value: unknown): string {\n if (value && typeof value === 'object') {\n const data = value as Record<string, unknown>\n if (typeof data.error === 'string') return data.error\n if (typeof data.message === 'string') return data.message\n }\n return typeof value === 'string' ? value : 'Browser Agent request failed'\n}\n\nfunction errorResult(tool: string, value: unknown, sessionId: string | null = null, replayId: string | null = null): CallToolResult {\n return structuredResult({\n ok: false,\n tool,\n session_id: sessionId,\n ...(replayId !== null ? { replay_id: replayId } : {}),\n error: errorMessage(value),\n raw: value && typeof value === 'object' ? value as Record<string, unknown> : { value },\n }, true)\n}\n\nfunction actionResult(\n tool: string,\n sessionId: string,\n ok: boolean,\n data: unknown,\n nextRecommendedTool: string | null = 'browser_screenshot',\n): CallToolResult {\n if (!ok) return errorResult(tool, data, sessionId)\n return structuredResult({\n ok: true,\n tool,\n session_id: sessionId,\n result: data && typeof data === 'object' ? data as Record<string, unknown> : { value: data },\n nextRecommendedTool,\n })\n}\n\nfunction outputBaseDir(): string {\n return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction safeFilePart(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 120) || 'replay'\n}\n\nfunction replayFilePath(sessionId: string, replayId: string, filename?: string): string {\n const requested = filename?.trim()\n const stamp = new Date().toISOString().replace(/[:.]/g, '-')\n const name = requested\n ? safeFilePart(requested).replace(/\\.mp4$/i, '')\n : `${stamp}-${safeFilePart(sessionId)}-${safeFilePart(replayId)}`\n return join(outputBaseDir(), 'browser-replays', `${name}.mp4`)\n}\n\nfunction annotatedReplayFilePath(sessionId: string, replayId: string, filename?: string): string {\n const requested = filename?.trim()\n if (requested) return replayFilePath(sessionId, replayId, requested)\n const stamp = new Date().toISOString().replace(/[:.]/g, '-')\n return replayFilePath(sessionId, replayId, `${stamp}-${safeFilePart(sessionId)}-${safeFilePart(replayId)}-annotated`)\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction expandElementBounds(\n element: { left: number; top: number; width: number; height: number },\n viewport: { width?: number; height?: number } | undefined,\n padding: number,\n) {\n const sourceWidth = finiteNumber(viewport?.width) && viewport!.width > 0 ? viewport!.width : 1920\n const sourceHeight = finiteNumber(viewport?.height) && viewport!.height > 0 ? viewport!.height : 1080\n const left = Math.max(0, element.left - padding)\n const top = Math.max(0, element.top - padding)\n const right = Math.min(sourceWidth, element.left + element.width + padding)\n const bottom = Math.min(sourceHeight, element.top + element.height + padding)\n return {\n left,\n top,\n width: Math.max(1, right - left),\n height: Math.max(1, bottom - top),\n sourceWidth,\n sourceHeight,\n }\n}\n\nexport function buildBrowserAgentMcpServer(opts: BrowserAgentHttpOptions): McpServer {\n const server = new McpServer({ name: 'browser-agent', version: PACKAGE_VERSION })\n registerBrowserAgentMcpTools(server, opts)\n return server\n}\n\nexport function registerBrowserAgentMcpTools(server: McpServer, opts: BrowserAgentHttpOptions): void {\n const baseUrl = opts.baseUrl.replace(/\\/$/, '')\n const consoleBase = (opts.consoleBaseUrl ?? opts.baseUrl).replace(/\\/$/, '')\n const timeoutMs = opts.timeoutMs ?? 90_000\n const localBrowser = new LocalBrowserAgentService()\n\n async function req(method: string, path: string, body?: Record<string, unknown>): Promise<{ ok: boolean; data: any }> {\n try {\n const res = await fetch(`${baseUrl}${path}`, {\n method,\n headers: { 'Content-Type': 'application/json', 'x-api-key': opts.apiKey },\n body: body ? JSON.stringify(body) : undefined,\n signal: AbortSignal.timeout(timeoutMs),\n })\n const data = await res.json().catch(() => ({}))\n return { ok: res.ok, data }\n } catch (err) {\n return { ok: false, data: { error: err instanceof Error ? err.message : String(err) } }\n }\n }\n\n async function downloadReplay(\n sessionId: string,\n replayId: string,\n filename?: string,\n ): Promise<{ ok: boolean; data: any }> {\n const path = `/agent/sessions/${encodeURIComponent(sessionId)}/replays/${encodeURIComponent(replayId)}/download`\n try {\n const res = await fetch(`${baseUrl}${path}`, {\n method: 'GET',\n headers: { 'x-api-key': opts.apiKey },\n signal: AbortSignal.timeout(timeoutMs),\n })\n if (!res.ok) {\n const data = await res.json().catch(async () => ({ error: await res.text().catch(() => `HTTP ${res.status}`) }))\n return { ok: false, data }\n }\n const bytes = Buffer.from(await res.arrayBuffer())\n const filePath = replayFilePath(sessionId, replayId, filename)\n mkdirSync(join(outputBaseDir(), 'browser-replays'), { recursive: true })\n writeFileSync(filePath, bytes)\n return {\n ok: true,\n data: {\n replay_id: replayId,\n file_path: filePath,\n bytes: bytes.length,\n mime_type: res.headers.get('content-type') ?? 'video/mp4',\n download_url: `${baseUrl}${path}`,\n },\n }\n } catch (err) {\n return { ok: false, data: { error: err instanceof Error ? err.message : String(err) } }\n }\n }\n\n const annotations = (title: string, readOnly = false) => ({\n title,\n readOnlyHint: readOnly,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: true,\n })\n\n function selectChromeProfile(matches: LocalChromeProfile[], email?: string): LocalChromeProfile | null {\n const wanted = email?.trim().toLowerCase()\n if (!wanted) return matches[0] ?? null\n return matches.find(profile => profile.email.toLowerCase() === wanted) ?? matches[0] ?? null\n }\n\n function localReplayUnsupported(tool: string, sessionId: string | null = null, replayId: string | null = null): CallToolResult {\n return errorResult(tool, {\n error: 'Local browser mode does not support replay recording yet. Use hosted mode for browser_replay_* tools.',\n mode: 'local',\n }, sessionId, replayId)\n }\n\n server.registerTool(\n 'browser_profile_list',\n {\n title: 'List Local Chrome Profiles',\n description:\n 'List local Chrome profile metadata visible to this MCP server: account email, Chrome profile directory, local path, and a suggested managed browser profile name. This reads Chrome Local State only; it does not read cookies, passwords, browsing history, or copy local browser state. Use browser_profile_import when the user wants MCP Scraper to clone a local Chrome profile for local browser mode.',\n inputSchema: BrowserProfileListInputSchema,\n outputSchema: BrowserProfileListOutputSchema,\n annotations: annotations('List Local Chrome Profiles', true),\n },\n async input => {\n try {\n const profiles = await listLocalChromeProfiles(input.user_data_dir, input.email)\n return structuredResult({\n ok: true,\n tool: 'browser_profile_list',\n session_id: null,\n profiles,\n count: profiles.length,\n hint: 'Use browser_profile_import to clone one profile for local mode. Use browser_profile_onboard only for hosted Kernel profile setup.',\n })\n } catch (err) {\n return errorResult('browser_profile_list', { error: err instanceof Error ? err.message : String(err) })\n }\n },\n )\n\n server.registerTool(\n 'browser_profile_import',\n {\n title: 'Import Local Chrome Profile',\n description:\n 'Clone one local Chrome profile into MCP Scraper managed storage for local browser mode. This copies browser state files such as cookies, history, local storage, session storage, and password database metadata into ~/.mcp-scraper/browser-profiles by default; it skips cache and lock files and never prints cookie or password values. Use this when the user wants browser_open to run locally with their existing logged-in Chrome state.',\n inputSchema: BrowserProfileImportInputSchema,\n outputSchema: BrowserProfileImportOutputSchema,\n annotations: { title: 'Import Local Chrome Profile', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },\n },\n async input => {\n try {\n const result = await importChromeProfile({\n email: input.email,\n name: input.name,\n chromeProfileDirectory: input.chrome_profile_directory,\n sourceUserDataDir: input.user_data_dir,\n outputDir: input.output_dir,\n overwrite: input.overwrite,\n browserExecutablePath: input.browser_executable_path,\n })\n return structuredResult({\n ok: true,\n tool: 'browser_profile_import',\n session_id: null,\n profile: result.profile,\n source_profile: result.sourceProfile,\n next_steps: [\n `Set MCP_SCRAPER_BROWSER_MODE=local in the MCP server config.`,\n `Set MCP_SCRAPER_BROWSER_PROFILE=${result.profile.name}.`,\n 'Restart the MCP client so it starts the local browser mode process.',\n 'Call browser_open with the same MCP server; it will open a local Chrome window using the cloned profile.',\n ],\n hint: 'The clone is local to this machine. Re-run browser_profile_sync after logging into new sites in normal Chrome.',\n })\n } catch (err) {\n return errorResult('browser_profile_import', { error: err instanceof Error ? err.message : String(err) })\n }\n },\n )\n\n server.registerTool(\n 'browser_profile_sync',\n {\n title: 'Sync Local Chrome Profile',\n description:\n 'Refresh an existing MCP Scraper managed local browser profile from the source Chrome profile recorded in its manifest. This overwrites the managed clone, copies browser state files again, skips cache and lock files, and never prints cookie or password values.',\n inputSchema: BrowserProfileSyncInputSchema,\n outputSchema: BrowserProfileSyncOutputSchema,\n annotations: { title: 'Sync Local Chrome Profile', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },\n },\n async input => {\n try {\n const result = await syncImportedChromeProfile(input.name, {\n outputDir: input.output_dir,\n browserExecutablePath: input.browser_executable_path,\n })\n return structuredResult({\n ok: true,\n tool: 'browser_profile_sync',\n session_id: null,\n profile: result.profile,\n source_profile: result.sourceProfile,\n hint: `Refreshed ${result.profile.name}. Restart local browser sessions that were using this profile.`,\n })\n } catch (err) {\n return errorResult('browser_profile_sync', { error: err instanceof Error ? err.message : String(err) })\n }\n },\n )\n\n server.registerTool(\n 'browser_profile_onboard',\n {\n title: 'Onboard Hosted Browser Profile',\n description:\n 'Create or load a saved hosted Kernel browser profile and open a live setup browser with profile saving enabled. Use this only for hosted browser mode. If email is provided, the tool reads local Chrome profile metadata only to suggest the Kernel profile name; it does not import local cookies. For local browser mode with real Chrome state, use browser_profile_import instead.',\n inputSchema: BrowserProfileOnboardInputSchema,\n outputSchema: BrowserProfileOnboardOutputSchema,\n annotations: annotations('Onboard Hosted Browser Profile'),\n },\n async input => {\n let chromeProfile: LocalChromeProfile | null = null\n if (input.email) {\n try {\n chromeProfile = selectChromeProfile(await listLocalChromeProfiles(input.user_data_dir, input.email), input.email)\n } catch (err) {\n return errorResult('browser_profile_onboard', { error: err instanceof Error ? err.message : String(err) })\n }\n }\n const profile = input.profile?.trim() || chromeProfile?.recommendedKernelProfileName || browserServiceProfileName()\n if (!profile) {\n return errorResult('browser_profile_onboard', {\n error: 'profile is required when no email match or BROWSER_AGENT_PROFILE_NAME is available',\n })\n }\n const setupUrl = input.url ?? 'https://accounts.google.com/'\n const open = await req('POST', '/agent/sessions', {\n label: input.label ?? `Profile setup: ${profile}`,\n profile,\n save_profile_changes: true,\n timeout_seconds: input.timeout_seconds,\n })\n if (!open.ok) return errorResult('browser_profile_onboard', open.data)\n const session = open.data\n const goto = await req('POST', `/agent/sessions/${session.session_id}/goto`, { url: setupUrl })\n if (!goto.ok) return errorResult('browser_profile_onboard', goto.data, session.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_profile_onboard',\n session_id: session.session_id,\n watch_url: `${consoleBase}/console/${session.session_id}`,\n live_view_url: session.live_view_url ?? null,\n profile,\n setup_url: setupUrl,\n chrome_profile: chromeProfile,\n next_steps: [\n 'Open the watch_url and complete the login manually.',\n 'After login is complete, call browser_close with this session_id to persist cookies and local storage to the Kernel profile.',\n 'Use BROWSER_AGENT_PROFILE_NAME or browser_open.profile with this profile name for future authenticated sessions.',\n ],\n raw: session,\n })\n },\n )\n\n server.registerTool(\n 'browser_open',\n {\n title: 'Open Browser Session',\n description:\n 'Open a browser you can drive. By default this creates a hosted cloud browser with a watch_url; when MCP_SCRAPER_BROWSER_MODE=local it opens a local Google Chrome window against an imported MCP Scraper Chrome profile. Returns a session_id used by all other browser_* tools. In hosted mode, anti-bot stealth and automatic CAPTCHA/Cloudflare solving are on by default. Call browser_close when done.',\n inputSchema: BrowserOpenInputSchema,\n outputSchema: BrowserOpenOutputSchema,\n annotations: annotations('Open Browser Session'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const session = await localBrowser.open(input)\n return structuredResult({\n ok: true,\n tool: 'browser_open',\n session_id: session.session_id,\n watch_url: session.watch_url,\n live_view_url: null,\n url: input.url ?? null,\n hint: 'Local Chrome is open on this machine. Call browser_screenshot to see the page and click by x,y coordinates.',\n raw: session,\n })\n } catch (err) {\n return errorResult('browser_open', { error: err instanceof Error ? err.message : String(err), mode: 'local' })\n }\n }\n const profile = input.profile ?? browserServiceProfileName()\n const saveProfileChanges = input.save_profile_changes ?? browserServiceProfileSaveChanges()\n const open = await req('POST', '/agent/sessions', {\n label: input.label,\n ...(profile ? { profile } : {}),\n ...(profile && typeof saveProfileChanges === 'boolean' ? { save_profile_changes: saveProfileChanges } : {}),\n timeout_seconds: input.timeout_seconds,\n })\n if (!open.ok) return errorResult('browser_open', open.data)\n const session = open.data\n if (input.url) {\n await req('POST', `/agent/sessions/${session.session_id}/goto`, { url: input.url })\n }\n return structuredResult({\n ok: true,\n tool: 'browser_open',\n session_id: session.session_id,\n watch_url: `${consoleBase}/console/${session.session_id}`,\n live_view_url: session.live_view_url ?? null,\n url: input.url ?? null,\n hint: 'Call browser_screenshot to see the page. Click by the x,y of an element from the snapshot.',\n raw: session,\n })\n },\n )\n\n server.registerTool(\n 'browser_screenshot',\n {\n title: 'See Page (Screenshot + Elements)',\n description:\n 'Capture what the browser currently shows. Returns a screenshot image PLUS a text snapshot listing interactive elements with their center x,y coordinates, the page url and title, and visible text. This is your primary way to perceive the page. Click elements by their listed x,y. If a Cloudflare/CAPTCHA challenge is visible, wait and screenshot again rather than clicking it.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserScreenshotOutputSchema,\n annotations: annotations('See Page', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.screenshot(input.session_id)\n const content: CallToolResult['content'] = []\n if (res.image_base64) content.push({ type: 'image', data: res.image_base64, mimeType: res.mime_type })\n const structured = {\n ok: true,\n tool: 'browser_screenshot',\n session_id: input.session_id,\n url: res.url ?? null,\n title: res.title ?? null,\n text: res.text,\n elements: res.elements,\n screenshot: { mime_type: res.mime_type, inline: true },\n }\n content.push({ type: 'text', text: JSON.stringify(structured) })\n return { content, structuredContent: structured }\n } catch (err) {\n return errorResult('browser_screenshot', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/screenshot`)\n if (!res.ok) return errorResult('browser_screenshot', res.data, input.session_id)\n const { image_base64, mime_type, url, title, elements, text } = res.data\n const content: CallToolResult['content'] = []\n if (image_base64) content.push({ type: 'image', data: image_base64, mimeType: mime_type ?? 'image/png' })\n const structured = {\n ok: true,\n tool: 'browser_screenshot',\n session_id: input.session_id,\n url: url ?? null,\n title: title ?? null,\n text: typeof text === 'string' ? text : '',\n elements: Array.isArray(elements) ? elements : [],\n screenshot: image_base64 ? { mime_type: mime_type ?? 'image/png', inline: true } : null,\n }\n content.push({\n type: 'text',\n text: JSON.stringify(structured),\n })\n return { content, structuredContent: structured }\n },\n )\n\n server.registerTool(\n 'browser_read',\n {\n title: 'Read Page Text + Elements',\n description:\n 'Return the page url, title, visible text, and the list of interactive elements (with x,y) without an image. Cheaper than browser_screenshot when you only need to read content or find a target element to click.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserReadOutputSchema,\n annotations: annotations('Read Page', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.read(input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_read',\n session_id: input.session_id,\n url: res.url ?? null,\n title: res.title ?? null,\n text: res.text,\n elements: res.elements,\n raw: res,\n })\n } catch (err) {\n return errorResult('browser_read', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/read`)\n if (!res.ok) return errorResult('browser_read', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_read',\n session_id: input.session_id,\n url: res.data?.url ?? null,\n title: res.data?.title ?? null,\n text: typeof res.data?.text === 'string' ? res.data.text : '',\n elements: Array.isArray(res.data?.elements) ? res.data.elements : [],\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_locate',\n {\n title: 'Locate DOM Targets',\n description:\n 'Locate exact visible DOM elements or text ranges in the current browser viewport and return left/top/width/height bounds in screenshot pixels. Use this before drawing annotations or when a callout must literally circle, box, underline, or point to a real element. Prefer CSS selectors for exact UI elements; use text when selector is unknown. When a replay is actively recording, the result includes replay_elapsed_seconds for timing.',\n inputSchema: BrowserLocateInputSchema,\n outputSchema: BrowserLocateOutputSchema,\n annotations: annotations('Locate DOM Targets', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.locate(input.session_id, input.targets)\n return structuredResult({\n ok: true,\n tool: 'browser_locate',\n session_id: input.session_id,\n url: res.url ?? null,\n title: res.title ?? null,\n viewport: res.viewport ?? null,\n replay: null,\n targets: Array.isArray(res.targets) ? res.targets : [],\n raw: res,\n })\n } catch (err) {\n return errorResult('browser_locate', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/locate`, { targets: input.targets })\n if (!res.ok) return errorResult('browser_locate', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_locate',\n session_id: input.session_id,\n url: res.data?.url ?? null,\n title: res.data?.title ?? null,\n viewport: res.data?.viewport ?? null,\n replay: res.data?.replay ?? null,\n targets: Array.isArray(res.data?.targets) ? res.data.targets : [],\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_goto',\n {\n title: 'Navigate To URL',\n description: 'Navigate an existing browser session to a URL when the user asks you to go to another page or continue browsing in the same session. Use browser_open first if no session exists. Follow with browser_screenshot to see redirects, login walls, CAPTCHA/Cloudflare state, or the loaded page.',\n inputSchema: BrowserGotoInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Navigate To URL'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.goto(input.session_id, input.url)\n return actionResult('browser_goto', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_goto', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/goto`, { url: input.url })\n return actionResult('browser_goto', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_click',\n {\n title: 'Click',\n description: 'Click a visible page target using screenshot pixel coordinates. Use this when the user asks you to press a button, open a menu, choose a result, or activate a visible UI element. Use x/y only from the latest browser_screenshot, browser_read, or browser_locate result; do not guess coordinates. Follow with browser_screenshot when the click may change the page.',\n inputSchema: BrowserClickInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Click'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.click(input.session_id, input)\n return actionResult('browser_click', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_click', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/click`, {\n x: input.x,\n y: input.y,\n button: input.button,\n num_clicks: input.num_clicks,\n })\n return actionResult('browser_click', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_type',\n {\n title: 'Type Text',\n description: 'Type text into the currently focused browser field. Use this when the user asks you to fill a search box, form field, login field, or editable text area. Click or Tab to the field first if focus is uncertain. Use browser_press with [\"Return\"] to submit, and browser_screenshot afterward when page state matters.',\n inputSchema: BrowserTypeInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Type Text'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.type(input.session_id, input)\n return actionResult('browser_type', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_type', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/type`, { text: input.text, delay: input.delay })\n return actionResult('browser_type', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_scroll',\n {\n title: 'Scroll',\n description: 'Scroll the page to reveal more content before reading, clicking, or locating elements. Positive delta_y scrolls down; negative delta_y scrolls up. Follow with browser_screenshot or browser_read to inspect newly revealed content.',\n inputSchema: BrowserScrollInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Scroll'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.scroll(input.session_id, input)\n return actionResult('browser_scroll', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_scroll', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/scroll`, {\n delta_y: input.delta_y,\n delta_x: input.delta_x,\n x: input.x,\n y: input.y,\n })\n return actionResult('browser_scroll', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_press',\n {\n title: 'Press Keys',\n description: 'Press keyboard keys or combinations in the active browser session. Use this for submit, Escape, Tab navigation, select-all, or keyboard shortcuts. Examples: [\"Return\"], [\"Escape\"], [\"Tab\"], [\"Ctrl+a\"], [\"Ctrl+Shift+Tab\"]. Use browser_type for text entry and browser_screenshot after keypresses that may change the page.',\n inputSchema: BrowserPressInputSchema,\n outputSchema: BrowserActionOutputSchema,\n annotations: annotations('Press Keys'),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.press(input.session_id, input)\n return actionResult('browser_press', input.session_id, true, res, 'browser_screenshot')\n } catch (err) {\n return errorResult('browser_press', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/press`, { keys: input.keys })\n return actionResult('browser_press', input.session_id, res.ok, res.data, 'browser_screenshot')\n },\n )\n\n server.registerTool(\n 'browser_replay_start',\n {\n title: 'Start Recording',\n description: 'Start recording an MP4 replay of the session. Returns replay_id, view_url when available, and a download_url. Use to capture a task for later review; stop with browser_replay_stop.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserReplayStartOutputSchema,\n annotations: annotations('Start Recording'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_start', input.session_id)\n const res = await req('POST', `/agent/sessions/${input.session_id}/replay/start`)\n if (!res.ok) return errorResult('browser_replay_start', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_replay_start',\n session_id: input.session_id,\n replay_id: res.data?.replay_id ?? res.data?.replayId ?? null,\n view_url: res.data?.view_url ?? res.data?.viewUrl ?? null,\n download_url: res.data?.download_url ?? res.data?.downloadUrl ?? null,\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_stop',\n {\n title: 'Stop Recording',\n description: 'Stop a replay recording and expose the final view_url and download_url. Use browser_replay_download to save the MP4 locally.',\n inputSchema: BrowserReplayStopInputSchema,\n outputSchema: BrowserReplayStopOutputSchema,\n annotations: annotations('Stop Recording'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_stop', input.session_id, input.replay_id)\n const res = await req('POST', `/agent/sessions/${input.session_id}/replay/stop`, { replay_id: input.replay_id })\n if (!res.ok) return errorResult('browser_replay_stop', res.data, input.session_id, input.replay_id)\n return structuredResult({\n ok: true,\n tool: 'browser_replay_stop',\n session_id: input.session_id,\n replay_id: res.data?.replay_id ?? res.data?.replayId ?? input.replay_id,\n view_url: res.data?.view_url ?? res.data?.viewUrl ?? null,\n download_url: res.data?.download_url ?? res.data?.downloadUrl ?? null,\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_list_replays',\n {\n title: 'List Replay Videos',\n description: 'List replay recordings for a browser session, including final view_url and authenticated download_url values when available.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserListReplaysOutputSchema,\n annotations: annotations('List Replay Videos', true),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_list_replays', input.session_id)\n const res = await req('GET', `/agent/sessions/${input.session_id}/replays`)\n if (!res.ok) return errorResult('browser_list_replays', res.data, input.session_id)\n const replays = Array.isArray(res.data?.replays) ? res.data.replays : []\n return structuredResult({\n ok: true,\n tool: 'browser_list_replays',\n session_id: input.session_id,\n replays,\n count: replays.length,\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_download',\n {\n title: 'Download Replay MP4',\n description: 'Download a replay recording through MCP Scraper and save the MP4 locally under MCP_SCRAPER_OUTPUT_DIR/browser-replays. Use after browser_replay_stop or browser_list_replays.',\n inputSchema: BrowserReplayDownloadInputSchema,\n outputSchema: BrowserReplayDownloadOutputSchema,\n annotations: annotations('Download Replay MP4'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_download', input.session_id, input.replay_id)\n const res = await downloadReplay(input.session_id, input.replay_id, input.filename)\n if (!res.ok) return errorResult('browser_replay_download', res.data, input.session_id, input.replay_id)\n return structuredResult({\n ok: true,\n tool: 'browser_replay_download',\n session_id: input.session_id,\n replay_id: input.replay_id,\n file_path: res.data?.file_path ?? null,\n bytes: typeof res.data?.bytes === 'number' ? res.data.bytes : null,\n mime_type: res.data?.mime_type ?? null,\n download_url: res.data?.download_url ?? null,\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_mark',\n {\n title: 'Mark Replay Annotation',\n description:\n 'While a replay is actively recording, locate one exact DOM target and return a ready-to-use annotation object with DOM bounds and replay-relative timing. Use this instead of guessing start_seconds or drawing rough rectangles. Workflow: start browser_replay_start, navigate until the target is visible and stable, call browser_replay_mark for each callout, then stop the replay and pass the returned annotations to browser_replay_annotate.',\n inputSchema: BrowserReplayMarkInputSchema,\n outputSchema: BrowserReplayMarkOutputSchema,\n annotations: annotations('Mark Replay Annotation', true),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_mark', input.session_id)\n const res = await req('POST', `/agent/sessions/${input.session_id}/locate`, { targets: [input.target] })\n if (!res.ok) return errorResult('browser_replay_mark', res.data, input.session_id)\n const target = res.data?.targets?.[0]\n const element = target?.element\n const elapsed = res.data?.replay?.replay_elapsed_seconds\n if (!target?.found || !element) {\n return errorResult('browser_replay_mark', { error: target?.error ?? 'target not found in current viewport', target }, input.session_id)\n }\n if (!finiteNumber(elapsed)) {\n return errorResult('browser_replay_mark', { error: 'no active replay clock found; call browser_replay_start before browser_replay_mark' }, input.session_id)\n }\n const padded = expandElementBounds(element, res.data?.viewport, input.padding ?? 8)\n const start = Math.max(0, elapsed + (input.start_offset_seconds ?? -0.25))\n const duration = input.duration_seconds ?? 4\n const annotation = {\n type: input.type ?? 'box',\n start_seconds: Number(start.toFixed(3)),\n end_seconds: Number((start + duration).toFixed(3)),\n left: Math.round(padded.left),\n top: Math.round(padded.top),\n width: Math.round(padded.width),\n height: Math.round(padded.height),\n ...(input.label ? { label: input.label } : {}),\n ...(input.color ? { color: input.color } : {}),\n ...(input.thickness ? { thickness: input.thickness } : {}),\n }\n return structuredResult({\n ok: true,\n tool: 'browser_replay_mark',\n session_id: input.session_id,\n replay_id: res.data?.replay?.replay_id ?? res.data?.replay?.replayId ?? null,\n annotation,\n source_width: padded.sourceWidth,\n source_height: padded.sourceHeight,\n replay: res.data.replay,\n target,\n hint: 'Append annotation to your annotations array. Use source_width/source_height with browser_replay_annotate.',\n })\n },\n )\n\n server.registerTool(\n 'browser_replay_annotate',\n {\n title: 'Annotate Replay MP4',\n description:\n 'Download a browser replay MP4, render visual annotations over it, and save a new annotated MP4 locally. Use this after browser_replay_stop when the user wants proof videos with circles, boxes, arrows, underlines, or labels. For accurate timing and placement, prefer annotations returned by browser_replay_mark while the replay is recording; otherwise use exact left/top/width/height bounds from browser_locate. If the replay video size differs from the screenshot coordinate space, pass source_width and source_height.',\n inputSchema: BrowserReplayAnnotateInputSchema,\n outputSchema: BrowserReplayAnnotateOutputSchema,\n annotations: annotations('Annotate Replay MP4'),\n },\n async input => {\n if (localBrowserModeEnabled()) return localReplayUnsupported('browser_replay_annotate', input.session_id, input.replay_id)\n const sourceName = input.filename ? `${input.filename}-source` : undefined\n const downloaded = await downloadReplay(input.session_id, input.replay_id, sourceName)\n if (!downloaded.ok) return errorResult('browser_replay_annotate', downloaded.data, input.session_id, input.replay_id)\n try {\n const sourcePath = String(downloaded.data.file_path)\n const outputPath = annotatedReplayFilePath(input.session_id, input.replay_id, input.filename)\n mkdirSync(join(outputBaseDir(), 'browser-replays'), { recursive: true })\n const result = await annotateReplayVideo(sourcePath, outputPath, {\n annotations: input.annotations,\n sourceWidth: input.source_width,\n sourceHeight: input.source_height,\n sourceLeftOffset: input.source_left_offset,\n sourceTopOffset: input.source_top_offset,\n })\n return structuredResult({\n ok: true,\n tool: 'browser_replay_annotate',\n session_id: input.session_id,\n replay_id: input.replay_id,\n source_file_path: sourcePath,\n annotated_file_path: result.filePath,\n bytes: result.bytes,\n width: result.width,\n height: result.height,\n annotation_count: result.annotationCount,\n mime_type: 'video/mp4',\n })\n } catch (err) {\n return errorResult('browser_replay_annotate', { error: err instanceof Error ? err.message : String(err) }, input.session_id, input.replay_id)\n }\n },\n )\n\n server.registerTool(\n 'browser_close',\n {\n title: 'Close Browser Session',\n description: 'Close and release a browser session when the task is done, when the user asks to stop the browser, or when active browser billing should end. Use browser_list_sessions first if you need to recover the session_id.',\n inputSchema: BrowserSessionInputSchema,\n outputSchema: BrowserCloseOutputSchema,\n annotations: { title: 'Close Browser Session', readOnlyHint: false, destructiveHint: true, idempotentHint: true, openWorldHint: false },\n },\n async input => {\n if (localBrowserModeEnabled()) {\n try {\n const res = await localBrowser.close(input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_close',\n session_id: input.session_id,\n closed: true,\n raw: res,\n })\n } catch (err) {\n return errorResult('browser_close', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('DELETE', `/agent/sessions/${input.session_id}`)\n if (!res.ok) return errorResult('browser_close', res.data, input.session_id)\n return structuredResult({\n ok: true,\n tool: 'browser_close',\n session_id: input.session_id,\n closed: true,\n raw: res.data,\n })\n },\n )\n\n server.registerTool(\n 'browser_list_sessions',\n {\n title: 'List Browser Sessions',\n description: 'List browser sessions and their status, with a watch_url for each. Use this to recover a session_id, find an active browser, or decide which session to close. Use browser_open to create a new session.',\n inputSchema: BrowserListInputSchema,\n outputSchema: BrowserListSessionsOutputSchema,\n annotations: annotations('List Browser Sessions', true),\n },\n async input => {\n if (localBrowserModeEnabled()) {\n const sessions = localBrowser.list(input.include_closed)\n return structuredResult({\n ok: true,\n tool: 'browser_list_sessions',\n session_id: null,\n sessions,\n count: sessions.length,\n })\n }\n const res = await req('GET', `/agent/sessions${input.include_closed ? '?all=1' : ''}`)\n if (!res.ok) return errorResult('browser_list_sessions', res.data)\n const sessions = (res.data.sessions ?? []).map((s: any) => ({ ...s, watch_url: `${consoleBase}/console/${s.session_id}` }))\n return structuredResult({\n ok: true,\n tool: 'browser_list_sessions',\n session_id: null,\n sessions,\n count: sessions.length,\n })\n },\n )\n\n server.registerTool(\n 'browser_capture_fanout',\n {\n title: 'Capture AI Search Fan-Out',\n description:\n 'Capture the query fan-out behind a ChatGPT or Claude web-search answer for Answer Engine Optimization (AEO): the exact sub-queries the model issued, every researched URL split into cited vs browsed-only (with citation frequency and snippet), each source tagged by category (First-party/vendor, News/media, Reddit, Social/video, Encyclopedia, Review site, Docs, Blog), plus top sourced sites and citation order. This returns the raw structured data; YOU analyze it — classify each sub-query by funnel stage (Problem-aware, Solution-aware, Decision-aware, Retention) and type (BoFu, Branded, Comparison, How-to, Search operator), name the brands the model researched, and give AEO insights. Sample asks: \"capture the fan-out for this ChatGPT answer\", \"what did Claude search and cite for best CRM\", \"show the sub-queries and sources behind this AI answer\". WRITE NOTE: passing prompt submits a real message in the user\\'s logged-in account (a new conversation turn) — only send when the user wants that; omit prompt to capture a prompt the user just ran. Setup, if not already done: import a logged-in session with browser_profile_import (local Chrome) or browser_profile_onboard (hosted Kernel), then browser_open and browser_goto to chatgpt.com or claude.ai. Fan-out is captured only as it streams, so the session must be open when the prompt runs. NOT for Google AI Overview citations — use harvest_paa for those; this tool is ChatGPT and Claude only.',\n inputSchema: BrowserCaptureFanoutInputSchema,\n outputSchema: BrowserCaptureFanoutOutputSchema,\n annotations: annotations('Capture AI Search Fan-Out'),\n },\n async input => {\n const emit = (result: Record<string, unknown>, exports: unknown) => structuredResult({\n ok: true,\n tool: 'browser_capture_fanout',\n session_id: input.session_id,\n platform: result.platform,\n captured_at: result.capturedAt,\n prompt: result.prompt,\n meta: result.meta,\n queries: result.queries,\n browsed_urls: result.browsedUrls,\n cited_urls: result.citedUrls,\n browsed_only: result.browsedOnly,\n snippets: result.snippets,\n counts: result.counts,\n aggregates: result.aggregates,\n first_party_domain: result.firstPartyDomain,\n exports: exports ?? null,\n ...(result.debug ? { debug: result.debug } : {}),\n })\n if (localBrowserModeEnabled()) {\n try {\n const { result, exports } = await localBrowser.captureFanout(input.session_id, input)\n return emit(result as unknown as Record<string, unknown>, exports)\n } catch (err) {\n return errorResult('browser_capture_fanout', { error: err instanceof Error ? err.message : String(err), mode: 'local' }, input.session_id)\n }\n }\n const res = await req('POST', `/agent/sessions/${input.session_id}/capture-fanout`, {\n prompt: input.prompt,\n wait_ms: input.wait_ms,\n first_party_domain: input.first_party_domain,\n export: false,\n })\n if (!res.ok) return errorResult('browser_capture_fanout', res.data, input.session_id)\n const hosted = (res.data?.result ?? res.data) as Record<string, unknown>\n return emit(hosted, res.data?.exports ?? null)\n },\n )\n\n}\n","import { readFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport interface LocalChromeProfile {\n email: string\n displayName: string\n chromeProfileDirectory: string\n chromeProfilePath: string\n recommendedKernelProfileName: string\n}\n\nexport function defaultChromeUserDataDir(): string {\n if (process.platform === 'darwin') return join(homedir(), 'Library', 'Application Support', 'Google', 'Chrome')\n if (process.platform === 'win32') {\n return join(process.env.LOCALAPPDATA ?? join(homedir(), 'AppData', 'Local'), 'Google', 'Chrome', 'User Data')\n }\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), '.config'), 'google-chrome')\n}\n\nexport function recommendedKernelProfileName(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/@/g, '-')\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 80) || 'browser-profile'\n}\n\nexport async function listLocalChromeProfiles(\n userDataDir = defaultChromeUserDataDir(),\n emailFilter?: string,\n): Promise<LocalChromeProfile[]> {\n const raw = await readFile(join(userDataDir, 'Local State'), 'utf8')\n const localState = JSON.parse(raw) as {\n profile?: {\n info_cache?: Record<string, {\n name?: string\n shortcut_name?: string\n user_name?: string\n gaia_name?: string\n }>\n }\n }\n const wanted = emailFilter?.trim().toLowerCase()\n return Object.entries(localState.profile?.info_cache ?? {})\n .map(([directory, info]) => {\n const email = (info.user_name ?? '').trim()\n const displayName = (info.name ?? info.shortcut_name ?? '').trim()\n const labelSource = email || displayName || directory\n return {\n email,\n displayName,\n chromeProfileDirectory: directory,\n chromeProfilePath: join(userDataDir, directory),\n recommendedKernelProfileName: recommendedKernelProfileName(labelSource),\n }\n })\n .filter(row => !wanted || row.email.toLowerCase() === wanted || row.displayName.toLowerCase().includes(wanted))\n}\n","export function browserServiceApiKey(): string | undefined {\n const value = (process.env.BROWSER_SERVICE_API_KEY ?? process.env.KERNEL_API_KEY)?.trim()\n return value || undefined\n}\n\nexport function browserServiceProxyId(): string | undefined {\n const value = (process.env.BROWSER_SERVICE_PROXY_ID ?? process.env.KERNEL_PROXY_ID)?.trim()\n return value || undefined\n}\n\nexport function browserServiceProfileName(): string | undefined {\n const value = (\n process.env.BROWSER_AGENT_PROFILE_NAME ??\n process.env.BROWSER_SERVICE_PROFILE_NAME ??\n process.env.KERNEL_BROWSER_PROFILE_NAME ??\n process.env.KERNEL_PROFILE_NAME\n )?.trim()\n return value || undefined\n}\n\nexport function browserServiceProfileSaveChanges(): boolean | undefined {\n const value = (\n process.env.BROWSER_AGENT_PROFILE_SAVE_CHANGES ??\n process.env.BROWSER_SERVICE_PROFILE_SAVE_CHANGES ??\n process.env.KERNEL_BROWSER_PROFILE_SAVE_CHANGES ??\n process.env.KERNEL_PROFILE_SAVE_CHANGES\n )?.trim().toLowerCase()\n if (!value) return undefined\n if (['1', 'true', 'yes', 'on'].includes(value)) return true\n if (['0', 'false', 'no', 'off'].includes(value)) return false\n return undefined\n}\n","import { existsSync } from 'node:fs'\nimport { cp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join, relative, sep } from 'node:path'\nimport {\n defaultChromeUserDataDir,\n listLocalChromeProfiles,\n recommendedKernelProfileName,\n type LocalChromeProfile,\n} from './chrome-profiles.js'\n\nexport interface ImportedBrowserProfileManifest {\n layoutVersion: 1\n name: string\n profileRoot: string\n userDataDir: string\n browserExecutablePath: string | null\n sourceUserDataDir: string\n sourceProfileDirectory: string\n sourceProfilePath: string\n email: string\n displayName: string\n createdAt: string\n updatedAt: string\n copyMode: 'chrome-profile-clone'\n}\n\nexport interface ImportChromeProfileOptions {\n email?: string\n name?: string\n chromeProfileDirectory?: string\n sourceUserDataDir?: string\n outputDir?: string\n overwrite?: boolean\n browserExecutablePath?: string\n}\n\nexport interface ImportChromeProfileResult {\n profile: ImportedBrowserProfileManifest\n sourceProfile: LocalChromeProfile\n excludedNames: string[]\n}\n\nconst EXCLUDED_PROFILE_NAMES = [\n 'Cache',\n 'Code Cache',\n 'Crashpad',\n 'DawnCache',\n 'DawnGraphiteCache',\n 'DawnWebGPUCache',\n 'GPUCache',\n 'GrShaderCache',\n 'ShaderCache',\n 'Shared Dictionary',\n]\n\nexport function defaultImportedBrowserProfilesDir(): string {\n return process.env.MCP_SCRAPER_BROWSER_PROFILE_BASE_DIR?.trim()\n || join(homedir(), '.mcp-scraper', 'browser-profiles')\n}\n\nexport function defaultChromeExecutablePath(): string | undefined {\n const envPath = process.env.MCP_SCRAPER_BROWSER_EXECUTABLE?.trim() || process.env.CHROME_PATH?.trim()\n if (envPath) return envPath\n\n const candidates = process.platform === 'darwin'\n ? ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome']\n : process.platform === 'win32'\n ? [\n join(process.env.PROGRAMFILES ?? 'C:\\\\Program Files', 'Google', 'Chrome', 'Application', 'chrome.exe'),\n join(process.env['PROGRAMFILES(X86)'] ?? 'C:\\\\Program Files (x86)', 'Google', 'Chrome', 'Application', 'chrome.exe'),\n ]\n : ['/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium-browser', '/usr/bin/chromium']\n\n return candidates.find(candidate => existsSync(candidate))\n}\n\nexport function localBrowserModeEnabled(): boolean {\n return process.env.MCP_SCRAPER_BROWSER_MODE?.trim().toLowerCase() === 'local'\n}\n\nexport function importedProfileName(value: string): string {\n return recommendedKernelProfileName(value)\n}\n\nexport function importedProfileRoot(name: string, outputDir = defaultImportedBrowserProfilesDir()): string {\n return join(outputDir, importedProfileName(name))\n}\n\nexport function importedProfileManifestPath(name: string, outputDir = defaultImportedBrowserProfilesDir()): string {\n return join(importedProfileRoot(name, outputDir), 'manifest.json')\n}\n\nexport function importedProfileUserDataDir(name: string, outputDir = defaultImportedBrowserProfilesDir()): string {\n return join(importedProfileRoot(name, outputDir), 'user-data')\n}\n\nasync function readExistingManifest(path: string): Promise<ImportedBrowserProfileManifest | null> {\n try {\n return JSON.parse(await readFile(path, 'utf8')) as ImportedBrowserProfileManifest\n } catch {\n return null\n }\n}\n\nfunction isExcludedProfilePath(sourceRoot: string, sourcePath: string): boolean {\n const rel = relative(sourceRoot, sourcePath)\n if (!rel) return false\n const parts = rel.split(sep).filter(Boolean)\n const last = parts[parts.length - 1] ?? ''\n if (last.startsWith('Singleton')) return true\n if (last === 'LOCK' || last.endsWith('.lock')) return true\n if (parts.some(part => EXCLUDED_PROFILE_NAMES.includes(part))) return true\n if (parts.includes('Service Worker') && parts.includes('CacheStorage')) return true\n return false\n}\n\nasync function copyProfileTree(sourceProfilePath: string, destinationProfilePath: string): Promise<void> {\n await cp(sourceProfilePath, destinationProfilePath, {\n recursive: true,\n force: true,\n errorOnExist: false,\n dereference: false,\n filter: source => !isExcludedProfilePath(sourceProfilePath, source),\n })\n}\n\nfunction selectProfile(profiles: LocalChromeProfile[], options: ImportChromeProfileOptions): LocalChromeProfile {\n const requestedDirectory = options.chromeProfileDirectory?.trim()\n const requestedEmail = options.email?.trim().toLowerCase()\n const exactDirectory = requestedDirectory\n ? profiles.find(profile => profile.chromeProfileDirectory === requestedDirectory)\n : undefined\n if (exactDirectory) return exactDirectory\n\n const exactEmail = requestedEmail\n ? profiles.find(profile => profile.email.toLowerCase() === requestedEmail)\n : undefined\n if (exactEmail) return exactEmail\n\n const first = profiles[0]\n if (first) return first\n\n const hint = requestedDirectory\n ? `Chrome profile directory \"${requestedDirectory}\"`\n : requestedEmail\n ? `Chrome account \"${requestedEmail}\"`\n : 'Chrome profile'\n throw new Error(`${hint} was not found in ${options.sourceUserDataDir ?? defaultChromeUserDataDir()}`)\n}\n\nasync function ensureProfilePathExists(profile: LocalChromeProfile): Promise<void> {\n const details = await stat(profile.chromeProfilePath).catch(() => null)\n if (!details?.isDirectory()) {\n throw new Error(`Chrome profile path does not exist or is not a directory: ${profile.chromeProfilePath}`)\n }\n}\n\nasync function writeNormalizedLocalState(\n sourceLocalStatePath: string,\n destinationLocalStatePath: string,\n sourceProfileDirectory: string,\n): Promise<void> {\n const raw = await readFile(sourceLocalStatePath, 'utf8')\n const localState = JSON.parse(raw) as {\n profile?: {\n info_cache?: Record<string, unknown>\n last_used?: string\n last_active_profiles?: string[]\n }\n }\n const selectedInfo = localState.profile?.info_cache?.[sourceProfileDirectory]\n ?? localState.profile?.info_cache?.Default\n ?? {}\n localState.profile = {\n ...(localState.profile ?? {}),\n info_cache: { Default: selectedInfo },\n last_used: 'Default',\n last_active_profiles: ['Default'],\n }\n await writeFile(destinationLocalStatePath, `${JSON.stringify(localState, null, 2)}\\n`)\n}\n\nexport async function importChromeProfile(options: ImportChromeProfileOptions = {}): Promise<ImportChromeProfileResult> {\n const sourceUserDataDir = options.sourceUserDataDir?.trim() || defaultChromeUserDataDir()\n const profiles = await listLocalChromeProfiles(sourceUserDataDir, options.email)\n const sourceProfile = selectProfile(profiles, { ...options, sourceUserDataDir })\n await ensureProfilePathExists(sourceProfile)\n\n const name = importedProfileName(options.name?.trim() || sourceProfile.recommendedKernelProfileName)\n const outputDir = options.outputDir?.trim() || defaultImportedBrowserProfilesDir()\n const profileRoot = importedProfileRoot(name, outputDir)\n const manifestPath = importedProfileManifestPath(name, outputDir)\n const userDataDir = importedProfileUserDataDir(name, outputDir)\n const existingManifest = await readExistingManifest(manifestPath)\n const existing = existsSync(profileRoot)\n\n if (existing && !options.overwrite) {\n throw new Error(`Imported browser profile \"${name}\" already exists at ${profileRoot}. Re-run with --overwrite to refresh it.`)\n }\n\n if (existing) await rm(profileRoot, { recursive: true, force: true })\n await mkdir(join(userDataDir, 'Default'), { recursive: true })\n await writeNormalizedLocalState(\n join(sourceUserDataDir, 'Local State'),\n join(userDataDir, 'Local State'),\n sourceProfile.chromeProfileDirectory,\n )\n await copyProfileTree(sourceProfile.chromeProfilePath, join(userDataDir, 'Default'))\n\n const now = new Date().toISOString()\n const manifest: ImportedBrowserProfileManifest = {\n layoutVersion: 1,\n name,\n profileRoot,\n userDataDir,\n browserExecutablePath: options.browserExecutablePath?.trim() || defaultChromeExecutablePath() || null,\n sourceUserDataDir,\n sourceProfileDirectory: sourceProfile.chromeProfileDirectory,\n sourceProfilePath: sourceProfile.chromeProfilePath,\n email: sourceProfile.email,\n displayName: sourceProfile.displayName,\n createdAt: existingManifest?.createdAt ?? now,\n updatedAt: now,\n copyMode: 'chrome-profile-clone',\n }\n await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\\n`)\n\n return {\n profile: manifest,\n sourceProfile,\n excludedNames: EXCLUDED_PROFILE_NAMES,\n }\n}\n\nexport async function loadImportedBrowserProfile(\n name = process.env.MCP_SCRAPER_BROWSER_PROFILE?.trim() || 'default',\n outputDir = defaultImportedBrowserProfilesDir(),\n): Promise<ImportedBrowserProfileManifest> {\n const profileName = importedProfileName(name)\n const manifestPath = importedProfileManifestPath(profileName, outputDir)\n const manifest = await readExistingManifest(manifestPath)\n if (!manifest) {\n throw new Error(\n `Imported browser profile \"${profileName}\" was not found. Run: mcp-scraper-cli browser import-chrome --name ${profileName}`,\n )\n }\n return manifest\n}\n\nexport async function syncImportedChromeProfile(\n name: string,\n options: Pick<ImportChromeProfileOptions, 'outputDir' | 'browserExecutablePath'> = {},\n): Promise<ImportChromeProfileResult> {\n const outputDir = options.outputDir?.trim() || defaultImportedBrowserProfilesDir()\n const manifest = await loadImportedBrowserProfile(name, outputDir)\n return importChromeProfile({\n name: manifest.name,\n sourceUserDataDir: manifest.sourceUserDataDir,\n chromeProfileDirectory: manifest.sourceProfileDirectory,\n outputDir,\n overwrite: true,\n browserExecutablePath: options.browserExecutablePath ?? manifest.browserExecutablePath ?? undefined,\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { existsSync } from 'node:fs'\nimport { basename } from 'node:path'\nimport { chromium } from 'playwright-extra'\nimport StealthPlugin from 'puppeteer-extra-plugin-stealth'\nimport type { BrowserContext, Page } from 'playwright'\n\nchromium.use(StealthPlugin())\nimport {\n defaultChromeExecutablePath,\n loadImportedBrowserProfile,\n type ImportedBrowserProfileManifest,\n} from '../../lib/local-browser-profiles.js'\nimport type {\n BrowserCaptureFanoutInput,\n BrowserClickInput,\n BrowserLocateInput,\n BrowserOpenInput,\n BrowserPressInput,\n BrowserScrollInput,\n BrowserTypeInput,\n} from '../../mcp/browser-agent-tool-schemas.js'\nimport { runFanoutCapture, type FanoutCaptureOutput } from '../fanout/run-capture.js'\n\ninterface LocalBrowserContextState {\n key: string\n context: BrowserContext\n profile: ResolvedLocalBrowserProfile\n}\n\ninterface ResolvedLocalBrowserProfile {\n name: string\n userDataDir: string\n browserExecutablePath: string | null\n manifest: ImportedBrowserProfileManifest | null\n}\n\ninterface LocalBrowserSessionState {\n sessionId: string\n label: string | null\n page: Page\n contextKey: string\n profileName: string\n userDataDir: string\n createdAt: string\n lastActionAt: string\n closedAt: string | null\n status: 'open' | 'closed'\n timeout?: NodeJS.Timeout\n}\n\ntype ReadPageResult = {\n url: string\n title: string\n text: string\n elements: Array<Record<string, unknown>>\n viewport: Record<string, unknown>\n}\n\nfunction directProfileDir(): string | undefined {\n return process.env.MCP_SCRAPER_BROWSER_PROFILE_DIR?.trim() || undefined\n}\n\nfunction configuredProfileName(profile?: string): string {\n return profile?.trim()\n || process.env.MCP_SCRAPER_BROWSER_PROFILE?.trim()\n || (directProfileDir() ? basename(directProfileDir()!) : 'default')\n}\n\nfunction launchExecutablePath(profile: ResolvedLocalBrowserProfile): string | undefined {\n const configured = process.env.MCP_SCRAPER_BROWSER_EXECUTABLE?.trim()\n || profile.browserExecutablePath\n || defaultChromeExecutablePath()\n return configured && existsSync(configured) ? configured : undefined\n}\n\nfunction ignoreDefaultArgsFor(executablePath?: string): string[] | undefined {\n if (!executablePath) return undefined\n if (process.platform !== 'darwin') return undefined\n if (!/Google Chrome\\.app\\/Contents\\/MacOS\\/Google Chrome$/.test(executablePath)) return undefined\n return ['--password-store=basic', '--use-mock-keychain']\n}\n\nfunction normalizeKeyCombo(value: string): string {\n return value\n .split('+')\n .map(part => {\n const trimmed = part.trim()\n const lower = trimmed.toLowerCase()\n if (lower === 'ctrl' || lower === 'control') return 'Control'\n if (lower === 'cmd' || lower === 'command' || lower === 'meta') return 'Meta'\n if (lower === 'option' || lower === 'alt') return 'Alt'\n if (lower === 'return') return 'Enter'\n if (lower === 'esc') return 'Escape'\n if (trimmed.length === 1) return trimmed.toUpperCase()\n return trimmed\n })\n .join('+')\n}\n\nfunction sessionSummary(session: LocalBrowserSessionState): Record<string, unknown> {\n return {\n session_id: session.sessionId,\n status: session.status,\n label: session.label,\n profile: session.profileName,\n user_data_dir: session.userDataDir,\n created_at: session.createdAt,\n last_action_at: session.lastActionAt,\n closed_at: session.closedAt,\n watch_url: `local://browser-session/${session.sessionId}`,\n url: session.status === 'open' ? session.page.url() : null,\n }\n}\n\nexport class LocalBrowserAgentService {\n private readonly contexts = new Map<string, LocalBrowserContextState>()\n private readonly sessions = new Map<string, LocalBrowserSessionState>()\n\n async open(input: BrowserOpenInput): Promise<Record<string, unknown>> {\n const profile = await this.resolveProfile(input.profile)\n const contextState = await this.ensureContext(profile)\n const pages = contextState.context.pages()\n const page = pages.length === 1 && !this.hasOpenSessionForContext(contextState.key)\n ? pages[0]\n : await contextState.context.newPage()\n const now = new Date().toISOString()\n const sessionId = `lbs_${randomUUID().replace(/-/g, '').slice(0, 20)}`\n const session: LocalBrowserSessionState = {\n sessionId,\n label: input.label ?? null,\n page,\n contextKey: contextState.key,\n profileName: profile.name,\n userDataDir: profile.userDataDir,\n createdAt: now,\n lastActionAt: now,\n closedAt: null,\n status: 'open',\n }\n const timeoutSeconds = input.timeout_seconds ?? 600\n if (timeoutSeconds > 0) {\n session.timeout = setTimeout(() => {\n void this.close(sessionId)\n }, timeoutSeconds * 1000)\n session.timeout.unref()\n }\n this.sessions.set(sessionId, session)\n\n if (input.url) await this.goto(sessionId, input.url)\n\n return {\n session_id: sessionId,\n watch_url: `local://browser-session/${sessionId}`,\n live_view_url: null,\n profile: profile.name,\n user_data_dir: profile.userDataDir,\n url: input.url ?? null,\n mode: 'local',\n }\n }\n\n async screenshot(sessionId: string): Promise<ReadPageResult & { image_base64: string; mime_type: string }> {\n const session = this.requireOpenSession(sessionId)\n await this.waitForPage(session.page)\n const image = await session.page.screenshot({ type: 'png', fullPage: false })\n const page = await this.read(sessionId)\n return {\n ...page,\n image_base64: image.toString('base64'),\n mime_type: 'image/png',\n }\n }\n\n async read(sessionId: string): Promise<ReadPageResult> {\n const session = this.requireOpenSession(sessionId)\n await this.waitForPage(session.page)\n this.touch(session)\n const title = await session.page.title().catch(() => '')\n const snapshot = await session.page.evaluate(() => {\n const cssEscape = (value: string) => {\n const escapeFn = (globalThis as { CSS?: { escape?: (input: string) => string } }).CSS?.escape\n return escapeFn ? escapeFn(value) : value.replace(/[\"\\\\#.:>+~[\\]()]/g, '\\\\$&')\n }\n const textFor = (element: Element): string => {\n const html = element as HTMLInputElement & HTMLElement\n return (\n element.getAttribute('aria-label')\n || element.getAttribute('title')\n || html.placeholder\n || html.value\n || html.innerText\n || element.textContent\n || ''\n ).replace(/\\s+/g, ' ').trim()\n }\n const selectorFor = (element: Element): string => {\n const id = (element as HTMLElement).id\n if (id) return `#${cssEscape(id)}`\n const name = element.getAttribute('name')\n const tag = element.tagName.toLowerCase()\n if (name) return `${tag}[name=\"${name.replace(/\"/g, '\\\\\"')}\"]`\n const parts: string[] = []\n let current: Element | null = element\n while (current && current !== document.body && parts.length < 4) {\n const currentTag = current.tagName.toLowerCase()\n const parent: Element | null = current.parentElement\n if (!parent) {\n parts.unshift(currentTag)\n break\n }\n const children = Array.from(parent.children) as Element[]\n const siblings = children.filter((child: Element) => child.tagName === current!.tagName)\n const index = siblings.indexOf(current) + 1\n parts.unshift(siblings.length > 1 ? `${currentTag}:nth-of-type(${index})` : currentTag)\n current = parent\n }\n return parts.join(' > ') || tag\n }\n const candidates = Array.from(document.querySelectorAll<HTMLElement>(\n 'a, button, input, textarea, select, summary, [role], [contenteditable=\"true\"], [tabindex]:not([tabindex=\"-1\"])',\n ))\n const elements = candidates\n .map((element, index) => {\n const rect = element.getBoundingClientRect()\n const style = window.getComputedStyle(element)\n const visible = rect.width > 0\n && rect.height > 0\n && style.display !== 'none'\n && style.visibility !== 'hidden'\n && Number(style.opacity || '1') > 0\n if (!visible) return null\n const label = textFor(element)\n return {\n index,\n tag: element.tagName.toLowerCase(),\n role: element.getAttribute('role') || null,\n text: label.slice(0, 180),\n selector: selectorFor(element),\n x: Math.round(rect.left + rect.width / 2),\n y: Math.round(rect.top + rect.height / 2),\n left: Math.round(rect.left),\n top: Math.round(rect.top),\n width: Math.round(rect.width),\n height: Math.round(rect.height),\n }\n })\n .filter(Boolean)\n .slice(0, 120)\n\n return {\n text: (document.body?.innerText || '').replace(/\\n{3,}/g, '\\n\\n').slice(0, 30_000),\n elements,\n viewport: {\n width: window.innerWidth,\n height: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n },\n }\n })\n\n return {\n url: session.page.url(),\n title,\n text: snapshot.text,\n elements: snapshot.elements as Array<Record<string, unknown>>,\n viewport: snapshot.viewport,\n }\n }\n\n async locate(sessionId: string, targets: BrowserLocateInput['targets']): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n const located = []\n for (const target of targets) {\n try {\n const locator = target.selector\n ? session.page.locator(target.selector)\n : session.page.getByText(target.text ?? '', { exact: target.match === 'exact' })\n const selected = locator.nth(target.index ?? 0)\n await selected.waitFor({ state: 'visible', timeout: 3000 }).catch(() => undefined)\n const box = await selected.boundingBox()\n const text = await selected.textContent({ timeout: 1000 }).catch(() => null)\n located.push({\n input: target,\n found: Boolean(box),\n element: box\n ? {\n left: Math.round(box.x),\n top: Math.round(box.y),\n width: Math.round(box.width),\n height: Math.round(box.height),\n x: Math.round(box.x + box.width / 2),\n y: Math.round(box.y + box.height / 2),\n text: (text ?? '').replace(/\\s+/g, ' ').trim().slice(0, 220),\n }\n : null,\n })\n } catch (err) {\n located.push({\n input: target,\n found: false,\n element: null,\n error: err instanceof Error ? err.message : String(err),\n })\n }\n }\n const read = await this.read(sessionId)\n return {\n url: read.url,\n title: read.title,\n viewport: read.viewport,\n replay: null,\n targets: located,\n }\n }\n\n async goto(sessionId: string, url: string): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n const response = await session.page.goto(url, { waitUntil: 'domcontentloaded', timeout: 45_000 }).catch(err => {\n throw new Error(err instanceof Error ? err.message : String(err))\n })\n await this.waitForPage(session.page)\n return {\n ok: true,\n url: session.page.url(),\n status: response?.status() ?? null,\n mode: 'local',\n }\n }\n\n async click(sessionId: string, input: BrowserClickInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n await session.page.mouse.click(input.x, input.y, {\n button: input.button ?? 'left',\n clickCount: input.num_clicks ?? 1,\n })\n await this.waitForPage(session.page)\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async type(sessionId: string, input: BrowserTypeInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n await session.page.keyboard.type(input.text, { delay: input.delay })\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async scroll(sessionId: string, input: BrowserScrollInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n if (typeof input.x === 'number' && typeof input.y === 'number') {\n await session.page.mouse.move(input.x, input.y)\n }\n await session.page.mouse.wheel((input.delta_x ?? 0) * 120, (input.delta_y ?? 5) * 120)\n await session.page.waitForTimeout(150).catch(() => undefined)\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async press(sessionId: string, input: BrowserPressInput): Promise<Record<string, unknown>> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n for (const key of input.keys) {\n await session.page.keyboard.press(normalizeKeyCombo(key))\n }\n await this.waitForPage(session.page)\n return { ok: true, mode: 'local', url: session.page.url() }\n }\n\n async close(sessionId: string): Promise<Record<string, unknown>> {\n const session = this.sessions.get(sessionId)\n if (!session || session.status === 'closed') {\n return { ok: true, closed: true, already_closed: true, mode: 'local' }\n }\n if (session.timeout) clearTimeout(session.timeout)\n session.status = 'closed'\n session.closedAt = new Date().toISOString()\n await session.page.close().catch(() => undefined)\n await this.closeContextIfUnused(session.contextKey)\n return { ok: true, closed: true, mode: 'local' }\n }\n\n list(includeClosed = false): Record<string, unknown>[] {\n return Array.from(this.sessions.values())\n .filter(session => includeClosed || session.status === 'open')\n .map(sessionSummary)\n }\n\n async captureFanout(sessionId: string, input: BrowserCaptureFanoutInput): Promise<FanoutCaptureOutput> {\n const session = this.requireOpenSession(sessionId)\n this.touch(session)\n return runFanoutCapture(session.page, input)\n }\n\n async screenshotOnly(sessionId: string): Promise<string> {\n const session = this.requireOpenSession(sessionId)\n await this.waitForPage(session.page)\n const img = await session.page.screenshot({ type: 'png', fullPage: false })\n return img.toString('base64')\n }\n\n private async resolveProfile(profile?: string): Promise<ResolvedLocalBrowserProfile> {\n const directDir = directProfileDir()\n const requestedName = configuredProfileName(profile)\n if (directDir && (!profile || requestedName === process.env.MCP_SCRAPER_BROWSER_PROFILE?.trim())) {\n return {\n name: requestedName,\n userDataDir: directDir,\n browserExecutablePath: process.env.MCP_SCRAPER_BROWSER_EXECUTABLE?.trim() || defaultChromeExecutablePath() || null,\n manifest: null,\n }\n }\n const manifest = await loadImportedBrowserProfile(requestedName)\n return {\n name: manifest.name,\n userDataDir: manifest.userDataDir,\n browserExecutablePath: manifest.browserExecutablePath,\n manifest,\n }\n }\n\n private async ensureContext(profile: ResolvedLocalBrowserProfile): Promise<LocalBrowserContextState> {\n const existing = this.contexts.get(profile.userDataDir)\n if (existing) return existing\n const executablePath = launchExecutablePath(profile)\n const context = await chromium.launchPersistentContext(profile.userDataDir, {\n headless: false,\n viewport: { width: 1440, height: 900 },\n acceptDownloads: true,\n ...(executablePath ? { executablePath } : {}),\n ...(ignoreDefaultArgsFor(executablePath) ? { ignoreDefaultArgs: ignoreDefaultArgsFor(executablePath) } : {}),\n })\n const state = { key: profile.userDataDir, context, profile }\n context.on('close', () => {\n this.contexts.delete(profile.userDataDir)\n const closedAt = new Date().toISOString()\n for (const session of this.sessions.values()) {\n if (session.contextKey === profile.userDataDir && session.status === 'open') {\n session.status = 'closed'\n session.closedAt = closedAt\n if (session.timeout) clearTimeout(session.timeout)\n }\n }\n })\n this.contexts.set(profile.userDataDir, state)\n return state\n }\n\n private requireOpenSession(sessionId: string): LocalBrowserSessionState {\n const session = this.sessions.get(sessionId)\n if (!session || session.status !== 'open') throw new Error(`Local browser session not found or closed: ${sessionId}`)\n return session\n }\n\n private touch(session: LocalBrowserSessionState): void {\n session.lastActionAt = new Date().toISOString()\n }\n\n private hasOpenSessionForContext(contextKey: string): boolean {\n return Array.from(this.sessions.values()).some(session => session.contextKey === contextKey && session.status === 'open')\n }\n\n private async closeContextIfUnused(contextKey: string): Promise<void> {\n if (this.hasOpenSessionForContext(contextKey)) return\n const state = this.contexts.get(contextKey)\n if (!state) return\n this.contexts.delete(contextKey)\n await state.context.close().catch(() => undefined)\n }\n\n private async waitForPage(page: Page): Promise<void> {\n await page.waitForLoadState('domcontentloaded', { timeout: 5_000 }).catch(() => undefined)\n await page.waitForTimeout(200).catch(() => undefined)\n }\n}\n","import type { CDPSession, Page } from 'playwright'\n\nconst ANSWER_RE = /\\/backend-api\\/(f\\/)?conversation$|\\/chat_conversations\\/[^/]+\\/(completion|retry_completion)$|\\/completion$/i\n\ninterface AnswerBody {\n url: string\n ct: string\n text: string\n}\n\nexport class FanoutCdpCapture {\n private client: CDPSession | null = null\n private reqUrl = new Map<string, string>()\n private ctById = new Map<string, string>()\n private answerIds = new Set<string>()\n private bodies: AnswerBody[] = []\n private pending: Promise<void>[] = []\n private answerStreams = 0\n\n async attach(page: Page): Promise<void> {\n if (this.client) return\n const client = await page.context().newCDPSession(page)\n this.client = client\n await client.send('Network.enable', { maxTotalBufferSize: 200_000_000, maxResourceBufferSize: 200_000_000 } as never)\n client.on('Network.requestWillBeSent', (e: Record<string, unknown>) => {\n const id = e.requestId as string\n const req = e.request as Record<string, unknown> | undefined\n if (id) this.reqUrl.set(id, (req?.url as string) || '')\n })\n client.on('Network.responseReceived', (e: Record<string, unknown>) => {\n const id = e.requestId as string\n const res = e.response as Record<string, unknown> | undefined\n const url = (res?.url as string) || this.reqUrl.get(id) || ''\n const headers = (res?.headers as Record<string, string>) || {}\n const ct = String(headers['content-type'] || headers['Content-Type'] || '')\n if (id) this.ctById.set(id, ct)\n if (id && (this.isAnswerUrl(url) || /event-stream/i.test(ct))) this.answerIds.add(id)\n })\n client.on('Network.loadingFinished', (e: Record<string, unknown>) => this.grab(e.requestId as string))\n }\n\n reset(): void {\n this.bodies = []\n this.answerStreams = 0\n this.answerIds.clear()\n this.pending = []\n }\n\n answerStreamCount(): number {\n return this.answerStreams\n }\n\n async drain(): Promise<void> {\n await Promise.all(this.pending)\n }\n\n bestAnswerText(): string {\n const eventStreams = this.bodies.filter((b) => /event-stream/i.test(b.ct))\n const answerStreams = eventStreams.filter((b) => this.isAnswerUrl(b.url)).sort((a, b) => b.text.length - a.text.length)\n if (answerStreams.length) return answerStreams.map((b) => b.text).join('\\n')\n const answerJson = this.bodies.filter((b) => this.isAnswerUrl(b.url)).sort((a, b) => b.text.length - a.text.length)\n if (answerJson.length) return answerJson[0].text\n if (eventStreams.length) return eventStreams.sort((a, b) => b.text.length - a.text.length)[0].text\n return ''\n }\n\n async detach(): Promise<void> {\n try {\n await this.client?.detach()\n } catch {\n this.client = null\n }\n this.client = null\n }\n\n private isAnswerUrl(url: string): boolean {\n let path = ''\n try {\n path = new URL(url).pathname\n } catch {\n path = String(url || '').split('?')[0]\n }\n return ANSWER_RE.test(path)\n }\n\n private grab(requestId: string | undefined): void {\n if (!requestId || !this.client || !this.answerIds.has(requestId)) return\n const url = this.reqUrl.get(requestId) || ''\n const ct = this.ctById.get(requestId) || ''\n const client = this.client\n const p = client\n .send('Network.getResponseBody', { requestId } as never)\n .then((r: Record<string, unknown>) => {\n const text = r.base64Encoded ? Buffer.from(String(r.body), 'base64').toString('utf8') : String(r.body || '')\n if (text) {\n this.bodies.push({ url, ct, text })\n if (this.isAnswerUrl(url)) this.answerStreams++\n }\n })\n .catch(() => undefined)\n this.pending.push(p)\n }\n}\n","const INTERNAL = /chatgpt\\.com|openai\\.com|oaiusercontent|oaistatic|claude\\.ai|anthropic\\.com/i\nconst TRACK = /^(utm_|oai|fbclid|gclid|ref$|ref_|sa$|usg$|ved$|sca_esv$|sources$)/i\n\nexport function domainOf(u: string): string {\n try {\n return new URL(u).hostname.replace(/^www\\./, '')\n } catch {\n return ''\n }\n}\n\nexport function normUrl(u: string): string {\n try {\n const x = new URL(u)\n x.hash = ''\n for (const k of [...x.searchParams.keys()]) {\n if (TRACK.test(k)) x.searchParams.delete(k)\n }\n return x.toString().replace(/\\/$/, '').toLowerCase()\n } catch {\n return String(u || '').toLowerCase()\n }\n}\n\nexport function isExternal(u: string): boolean {\n const h = domainOf(u)\n return Boolean(h) && !INTERNAL.test(h)\n}\n\nexport function unesc(s: string): string {\n try {\n return JSON.parse('\"' + s + '\"')\n } catch {\n return String(s).replace(/\\\\(.)/g, '$1')\n }\n}\n\nexport function stripCitationMarkers(s: string): string {\n return String(s || '')\n .replace(/[-]/g, '')\n .replace(/cite(?:turn\\d+\\w+?\\d+)+/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n}\n\nexport function sliceBalanced(text: string, openIdx: number): string | null {\n const open = text[openIdx]\n const close = open === '[' ? ']' : '}'\n let depth = 0\n let inStr = false\n let esc = false\n for (let i = openIdx; i < text.length; i++) {\n const ch = text[i]\n if (inStr) {\n if (esc) esc = false\n else if (ch === '\\\\') esc = true\n else if (ch === '\"') inStr = false\n continue\n }\n if (ch === '\"') {\n inStr = true\n continue\n }\n if (ch === open) depth++\n else if (ch === close) {\n depth--\n if (depth === 0) return text.slice(openIdx, i + 1)\n }\n }\n return null\n}\n\nexport function findJsonValues(text: string, field: string): unknown[] {\n const out: unknown[] = []\n const re = new RegExp('\"' + field + '\"\\\\s*:\\\\s*(\\\\[|\\\\{)', 'g')\n let m: RegExpExecArray | null\n while ((m = re.exec(text))) {\n const openIdx = m.index + m[0].length - 1\n const slice = sliceBalanced(text, openIdx)\n if (slice) {\n try {\n out.push(JSON.parse(slice))\n } catch {\n continue\n }\n }\n }\n return out\n}\n\nexport function stringsInArrayBody(arrBody: string): string[] {\n const out: string[] = []\n const re = /\"((?:[^\"\\\\]|\\\\.){2,300}?)\"/g\n let m: RegExpExecArray | null\n while ((m = re.exec(arrBody))) out.push(unesc(m[1]))\n return out\n}\n\nexport function cleanQuery(q: string): string | null {\n const t = (q || '').trim()\n if (t.length < 2 || t.length > 300) return null\n return t\n}\n","import type { FanoutAdapter, FanoutSource, FanoutSnippet, ParsedFanout } from '../types.js'\nimport {\n cleanQuery,\n domainOf,\n findJsonValues,\n isExternal,\n normUrl,\n stringsInArrayBody,\n stripCitationMarkers,\n unesc,\n} from '../parse-helpers.js'\n\ninterface SourceAcc {\n url: string\n domain: string\n title: string\n cited: boolean\n timesCited: number\n firstOrder: number\n snippet: string\n round: number | null\n}\n\nfunction roundOf(refId: string | null): number | null {\n const m = /^turn(\\d+)/.exec(refId || '')\n return m ? Number(m[1]) : null\n}\n\nfunction normRef(r: unknown): string | null {\n if (typeof r === 'string') {\n const m = /turn(\\d+)(search|news|ref|video|image|product)(\\d+)/.exec(r)\n return m ? `turn${m[1]}${m[2]}${m[3]}` : null\n }\n if (r && typeof r === 'object') {\n const o = r as Record<string, unknown>\n if (o.turn_index != null) {\n return `turn${o.turn_index}${o.ref_type || 'search'}${o.ref_index != null ? o.ref_index : ''}`\n }\n }\n return null\n}\n\nfunction refsInText(s: string): string[] {\n return (String(s || '').match(/turn\\d+(?:search|news|ref|video|image|product)\\d+/g) || [])\n .map(normRef)\n .filter((x): x is string => Boolean(x))\n}\n\nfunction collectInto(arr: unknown[], v: unknown): void {\n if (Array.isArray(v)) arr.push(...v)\n else if (v && typeof v === 'object') arr.push(v)\n}\n\nfunction reconstructFromSsePatches(raw: string): string {\n const contentReferences: unknown[] = []\n const searchResultGroups: unknown[] = []\n const citations: unknown[] = []\n const citedUrls = new Set<string>()\n const state = { found: false }\n\n const handleOp = (op: unknown): void => {\n if (!op || typeof op !== 'object') return\n const o = op as Record<string, unknown>\n const v = o.v\n if (o.o === 'patch' && Array.isArray(v)) {\n state.found = true\n v.forEach(handleOp)\n return\n }\n const path = typeof o.p === 'string' ? o.p : ''\n if ((path === '' || path === '/message') && v && typeof v === 'object') {\n const root = v as Record<string, unknown>\n const msg = (root.message as Record<string, unknown>) || root\n const md = msg && (msg.metadata as Record<string, unknown>)\n if (md) {\n collectInto(contentReferences, md.content_references)\n collectInto(searchResultGroups, md.search_result_groups)\n collectInto(citations, md.citations)\n state.found = true\n }\n }\n if (!path) return\n if (/\\/safe_urls$/.test(path) && Array.isArray(v)) {\n for (const u of v) if (typeof u === 'string') citedUrls.add(u)\n state.found = true\n } else if (path.includes('content_references')) {\n collectInto(contentReferences, v)\n state.found = true\n } else if (path.includes('search_result_groups')) {\n collectInto(searchResultGroups, v)\n state.found = true\n } else if (path.includes('citations')) {\n collectInto(citations, v)\n state.found = true\n }\n }\n\n for (const line of raw.split('\\n')) {\n const s = (line.startsWith('data:') ? line.slice(5) : line).trim()\n if (!s || s === '[DONE]' || (s[0] !== '{' && s[0] !== '[')) continue\n let parsed: unknown\n try {\n parsed = JSON.parse(s)\n } catch {\n continue\n }\n const ops = Array.isArray(parsed) ? parsed : [parsed]\n ops.forEach(handleOp)\n }\n\n if (!state.found) return raw\n const citedRefs = [...citedUrls].map((url) => ({ type: 'grouped_webpages', items: [{ url }] }))\n const synthetic = JSON.stringify({\n content_references: [...contentReferences, ...citedRefs],\n search_result_groups: searchResultGroups,\n citations,\n })\n return raw + '\\n' + synthetic\n}\n\nexport const chatgptAdapter: FanoutAdapter = {\n platform: 'ChatGPT',\n matchesHost(hostname) {\n return /(^|\\.)chatgpt\\.com$|(^|\\.)openai\\.com$/i.test(hostname)\n },\n parse(rawInput, prompt): ParsedFanout {\n const raw = reconstructFromSsePatches(rawInput)\n const sources = new Map<string, SourceAcc>()\n const snippets = new Map<string, FanoutSnippet>()\n const queries = new Set<string>()\n const unmapped = new Set<string>()\n const meta = { model: '', finishType: '', title: '', rounds: 0 }\n\n const ensure = (url: string): SourceAcc | null => {\n if (!isExternal(url)) return null\n const k = normUrl(url)\n let s = sources.get(k)\n if (!s) {\n s = { url, domain: domainOf(url), title: '', cited: false, timesCited: 0, firstOrder: Infinity, snippet: '', round: null }\n sources.set(k, s)\n }\n return s\n }\n const addSnippet = (url: string, title: string, text: string) => {\n const clean = stripCitationMarkers(text)\n if (!isExternal(url) || clean.length < 2) return\n snippets.set(normUrl(url), { url, domain: domainOf(url), title: title || domainOf(url), text: clean.slice(0, 400) })\n }\n\n for (const m of raw.matchAll(/\"([a-z_]*(?:quer|search)[a-z_]*)\"\\s*:/gi)) unmapped.add(m[1])\n\n for (const m of raw.matchAll(/\"search_model_queries\"\\s*:\\s*\\[([^\\]]*)\\]/g)) {\n for (const q of stringsInArrayBody(m[1])) {\n const c = cleanQuery(q)\n if (c) queries.add(c)\n }\n }\n for (const m of raw.matchAll(/\"(?:search_queries|queries|search_query)\"\\s*:\\s*\\[([^\\]]*)\\]/g)) {\n for (const q of stringsInArrayBody(m[1])) {\n const c = cleanQuery(q)\n if (c) queries.add(c)\n }\n }\n\n for (const v of findJsonValues(raw, 'search_result_groups')) {\n if (!Array.isArray(v)) continue\n for (const g of v) {\n const entries = (g && typeof g === 'object' && Array.isArray((g as Record<string, unknown>).entries))\n ? ((g as Record<string, unknown>).entries as Array<Record<string, unknown>>)\n : []\n for (const e of entries) {\n const url = typeof e.url === 'string' ? e.url : ''\n const s = ensure(url)\n if (!s) continue\n if (!s.title && typeof e.title === 'string') s.title = e.title.slice(0, 200)\n const ref = normRef(e.ref_id)\n if (ref && s.round == null) s.round = roundOf(ref)\n if (typeof e.snippet === 'string' && e.snippet) addSnippet(url, s.title, e.snippet)\n }\n }\n }\n\n for (const m of raw.matchAll(/\"url\"\\s*:\\s*\"(https?:\\/\\/[^\"\\\\]+)\"(?:[\\s\\S]{0,120}?\"(?:title|name)\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.){0,200})\")?/g)) {\n const s = ensure(m[1])\n if (s && !s.title && m[2]) s.title = unesc(m[2]).slice(0, 200)\n }\n\n let spanTotal = 0\n for (const cr of findJsonValues(raw, 'content_references')) {\n if (!Array.isArray(cr)) continue\n for (const ref of cr as Array<Record<string, unknown>>) {\n const type = typeof ref.type === 'string' ? ref.type : ''\n const isBundle = /sources_footnote|nav_list|alt_text/.test(type)\n const refs = refsInText(typeof ref.matched_text === 'string' ? ref.matched_text : '')\n if (!isBundle) spanTotal++\n const ord = typeof ref.start_idx === 'number' ? ref.start_idx : (isBundle ? Infinity : spanTotal)\n const items = Array.isArray(ref.items) ? (ref.items as Array<Record<string, unknown>>) : []\n items.forEach((it, idx) => {\n const refForItem = refs.length === items.length ? refs[idx] : refs[0]\n const urls = [it.url]\n .concat((Array.isArray(it.supporting_websites) ? it.supporting_websites : []).map((s) => (s as Record<string, unknown>)?.url))\n .filter((u): u is string => typeof u === 'string')\n for (const u of urls) {\n const s = ensure(u)\n if (!s) continue\n if (!isBundle) {\n s.cited = true\n s.timesCited++\n if (ord < s.firstOrder) s.firstOrder = ord\n } else if (!s.cited) {\n s.cited = true\n }\n if (refForItem && s.round == null) s.round = roundOf(refForItem)\n }\n if (typeof it.url === 'string' && typeof it.snippet === 'string') addSnippet(it.url, typeof it.title === 'string' ? it.title : '', it.snippet)\n })\n }\n }\n\n for (const v of findJsonValues(raw, 'citations')) {\n if (!Array.isArray(v)) continue\n v.forEach((c, i) => {\n const md = (c && typeof c === 'object' ? (c as Record<string, unknown>).metadata : null) as Record<string, unknown> | null\n if (!md || typeof md.url !== 'string') return\n const s = ensure(md.url)\n if (!s) return\n s.cited = true\n s.timesCited++\n const ord = typeof (c as Record<string, unknown>).start_ix === 'number' ? (c as Record<string, unknown>).start_ix as number : i\n if (ord < s.firstOrder) s.firstOrder = ord\n if (typeof md.text === 'string') addSnippet(md.url, typeof md.title === 'string' ? md.title : '', md.text)\n })\n }\n\n for (const m of raw.matchAll(/\"content_type\"\\s*:\\s*\"tether_quote\"([\\s\\S]{0,4000}?)\"text\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/g)) {\n const url = (m[1].match(/\"url\"\\s*:\\s*\"([^\"]+)\"/) || [])[1]\n const title = (m[1].match(/\"title\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/) || [])[1]\n if (url) {\n ensure(url)\n addSnippet(url, title ? unesc(title) : '', unesc(m[2]))\n }\n }\n\n const modelMatches = [...raw.matchAll(/\"resolved_model_slug\"\\s*:\\s*\"([^\"]+)\"/g)]\n const slugMatches = modelMatches.length ? modelMatches : [...raw.matchAll(/\"model_slug\"\\s*:\\s*\"([^\"]+)\"/g)]\n if (slugMatches.length) meta.model = slugMatches[slugMatches.length - 1][1]\n const finish = raw.match(/\"finish_details\"\\s*:\\s*\\{[^}]*\"type\"\\s*:\\s*\"([^\"]+)\"/)\n if (finish) meta.finishType = finish[1]\n\n const searchRounds = (raw.match(/\"recipient\"\\s*:\\s*\"(?:web|browser)\"[\\s\\S]{0,400}?\"content_type\"\\s*:\\s*\"code\"[\\s\\S]{0,200}?search\\(/g) || []).length\n const sourceRounds = new Set<number>()\n for (const s of sources.values()) if (s.round != null) sourceRounds.add(s.round)\n meta.rounds = Math.max(searchRounds, sourceRounds.size)\n\n const ordered: FanoutSource[] = [...sources.values()]\n .sort((a, b) => (a.cited === b.cited ? b.timesCited - a.timesCited || a.firstOrder - b.firstOrder : a.cited ? -1 : 1))\n .map((s) => ({\n url: s.url,\n domain: s.domain,\n title: s.title || s.domain,\n cited: s.cited,\n timesCited: s.timesCited,\n snippet: snippets.get(normUrl(s.url))?.text || '',\n round: s.round,\n }))\n\n return {\n subQueries: [...queries],\n sources: ordered,\n snippets: [...snippets.values()],\n meta,\n unmappedKeys: [...unmapped].slice(0, 50),\n }\n },\n}\n","import type { FanoutAdapter, FanoutSource, FanoutSnippet, ParsedFanout } from '../types.js'\nimport { cleanQuery, domainOf, isExternal, normUrl, unesc } from '../parse-helpers.js'\n\ninterface SourceAcc {\n url: string\n domain: string\n title: string\n cited: boolean\n timesCited: number\n snippet: string\n round: number | null\n}\n\nfunction isFavicon(u: string): boolean {\n return /\\/s2\\/favicons/i.test(u) || /favicon/i.test(u)\n}\n\nexport const claudeAdapter: FanoutAdapter = {\n platform: 'Claude',\n matchesHost(hostname) {\n return /(^|\\.)claude\\.ai$/i.test(hostname)\n },\n parse(raw, prompt): ParsedFanout {\n const sources = new Map<string, SourceAcc>()\n const snippets = new Map<string, FanoutSnippet>()\n const queries = new Set<string>()\n const unmapped = new Set<string>()\n const meta = { model: '', finishType: '', title: '', rounds: 0 }\n\n const ensure = (url: string): SourceAcc | null => {\n if (!url || !isExternal(url) || isFavicon(url)) return null\n const k = normUrl(url)\n let s = sources.get(k)\n if (!s) {\n s = { url, domain: domainOf(url), title: '', cited: false, timesCited: 0, snippet: '', round: null }\n sources.set(k, s)\n }\n return s\n }\n\n const toolInputs = new Map<number, { name: string; buf: string }>()\n const searchBlocks = new Set<number>()\n const finalizeTool = (index: number) => {\n const t = toolInputs.get(index)\n if (!t || !/web_search|web_fetch|search|browse/i.test(t.name)) return\n try {\n const input = JSON.parse(t.buf) as Record<string, unknown>\n if (typeof input.query === 'string') {\n const q = cleanQuery(input.query)\n if (q) queries.add(q)\n }\n } catch {\n const m = t.buf.match(/\"query\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/)\n if (m) {\n const q = cleanQuery(unesc(m[1]))\n if (q) queries.add(q)\n }\n }\n }\n\n for (const line of raw.split('\\n')) {\n const s = (line.startsWith('data:') ? line.slice(5) : line).trim()\n if (!s || (s[0] !== '{' && s[0] !== '[')) continue\n let ev: Record<string, unknown>\n try {\n ev = JSON.parse(s) as Record<string, unknown>\n } catch {\n continue\n }\n const type = ev.type\n if (type === 'content_block_start') {\n const cb = (ev.content_block as Record<string, unknown>) || {}\n const index = typeof ev.index === 'number' ? ev.index : -1\n if (cb.type === 'tool_use' && index >= 0) {\n const name = typeof cb.name === 'string' ? cb.name : ''\n toolInputs.set(index, { name, buf: '' })\n if (/web_search|web_fetch|search|browse/i.test(name)) searchBlocks.add(index)\n }\n } else if (type === 'content_block_delta') {\n const d = (ev.delta as Record<string, unknown>) || {}\n const index = typeof ev.index === 'number' ? ev.index : -1\n if (d.type === 'input_json_delta' && typeof d.partial_json === 'string') {\n const t = toolInputs.get(index)\n if (t) t.buf += d.partial_json\n } else if (d.type === 'citation_start_delta') {\n const c = (d.citation as Record<string, unknown>) || {}\n if (typeof c.url === 'string') {\n const src = ensure(c.url)\n if (src) {\n src.cited = true\n src.timesCited++\n if (!src.title && typeof c.title === 'string') src.title = c.title.slice(0, 200)\n if (typeof c.cited_text === 'string' && c.cited_text) {\n snippets.set(normUrl(c.url), { url: c.url, domain: domainOf(c.url), title: src.title, text: String(c.cited_text).slice(0, 400) })\n }\n }\n }\n }\n } else if (type === 'content_block_stop') {\n const index = typeof ev.index === 'number' ? ev.index : -1\n if (index >= 0) finalizeTool(index)\n } else if (type === 'message_delta' || type === 'message_stop' || type === 'message_start') {\n const d = (ev.delta as Record<string, unknown>) || (ev.message as Record<string, unknown>) || {}\n if (typeof d.stop_reason === 'string' && !meta.finishType) meta.finishType = d.stop_reason\n if (typeof d.model === 'string' && !meta.model) meta.model = d.model\n }\n }\n\n for (const index of searchBlocks) finalizeTool(index)\n\n for (const m of raw.matchAll(/\"title\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.){1,200})\"\\s*,\\s*\"url\"\\s*:\\s*\"(https?:\\/\\/[^\"\\\\]+)\"/g)) {\n const src = ensure(m[2])\n if (src && !src.title) src.title = unesc(m[1]).slice(0, 200)\n }\n for (const m of raw.matchAll(/\"url\"\\s*:\\s*\"(https?:\\/\\/[^\"\\\\]+)\"/g)) ensure(m[1])\n\n for (const m of raw.matchAll(/\\\\\"title\\\\\"\\s*:\\s*\\\\\"((?:[^\"\\\\]|\\\\.){1,160}?)\\\\\"[\\s\\S]{0,160}?\\\\\"url\\\\\"\\s*:\\s*\\\\\"(https?:[^\"\\\\]+)\\\\\"/g)) {\n const src = ensure(m[2])\n if (src && !src.title) src.title = unesc(unesc(m[1])).slice(0, 200)\n }\n for (const m of raw.matchAll(/\\\\\"url\\\\\"\\s*:\\s*\\\\\"(https?:[^\"\\\\]+)\\\\\"/g)) ensure(m[1])\n\n if (!meta.model) {\n const mm = raw.match(/\"model\"\\s*:\\s*\"(claude[^\"]+)\"/)\n if (mm) meta.model = mm[1]\n }\n meta.rounds = queries.size > 0 ? searchBlocks.size : 0\n\n for (const m of raw.matchAll(/\"([a-z_]*(?:quer|search)[a-z_]*)\"\\s*:/gi)) unmapped.add(m[1])\n\n const ordered: FanoutSource[] = [...sources.values()]\n .sort((a, b) => (a.cited === b.cited ? b.timesCited - a.timesCited : a.cited ? -1 : 1))\n .map((s) => ({\n url: s.url,\n domain: s.domain,\n title: s.title || s.domain,\n cited: s.cited,\n timesCited: s.timesCited,\n snippet: snippets.get(normUrl(s.url))?.text || '',\n round: s.round,\n }))\n\n return {\n subQueries: [...queries],\n sources: ordered,\n snippets: [...snippets.values()],\n meta,\n unmappedKeys: [...unmapped].slice(0, 50),\n }\n },\n}\n","import type { FanoutAdapter, FanoutPlatform } from '../types.js'\nimport { chatgptAdapter } from './chatgpt.js'\nimport { claudeAdapter } from './claude.js'\n\nexport const FANOUT_ADAPTERS: FanoutAdapter[] = [chatgptAdapter, claudeAdapter]\n\nexport function adapterForHost(hostname: string): FanoutAdapter | null {\n return FANOUT_ADAPTERS.find((a) => a.matchesHost(hostname)) ?? null\n}\n\nexport function adapterForPlatform(platform: FanoutPlatform): FanoutAdapter | null {\n return FANOUT_ADAPTERS.find((a) => a.platform === platform) ?? null\n}\n\nexport { chatgptAdapter, claudeAdapter }\n","import type { FanoutPlatform, FanoutResult, ParsedFanout } from './types.js'\n\nexport interface BuildContext {\n platform: FanoutPlatform\n parsed: ParsedFanout\n prompt: string\n ready: boolean\n rawBytes: number\n}\n\nexport function buildFanoutResult(ctx: BuildContext): FanoutResult {\n const { platform, parsed, ready, rawBytes } = ctx\n const browsedUrls = parsed.sources\n const citedUrls = browsedUrls.filter((s) => s.cited)\n const browsedOnly = browsedUrls.filter((s) => !s.cited)\n const prompt = ctx.prompt || parsed.meta.title || ''\n\n const result: FanoutResult = {\n platform,\n capturedAt: new Date().toISOString(),\n prompt,\n meta: parsed.meta,\n subQueries: parsed.subQueries,\n browsedUrls,\n citedUrls,\n browsedOnly,\n snippets: parsed.snippets,\n counts: {\n subQueries: parsed.subQueries.length,\n browsed: browsedUrls.length,\n cited: citedUrls.length,\n browsedOnly: browsedOnly.length,\n },\n }\n\n if (parsed.subQueries.length === 0 && browsedUrls.length === 0) {\n result.debug = {\n interceptorReady: ready,\n rawBytes,\n unmappedKeys: parsed.unmappedKeys,\n note: ready\n ? 'Capture hook is live but no fan-out was seen yet. Run a NEW prompt that triggers web search in this session, then call browser_capture_fanout again. Fan-out is only captured as it streams; past answers from before the session opened cannot be recovered.'\n : 'Capture hook not detected on this page. The session must be opened with MCP_SCRAPER_BROWSER_MODE=local and navigated to chatgpt.com or claude.ai after opening, so the hook installs before the site scripts run.',\n }\n }\n\n return result\n}\n","import type { FanoutResult, FanoutSource } from './types.js'\n\nexport type SiteType =\n | 'First-party/vendor'\n | 'News/media'\n | 'Reddit'\n | 'Social/video'\n | 'Encyclopedia'\n | 'Review site'\n | 'Docs'\n | 'Blog'\n\nexport interface ClassifiedSource extends FanoutSource {\n siteType: SiteType\n}\n\nexport interface FanoutAggregates {\n topSites: Array<{ domain: string; count: number; cited: boolean; timesCited: number; siteType: SiteType }>\n citationOrder: Array<{ rank: number; domain: string; url: string; timesCited: number }>\n byCategory: Record<SiteType, number>\n}\n\nexport interface EnrichedFanout {\n platform: FanoutResult['platform']\n capturedAt: string\n prompt: string\n meta: FanoutResult['meta']\n queries: string[]\n browsedUrls: ClassifiedSource[]\n citedUrls: ClassifiedSource[]\n browsedOnly: ClassifiedSource[]\n snippets: FanoutResult['snippets']\n counts: FanoutResult['counts']\n aggregates: FanoutAggregates\n firstPartyDomain: string | null\n debug?: FanoutResult['debug']\n}\n\nexport interface EnrichOptions {\n firstPartyDomain?: string\n}\n\nconst SOCIAL = /(^|\\.)(youtube\\.com|youtu\\.be|instagram\\.com|tiktok\\.com|facebook\\.com|fb\\.com|x\\.com|twitter\\.com|linkedin\\.com|pinterest\\.com|threads\\.net|vimeo\\.com)$/i\nconst ENCYCLOPEDIA = /(^|\\.)(wikipedia\\.org|wikimedia\\.org|britannica\\.com|merriam-webster\\.com|dictionary\\.com|fandom\\.com|investopedia\\.com)$/i\nconst REVIEW = /(^|\\.)(yelp\\.com|trustpilot\\.com|g2\\.com|capterra\\.com|angi\\.com|angieslist\\.com|bbb\\.org|consumeraffairs\\.com|bestcompany\\.com|sitejabber\\.com|clutch\\.co|bestpickreports\\.com|homeguide\\.com|porch\\.com|ontoplist\\.com|thumbtack\\.com)$/i\nconst NEWS = /(^|\\.)(reuters\\.com|apnews\\.com|nytimes\\.com|wsj\\.com|washingtonpost\\.com|bloomberg\\.com|cnbc\\.com|forbes\\.com|bbc\\.com|theguardian\\.com|cnn\\.com|npr\\.org|usatoday\\.com|expressnews\\.com|mysanantonio\\.com|beaumontenterprise\\.com)$/i\n\nexport function classifyDomain(domain: string, firstPartyDomain?: string): SiteType {\n const d = domain.toLowerCase().replace(/^www\\./, '')\n if (firstPartyDomain) {\n const fp = firstPartyDomain.toLowerCase().replace(/^www\\./, '')\n if (fp && (d === fp || d.endsWith('.' + fp))) return 'First-party/vendor'\n }\n if (/(^|\\.)reddit\\.com$/i.test(d)) return 'Reddit'\n if (SOCIAL.test(d)) return 'Social/video'\n if (ENCYCLOPEDIA.test(d)) return 'Encyclopedia'\n if (REVIEW.test(d)) return 'Review site'\n if (NEWS.test(d) || /(^|\\.)news\\./i.test(d)) return 'News/media'\n if (/^docs?\\.|^developer\\.|^developers\\.|readthedocs|\\.dev$/i.test(d)) return 'Docs'\n return 'Blog'\n}\n\nfunction emptyCategoryCounts(): Record<SiteType, number> {\n return { 'First-party/vendor': 0, 'News/media': 0, Reddit: 0, 'Social/video': 0, Encyclopedia: 0, 'Review site': 0, Docs: 0, Blog: 0 }\n}\n\nexport function enrichFanout(result: FanoutResult, opts: EnrichOptions = {}): EnrichedFanout {\n const addSiteType = (s: FanoutSource): ClassifiedSource => ({ ...s, siteType: classifyDomain(s.domain, opts.firstPartyDomain) })\n const browsedUrls = result.browsedUrls.map(addSiteType)\n const citedUrls = result.citedUrls.map(addSiteType)\n const browsedOnly = result.browsedOnly.map(addSiteType)\n\n const byCategory = emptyCategoryCounts()\n const domainAgg = new Map<string, { domain: string; count: number; cited: boolean; timesCited: number; siteType: SiteType }>()\n for (const s of browsedUrls) {\n byCategory[s.siteType]++\n const cur = domainAgg.get(s.domain)\n if (!cur) domainAgg.set(s.domain, { domain: s.domain, count: 1, cited: s.cited, timesCited: s.timesCited, siteType: s.siteType })\n else {\n cur.count++\n cur.cited = cur.cited || s.cited\n cur.timesCited += s.timesCited\n }\n }\n const topSites = [...domainAgg.values()].sort((a, b) => b.count - a.count || b.timesCited - a.timesCited)\n\n const citationOrder = citedUrls\n .slice()\n .sort((a, b) => b.timesCited - a.timesCited)\n .map((s, i) => ({ rank: i + 1, domain: s.domain, url: s.url, timesCited: s.timesCited }))\n\n return {\n platform: result.platform,\n capturedAt: result.capturedAt,\n prompt: result.prompt,\n meta: result.meta,\n queries: result.subQueries,\n browsedUrls,\n citedUrls,\n browsedOnly,\n snippets: result.snippets,\n counts: result.counts,\n aggregates: { topSites, citationOrder, byCategory },\n firstPartyDomain: opts.firstPartyDomain ? opts.firstPartyDomain.toLowerCase().replace(/^www\\./, '') : null,\n ...(result.debug ? { debug: result.debug } : {}),\n }\n}\n","import { mkdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport Papa from 'papaparse'\nimport type { EnrichedFanout } from './classify.js'\n\nexport interface FanoutExportPaths {\n dir: string\n json: string\n queriesCsv: string\n queriesTsv: string\n citationsCsv: string\n sourcesCsv: string\n domainsCsv: string\n report: string\n}\n\nfunction outputBaseDir(): string {\n return process.env.MCP_SCRAPER_OUTPUT_DIR?.trim() || join(homedir(), 'Downloads', 'mcp-scraper')\n}\n\nfunction safe(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 80) || 'capture'\n}\n\nfunction writeTable(path: string, rows: Array<Record<string, unknown>>, delimiter: ','): void\nfunction writeTable(path: string, rows: Array<Record<string, unknown>>, delimiter: '\\t'): void\nfunction writeTable(path: string, rows: Array<Record<string, unknown>>, delimiter: string): void {\n writeFileSync(path, Papa.unparse(rows.length ? rows : [{}], { delimiter }))\n}\n\nexport function exportFanout(enriched: EnrichedFanout): FanoutExportPaths {\n const stamp = safe(enriched.capturedAt.replace(/[:.]/g, '-'))\n const dir = join(outputBaseDir(), 'fanout', `${stamp}-${safe(enriched.platform)}`)\n mkdirSync(dir, { recursive: true })\n\n const queryRows = enriched.queries.map((q, i) => ({ index: i + 1, query: q }))\n const citationRows = enriched.aggregates.citationOrder.map((c) => {\n const src = enriched.citedUrls.find((s) => s.url === c.url)\n return { rank: c.rank, domain: c.domain, url: c.url, timesCited: c.timesCited, siteType: src?.siteType ?? '', title: src?.title ?? '' }\n })\n const sourceRows = enriched.browsedUrls.map((s) => ({ domain: s.domain, url: s.url, cited: s.cited, timesCited: s.timesCited, siteType: s.siteType, title: s.title, round: s.round ?? '' }))\n const domainRows = enriched.aggregates.topSites.map((d) => ({ domain: d.domain, count: d.count, cited: d.cited, timesCited: d.timesCited, siteType: d.siteType }))\n\n const paths: FanoutExportPaths = {\n dir,\n json: join(dir, 'fanout.json'),\n queriesCsv: join(dir, 'queries.csv'),\n queriesTsv: join(dir, 'queries.tsv'),\n citationsCsv: join(dir, 'citations.csv'),\n sourcesCsv: join(dir, 'sources.csv'),\n domainsCsv: join(dir, 'domains.csv'),\n report: join(dir, 'report.html'),\n }\n\n writeFileSync(paths.json, JSON.stringify(enriched, null, 2))\n writeTable(paths.queriesCsv, queryRows, ',')\n writeTable(paths.queriesTsv, queryRows, '\\t')\n writeTable(paths.citationsCsv, citationRows, ',')\n writeTable(paths.sourcesCsv, sourceRows, ',')\n writeTable(paths.domainsCsv, domainRows, ',')\n writeFileSync(paths.report, renderReportHtml(enriched))\n\n return paths\n}\n\nfunction esc(s: string): string {\n return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;')\n}\n\nexport function renderReportHtml(enriched: EnrichedFanout): string {\n const data = JSON.stringify(enriched).replace(/</g, '\\\\u003c')\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>AI Search Fan-Out — ${esc(enriched.platform)}</title>\n<style>\n:root{--bg:#0b0d12;--panel:#151922;--line:#252b38;--ink:#e8ecf3;--mut:#8b95a7;--acc:#5b9dff;--cite:#39d98a;--browse:#5a6677}\n*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.5 -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}\n.wrap{max-width:980px;margin:0 auto;padding:28px 20px 80px}\nh1{font-size:20px;margin:0 0 2px}.sub{color:var(--mut);margin:0 0 20px;font-size:13px}\n.stat{font-size:30px;font-weight:700}.stat small{font-size:13px;font-weight:400;color:var(--mut)}\n.cards{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin:18px 0}\n.card{background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:12px 14px}\n.card b{font-size:22px;display:block}.card span{color:var(--mut);font-size:12px}\n.bars{margin:8px 0 22px}.bar{display:flex;align-items:center;gap:8px;margin:4px 0}\n.bar .lab{width:150px;color:var(--mut);font-size:12px;text-align:right}.bar .track{flex:1;background:#10141c;border-radius:5px;overflow:hidden}\n.bar .fill{background:var(--acc);height:16px}.bar .n{width:34px;font-size:12px;color:var(--mut)}\n.tabs{display:flex;gap:8px;margin:22px 0 12px}.tab{background:var(--panel);border:1px solid var(--line);color:var(--ink);padding:7px 14px;border-radius:8px;cursor:pointer}\n.tab.on{background:var(--acc);border-color:var(--acc);color:#04101f;font-weight:600}\n.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}\n.chip{background:var(--panel);border:1px solid var(--line);color:var(--mut);padding:4px 10px;border-radius:20px;cursor:pointer;font-size:12px}\n.chip.on{border-color:var(--acc);color:var(--ink)}.chip b{color:var(--ink)}\n.row{background:var(--panel);border:1px solid var(--line);border-radius:8px;padding:10px 12px;margin:6px 0;display:flex;gap:10px;align-items:flex-start}\n.row .idx{color:var(--mut);min-width:22px}.row .main{flex:1}\n.tag{font-size:11px;padding:2px 7px;border-radius:6px;border:1px solid var(--line);color:var(--mut);margin-right:5px}\n.dom{font-weight:600}.url{color:var(--mut);font-size:12px;word-break:break-all}\n.pill{font-size:11px;padding:2px 7px;border-radius:6px}.pill.cite{background:rgba(57,217,138,.15);color:var(--cite)}.pill.brow{background:rgba(90,102,119,.2);color:#aeb8c8}\n.copy{background:none;border:1px solid var(--line);color:var(--mut);border-radius:6px;cursor:pointer;font-size:11px;padding:2px 8px}\n.hide{display:none}\n</style>\n</head>\n<body><div class=\"wrap\">\n<h1>AI Search Fan-Out</h1>\n<p class=\"sub\" id=\"sub\"></p>\n<div class=\"stat\" id=\"stat\"></div>\n<div class=\"cards\" id=\"cards\"></div>\n<div id=\"charts\"></div>\n<div class=\"tabs\"><button class=\"tab on\" data-tab=\"q\">Queries</button><button class=\"tab\" data-tab=\"u\">URLs</button></div>\n<div class=\"chips\" id=\"chips\"></div>\n<div id=\"list\"></div>\n</div>\n<script>\nconst D=${data};\nconst el=(t,c,h)=>{const e=document.createElement(t);if(c)e.className=c;if(h!=null)e.innerHTML=h;return e};\ndocument.getElementById('sub').textContent=D.platform+' · '+(D.meta.model||'model n/a')+' · '+D.meta.rounds+' search round(s) · prompt: '+(D.prompt||'');\ndocument.getElementById('stat').innerHTML='Total Fan-Out: '+D.counts.subQueries+' <small>sub-queries · '+D.counts.browsed+' URLs researched · '+D.counts.cited+' cited</small>';\nconst cards=[['Sub-queries',D.counts.subQueries],['Researched',D.counts.browsed],['Cited',D.counts.cited],['Browsed-only',D.counts.browsedOnly]];\nconst cc=document.getElementById('cards');cards.forEach(([k,v])=>{const c=el('div','card');c.appendChild(el('b',null,v));c.appendChild(el('span',null,k));cc.appendChild(c)});\nfunction barChart(title,obj){const max=Math.max(1,...Object.values(obj));const box=el('div','bars');box.appendChild(el('div',null,'<b>'+title+'</b>'));Object.entries(obj).forEach(([k,v])=>{const r=el('div','bar');r.appendChild(el('div','lab',k));const t=el('div','track');const f=el('div','fill');f.style.width=(v/max*100)+'%';t.appendChild(f);r.appendChild(t);r.appendChild(el('div','n',v));box.appendChild(r)});return box}\nconst charts=document.getElementById('charts');\ncharts.appendChild(barChart('URL Categories',D.aggregates.byCategory));\nlet tab='q',filter=null;\nconst chips=document.getElementById('chips'),list=document.getElementById('list');\nfunction render(){\n chips.innerHTML='';list.innerHTML='';\n if(tab==='q'){\n D.queries.forEach((q,i)=>{const r=el('div','row');r.appendChild(el('div','idx',i+1));const m=el('div','main');m.appendChild(el('div',null,esc(q)));r.appendChild(m);const b=el('button','copy','copy');b.onclick=()=>navigator.clipboard.writeText(q);r.appendChild(b);list.appendChild(r)});\n } else {\n const counts={};D.browsedUrls.forEach(s=>{counts[s.siteType]=(counts[s.siteType]||0)+1});\n Object.entries(counts).forEach(([k,v])=>{const c=el('button','chip'+(filter===k?' on':''),k+' <b>'+v+'</b>');c.onclick=()=>{filter=filter===k?null:k;render()};chips.appendChild(c)});\n D.browsedUrls.forEach(s=>{if(filter&&s.siteType!==filter)return;const r=el('div','row');const m=el('div','main');m.appendChild(el('div',null,'<span class=\"dom\">'+esc(s.domain)+'</span> <span class=\"pill '+(s.cited?'cite':'brow')+'\">'+(s.cited?'cited '+s.timesCited+'×':'browsed')+'</span> <span class=\"tag\">'+s.siteType+'</span>'));m.appendChild(el('div','url',esc(s.url)));r.appendChild(m);list.appendChild(r)});\n }\n}\nfunction esc(s){return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')}\ndocument.querySelectorAll('.tab').forEach(t=>t.onclick=()=>{document.querySelectorAll('.tab').forEach(x=>x.classList.remove('on'));t.classList.add('on');tab=t.dataset.tab;filter=null;render()});\nrender();\n</script>\n</body></html>`\n}\n","import type { Page } from 'playwright'\nimport { FanoutCdpCapture } from './cdp-capture.js'\nimport { adapterForHost } from './adapters/index.js'\nimport { buildFanoutResult } from './build.js'\nimport { enrichFanout, type EnrichedFanout } from './classify.js'\nimport { exportFanout, type FanoutExportPaths } from './export.js'\n\nexport interface FanoutCaptureInput {\n prompt?: string\n wait_ms?: number\n first_party_domain?: string\n reset?: boolean\n export?: boolean\n}\n\nexport interface FanoutCaptureOutput {\n result: EnrichedFanout\n exports: FanoutExportPaths | null\n}\n\nconst COMPOSER_SELECTORS = [\n '#prompt-textarea',\n 'div#prompt-textarea',\n 'textarea[data-testid=\"prompt-textarea\"]',\n 'div.ProseMirror[contenteditable=\"true\"]',\n 'div[contenteditable=\"true\"]',\n 'textarea',\n]\n\nasync function sendPrompt(page: Page, text: string): Promise<boolean> {\n for (const selector of COMPOSER_SELECTORS) {\n const locator = page.locator(selector).first()\n try {\n await locator.waitFor({ state: 'visible', timeout: 12_000 })\n } catch {\n continue\n }\n await locator.click({ timeout: 4_000 }).catch(() => undefined)\n await locator.focus().catch(() => undefined)\n await page.keyboard.type(text, { delay: 12 })\n await page.waitForTimeout(300).catch(() => undefined)\n await page.keyboard.press('Enter')\n return true\n }\n return false\n}\n\nasync function waitForAnswer(page: Page, cap: FanoutCdpCapture, baseline: number, waitMs: number): Promise<void> {\n const start = Date.now()\n while (Date.now() - start < waitMs && cap.answerStreamCount() <= baseline) {\n await page.waitForTimeout(400).catch(() => undefined)\n }\n await page.waitForTimeout(1_000).catch(() => undefined)\n}\n\nexport async function runFanoutCapture(page: Page, input: FanoutCaptureInput): Promise<FanoutCaptureOutput> {\n const cap = new FanoutCdpCapture()\n await cap.attach(page)\n try {\n const baseline = cap.answerStreamCount()\n if (input.prompt) await sendPrompt(page, input.prompt).catch(() => false)\n const waitMs = input.wait_ms ?? (input.prompt ? 90_000 : 8_000)\n await waitForAnswer(page, cap, baseline, waitMs)\n await cap.drain()\n\n let hostname = ''\n try {\n hostname = new URL(page.url()).hostname\n } catch {\n hostname = ''\n }\n const adapter = adapterForHost(hostname)\n if (!adapter) {\n throw new Error(`browser_capture_fanout supports chatgpt.com and claude.ai only; the session is on ${hostname || 'an unknown page'}. Navigate there first with browser_goto.`)\n }\n\n const text = cap.bestAnswerText()\n const parsed = adapter.parse(text, input.prompt || '')\n const result = buildFanoutResult({ platform: adapter.platform, parsed, prompt: input.prompt || '', ready: true, rawBytes: text.length })\n const enriched = enrichFanout(result, { firstPartyDomain: input.first_party_domain })\n const exports = input.export ? exportFanout(enriched) : null\n return { result: enriched, exports }\n } finally {\n await cap.detach().catch(() => undefined)\n }\n}\n","export const PACKAGE_VERSION = '0.3.2'\n","import { z } from 'zod'\n\nconst NullableString = z.string().nullable()\nconst BrowserRawObject = z.record(z.unknown())\n\nconst BrowserElementOutput = z.record(z.unknown())\n\nconst BrowserBaseOutput = {\n ok: z.boolean().describe('Whether the browser-agent action succeeded.'),\n tool: z.string().describe('Browser Agent MCP tool that produced this response.'),\n session_id: NullableString.describe('Browser session id when the response is scoped to a session.'),\n}\n\nconst BrowserReplayBaseOutput = {\n ...BrowserBaseOutput,\n replay_id: NullableString.describe('Replay id when the response is scoped to a replay.'),\n}\n\nexport const BrowserOpenInputSchema = {\n label: z.string().optional().describe('Optional human label for this session, shown in the watch console.'),\n url: z.string().url().optional().describe('Optional URL to navigate to immediately after opening.'),\n profile: z.string().optional().describe('Optional saved profile name to load a logged-in session for a site.'),\n save_profile_changes: z.boolean().optional().describe('Persist cookies and local storage back to the named profile when the session is closed. Use this for profile setup or intentional auth refreshes; avoid parallel sessions writing to the same profile.'),\n timeout_seconds: z.number().int().min(60).max(259200).optional().describe('How long the session may live before auto-termination. Defaults to 600. The browser idles into a zero-cost standby between actions, so a longer timeout is cheap.'),\n}\nexport type BrowserOpenInput = z.infer<ReturnType<typeof z.object<typeof BrowserOpenInputSchema>>>\n\nexport const BrowserProfileListInputSchema = {\n email: z.string().optional().describe('Optional Chrome account email or displayed profile name to filter for, for example seo@example.com.'),\n user_data_dir: z.string().optional().describe('Optional Chrome user data directory. Defaults to the current OS Chrome profile root.'),\n}\nexport type BrowserProfileListInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileListInputSchema>>>\n\nexport const BrowserProfileOnboardInputSchema = {\n email: z.string().optional().describe('Optional local Chrome account email to find and convert into a suggested Kernel profile name.'),\n profile: z.string().optional().describe('Optional Kernel browser profile name to create/load. If omitted, email is used to derive one.'),\n user_data_dir: z.string().optional().describe('Optional Chrome user data directory for email lookup. Defaults to the current OS Chrome profile root.'),\n url: z.string().url().optional().describe('Setup URL to open after creating the browser. Defaults to https://accounts.google.com/.'),\n label: z.string().optional().describe('Optional human label for this setup session.'),\n timeout_seconds: z.number().int().min(60).max(259200).optional().describe('How long the setup session may live before auto-termination. Defaults to 600.'),\n}\nexport type BrowserProfileOnboardInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileOnboardInputSchema>>>\n\nexport const BrowserProfileImportInputSchema = {\n email: z.string().optional().describe('Optional Chrome account email or displayed profile name to select from Chrome Local State.'),\n name: z.string().optional().describe('Name for the managed MCP Scraper browser profile. Defaults to a slug derived from the selected Chrome account.'),\n chrome_profile_directory: z.string().optional().describe('Optional Chrome profile directory to import, for example Default or Profile 1.'),\n user_data_dir: z.string().optional().describe('Optional source Chrome user data directory. Defaults to the current OS Chrome profile root.'),\n output_dir: z.string().optional().describe('Optional managed profile base directory. Defaults to ~/.mcp-scraper/browser-profiles.'),\n browser_executable_path: z.string().optional().describe('Optional Chrome executable path for local browser launches. Defaults to the installed Google Chrome path when found.'),\n overwrite: z.boolean().default(false).describe('Overwrite an existing managed profile clone with the same name.'),\n}\nexport type BrowserProfileImportInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileImportInputSchema>>>\n\nexport const BrowserProfileSyncInputSchema = {\n name: z.string().describe('Managed MCP Scraper browser profile name to refresh from its recorded source Chrome profile.'),\n output_dir: z.string().optional().describe('Optional managed profile base directory. Defaults to ~/.mcp-scraper/browser-profiles.'),\n browser_executable_path: z.string().optional().describe('Optional Chrome executable path to store in the refreshed profile manifest.'),\n}\nexport type BrowserProfileSyncInput = z.infer<ReturnType<typeof z.object<typeof BrowserProfileSyncInputSchema>>>\n\nexport const BrowserSessionInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n}\nexport type BrowserSessionInput = z.infer<ReturnType<typeof z.object<typeof BrowserSessionInputSchema>>>\n\nexport const BrowserLocateTargetSchema = z.object({\n name: z.string().optional().describe('Optional label for this target, echoed in the result.'),\n selector: z.string().optional().describe('CSS selector for the exact DOM element to locate, for example h1, input[name=\"q\"], or [data-testid=\"result\"].'),\n text: z.string().optional().describe('Visible text to locate when a selector is not known. The tool returns the text range bounds when possible.'),\n match: z.enum(['contains', 'exact']).default('contains').describe('How to match text targets. Defaults to contains.'),\n index: z.number().int().min(0).default(0).describe('Zero-based match index when multiple elements match.'),\n}).refine(value => Boolean(value.selector || value.text), {\n message: 'target requires selector or text',\n})\n\nexport const BrowserLocateInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n targets: z.array(BrowserLocateTargetSchema).min(1).max(20).describe('DOM targets to locate in the current viewport. Use selectors for exact elements, or text for visible text ranges.'),\n}\nexport type BrowserLocateInput = z.infer<ReturnType<typeof z.object<typeof BrowserLocateInputSchema>>>\n\nexport const BrowserGotoInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n url: z.string().url().describe('URL to navigate the browser to.'),\n}\nexport type BrowserGotoInput = z.infer<ReturnType<typeof z.object<typeof BrowserGotoInputSchema>>>\n\nexport const BrowserClickInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n x: z.number().describe('X coordinate to click, in screenshot pixels. Use only coordinates from the latest browser_screenshot, browser_read, or browser_locate result; do not guess.'),\n y: z.number().describe('Y coordinate to click, in screenshot pixels. Use only coordinates from the latest browser_screenshot, browser_read, or browser_locate result; do not guess.'),\n button: z.enum(['left', 'right', 'middle']).default('left').describe('Mouse button.'),\n num_clicks: z.number().int().min(1).max(3).optional().describe('Number of clicks, e.g. 2 for double-click.'),\n}\nexport type BrowserClickInput = z.infer<ReturnType<typeof z.object<typeof BrowserClickInputSchema>>>\n\nexport const BrowserTypeInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n text: z.string().describe('Text to type at the current focus. Click a field first to focus it.'),\n delay: z.number().int().min(0).max(500).optional().describe('Optional per-keystroke delay in ms for human-like typing.'),\n}\nexport type BrowserTypeInput = z.infer<ReturnType<typeof z.object<typeof BrowserTypeInputSchema>>>\n\nexport const BrowserScrollInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n delta_y: z.number().default(5).describe('Vertical scroll in wheel units. Positive scrolls down, negative up.'),\n delta_x: z.number().default(0).describe('Horizontal scroll in wheel units.'),\n x: z.number().optional().describe('X position to scroll at. Defaults to screen center.'),\n y: z.number().optional().describe('Y position to scroll at. Defaults to screen center.'),\n}\nexport type BrowserScrollInput = z.infer<ReturnType<typeof z.object<typeof BrowserScrollInputSchema>>>\n\nexport const BrowserPressInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n keys: z.array(z.string()).min(1).describe('Keys or combinations to press, e.g. [\"Return\"], [\"Ctrl+a\"], [\"Ctrl+Shift+Tab\"].'),\n}\nexport type BrowserPressInput = z.infer<ReturnType<typeof z.object<typeof BrowserPressInputSchema>>>\n\nexport const BrowserReplayStopInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n replay_id: z.string().describe('The replay id returned by browser_replay_start or browser_list_replays. Use only a returned replay_id; do not construct one yourself.'),\n}\nexport type BrowserReplayStopInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayStopInputSchema>>>\n\nexport const BrowserReplayDownloadInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n replay_id: z.string().describe('The replay id returned by browser_replay_start or browser_list_replays. Use only a returned replay_id; do not construct one yourself.'),\n filename: z.string().optional().describe('Optional local MP4 filename. Defaults to a timestamped replay filename.'),\n}\nexport type BrowserReplayDownloadInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayDownloadInputSchema>>>\n\nexport const BrowserReplayAnnotationSchema = z.object({\n type: z.enum(['box', 'circle', 'underline', 'arrow', 'label']).default('box').describe('Annotation style to draw over the replay.'),\n start_seconds: z.number().min(0).default(0).describe('When the annotation should appear in the replay.'),\n end_seconds: z.number().min(0).optional().describe('When the annotation should disappear. Defaults to two seconds after start_seconds.'),\n left: z.number().optional().describe('Target left edge in browser screenshot pixels. Use element.left from browser_screenshot/browser_read.'),\n top: z.number().optional().describe('Target top edge in browser screenshot pixels. Use element.top from browser_screenshot/browser_read.'),\n width: z.number().positive().optional().describe('Target width in browser screenshot pixels. Use element.width from browser_screenshot/browser_read.'),\n height: z.number().positive().optional().describe('Target height in browser screenshot pixels. Use element.height from browser_screenshot/browser_read.'),\n x: z.number().optional().describe('Point target x coordinate in browser screenshot pixels when no box is available.'),\n y: z.number().optional().describe('Point target y coordinate in browser screenshot pixels when no box is available.'),\n from_x: z.number().optional().describe('Arrow start x coordinate in browser screenshot pixels. Defaults near the target.'),\n from_y: z.number().optional().describe('Arrow start y coordinate in browser screenshot pixels. Defaults near the target.'),\n to_x: z.number().optional().describe('Arrow target x coordinate in browser screenshot pixels. Defaults to the target box center.'),\n to_y: z.number().optional().describe('Arrow target y coordinate in browser screenshot pixels. Defaults to the target box center.'),\n label: z.string().max(120).optional().describe('Optional text callout to render near the annotation.'),\n color: z.string().regex(/^#?[0-9a-fA-F]{6}$/).optional().describe('Annotation color as hex, for example #ff3b30.'),\n thickness: z.number().min(1).max(24).optional().describe('Stroke thickness in pixels. Defaults to 5.'),\n})\n\nexport const BrowserReplayMarkInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself. A replay must already be recording.'),\n target: BrowserLocateTargetSchema.describe('The exact DOM element or text range to mark in the current viewport.'),\n type: z.enum(['box', 'circle', 'underline', 'arrow']).default('box').describe('Annotation style to generate. Labels are included on the returned annotation when label is provided.'),\n label: z.string().max(120).optional().describe('Optional callout text to render near the target.'),\n color: z.string().regex(/^#?[0-9a-fA-F]{6}$/).optional().describe('Annotation color as hex, for example #ff3b30.'),\n thickness: z.number().min(1).max(24).optional().describe('Stroke thickness in pixels. Defaults to 5.'),\n padding: z.number().min(0).max(80).default(8).describe('Pixels to expand the DOM bounds so the highlight does not touch the text edge.'),\n start_offset_seconds: z.number().min(-5).max(10).default(-0.25).describe('Offset from the current replay time. Negative values make the callout appear just before the mark action is captured.'),\n duration_seconds: z.number().min(0.5).max(30).default(4).describe('How long the generated annotation should remain visible.'),\n}\nexport type BrowserReplayMarkInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayMarkInputSchema>>>\n\nexport const BrowserReplayAnnotateInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. Use only a returned session_id; do not construct one yourself.'),\n replay_id: z.string().describe('The replay id returned by browser_replay_start or browser_list_replays. Use only a returned replay_id; do not construct one yourself.'),\n annotations: z.array(BrowserReplayAnnotationSchema).min(1).max(50).describe('Timed overlay annotations to render on the replay. Prefer annotations returned by browser_replay_mark; otherwise use exact DOM bounds from browser_locate/browser_screenshot/browser_read.'),\n filename: z.string().optional().describe('Optional output MP4 filename. Defaults to a timestamped annotated replay filename.'),\n source_width: z.number().positive().optional().describe('Width of the screenshot coordinate space used for annotations. Defaults to the replay video width.'),\n source_height: z.number().positive().optional().describe('Height of the coordinate space used for annotations. When this is a page viewport height smaller than the replay video height, the annotator infers the browser chrome top offset.'),\n source_left_offset: z.number().min(0).optional().describe('Optional explicit X offset from annotation coordinates to replay video coordinates. Usually omitted.'),\n source_top_offset: z.number().min(0).optional().describe('Optional explicit Y offset from annotation coordinates to replay video coordinates. Usually omitted because browser chrome offset is inferred when source_height is a page viewport height.'),\n}\nexport type BrowserReplayAnnotateInput = z.infer<ReturnType<typeof z.object<typeof BrowserReplayAnnotateInputSchema>>>\n\nexport const BrowserListInputSchema = {\n include_closed: z.boolean().default(false).describe('Include closed sessions in the list.'),\n}\nexport type BrowserListInput = z.infer<ReturnType<typeof z.object<typeof BrowserListInputSchema>>>\n\nexport const BrowserCaptureFanoutInputSchema = {\n session_id: z.string().describe('The session id returned by browser_open or browser_list_sessions. The session must be a local-mode session on chatgpt.com or claude.ai that is logged in. Use only a returned session_id; do not construct one yourself.'),\n prompt: z.string().optional().describe('Optional prompt to type into the chat composer and submit before capturing. Omit to passively capture the fan-out of a prompt the user just ran in the visible browser. The prompt must trigger web search for there to be a fan-out.'),\n wait_ms: z.number().int().min(0).max(180000).optional().describe('How long to wait for the answer stream to finish before parsing. Defaults to 90000 when a prompt is sent, 8000 for passive capture. Capture ends as soon as the answer stream finishes.'),\n first_party_domain: z.string().optional().describe('The brand/site being researched, for example example.com. Sources on this domain are tagged First-party/vendor. Set this when the prompt is about a specific business.'),\n reset: z.boolean().default(false).describe('Clear any previously buffered stream for this page before capturing. Use when re-running to avoid mixing turns.'),\n export: z.boolean().default(false).describe('When true, write JSON, CSV, TSV exports (queries, citations, sources, domains) and a self-contained HTML report to MCP_SCRAPER_OUTPUT_DIR/fanout and return their paths.'),\n}\nexport type BrowserCaptureFanoutInput = z.infer<ReturnType<typeof z.object<typeof BrowserCaptureFanoutInputSchema>>>\n\nconst FanoutSourceOutput = z.object({\n url: z.string(),\n domain: z.string(),\n title: z.string(),\n cited: z.boolean(),\n timesCited: z.number().int().min(0),\n snippet: z.string(),\n round: z.number().int().nullable(),\n siteType: z.string().describe('URL category: First-party/vendor, News/media, Reddit, Social/video, Encyclopedia, Review site, Docs, or Blog.'),\n})\n\nexport const BrowserCaptureFanoutOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_capture_fanout'),\n platform: z.enum(['ChatGPT', 'Claude']).describe('Which AI-search surface the fan-out was captured from.'),\n captured_at: z.string(),\n prompt: z.string().describe('The user prompt that triggered the captured fan-out, when recoverable.'),\n meta: z.object({\n model: z.string(),\n finishType: z.string(),\n title: z.string(),\n rounds: z.number().int().min(0),\n }),\n queries: z.array(z.string()).describe('Every web-search sub-query the model issued, in capture order. Classify these by funnel stage and type yourself from the text.'),\n browsed_urls: z.array(FanoutSourceOutput).describe('Every researched URL (cited and browsed-only), cited first.'),\n cited_urls: z.array(FanoutSourceOutput).describe('The subset of researched URLs actually cited in the final answer.'),\n browsed_only: z.array(FanoutSourceOutput).describe('Researched URLs the model pulled but did not cite.'),\n snippets: z.array(z.object({ url: z.string(), domain: z.string(), title: z.string(), text: z.string() })),\n counts: z.object({\n subQueries: z.number().int().min(0),\n browsed: z.number().int().min(0),\n cited: z.number().int().min(0),\n browsedOnly: z.number().int().min(0),\n }),\n aggregates: z.object({\n topSites: z.array(z.object({ domain: z.string(), count: z.number().int(), cited: z.boolean(), timesCited: z.number().int(), siteType: z.string() })),\n citationOrder: z.array(z.object({ rank: z.number().int(), domain: z.string(), url: z.string(), timesCited: z.number().int() })),\n byCategory: z.record(z.number().int()),\n }).describe('Objective aggregates: top sourced sites by frequency, citation order, and URL-category counts.'),\n first_party_domain: z.string().nullable(),\n exports: z.object({\n dir: z.string(),\n json: z.string(),\n queriesCsv: z.string(),\n queriesTsv: z.string(),\n citationsCsv: z.string(),\n sourcesCsv: z.string(),\n domainsCsv: z.string(),\n report: z.string(),\n }).nullable().describe('Local file paths when export=true, otherwise null.'),\n debug: z.object({\n interceptorReady: z.boolean(),\n rawBytes: z.number().int().min(0),\n unmappedKeys: z.array(z.string()),\n note: z.string(),\n }).optional(),\n}\n\nexport const BrowserOpenOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_open'),\n session_id: z.string().describe('Session id returned by browser_open. Use only this exact value in later browser_* calls; do not construct one yourself.'),\n watch_url: z.string().describe('Human watch/takeover URL for this browser session.'),\n live_view_url: NullableString.describe('Raw live-view URL from the browser service when available.'),\n url: NullableString.describe('Initial URL requested by the caller, when provided.'),\n hint: z.string(),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserProfileListOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_list'),\n session_id: z.null(),\n profiles: z.array(BrowserRawObject),\n count: z.number().int().min(0),\n hint: z.string(),\n}\n\nexport const BrowserProfileOnboardOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_onboard'),\n session_id: z.string(),\n watch_url: z.string(),\n live_view_url: NullableString,\n profile: z.string(),\n setup_url: z.string(),\n chrome_profile: BrowserRawObject.nullable(),\n next_steps: z.array(z.string()),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserProfileImportOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_import'),\n session_id: z.null(),\n profile: BrowserRawObject,\n source_profile: BrowserRawObject,\n next_steps: z.array(z.string()),\n hint: z.string(),\n}\n\nexport const BrowserProfileSyncOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_profile_sync'),\n session_id: z.null(),\n profile: BrowserRawObject,\n source_profile: BrowserRawObject,\n hint: z.string(),\n}\n\nexport const BrowserScreenshotOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_screenshot'),\n url: NullableString,\n title: NullableString,\n text: z.string(),\n elements: z.array(BrowserElementOutput),\n screenshot: z.object({\n mime_type: z.string(),\n inline: z.boolean(),\n }).nullable(),\n}\n\nexport const BrowserReadOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_read'),\n url: NullableString,\n title: NullableString,\n text: z.string(),\n elements: z.array(BrowserElementOutput),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserLocateOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_locate'),\n url: NullableString,\n title: NullableString,\n viewport: BrowserRawObject.nullable(),\n replay: BrowserRawObject.nullable(),\n targets: z.array(BrowserRawObject),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserActionOutputSchema = {\n ...BrowserBaseOutput,\n result: BrowserRawObject.describe('Provider action result. Check ok and follow with browser_screenshot/browser_read when page state matters.'),\n nextRecommendedTool: z.string().nullable(),\n}\n\nexport const BrowserReplayStartOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_start'),\n view_url: NullableString,\n download_url: NullableString,\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserReplayStopOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_stop'),\n view_url: NullableString,\n download_url: NullableString,\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserListReplaysOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_list_replays'),\n replays: z.array(BrowserRawObject),\n count: z.number().int().min(0),\n}\n\nexport const BrowserReplayDownloadOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_download'),\n file_path: NullableString,\n bytes: z.number().int().min(0).nullable(),\n mime_type: NullableString,\n download_url: NullableString,\n}\n\nexport const BrowserReplayMarkOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_mark'),\n annotation: BrowserRawObject,\n source_width: z.number().nullable(),\n source_height: z.number().nullable(),\n target: BrowserRawObject.nullable(),\n hint: z.string(),\n}\n\nexport const BrowserReplayAnnotateOutputSchema = {\n ...BrowserReplayBaseOutput,\n tool: z.literal('browser_replay_annotate'),\n source_file_path: NullableString,\n annotated_file_path: NullableString,\n bytes: z.number().int().min(0).nullable(),\n width: z.number().int().min(0).nullable(),\n height: z.number().int().min(0).nullable(),\n annotation_count: z.number().int().min(0).nullable(),\n mime_type: NullableString,\n}\n\nexport const BrowserCloseOutputSchema = {\n ...BrowserBaseOutput,\n tool: z.literal('browser_close'),\n closed: z.boolean(),\n raw: BrowserRawObject.optional(),\n}\n\nexport const BrowserListSessionsOutputSchema = {\n ok: z.boolean(),\n tool: z.literal('browser_list_sessions'),\n session_id: z.null(),\n sessions: z.array(BrowserRawObject),\n count: z.number().int().min(0),\n}\n","import { execFile } from 'node:child_process'\nimport { mkdtemp, rm, stat, writeFile } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport { promisify } from 'node:util'\n\nconst execFileAsync = promisify(execFile)\n\nexport type ReplayAnnotationType = 'box' | 'circle' | 'underline' | 'arrow' | 'label'\n\nexport interface ReplayAnnotation {\n type?: ReplayAnnotationType\n start_seconds?: number\n end_seconds?: number\n left?: number\n top?: number\n width?: number\n height?: number\n x?: number\n y?: number\n from_x?: number\n from_y?: number\n to_x?: number\n to_y?: number\n label?: string\n color?: string\n thickness?: number\n}\n\nexport interface AnnotateReplayOptions {\n annotations: ReplayAnnotation[]\n sourceWidth?: number\n sourceHeight?: number\n sourceLeftOffset?: number\n sourceTopOffset?: number\n}\n\ninterface Size {\n width: number\n height: number\n}\n\ninterface Rect {\n left: number\n top: number\n width: number\n height: number\n}\n\ninterface CoordinateTransform {\n scaleX: number\n scaleY: number\n offsetX: number\n offsetY: number\n}\n\nexport interface AnnotatedReplayResult {\n filePath: string\n bytes: number\n width: number\n height: number\n annotationCount: number\n}\n\nfunction finiteNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value)\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n\nfunction formatAssTime(seconds: number): string {\n const safe = Math.max(0, seconds)\n const hours = Math.floor(safe / 3600)\n const minutes = Math.floor((safe % 3600) / 60)\n const wholeSeconds = Math.floor(safe % 60)\n const centiseconds = Math.floor((safe - Math.floor(safe)) * 100)\n return `${hours}:${String(minutes).padStart(2, '0')}:${String(wholeSeconds).padStart(2, '0')}.${String(centiseconds).padStart(2, '0')}`\n}\n\nfunction cssHexToAssColor(color?: string): string {\n const normalized = color?.trim().match(/^#?([0-9a-fA-F]{6})$/)?.[1] ?? 'ff3b30'\n const red = normalized.slice(0, 2)\n const green = normalized.slice(2, 4)\n const blue = normalized.slice(4, 6)\n return `&H${blue}${green}${red}&`\n}\n\nfunction escapeAssText(value: string): string {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\\{/g, '\\\\{')\n .replace(/\\}/g, '\\\\}')\n .replace(/\\r?\\n/g, '\\\\N')\n}\n\nfunction resolveCoordinateTransform(video: Size, source: Size, options: AnnotateReplayOptions): CoordinateTransform {\n const explicitOffsetX = finiteNumber(options.sourceLeftOffset) ? options.sourceLeftOffset : null\n const explicitOffsetY = finiteNumber(options.sourceTopOffset) ? options.sourceTopOffset : null\n const inferredTopOffset =\n explicitOffsetY == null &&\n Math.round(source.width) === Math.round(video.width) &&\n source.height < video.height &&\n video.height - source.height <= 220\n ? video.height - source.height\n : 0\n const offsetX = explicitOffsetX ?? 0\n const offsetY = explicitOffsetY ?? inferredTopOffset\n return {\n scaleX: (video.width - offsetX) / source.width,\n scaleY: (video.height - offsetY) / source.height,\n offsetX,\n offsetY,\n }\n}\n\nfunction transformPoint(x: number, y: number, transform: CoordinateTransform): { x: number; y: number } {\n return {\n x: x * transform.scaleX + transform.offsetX,\n y: y * transform.scaleY + transform.offsetY,\n }\n}\n\nfunction scaleRect(annotation: ReplayAnnotation, transform: CoordinateTransform): Rect {\n if (\n finiteNumber(annotation.left) &&\n finiteNumber(annotation.top) &&\n finiteNumber(annotation.width) &&\n finiteNumber(annotation.height)\n ) {\n const origin = transformPoint(annotation.left, annotation.top, transform)\n return {\n left: origin.x,\n top: origin.y,\n width: annotation.width * transform.scaleX,\n height: annotation.height * transform.scaleY,\n }\n }\n if (finiteNumber(annotation.x) && finiteNumber(annotation.y)) {\n const radius = finiteNumber(annotation.width) ? annotation.width / 2 : 28\n const point = transformPoint(annotation.x, annotation.y, transform)\n return {\n left: point.x - radius * transform.scaleX,\n top: point.y - radius * transform.scaleY,\n width: radius * 2 * transform.scaleX,\n height: radius * 2 * transform.scaleY,\n }\n }\n throw new Error('annotation needs either left/top/width/height or x/y')\n}\n\nfunction rectPath(rect: Rect): string {\n const x1 = Math.round(rect.left)\n const y1 = Math.round(rect.top)\n const x2 = Math.round(rect.left + rect.width)\n const y2 = Math.round(rect.top + rect.height)\n return `m ${x1} ${y1} l ${x2} ${y1} l ${x2} ${y2} l ${x1} ${y2} l ${x1} ${y1}`\n}\n\nfunction ellipsePath(rect: Rect): string {\n const cx = rect.left + rect.width / 2\n const cy = rect.top + rect.height / 2\n const rx = Math.max(4, rect.width / 2)\n const ry = Math.max(4, rect.height / 2)\n const points: string[] = []\n for (let i = 0; i <= 32; i += 1) {\n const t = (Math.PI * 2 * i) / 32\n const x = Math.round(cx + Math.cos(t) * rx)\n const y = Math.round(cy + Math.sin(t) * ry)\n points.push(`${i === 0 ? 'm' : 'l'} ${x} ${y}`)\n }\n return points.join(' ')\n}\n\nfunction filledRectPath(left: number, top: number, width: number, height: number): string {\n return rectPath({ left, top, width, height })\n}\n\nfunction arrowPath(fromX: number, fromY: number, toX: number, toY: number, thickness: number): string {\n const dx = toX - fromX\n const dy = toY - fromY\n const length = Math.max(1, Math.hypot(dx, dy))\n const ux = dx / length\n const uy = dy / length\n const px = -uy\n const py = ux\n const half = thickness / 2\n const head = Math.max(14, thickness * 4)\n const baseX = toX - ux * head\n const baseY = toY - uy * head\n const p1x = Math.round(fromX + px * half)\n const p1y = Math.round(fromY + py * half)\n const p2x = Math.round(baseX + px * half)\n const p2y = Math.round(baseY + py * half)\n const p3x = Math.round(baseX + px * head * 0.55)\n const p3y = Math.round(baseY + py * head * 0.55)\n const p4x = Math.round(toX)\n const p4y = Math.round(toY)\n const p5x = Math.round(baseX - px * head * 0.55)\n const p5y = Math.round(baseY - py * head * 0.55)\n const p6x = Math.round(baseX - px * half)\n const p6y = Math.round(baseY - py * half)\n const p7x = Math.round(fromX - px * half)\n const p7y = Math.round(fromY - py * half)\n return `m ${p1x} ${p1y} l ${p2x} ${p2y} l ${p3x} ${p3y} l ${p4x} ${p4y} l ${p5x} ${p5y} l ${p6x} ${p6y} l ${p7x} ${p7y} l ${p1x} ${p1y}`\n}\n\nfunction eventLine(start: number, end: number, body: string): string {\n return `Dialogue: 0,${formatAssTime(start)},${formatAssTime(end)},Default,,0,0,0,,${body}`\n}\n\nfunction labelLine(start: number, end: number, x: number, y: number, label: string): string {\n const safeX = Math.round(x)\n const safeY = Math.round(y)\n return eventLine(\n start,\n end,\n `{\\\\an7\\\\pos(${safeX},${safeY})\\\\fs30\\\\bord4\\\\shad0\\\\c&HFFFFFF&\\\\3c&H000000&}${escapeAssText(label)}`,\n )\n}\n\nfunction shapeLine(start: number, end: number, path: string, color: string, thickness: number, filled = false): string {\n const fillAlpha = filled ? '&H00&' : '&HFF&'\n const border = filled ? 0 : thickness\n return eventLine(\n start,\n end,\n `{\\\\an7\\\\pos(0,0)\\\\p1\\\\bord${border}\\\\shad0\\\\1a${fillAlpha}\\\\1c${color}\\\\3c${color}}${path}`,\n )\n}\n\nexport function buildAssSubtitle(options: AnnotateReplayOptions, video: Size): string {\n const source = {\n width: options.sourceWidth && options.sourceWidth > 0 ? options.sourceWidth : video.width,\n height: options.sourceHeight && options.sourceHeight > 0 ? options.sourceHeight : video.height,\n }\n const transform = resolveCoordinateTransform(video, source, options)\n const lines: string[] = []\n for (const annotation of options.annotations) {\n const start = Math.max(0, annotation.start_seconds ?? 0)\n const end = annotation.end_seconds && annotation.end_seconds > start ? annotation.end_seconds : start + 2\n const type = annotation.type ?? 'box'\n const color = cssHexToAssColor(annotation.color)\n const thickness = Math.round(clamp(annotation.thickness ?? 5, 2, 24))\n if (type === 'label') {\n if (!annotation.label) throw new Error('label annotation needs label')\n const rect = scaleRect(annotation, transform)\n lines.push(labelLine(start, end, rect.left, Math.max(8, rect.top), annotation.label))\n continue\n }\n if (type === 'arrow') {\n const rect = finiteNumber(annotation.to_x) && finiteNumber(annotation.to_y)\n ? null\n : scaleRect(annotation, transform)\n const toPoint = finiteNumber(annotation.to_x) && finiteNumber(annotation.to_y)\n ? transformPoint(annotation.to_x, annotation.to_y, transform)\n : null\n const toX = toPoint ? toPoint.x : rect!.left + rect!.width / 2\n const toY = toPoint ? toPoint.y : rect!.top + rect!.height / 2\n const fromPoint = finiteNumber(annotation.from_x) && finiteNumber(annotation.from_y)\n ? transformPoint(annotation.from_x, annotation.from_y, transform)\n : null\n const fromX = fromPoint ? fromPoint.x : clamp(toX - 120, 12, video.width - 12)\n const fromY = fromPoint ? fromPoint.y : clamp(toY - 90, 12, video.height - 12)\n lines.push(shapeLine(start, end, arrowPath(fromX, fromY, toX, toY, thickness), color, thickness, true))\n if (annotation.label) lines.push(labelLine(start, end, fromX + 8, Math.max(96, fromY - 36), annotation.label))\n continue\n }\n const rect = scaleRect(annotation, transform)\n if (type === 'underline') {\n const underlineTop = rect.top + rect.height + thickness\n lines.push(shapeLine(start, end, filledRectPath(rect.left, underlineTop, rect.width, thickness), color, 0, true))\n } else if (type === 'circle') {\n lines.push(shapeLine(start, end, ellipsePath(rect), color, thickness))\n } else {\n lines.push(shapeLine(start, end, rectPath(rect), color, thickness))\n }\n if (annotation.label) lines.push(labelLine(start, end, rect.left, Math.max(8, rect.top - 38), annotation.label))\n }\n\n return [\n '[Script Info]',\n 'ScriptType: v4.00+',\n `PlayResX: ${Math.round(video.width)}`,\n `PlayResY: ${Math.round(video.height)}`,\n 'ScaledBorderAndShadow: yes',\n '',\n '[V4+ Styles]',\n 'Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding',\n 'Style: Default,Arial,30,&H00FFFFFF,&H000000FF,&H00000000,&H90000000,0,0,0,0,100,100,0,0,1,2,0,7,0,0,0,1',\n '',\n '[Events]',\n 'Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text',\n ...lines,\n '',\n ].join('\\n')\n}\n\nasync function videoSize(inputFilePath: string): Promise<Size> {\n const { stdout } = await execFileAsync('ffprobe', [\n '-v',\n 'error',\n '-select_streams',\n 'v:0',\n '-show_entries',\n 'stream=width,height',\n '-of',\n 'json',\n inputFilePath,\n ], { maxBuffer: 1024 * 1024 })\n const parsed = JSON.parse(stdout) as { streams?: Array<{ width?: number; height?: number }> }\n const stream = parsed.streams?.[0]\n if (!stream?.width || !stream.height) throw new Error('could not read replay video dimensions')\n return { width: stream.width, height: stream.height }\n}\n\nfunction ffmpegFilterPath(path: string): string {\n return path.replace(/\\\\/g, '\\\\\\\\').replace(/:/g, '\\\\:')\n}\n\nexport async function annotateReplayVideo(\n inputFilePath: string,\n outputFilePath: string,\n options: AnnotateReplayOptions,\n): Promise<AnnotatedReplayResult> {\n if (!options.annotations.length) throw new Error('annotations must include at least one item')\n const size = await videoSize(inputFilePath)\n const tmp = await mkdtemp(join(tmpdir(), 'mcp-scraper-ass-'))\n const assPath = join(tmp, 'annotations.ass')\n try {\n await writeFile(assPath, buildAssSubtitle(options, size), 'utf8')\n await execFileAsync('ffmpeg', [\n '-y',\n '-i',\n inputFilePath,\n '-vf',\n `ass=${ffmpegFilterPath(assPath)}`,\n '-c:v',\n 'libx264',\n '-pix_fmt',\n 'yuv420p',\n '-movflags',\n '+faststart',\n '-c:a',\n 'copy',\n outputFilePath,\n ], { maxBuffer: 1024 * 1024 * 20 })\n const out = await stat(outputFilePath)\n return {\n filePath: outputFilePath,\n bytes: out.size,\n width: size.width,\n height: size.height,\n annotationCount: options.annotations.length,\n }\n } finally {\n await rm(tmp, { recursive: true, force: true })\n }\n}\n"],"mappings":"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","names":["import_node_fs","import_node_os","import_node_path","import_node_fs","import_node_os","import_node_path","import_promises","import_node_os","import_node_path","import_node_fs","import_node_path","esc","import_node_fs","import_node_os","import_node_path","Papa","exports","StealthPlugin","import_promises","import_node_os","import_node_path","safe","rect","outputBaseDir","finiteNumber","server","baseUrl","session","res","content","structured","sessions","exports"]}