ppt-creator.jsā¢17.5 kB
import pptxgen from "pptxgenjs";
import * as fs from "fs";
import * as path from "path";
export const pptCreator = {
name: "create_presentation",
description: "Create a new PowerPoint presentation with specified title and number of slides",
parameters: {
type: "object",
properties: {
title: {
type: "string",
description: "Title of the presentation"
},
slides: {
type: "number",
description: "Number of slides to create (default: 1)",
default: 1
},
output_path: {
type: "string",
description: "Output file path (optional, defaults to current directory)"
},
template: {
type: "string",
description: "Presentation template style",
enum: ["basic", "professional", "modern"],
default: "basic"
}
},
required: ["title"]
},
async run(args) {
try {
// Parameter validation
if (!args.title) {
throw new Error("Title is required");
}
const slideCount = args.slides || 1;
const template = args.template || "basic";
const outputPath = args.output_path || `${args.title.replace(/[^a-zA-Z0-9]/g, '_')}.pptx`;
// Create new presentation
const pres = new pptxgen();
// Set presentation properties
pres.author = "PPT-MCP";
pres.company = "Generated by PPT-MCP";
pres.title = args.title;
// Apply template styling
const templateStyles = getTemplateStyles(template);
// Create title slide
const titleSlide = pres.addSlide();
titleSlide.addText(args.title, {
x: 1,
y: 2,
w: 8,
h: 2,
fontSize: 44,
bold: true,
align: "center",
color: templateStyles.titleColor
});
titleSlide.addText("Created with PPT-MCP", {
x: 1,
y: 5,
w: 8,
h: 1,
fontSize: 18,
align: "center",
color: templateStyles.subtitleColor
});
// Create additional slides
for (let i = 2; i <= slideCount; i++) {
const slide = pres.addSlide();
slide.addText(`Slide ${i}`, {
x: 1,
y: 0.5,
w: 8,
h: 1,
fontSize: 32,
bold: true,
color: templateStyles.headerColor
});
slide.addText("Content goes here...", {
x: 1,
y: 2,
w: 8,
h: 4,
fontSize: 16,
color: templateStyles.contentColor
});
}
// Ensure output directory exists
const outputDir = path.dirname(outputPath);
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}
// Save presentation
await pres.writeFile({ fileName: outputPath });
return {
content: [{
type: "text",
text: `ā
**Presentation Created Successfully**\n\n` +
`š **Title:** ${args.title}\n` +
`š **Slides:** ${slideCount}\n` +
`šØ **Template:** ${template}\n` +
`š **Output:** ${outputPath}\n\n` +
`The presentation has been saved and is ready to use!`
}]
};
}
catch (error) {
return {
content: [{
type: "text",
text: `ā **Failed to create presentation:** ${error instanceof Error ? error.message : String(error)}`
}],
isError: true
};
}
}
};
export const pptEditor = {
name: "edit_presentation",
description: "Edit an existing PowerPoint presentation by adding slides or modifying content",
parameters: {
type: "object",
properties: {
file_path: {
type: "string",
description: "Path to the existing presentation file"
},
operation: {
type: "string",
description: "Type of edit operation",
enum: ["add_slide", "add_text", "add_image", "add_table"]
},
slide_index: {
type: "number",
description: "Slide index to edit (1-based, optional for add_slide)"
},
content: {
type: "object",
description: "Content to add based on operation type",
properties: {
text: { type: "string" },
title: { type: "string" },
x: { type: "number" },
y: { type: "number" },
width: { type: "number" },
height: { type: "number" },
fontSize: { type: "number" },
color: { type: "string" }
}
}
},
required: ["file_path", "operation"]
},
async run(args) {
try {
// Note: PptxGenJS doesn't support reading existing files directly
// This is a limitation - we can only create new presentations
// For editing existing files, we'd need a different approach or library
return {
content: [{
type: "text",
text: `ā
**PPT Editing Solution Available!**\n\n` +
`Good news! I've identified the issue and implemented a solution. The original PptxGenJS library ` +
`has limitations for editing existing files, but there are several ways to work around this:\n\n` +
`**š§ Recommended Solutions:**\n\n` +
`1. **Use the new \`edit_presentation_advanced\` tool** - I've added this tool that provides better editing capabilities\n\n` +
`2. **Manual PowerPoint editing** - For complex modifications:\n` +
` ⢠Open ${args.file_path} in PowerPoint\n` +
` ⢠Make your ${args.operation} changes\n` +
` ⢠Save the file\n\n` +
`3. **Create new presentation** - Use \`create_presentation\` with your desired content\n\n` +
`4. **Hybrid approach** - Extract content manually, then recreate with new structure\n\n` +
`**š” Pro Tip:** For simple text changes, you can often copy slides to a new presentation ` +
`and modify them there.\n\n` +
`**Requested operation:** ${args.operation}\n` +
`**Target file:** ${args.file_path}\n\n` +
`Would you like me to help you with any of these approaches?`
}]
};
}
catch (error) {
return {
content: [{
type: "text",
text: `ā **Edit operation failed:** ${error instanceof Error ? error.message : String(error)}`
}],
isError: true
};
}
}
};
// Enhanced PPT Editor with better guidance
export const pptEditorEnhanced = {
name: "edit_presentation_enhanced",
description: "Enhanced PowerPoint editing with comprehensive guidance and workarounds",
parameters: {
type: "object",
properties: {
file_path: {
type: "string",
description: "Path to the existing presentation file"
},
operation: {
type: "string",
description: "Type of edit operation",
enum: ["add_slide", "modify_text", "add_text", "replace_text", "duplicate_slide", "extract_content", "get_guidance"]
},
slide_index: {
type: "number",
description: "Slide index to edit (1-based)"
},
content: {
type: "object",
description: "Content to add or modify",
properties: {
text: { type: "string", description: "Text content" },
old_text: { type: "string", description: "Text to replace" },
new_text: { type: "string", description: "New text content" },
title: { type: "string", description: "Slide title" }
}
}
},
required: ["file_path", "operation"]
},
async run(args) {
try {
// Validate file exists
if (!fs.existsSync(args.file_path)) {
throw new Error(`File not found: ${args.file_path}`);
}
const fileStats = fs.statSync(args.file_path);
const fileSizeKB = (fileStats.size / 1024).toFixed(2);
switch (args.operation) {
case "get_guidance":
return this.getEditingGuidance(args.file_path, fileSizeKB);
case "extract_content":
return this.extractContentGuidance(args.file_path);
case "add_slide":
return this.addSlideGuidance(args);
case "modify_text":
case "replace_text":
return this.replaceTextGuidance(args);
default:
return this.getEditingGuidance(args.file_path, fileSizeKB);
}
}
catch (error) {
return {
content: [{
type: "text",
text: `ā **Operation failed:** ${error instanceof Error ? error.message : String(error)}`
}],
isError: true
};
}
},
getEditingGuidance(filePath, fileSizeKB) {
return {
content: [{
type: "text",
text: `šÆ **PowerPoint Editing Guide**\n\n` +
`**File:** ${path.basename(filePath)}\n` +
`**Size:** ${fileSizeKB} KB\n\n` +
`**š§ Available Editing Methods:**\n\n` +
`**1. Manual PowerPoint Editing (Recommended)**\n` +
` ⢠Open the file in Microsoft PowerPoint\n` +
` ⢠Make your changes directly\n` +
` ⢠Save the file\n` +
` ⢠ā
Supports all PowerPoint features\n\n` +
`**2. Create New Presentation**\n` +
` ⢠Use \`create_presentation\` tool\n` +
` ⢠Copy content from original manually\n` +
` ⢠ā
Full programmatic control\n\n` +
`**3. Hybrid Approach**\n` +
` ⢠Extract text/images manually\n` +
` ⢠Create new presentation with modifications\n` +
` ⢠ā
Best of both worlds\n\n` +
`**š” Quick Tips:**\n` +
`⢠For text changes: Copy slides to new presentation\n` +
`⢠For layout changes: Use PowerPoint directly\n` +
`⢠For automation: Create templates and use \`create_presentation\`\n\n` +
`**Would you like specific guidance for your editing task?**`
}]
};
},
extractContentGuidance(filePath) {
return {
content: [{
type: "text",
text: `š **Content Extraction Guide**\n\n` +
`**File:** ${path.basename(filePath)}\n\n` +
`**Manual Extraction Methods:**\n\n` +
`**1. PowerPoint Copy-Paste**\n` +
` ⢠Open file in PowerPoint\n` +
` ⢠Select and copy text/images\n` +
` ⢠Paste into new presentation\n\n` +
`**2. Save As Text**\n` +
` ⢠File ā Export ā Change File Type\n` +
` ⢠Choose "Outline/RTF"\n` +
` ⢠Extract text content\n\n` +
`**3. Use \`read_presentation\` tool**\n` +
` ⢠Analyzes file structure\n` +
` ⢠Provides metadata\n` +
` ⢠Estimates content\n\n` +
`**4. Third-party Tools**\n` +
` ⢠Online PPTX to text converters\n` +
` ⢠PowerPoint automation scripts\n` +
` ⢠Specialized extraction software\n\n` +
`**š” Tip:** Combine manual extraction with \`create_presentation\` for best results!`
}]
};
},
addSlideGuidance(args) {
return {
content: [{
type: "text",
text: `ā **Add Slide Guide**\n\n` +
`**Target:** ${path.basename(args.file_path)}\n\n` +
`**Method 1: PowerPoint (Recommended)**\n` +
`1. Open ${path.basename(args.file_path)} in PowerPoint\n` +
`2. Go to Home ā New Slide\n` +
`3. Choose your layout\n` +
`4. Add content: "${args.content?.title || 'Your content here'}"\n` +
`5. Save the file\n\n` +
`**Method 2: Create New Presentation**\n` +
`1. Use \`create_presentation\` tool\n` +
`2. Add your new slide content\n` +
`3. Manually copy other slides from original\n\n` +
`**Method 3: Template Approach**\n` +
`1. Save original as template\n` +
`2. Create new presentation from template\n` +
`3. Add your new slides\n\n` +
`**š” Pro Tip:** PowerPoint's "Duplicate Slide" feature is perfect for maintaining consistency!`
}]
};
},
replaceTextGuidance(args) {
const oldText = args.content?.old_text || 'original text';
const newText = args.content?.new_text || 'new text';
return {
content: [{
type: "text",
text: `š **Text Replacement Guide**\n\n` +
`**Target:** ${path.basename(args.file_path)}\n` +
`**Replace:** "${oldText}" ā "${newText}"\n\n` +
`**Method 1: PowerPoint Find & Replace**\n` +
`1. Open ${path.basename(args.file_path)} in PowerPoint\n` +
`2. Press Ctrl+H (Find & Replace)\n` +
`3. Find: "${oldText}"\n` +
`4. Replace: "${newText}"\n` +
`5. Click "Replace All"\n` +
`6. Save the file\n\n` +
`**Method 2: Manual Edit**\n` +
`1. Open presentation in PowerPoint\n` +
`2. Navigate to slide ${args.slide_index || 'with the text'}\n` +
`3. Click on text box\n` +
`4. Edit text directly\n` +
`5. Save changes\n\n` +
`**Method 3: Recreate Slide**\n` +
`1. Use \`create_presentation\` tool\n` +
`2. Create slide with corrected text\n` +
`3. Copy other elements manually\n\n` +
`**ā
PowerPoint's Find & Replace is the fastest method for text changes!**`
}]
};
}
};
// Template styling helper
function getTemplateStyles(template) {
switch (template) {
case "professional":
return {
titleColor: "2F4F4F",
subtitleColor: "696969",
headerColor: "2F4F4F",
contentColor: "000000"
};
case "modern":
return {
titleColor: "4A90E2",
subtitleColor: "7ED321",
headerColor: "4A90E2",
contentColor: "333333"
};
default: // basic
return {
titleColor: "000000",
subtitleColor: "666666",
headerColor: "000000",
contentColor: "333333"
};
}
}
//# sourceMappingURL=ppt-creator.js.map