UNPKG

@danielsogl/lighthouse-mcp

Version:

A comprehensive Model Context Protocol (MCP) server that provides web performance auditing, accessibility testing, SEO analysis, security assessment, and Core Web Vitals monitoring using Google Lighthouse. Enables LLMs and AI agents to perform detailed we

161 lines (160 loc) 6.2 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.launchChrome = launchChrome; exports.getScreenEmulation = getScreenEmulation; exports.buildLighthouseOptions = buildLighthouseOptions; exports.runRawLighthouseAudit = runRawLighthouseAudit; exports.filterAuditsByCategory = filterAuditsByCategory; exports.formatCategoryScores = formatCategoryScores; exports.extractKeyMetrics = extractKeyMetrics; exports.runLighthouseAudit = runLighthouseAudit; exports.getDetailedAuditResults = getDetailedAuditResults; const lighthouse_1 = __importDefault(require("lighthouse")); const chromeLauncher = __importStar(require("chrome-launcher")); const lighthouse_constants_1 = require("./lighthouse-constants"); // Helper function to launch Chrome with standard configuration async function launchChrome() { return chromeLauncher.launch({ chromeFlags: lighthouse_constants_1.CHROME_FLAGS, }); } // Helper function to get screen emulation settings function getScreenEmulation(device) { const dimensions = lighthouse_constants_1.SCREEN_DIMENSIONS[device]; return { mobile: device !== "desktop", width: dimensions.width, height: dimensions.height, deviceScaleFactor: 1, disabled: false, }; } // Helper function to build Lighthouse options function buildLighthouseOptions(port, device, categories, throttling = false) { return { logLevel: "info", output: "json", onlyCategories: categories, port, formFactor: device, screenEmulation: getScreenEmulation(device), throttling: throttling ? lighthouse_constants_1.THROTTLING_CONFIG.enabled : lighthouse_constants_1.THROTTLING_CONFIG.disabled, }; } // Helper function to run a raw Lighthouse audit async function runRawLighthouseAudit(url, categories, device = "desktop", throttling = false) { const chrome = await launchChrome(); try { const options = buildLighthouseOptions(chrome.port, device, categories, throttling); const runnerResult = (await (0, lighthouse_1.default)(url, options)); if (!runnerResult) { throw new Error("Failed to run Lighthouse audit"); } return runnerResult; } finally { await chrome.kill(); } } // Helper function to filter audits by category function filterAuditsByCategory(lhr, categoryKey) { return Object.entries(lhr.audits) .filter(([key]) => lhr.categories[categoryKey]?.auditRefs?.some((ref) => ref.id === key)) .map(([key, audit]) => ({ id: key, title: audit.title, description: audit.description, score: audit.score, scoreDisplayMode: audit.scoreDisplayMode, displayValue: audit.displayValue, })); } // Helper function to format category scores from LHR function formatCategoryScores(lhr) { const auditCategories = {}; for (const [key, category] of Object.entries(lhr.categories)) { auditCategories[key] = { title: category.title, score: Math.round((category.score || 0) * 100), description: category.description, }; } return auditCategories; } // Helper function to extract key metrics from LHR function extractKeyMetrics(lhr) { const metrics = {}; if (lhr.audits) { for (const metric of lighthouse_constants_1.KEY_METRICS) { const audit = lhr.audits[metric]; if (audit) { metrics[metric] = { title: audit.title, value: audit.numericValue || 0, displayValue: audit.displayValue || "N/A", score: audit.score !== null ? Math.round((audit.score || 0) * 100) : null, }; } } } return metrics; } // Main function to run Lighthouse audit with formatted results async function runLighthouseAudit(url, categories, device = "desktop", throttling = false) { const runnerResult = await runRawLighthouseAudit(url, categories, device, throttling); const { lhr } = runnerResult; return { url: lhr.finalDisplayedUrl, fetchTime: lhr.fetchTime, version: lhr.lighthouseVersion, userAgent: lhr.userAgent, device, categories: formatCategoryScores(lhr), metrics: extractKeyMetrics(lhr), }; } // Helper function to get detailed audit results for a category async function getDetailedAuditResults(url, category, device) { const runnerResult = await runRawLighthouseAudit(url, [category], device); const { lhr } = runnerResult; return { lhr, audits: filterAuditsByCategory(lhr, category), }; }