UNPKG

puppeteer-vision-mcp-server

Version:

MCP Server for scraping webpages and converting to markdown

212 lines (211 loc) 7.38 kB
import fs from 'fs'; import { execSync } from 'child_process'; import * as path from 'path'; import * as os from 'os'; import { config } from '../config.js'; /** * Attempts to find Chrome installation on the current system * @returns Path to Chrome executable or null if not found */ export async function findChrome() { const platform = process.platform; try { // If using Chrome for Testing, use different search paths if (config.useChromeForTesting) { return findChromeForTesting(platform); } // Different strategies based on OS for regular Chrome if (platform === 'win32') { return findChromeWindows(); } else if (platform === 'darwin') { return findChromeMacOS(); } else if (platform === 'linux') { return findChromeLinux(); } } catch (error) { console.warn('Error while trying to find Chrome:', error); } console.warn('Could not find Chrome installation. Using default Puppeteer browser.'); return null; } /** * Attempts to find Chrome for Testing installation * @param platform The current platform (win32, darwin, linux) * @returns Path to Chrome for Testing executable or null if not found */ function findChromeForTesting(platform) { // Common locations for Chrome for Testing const commonPaths = { win32: [ path.join(os.homedir(), 'AppData', 'Local', 'Google', 'Chrome for Testing', 'chrome.exe'), 'C:\\Program Files\\Google\\Chrome for Testing\\chrome.exe', 'C:\\Program Files (x86)\\Google\\Chrome for Testing\\chrome.exe', ], darwin: [ '/Applications/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing', path.join(os.homedir(), 'Applications', 'Google Chrome for Testing.app', 'Contents', 'MacOS', 'Google Chrome for Testing'), '/Applications/Chrome for Testing.app/Contents/MacOS/Chrome for Testing', ], linux: [ '/usr/bin/google-chrome-for-testing', '/usr/local/bin/chrome-for-testing', path.join(os.homedir(), 'chrome-for-testing', 'chrome'), ], }; // Check common locations const paths = commonPaths[platform] || []; for (const chromePath of paths) { if (fs.existsSync(chromePath)) { return chromePath; } } // Check in common download directories if it's a standalone download const downloadDirs = [ path.join(os.homedir(), 'Downloads'), path.join(os.homedir(), 'chrome-for-testing'), path.join(os.homedir(), 'Documents', 'chrome-for-testing'), '/tmp/chrome-for-testing', ]; for (const dir of downloadDirs) { if (fs.existsSync(dir)) { try { // Look for chrome-*/chrome or chrome-*/chrome.exe const files = fs.readdirSync(dir); for (const file of files) { if (file.startsWith('chrome-')) { const chromeDir = path.join(dir, file); if (fs.statSync(chromeDir).isDirectory()) { const executable = platform === 'win32' ? 'chrome.exe' : 'chrome'; const executablePath = path.join(chromeDir, executable); if (fs.existsSync(executablePath)) { return executablePath; } } } } } catch (e) { // Continue to the next directory } } } console.warn('Chrome for Testing not found. Falling back to regular Chrome.'); // Fall back to regular Chrome if Chrome for Testing not found if (platform === 'win32') { return findChromeWindows(); } else if (platform === 'darwin') { return findChromeMacOS(); } else if (platform === 'linux') { return findChromeLinux(); } return null; } /** * Finds Chrome installation on Windows * @returns Path to Chrome executable or null if not found */ function findChromeWindows() { const commonPaths = [ 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', `${os.homedir()}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe`, ]; // Check for Chrome in common locations for (const path of commonPaths) { if (fs.existsSync(path)) { return path; } } // Try to find via registry try { const regOutput = execSync('reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe" /ve', { encoding: 'utf8' }); const regMatch = regOutput.match(/REG_SZ\s+(.+)$/m); if (regMatch && regMatch[1]) { const chromePath = regMatch[1].trim(); if (fs.existsSync(chromePath)) { return chromePath; } } } catch (e) { // Registry query failed, continue with other methods } return null; } /** * Finds Chrome installation on macOS * @returns Path to Chrome executable or null if not found */ function findChromeMacOS() { const commonPaths = [ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', `${os.homedir()}/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`, ]; // Check for Chrome in common locations for (const path of commonPaths) { if (fs.existsSync(path)) { return path; } } // Try to find via mdfind (Spotlight) try { const mdfindOutput = execSync('mdfind "kMDItemCFBundleIdentifier == com.google.Chrome"', { encoding: 'utf8' }); if (mdfindOutput.trim()) { const chromeAppPath = mdfindOutput.trim().split('\n')[0]; if (chromeAppPath) { const chromeBinaryPath = path.join(chromeAppPath, 'Contents/MacOS/Google Chrome'); if (fs.existsSync(chromeBinaryPath)) { return chromeBinaryPath; } } } } catch (e) { // mdfind failed, continue with other methods } return null; } /** * Finds Chrome installation on Linux * @returns Path to Chrome executable or null if not found */ function findChromeLinux() { const commonNames = [ 'google-chrome', 'chrome', 'chromium', 'chromium-browser', ]; // Try to find via which command for (const name of commonNames) { try { const whichOutput = execSync(`which ${name}`, { encoding: 'utf8' }); if (whichOutput.trim()) { return whichOutput.trim(); } } catch (e) { // which command failed for this binary, try next } } // Check common locations const commonPaths = [ '/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chrome', '/usr/bin/chromium', '/usr/bin/chromium-browser', '/snap/bin/chromium', ]; for (const path of commonPaths) { if (fs.existsSync(path)) { return path; } } return null; }