puppeteer-vision-mcp-server
Version:
MCP Server for scraping webpages and converting to markdown
212 lines (211 loc) • 7.38 kB
JavaScript
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;
}