hatch-slidev-builder-mcp
Version:
A comprehensive MCP server for creating Slidev presentations with component library, interactive elements, and team collaboration features
60 lines (59 loc) • 10.4 kB
JavaScript
/**
* Enhanced Slidev Builder Tool with 4-Layer Architecture
* Combines Content Intelligence, Layout Optimization, Asset Intelligence, and Style Orchestration
*/
import { z } from 'zod';
import { SlidevBuilderOrchestrator } from '../layers/SlidevOrchestrator.js';
import path from 'path';
import fs from 'fs/promises';
const generateIntelligentDeckSchema = z.object({
content: z.string().describe('The main content or description for the presentation'),
title: z.string().describe('Title of the presentation'),
audience: z.enum(['executive', 'technical', 'general']).describe('Target audience type'),
presentation_type: z.enum(['business', 'technical', 'creative', 'educational']).describe('Type of presentation'),
brand_guidelines: z.string().optional().describe('Brand guidelines to follow (e.g., "hatch_corporate")'),
output_dir: z.string().describe('Output directory for the generated presentation'),
time_constraint: z.number().optional().describe('Time constraint in minutes'),
accessibility_requirements: z.array(z.string()).optional().describe('Specific accessibility requirements'),
enable_ai_enhancement: z.boolean().default(true).describe('Enable AI-powered content enhancement'),
include_speaker_notes: z.boolean().default(false).describe('Include speaker notes for each slide')
});
export async function generateIntelligentDeck(args) {
try {
console.log('🚀 Starting Intelligent Slide Deck Generation...');
// Prepare the generation request
const request = {
content: args.content,
audience: args.audience,
presentation_type: args.presentation_type,
brand_guidelines: args.brand_guidelines || 'hatch_corporate',
time_constraint: args.time_constraint,
accessibility_requirements: args.accessibility_requirements || []
};
// Generate slides using 4-layer orchestrator
const result = await SlidevBuilderOrchestrator.generateSlideDeck(request);
// Create output directory
await fs.mkdir(args.output_dir, { recursive: true });
// Generate slides.md file
const slidesContent = this.generateSlidesMarkdown(args.title, result);
await fs.writeFile(path.join(args.output_dir, 'slides.md'), slidesContent);
// Generate package.json
const packageJson = this.generatePackageJson(args.title);
await fs.writeFile(path.join(args.output_dir, 'package.json'), JSON.stringify(packageJson, null, 2));
// Generate theme configuration
const themeConfig = this.generateThemeConfig(result.slides[0]?.style);
await fs.writeFile(path.join(args.output_dir, 'theme.config.ts'), themeConfig);
// Generate custom CSS
const customCSS = this.generateCustomCSS(result.slides);
await fs.writeFile(path.join(args.output_dir, 'style.css'), customCSS);
// Generate speaker notes if requested
if (args.include_speaker_notes) {
const speakerNotes = this.generateSpeakerNotes(result);
await fs.writeFile(path.join(args.output_dir, 'speaker-notes.md'), speakerNotes);
}
n;
n;
}
finally {
}
} // Generate presentation analysis report\n const analysisReport = this.generateAnalysisReport(result);\n await fs.writeFile(path.join(args.output_dir, 'presentation-analysis.json'), JSON.stringify(analysisReport, null, 2));\n \n console.log('✅ Intelligent Slide Deck Generation Complete!');\n \n return {\n success: true,\n output_directory: args.output_dir,\n slides_generated: result.slides.length,\n estimated_duration: `${Math.round(result.presentation_metadata.estimated_duration / 60)} minutes`,\n quality_score: `${Math.round(result.quality_metrics.overall_score * 100)}%`,\n accessibility_score: `${Math.round(result.presentation_metadata.accessibility_score * 100)}%`,\n brand_compliance: `${Math.round(result.presentation_metadata.brand_compliance * 100)}%`,\n optimization_suggestions: result.optimization_suggestions,\n files_created: [\n 'slides.md',\n 'package.json', \n 'theme.config.ts',\n 'style.css',\n ...(args.include_speaker_notes ? ['speaker-notes.md'] : []),\n 'presentation-analysis.json'\n ],\n next_steps: [\n 'Run `npm install` to install dependencies',\n 'Run `npm run dev` to start development server',\n 'Run `npm run build` to build for production',\n 'Run `npm run export` to export as PDF'\n ]\n };\n \n } catch (error) {\n console.error('❌ Error generating intelligent deck:', error);\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n troubleshooting: [\n 'Check that the output directory is writable',\n 'Ensure all required dependencies are installed',\n 'Verify the content input is properly formatted',\n 'Check network connectivity for asset downloads'\n ]\n };\n }\n}\n\n/**\n * Generate the main slides.md file\n */\nfunction generateSlidesMarkdown(title: string, result: any): string {\n const frontmatter = `---\ntheme: hatch-corporate\nbackground: false\nclass: text-center\nhighlighter: shiki\nlineNumbers: false\ninfo: |\n ## ${title}\n \n Generated with HAIA+ Slidev Builder\n 4-Layer Architecture: Content → Layout → Assets → Style\n \ndrawings:\n persist: false\ntransition: slide-left\ntitle: ${title}\nmdc: true\n---\n\n`;\n \n const slidesMarkdown = result.slides\n .map((slide: any) => slide.markdown)\n .join('\\n\\n---\\n\\n');\n \n return frontmatter + slidesMarkdown;\n}\n\n/**\n * Generate package.json for the presentation\n */\nfunction generatePackageJson(title: string) {\n return {\n \"name\": title.toLowerCase().replace(/\\s+/g, '-'),\n \"version\": \"1.0.0\",\n \"description\": `${title} - Generated with HAIA+ Slidev Builder`,\n \"scripts\": {\n \"dev\": \"slidev\",\n \"build\": \"slidev build\",\n \"export\": \"slidev export\",\n \"export-pdf\": \"slidev export --format pdf\",\n \"export-png\": \"slidev export --format png\",\n \"preview\": \"slidev preview\"\n },\n \"dependencies\": {\n \"@slidev/cli\": \"^0.48.0\",\n \"@slidev/theme-default\": \"latest\"\n },\n \"devDependencies\": {\n \"@slidev/types\": \"latest\"\n }\n };\n}\n\n/**\n * Generate theme configuration\n */\nfunction generateThemeConfig(styleRecommendation: any): string {\n return `import { defineTheme } from '@slidev/types'\n\nexport default defineTheme({\n name: 'hatch-corporate-enhanced',\n colorSchema: 'auto',\n layouts: {\n default: './layouts/default.vue',\n cover: './layouts/cover.vue',\n center: './layouts/center.vue',\n 'two-cols': './layouts/two-cols.vue'\n },\n tokens: {\n // Hatch Corporate Colors\n primary: '#095078',\n secondary: '#ACBCC8', \n accent: '#E84B37',\n accentAlt: '#E75300',\n gray: '#425563',\n lightGray: '#A0AEC0',\n background: '#f4f4f4',\n white: '#FFFFFF'\n }\n})\n`;\n}\n\n/**\n * Generate custom CSS combining all style recommendations\n */\nfunction generateCustomCSS(slides: any[]): string {\n const baseCSS = slides[0]?.style?.css_framework || '';\n \n return `/* HAIA+ Slidev Builder - Enhanced Styles */\n/* Generated with 4-Layer Architecture */\n\n${baseCSS}\n\n/* Additional enhancements */\n.slidev-layout {\n background: var(--hatch-background);\n font-family: var(--font-primary);\n}\n\n.slide-enter-active,\n.slide-leave-active {\n transition: all 0.3s ease;\n}\n\n.slide-enter-from {\n opacity: 0;\n transform: translateX(30px);\n}\n\n.slide-leave-to {\n opacity: 0;\n transform: translateX(-30px);\n}\n\n/* Print styles */\n@media print {\n .slide {\n break-inside: avoid;\n page-break-inside: avoid;\n }\n}\n`;\n}\n\n/**\n * Generate speaker notes\n */\nfunction generateSpeakerNotes(result: any): string {\n let notes = `# Speaker Notes\\n\\n## Presentation Overview\\n\\n- **Total Slides:** ${result.presentation_metadata.total_slides}\\n- **Estimated Duration:** ${Math.round(result.presentation_metadata.estimated_duration / 60)} minutes\\n- **Quality Score:** ${Math.round(result.quality_metrics.overall_score * 100)}%\\n\\n---\\n\\n`;\n \n result.slides.forEach((slide: any, index: number) => {\n notes += `## Slide ${index + 1}: ${slide.title}\\n\\n`;\n notes += `**Type:** ${slide.type}\\n`;\n notes += `**Estimated Time:** ${slide.estimated_time} seconds\\n\\n`;\n notes += `**Key Points:**\\n${slide.content.split(', ').map((point: string) => `- ${point}`).join('\\n')}\\n\\n`;\n notes += `**Layout Strategy:** ${slide.layout.reason}\\n\\n`;\n notes += `**Asset Strategy:** ${slide.assets.reasoning}\\n\\n`;\n notes += `**Style Strategy:** ${slide.style.reasoning}\\n\\n`;\n notes += `---\\n\\n`;\n });\n \n return notes;\n}\n\n/**\n * Generate analysis report\n */\nfunction generateAnalysisReport(result: any) {\n return {\n generation_timestamp: new Date().toISOString(),\n methodology: \"4-Layer Architecture\",\n layers: {\n \"1_content_intelligence\": \"Analyzed content structure using proven frameworks\",\n \"2_layout_optimization\": \"Applied responsive design patterns and visual hierarchy\",\n \"3_asset_intelligence\": \"Curated assets with semantic matching and brand compliance\",\n \"4_style_orchestration\": \"Generated cohesive design system with Hatch branding\"\n },\n presentation_metadata: result.presentation_metadata,\n quality_metrics: result.quality_metrics,\n optimization_suggestions: result.optimization_suggestions,\n slides_analysis: result.slides.map((slide: any) => ({\n id: slide.id,\n type: slide.type,\n title: slide.title,\n layout_confidence: slide.layout.confidence_score,\n asset_confidence: slide.assets.confidence_score,\n accessibility_score: slide.layout.accessibility_score\n }))\n };\n}\n\nexport const generateIntelligentDeckTool = {\n name: 'generate_intelligent_deck',\n description: 'Generate a complete Slidev presentation using 4-layer architecture: Content Intelligence, Layout Optimization, Asset Intelligence, and Style Orchestration',\n inputSchema: generateIntelligentDeckSchema\n};\n"