Skip to main content
Glama

Fetch MCP

by jae-jae
browserInstall.ts5.45 kB
import { spawn } from "child_process"; import { createRequire } from "module"; import { existsSync } from "fs"; import { logger } from "../utils/logger.js"; // Create require for ES modules const require = createRequire(import.meta.url); /** * Tool definition for browser_install */ export const browserInstallTool = { name: "browser_install", description: "Install Playwright Chromium browser binary. Call this if you get an error about the browser not being installed.", inputSchema: { type: "object", properties: { withDeps: { type: "boolean", description: "Install system dependencies required by Chromium browser. Default is false", default: false }, force: { type: "boolean", description: "Force installation even if Chromium is already installed. Default is false", default: false } }, required: [] } }; /** * Implementation of the browser_install tool */ export async function browserInstall(args: any) { const withDeps = args?.withDeps === true; const force = args?.force === true; logger.info("[BrowserInstall] Starting installation of Chromium browser..."); try { // Build the command arguments const installArgs = ["playwright", "install"]; if (withDeps) { installArgs.push("--with-deps"); } if (force) { installArgs.push("--force"); } installArgs.push("chromium"); logger.debug(`[BrowserInstall] Executing: npx ${installArgs.join(" ")}`); // Execute the installation command const result = await executePlaywrightInstall(installArgs); if (result.success) { const successMessage = `Successfully installed Chromium browser${withDeps ? " with system dependencies" : ""}`; logger.info(`[BrowserInstall] ${successMessage}`); return { content: [ { type: "text", text: `✅ ${successMessage}\n\n${result.output}` } ] }; } else { const errorMessage = `Failed to install Chromium browser: ${result.error}`; logger.error(`[BrowserInstall] ${errorMessage}`); return { content: [ { type: "text", text: `❌ ${errorMessage}\n\nOutput:\n${result.output}\n\nError:\n${result.error}` } ] }; } } catch (error: any) { const errorMessage = `Chromium installation failed: ${error.message}`; logger.error(`[BrowserInstall] ${errorMessage}`); return { content: [ { type: "text", text: `❌ ${errorMessage}\n\nPlease check your internet connection and try again. You may also need to run with elevated privileges.` } ] }; } } /** * Execute playwright install command with dual strategy: * 1. Try to use local playwright CLI (ensures version consistency) * 2. Fallback to npx if local CLI not found (ensures availability) */ function executePlaywrightInstall(args: string[]): Promise<{success: boolean, output: string, error: string}> { return new Promise((resolve) => { let command: string; let commandArgs: string[]; let strategyUsed: string; // Strategy 1: Try to use local playwright CLI try { const playwrightPackagePath = require.resolve("playwright/package.json"); const playwrightDir = playwrightPackagePath.replace("/package.json", ""); const playwrightCliPath = `${playwrightDir}/cli.js`; // Verify CLI file exists if (existsSync(playwrightCliPath)) { // Remove 'playwright' from args as we're directly calling the CLI const filteredArgs = args.filter(arg => arg !== "playwright"); command = "node"; commandArgs = [playwrightCliPath, ...filteredArgs]; strategyUsed = "local CLI"; logger.info(`[BrowserInstall] Using local Playwright CLI: ${playwrightCliPath}`); logger.debug(`[BrowserInstall] Command: node ${commandArgs.join(" ")}`); } else { throw new Error("CLI file not found"); } } catch (error: any) { // Strategy 2: Fallback to npx command = "npx"; commandArgs = args; strategyUsed = "npx fallback"; logger.warn(`[BrowserInstall] Local CLI not found, falling back to npx: ${error.message}`); logger.debug(`[BrowserInstall] Command: npx ${commandArgs.join(" ")}`); } const child = spawn(command, commandArgs, { stdio: "pipe", shell: process.platform === "win32" }); let stdout = ""; let stderr = ""; child.stdout?.on("data", (data) => { const output = data.toString(); stdout += output; logger.debug(`[BrowserInstall] [${strategyUsed}] stdout: ${output.trim()}`); }); child.stderr?.on("data", (data) => { const output = data.toString(); stderr += output; logger.debug(`[BrowserInstall] [${strategyUsed}] stderr: ${output.trim()}`); }); child.on("close", (code) => { const success = code === 0; logger.info(`[BrowserInstall] [${strategyUsed}] Process exited with code: ${code}`); resolve({ success, output: stdout, error: stderr }); }); child.on("error", (error) => { logger.error(`[BrowserInstall] [${strategyUsed}] Process error: ${error.message}`); resolve({ success: false, output: stdout, error: error.message }); }); }); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jae-jae/fetcher-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server