screenshot-element
Capture a screenshot of a specific webpage element using a CSS selector. Save the image in PNG, JPEG, or WebP format with customizable quality and padding for precise visual verification.
Instructions
Captures a screenshot of a specific element on a webpage using a CSS selector
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Image format for the screenshot | png |
| padding | No | Padding around the element in pixels | |
| quality | No | Quality of the image (0-100), only applicable for jpeg and webp | |
| selector | Yes | CSS selector for the element to screenshot | |
| url | Yes | The URL of the webpage | |
| useDefaultBrowser | No | Whether to use the system's default browser instead of Puppeteer's bundled Chromium | |
| useSavedAuth | No | Whether to use saved cookies from previous login | |
| visibleBrowser | No | Whether to show the browser window (non-headless mode) | |
| waitForSelector | No | Whether to wait for the selector to appear |
Implementation Reference
- src/index.ts:768-900 (handler)The handler function that executes the screenshot-element tool logic. It launches a browser (Puppeteer or default), loads cookies if requested, navigates to the URL, waits for the element selector, captures a screenshot of the specific element with optional padding/format/quality, and returns the base64 image.async ({ url, selector, waitForSelector, format, quality, padding, useSavedAuth, useDefaultBrowser, visibleBrowser }) => { let page: Page | null = null; try { // Initialize browser with appropriate options const isHeadless = !visibleBrowser; const browserInstance = await initBrowser(isHeadless, useDefaultBrowser && visibleBrowser); // Create a new page page = await browserInstance.newPage(); // Load saved cookies if requested if (useSavedAuth) { const cookies = await loadCookies(url); if (cookies.length > 0) { await page.setCookie(...cookies); } } // Set viewport (matching screenshot-page tool) await page.setViewport({ width: 1920, height: 1080 }); // Set user agent to avoid bot detection await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); // Additional anti-detection measures for Google await page.evaluateOnNewDocument(() => { // Remove webdriver property delete (window.navigator as any).webdriver; // Override the plugins property to add fake plugins Object.defineProperty(window.navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] }); // Override the languages property Object.defineProperty(window.navigator, 'languages', { get: () => ['en-US', 'en'] }); // Override permissions Object.defineProperty(window.navigator, 'permissions', { get: () => ({ query: () => Promise.resolve({ state: 'granted' }) }) }); }); // Navigate to the URL await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 }); // Wait for the selector if requested if (waitForSelector) { await page.waitForSelector(selector, { timeout: 10000 }); } // Get the element const element = await page.$(selector); if (!element) { return { isError: true, content: [ { type: "text", text: `Element not found with selector: ${selector}`, }, ], }; } // Add padding if requested if (padding > 0) { await page.evaluate((sel, pad) => { const el = document.querySelector(sel); if (el) { (el as HTMLElement).style.padding = `${pad}px`; } }, selector, padding); } // Prepare screenshot options const screenshotOptions: any = { encoding: 'base64', type: format }; // Add quality option for jpeg and webp if ((format === 'jpeg' || format === 'webp') && quality !== undefined) { screenshotOptions.quality = quality; } // Take screenshot of the element const screenshot = await element.screenshot(screenshotOptions) as string; // Determine browser type for response const browserType = useDefaultBrowser && visibleBrowser ? 'default browser' : 'Puppeteer browser'; const browserMode = visibleBrowser ? 'visible' : 'headless'; return { content: [ { type: "text", text: `Element screenshot captured successfully!\n\nBrowser: ${browserType} (${browserMode})\nURL: ${url}\nSelector: ${selector}\nFormat: ${format}` }, { type: "image", data: screenshot, mimeType: `image/${format}` } ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { isError: true, content: [ { type: "text", text: `Error capturing element screenshot: ${errorMessage}`, }, ], }; } finally { // Close the page if (page) { await page.close().catch(() => {}); } } }
- src/index.ts:757-767 (schema)The input schema defined using Zod for the screenshot-element tool parameters.{ url: z.string().url().describe("The URL of the webpage"), selector: z.string().describe("CSS selector for the element to screenshot"), waitForSelector: z.boolean().optional().default(true).describe("Whether to wait for the selector to appear"), format: z.enum(['png', 'jpeg', 'webp']).optional().default('png').describe("Image format for the screenshot"), quality: z.number().min(0).max(100).optional().describe("Quality of the image (0-100), only applicable for jpeg and webp"), padding: z.number().optional().default(0).describe("Padding around the element in pixels"), useSavedAuth: z.boolean().optional().default(true).describe("Whether to use saved cookies from previous login"), useDefaultBrowser: z.boolean().optional().default(false).describe("Whether to use the system's default browser instead of Puppeteer's bundled Chromium"), visibleBrowser: z.boolean().optional().default(false).describe("Whether to show the browser window (non-headless mode)") },
- src/index.ts:754-901 (registration)The registration of the screenshot-element tool using server.tool(), including name, description, schema, and inline handler.server.tool( "screenshot-element", "Captures a screenshot of a specific element on a webpage using a CSS selector", { url: z.string().url().describe("The URL of the webpage"), selector: z.string().describe("CSS selector for the element to screenshot"), waitForSelector: z.boolean().optional().default(true).describe("Whether to wait for the selector to appear"), format: z.enum(['png', 'jpeg', 'webp']).optional().default('png').describe("Image format for the screenshot"), quality: z.number().min(0).max(100).optional().describe("Quality of the image (0-100), only applicable for jpeg and webp"), padding: z.number().optional().default(0).describe("Padding around the element in pixels"), useSavedAuth: z.boolean().optional().default(true).describe("Whether to use saved cookies from previous login"), useDefaultBrowser: z.boolean().optional().default(false).describe("Whether to use the system's default browser instead of Puppeteer's bundled Chromium"), visibleBrowser: z.boolean().optional().default(false).describe("Whether to show the browser window (non-headless mode)") }, async ({ url, selector, waitForSelector, format, quality, padding, useSavedAuth, useDefaultBrowser, visibleBrowser }) => { let page: Page | null = null; try { // Initialize browser with appropriate options const isHeadless = !visibleBrowser; const browserInstance = await initBrowser(isHeadless, useDefaultBrowser && visibleBrowser); // Create a new page page = await browserInstance.newPage(); // Load saved cookies if requested if (useSavedAuth) { const cookies = await loadCookies(url); if (cookies.length > 0) { await page.setCookie(...cookies); } } // Set viewport (matching screenshot-page tool) await page.setViewport({ width: 1920, height: 1080 }); // Set user agent to avoid bot detection await page.setUserAgent('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'); // Additional anti-detection measures for Google await page.evaluateOnNewDocument(() => { // Remove webdriver property delete (window.navigator as any).webdriver; // Override the plugins property to add fake plugins Object.defineProperty(window.navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] }); // Override the languages property Object.defineProperty(window.navigator, 'languages', { get: () => ['en-US', 'en'] }); // Override permissions Object.defineProperty(window.navigator, 'permissions', { get: () => ({ query: () => Promise.resolve({ state: 'granted' }) }) }); }); // Navigate to the URL await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 }); // Wait for the selector if requested if (waitForSelector) { await page.waitForSelector(selector, { timeout: 10000 }); } // Get the element const element = await page.$(selector); if (!element) { return { isError: true, content: [ { type: "text", text: `Element not found with selector: ${selector}`, }, ], }; } // Add padding if requested if (padding > 0) { await page.evaluate((sel, pad) => { const el = document.querySelector(sel); if (el) { (el as HTMLElement).style.padding = `${pad}px`; } }, selector, padding); } // Prepare screenshot options const screenshotOptions: any = { encoding: 'base64', type: format }; // Add quality option for jpeg and webp if ((format === 'jpeg' || format === 'webp') && quality !== undefined) { screenshotOptions.quality = quality; } // Take screenshot of the element const screenshot = await element.screenshot(screenshotOptions) as string; // Determine browser type for response const browserType = useDefaultBrowser && visibleBrowser ? 'default browser' : 'Puppeteer browser'; const browserMode = visibleBrowser ? 'visible' : 'headless'; return { content: [ { type: "text", text: `Element screenshot captured successfully!\n\nBrowser: ${browserType} (${browserMode})\nURL: ${url}\nSelector: ${selector}\nFormat: ${format}` }, { type: "image", data: screenshot, mimeType: `image/${format}` } ], }; } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); return { isError: true, content: [ { type: "text", text: `Error capturing element screenshot: ${errorMessage}`, }, ], }; } finally { // Close the page if (page) { await page.close().catch(() => {}); } } } );