get_lcp_opportunities
Identify Large Contentful Paint (LCP) optimization opportunities for a website by analyzing its performance. Input the URL, choose a device type, and set thresholds to receive actionable recommendations for improving LCP.
Instructions
Get LCP optimization opportunities for a website
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device to emulate (default: desktop) | desktop |
| includeDetails | No | Include detailed metrics and recommendations | |
| threshold | No | LCP threshold in seconds (default: 2.5) | |
| url | Yes | URL to audit |
Implementation Reference
- src/lighthouse-performance.ts:139-174 (handler)Core handler function that executes Lighthouse performance audit, extracts LCP value, identifies improvement opportunities from predefined audits, and returns structured results including whether improvement is needed.export async function getLcpOpportunities( url: string, device: "desktop" | "mobile" = "desktop", threshold = DEFAULTS.LCP_THRESHOLD, ) { const runnerResult = await runRawLighthouseAudit(url, ["performance"], device); const { lhr } = runnerResult; const lcpValue = (lhr.audits["largest-contentful-paint"]?.numericValue || 0) / 1000; const needsImprovement = lcpValue > threshold; const opportunities = LCP_OPPORTUNITIES.map((auditId) => { const audit = lhr.audits[auditId]; if (audit && audit.score !== null && audit.score < 1) { return { id: auditId, title: audit.title, description: audit.description, score: audit.score, displayValue: audit.displayValue, numericValue: audit.numericValue, }; } return null; }).filter(Boolean); return { url: lhr.finalDisplayedUrl, device, lcpValue, threshold, needsImprovement, opportunities, fetchTime: lhr.fetchTime, }; }
- src/tools/performance.ts:305-365 (registration)MCP server tool registration for 'get_lcp_opportunities', wrapping the handler with error handling, structured response formatting, and recommendations.server.tool( "get_lcp_opportunities", "Get LCP optimization opportunities for a website", lcpOpportunitiesSchema, async ({ url, device, threshold, includeDetails }) => { try { const result = await getLcpOpportunities(url, device, threshold); const structuredResult = createStructuredPerformance( "LCP Optimization Opportunities", result.url, result.device, { lcpValue: result.lcpValue, threshold: result.threshold, needsImprovement: result.needsImprovement, opportunities: result.opportunities || [], fetchTime: result.fetchTime, includeDetails, }, !result.needsImprovement ? ["LCP performance is within acceptable range"] : [ "Optimize image loading and compression", "Implement resource hints (preload, prefetch)", "Reduce server response times", "Minimize render-blocking resources", ], ); return { content: [ { type: "text" as const, text: JSON.stringify(structuredResult, null, 2), }, ], }; } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : String(error); return { content: [ { type: "text" as const, text: JSON.stringify( { error: "LCP opportunities analysis failed", url, device: device || "desktop", message: errorMessage, }, null, 2, ), }, ], isError: true, }; } }, );
- src/schemas.ts:97-102 (schema)Input schema validation using Zod for the get_lcp_opportunities tool parameters: URL, device, includeDetails, and optional LCP threshold.export const lcpOpportunitiesSchema = { url: baseSchemas.url, device: baseSchemas.device, includeDetails: baseSchemas.includeDetails, threshold: z.number().min(0).optional().describe("LCP threshold in seconds (default: 2.5)"), };