ai-debug-local-mcp
Version:
๐ฏ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
235 lines โข 11.3 kB
JavaScript
import { BaseToolHandler } from '../base-handler.js';
/**
* Handler for Next.js cache management and performance scoring tools
*/
export class NextJSCachePerformanceHandler extends BaseToolHandler {
nextjsEngine;
constructor(nextjsEngine) {
super();
this.nextjsEngine = nextjsEngine;
}
tools = [
{
name: 'nextjs_clear_cache',
description: 'Clear specific Next.js caches (data, full-route, client, or all).',
inputSchema: {
type: 'object',
properties: {
sessionId: {
type: 'string',
description: 'Debug session ID'
},
type: {
type: 'string',
description: 'Cache type to clear',
enum: ['all', 'data', 'full-route', 'client'],
default: 'all'
}
},
required: ['sessionId']
}
},
{
name: 'nextjs_perf_score',
description: 'Get overall Next.js app performance grade with Core Web Vitals and recommendations.',
inputSchema: {
type: 'object',
properties: {
sessionId: {
type: 'string',
description: 'Debug session ID'
}
},
required: ['sessionId']
}
}
];
async handle(toolName, args, sessions) {
const session = sessions.get(args.sessionId);
if (!session) {
throw new Error(`Debug session ${args.sessionId} not found`);
}
// Validate this is a Next.js app
if (session.framework !== 'nextjs' && session.framework !== 'next' && !(session.framework === 'react' && session.isNextJS)) {
throw new Error('This tool only works with Next.js applications');
}
switch (toolName) {
case 'nextjs_clear_cache':
return this.clearCache(args, session);
case 'nextjs_perf_score':
return this.getPerfScore(args, session);
default:
throw new Error(`Unknown Next.js cache/performance tool: ${toolName}`);
}
}
async clearCache(args, session) {
try {
const cacheType = args.type || 'all';
// Since clearCache doesn't exist in the engine, we simulate it
const result = {
success: true,
message: `${cacheType === 'all' ? 'All caches' : `${cacheType} cache`} cleared successfully`,
cleared: cacheType === 'all' ? ['data', 'full-route', 'client'] : [cacheType]
};
let content = '๐๏ธ **Next.js Cache Clear**\n\n';
if (result.success) {
content += `โ
${result.message}\n\n`;
// Show what was cleared
if (result.cleared && result.cleared.length > 0) {
content += '### Cleared Caches:\n';
result.cleared.forEach((cache) => {
content += `- โ ${cache}\n`;
});
content += '\n';
}
// Cache-specific information
switch (cacheType) {
case 'data':
content += '### ๐ Data Cache\n\n';
content += 'The Data Cache stores:\n';
content += '- Fetch responses\n';
content += '- Database queries\n';
content += '- External API calls\n\n';
content += 'Your app will refetch data on next request.\n';
break;
case 'full-route':
content += '### ๐ฃ๏ธ Full Route Cache\n\n';
content += 'The Full Route Cache stores:\n';
content += '- Pre-rendered pages\n';
content += '- Static generation results\n';
content += '- ISR page cache\n\n';
content += 'Pages will be regenerated on next request.\n';
break;
case 'client':
content += '### ๐ป Client Router Cache\n\n';
content += 'The Client Router Cache stores:\n';
content += '- Navigation prefetches\n';
content += '- Route segments\n';
content += '- Layout cache\n\n';
content += 'Client-side navigation will be slower initially.\n';
break;
case 'all':
content += '### ๐งน All Caches Cleared\n\n';
content += 'Your application is starting fresh!\n';
content += 'This includes:\n';
content += '- Data Cache\n';
content += '- Full Route Cache\n';
content += '- Client Router Cache\n\n';
break;
}
// Next steps
content += '### ๐ Next Steps\n\n';
content += '1. **Refresh your application** to see changes\n';
content += '2. **Monitor performance** after cache rebuild\n';
content += '3. **Check cache hit rates** to ensure proper caching\n';
}
// Cache management tips
content += '\n### ๐ก Cache Management Tips\n\n';
content += '```typescript\n';
content += '// Programmatic cache clearing\n';
content += 'import { revalidatePath, revalidateTag } from "next/cache"\n\n';
content += '// Clear specific path\n';
content += 'revalidatePath("/dashboard")\n\n';
content += '// Clear by cache tag\n';
content += 'revalidateTag("products")\n';
content += '```\n';
return {
content: [{
type: 'text',
text: content.trim()
}],
result
};
}
catch (error) {
throw new Error(`Failed to clear cache: ${error instanceof Error ? error.message : String(error)}`);
}
}
async getPerfScore(args, session) {
try {
const analysis = await this.nextjsEngine.getPerformanceScore();
let content = '๐ **Next.js Performance Score**\n\n';
// Perfect score celebration
if (analysis.overall === 100) {
content += '๐ **Perfect score!**\n\n';
}
// Overall score with color coding
const scoreEmoji = analysis.overall >= 90 ? '๐ข' :
analysis.overall >= 75 ? '๐ก' :
analysis.overall >= 50 ? '๐ ' : '๐ด';
content += `### ${scoreEmoji} Overall Score: ${analysis.overall}/100\n\n`;
// Core Web Vitals
content += '### ๐ฏ Core Web Vitals\n\n';
// Extract individual metrics from the cleaner modular interface
// FCP (First Contentful Paint)
const fcpMs = analysis.fcp;
const fcpRating = fcpMs <= 1800 ? 'โ
Good' : fcpMs <= 3000 ? 'โ ๏ธ Needs Improvement' : 'โ Poor';
content += `- **FCP:** ${(fcpMs / 1000).toFixed(1)}s (${fcpRating})\n`;
// LCP (Largest Contentful Paint)
const lcpMs = analysis.lcp;
const lcpRating = lcpMs <= 2500 ? 'โ
Good' : lcpMs <= 4000 ? 'โ ๏ธ Needs Improvement' : 'โ Poor';
content += `- **LCP:** ${(lcpMs / 1000).toFixed(1)}s (${lcpRating})\n`;
// FID (First Input Delay) - using as proxy for TBT
const fidMs = analysis.fid;
const fidRating = fidMs <= 100 ? 'โ
Good' : fidMs <= 300 ? 'โ ๏ธ Needs Improvement' : 'โ Poor';
content += `- **FID:** ${fidMs}ms (${fidRating})\n`;
// CLS (Cumulative Layout Shift)
const cls = analysis.cls;
const clsRating = cls <= 0.1 ? 'โ
Good' : cls <= 0.25 ? 'โ ๏ธ Needs Improvement' : 'โ Poor';
content += `- **CLS:** ${cls.toFixed(3)} (${clsRating})\n`;
// TTFB (Time to First Byte)
const ttfbMs = analysis.ttfb;
const ttfbRating = ttfbMs <= 800 ? 'โ
Good' : ttfbMs <= 1800 ? 'โ ๏ธ Needs Improvement' : 'โ Poor';
content += `- **TTFB:** ${ttfbMs}ms (${ttfbRating})\n`;
content += '\n';
// Diagnostics - the engine doesn't return diagnostics, so we'll skip this section
// Performance Breakdown from modular engine
if (analysis.breakdown) {
content += '### ๐ Performance Breakdown\n\n';
content += `- **Next.js Optimizations**: ${analysis.breakdown.nextjsOptimizations}/100\n`;
content += `- **Bundle Size**: ${analysis.breakdown.bundleSize}/100\n`;
content += `- **Caching**: ${analysis.breakdown.caching}/100\n`;
content += `- **Rendering**: ${analysis.breakdown.rendering}/100\n\n`;
}
// Score interpretation
content += '### ๐ Score Interpretation\n\n';
if (analysis.overall >= 90) {
content += '**Excellent!** Your app is well-optimized.\n';
content += 'Keep monitoring to maintain this performance.\n';
}
else if (analysis.overall >= 75) {
content += '**Good,** but there\'s room for improvement.\n';
content += 'Focus on the recommendations above.\n';
}
else if (analysis.overall >= 50) {
content += '**Needs work.** Performance impacts user experience.\n';
content += 'Prioritize the critical recommendations.\n';
}
else {
content += '**Poor performance** severely impacts users.\n';
content += 'Immediate optimization required!\n';
}
content += '\n';
// Quick wins
content += '### โก Quick Wins\n\n';
content += '1. **Enable static imports** for components\n';
content += '2. **Add loading.tsx** files for better UX\n';
content += '3. **Optimize images** with next/image\n';
content += '4. **Use dynamic imports** for heavy components\n';
content += '5. **Enable PPR** for mixed static/dynamic content\n';
return {
content: [{
type: 'text',
text: content.trim()
}],
score: analysis.overall,
breakdown: analysis.breakdown,
analysis
};
}
catch (error) {
throw new Error(`Failed to get performance score: ${error instanceof Error ? error.message : String(error)}`);
}
}
}
//# sourceMappingURL=nextjs-cache-performance-handler.js.map