record_page
Record browser sessions as video by opening URLs with customizable viewport dimensions for different platform requirements.
Instructions
Open a URL in a browser and start recording video. Returns a session ID. Call stop_recording when done. Common sizes: 1280x720 (16:9, README/YouTube), 1080x1920 (9:16, IG Reels/TikTok), 1080x1080 (1:1, Instagram/LinkedIn).
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | URL to open and record | |
| width | No | Viewport width in pixels | |
| height | No | Viewport height in pixels |
Implementation Reference
- src/index.js:19-39 (handler)Registration of the 'record_page' tool in index.js, which calls startRecording.
mcp.tool( 'record_page', 'Open a URL in a browser and start recording video. Returns a session ID. Call stop_recording when done. Common sizes: 1280x720 (16:9, README/YouTube), 1080x1920 (9:16, IG Reels/TikTok), 1080x1080 (1:1, Instagram/LinkedIn).', { url: z.string().describe('URL to open and record'), width: z.number().optional().default(1280).describe('Viewport width in pixels'), height: z.number().optional().default(720).describe('Viewport height in pixels') }, async ({ url, width, height }) => { try { const result = await startRecording(url, { width, height }); return { content: [{ type: 'text', text: `Recording started!\n\nSession: ${result.sessionId}\nURL: ${result.url}\nStarted: ${result.startedAt}\n\nUse interact_page to scroll/click/hover during recording.\nCall stop_recording with sessionId "${result.sessionId}" when done.` }] }; } catch (err) { return { content: [{ type: 'text', text: `Error: ${err.message}` }], isError: true }; } } - src/recorder.js:30-58 (handler)The startRecording function, which actually opens the Playwright page and initializes video recording.
export async function startRecording(url, options = {}) { const b = await ensureBrowser(); const width = options.width || 1280; const height = options.height || 720; const outputDir = options.outputDir || DEFAULT_OUTPUT_DIR; const sessionId = randomUUID().slice(0, 8); await mkdir(outputDir, { recursive: true }); // Each context gets its own video recording const context = await b.newContext({ recordVideo: { dir: outputDir, size: { width, height } }, viewport: { width, height } }); const page = await context.newPage(); // Use 'load' instead of 'networkidle' — some pages never idle (WebSocket, polling) await page.goto(url, { waitUntil: 'load', timeout: 30_000 }); const startedAt = new Date().toISOString(); sessions.set(sessionId, { context, page, url, startedAt, outputDir }); return { sessionId, url, startedAt }; }