We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/bermingham85/mcp-puppet-pipeline'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
// COMPLETE AUTOMATED SYSTEM INTEGRATION
// This connects all components and runs the full automation
const { exec, execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const WebSocket = require('ws');
class FullAutomationSystem {
constructor() {
this.videoPath = 'C:\\puppet_production\\rendernet_media_vid_NS5ozVwpwE.mp4';
this.outputBase = 'C:\\puppet_production\\automated_output';
this.mcpServer = 'ws://localhost:3000/mcp';
}
async run() {
console.log('π FULL AUTOMATION SYSTEM STARTING...\n');
try {
// Step 1: Setup directories
await this.setupDirectories();
// Step 2: Extract frame from video
const framePath = await this.extractFrame();
// Step 3: Process through puppet pipeline
const result = await this.processPuppetPipeline(framePath);
// Step 4: Generate content package
await this.generateContentPackage(result);
console.log('\nβ
AUTOMATION COMPLETE!');
console.log(`π Output directory: ${this.outputBase}`);
// Open output folder
exec(`explorer "${this.outputBase}"`);
} catch (error) {
console.error('β Automation failed:', error);
this.fallbackProcessing();
}
}
async setupDirectories() {
const dirs = [
this.outputBase,
path.join(this.outputBase, 'frames'),
path.join(this.outputBase, 'puppets'),
path.join(this.outputBase, 'scenes'),
path.join(this.outputBase, 'videos'),
path.join(this.outputBase, 'packages')
];
for (const dir of dirs) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
}
console.log('β
Directories created');
}
extractFrame() {
return new Promise((resolve, reject) => {
const framePath = path.join(this.outputBase, 'frames', 'reference_frame.jpg');
const cmd = `ffmpeg -i "${this.videoPath}" -ss 00:00:02 -vframes 1 -q:v 2 "${framePath}" -y`;
console.log('πΈ Extracting optimal frame from video...');
exec(cmd, (error, stdout, stderr) => {
if (error) {
// Try alternative timestamps
const altCmd = `ffmpeg -i "${this.videoPath}" -ss 00:00:01 -vframes 1 "${framePath}" -y`;
exec(altCmd, (error2) => {
if (error2) {
reject(error2);
} else {
console.log('β
Frame extracted successfully');
resolve(framePath);
}
});
} else {
console.log('β
Frame extracted successfully');
resolve(framePath);
}
});
});
}
processPuppetPipeline(framePath) {
return new Promise((resolve, reject) => {
console.log('π¨ Processing through puppet pipeline...');
const ws = new WebSocket(this.mcpServer);
ws.on('open', () => {
console.log('π‘ Connected to MCP server');
const request = {
jsonrpc: '2.0',
id: Date.now(),
method: 'hybrid_puppet_pipeline',
params: {
reference_image_path: framePath,
character_name: 'AutoGenerated_Character',
proof_of_concept: true, // Start with proof of concept
create_affogato_character: true,
scene_generations: [
{
scene_prompt: 'Character as action movie hero with explosions and dramatic lighting',
output_path: path.join(this.outputBase, 'scenes', 'action_hero.png'),
quality: 'Plus'
},
{
scene_prompt: 'Character in futuristic cyberpunk environment with neon lights',
output_path: path.join(this.outputBase, 'scenes', 'cyberpunk.png'),
quality: 'Plus'
},
{
scene_prompt: 'Character in professional business setting',
output_path: path.join(this.outputBase, 'scenes', 'business.png'),
quality: 'Regular'
}
],
voice_videos: [
{
image_path: path.join(this.outputBase, 'scenes', 'action_hero.png'),
script: 'Welcome to the future of automated content creation.',
voice_id: '21m00Tcm4TlvDq8ikWAM',
output_path: path.join(this.outputBase, 'videos', 'intro.mp4'),
duration: 5
}
]
}
};
ws.send(JSON.stringify(request));
console.log('β³ Pipeline processing... This may take a few minutes.');
});
ws.on('message', (data) => {
const response = JSON.parse(data.toString());
console.log('β
Pipeline completed');
ws.close();
resolve(response.result || response);
});
ws.on('error', (err) => {
console.error('WebSocket error:', err);
ws.close();
reject(err);
});
// Timeout after 5 minutes
setTimeout(() => {
ws.close();
reject(new Error('Pipeline timeout'));
}, 300000);
});
}
async generateContentPackage(pipelineResult) {
console.log('π¦ Generating content package...');
const packageData = {
created: new Date().toISOString(),
source_video: this.videoPath,
pipeline_result: pipelineResult,
outputs: {
frames: fs.readdirSync(path.join(this.outputBase, 'frames')),
scenes: fs.readdirSync(path.join(this.outputBase, 'scenes')).filter(f => f.endsWith('.png')),
videos: fs.readdirSync(path.join(this.outputBase, 'videos')).filter(f => f.endsWith('.mp4'))
},
status: 'complete'
};
const packagePath = path.join(this.outputBase, 'packages', 'content_package.json');
fs.writeFileSync(packagePath, JSON.stringify(packageData, null, 2));
console.log('β
Content package generated');
// Generate HTML preview
this.generateHTMLPreview(packageData);
}
generateHTMLPreview(packageData) {
const html = `<!DOCTYPE html>
<html>
<head>
<title>Puppet Production Results</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; background: #1a1a1a; color: #fff; }
h1 { color: #4CAF50; }
.section { margin: 20px 0; padding: 20px; background: #2a2a2a; border-radius: 10px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
.item { background: #333; padding: 10px; border-radius: 5px; }
img { width: 100%; height: auto; border-radius: 5px; }
.status { color: #4CAF50; font-weight: bold; }
</style>
</head>
<body>
<h1>π¬ Automated Puppet Production Results</h1>
<div class="section">
<h2>π Summary</h2>
<p>Source Video: ${packageData.source_video}</p>
<p>Generated: ${packageData.created}</p>
<p>Status: <span class="status">${packageData.status.toUpperCase()}</span></p>
</div>
<div class="section">
<h2>πΌοΈ Generated Scenes</h2>
<div class="grid">
${packageData.outputs.scenes.map(scene => `
<div class="item">
<img src="../scenes/${scene}" alt="${scene}">
<p>${scene}</p>
</div>
`).join('')}
</div>
</div>
<div class="section">
<h2>π₯ Videos</h2>
${packageData.outputs.videos.map(video => `
<div class="item">
<video controls width="100%">
<source src="../videos/${video}" type="video/mp4">
</video>
<p>${video}</p>
</div>
`).join('')}
</div>
</body>
</html>`;
const previewPath = path.join(this.outputBase, 'preview.html');
fs.writeFileSync(previewPath, html);
console.log('β
HTML preview generated');
// Open preview in browser
exec(`start "${previewPath}"`);
}
async fallbackProcessing() {
console.log('\nπ Running fallback processing...');
try {
// Extract frame manually
const framePath = path.join(this.outputBase, 'frames', 'fallback_frame.jpg');
execSync(`ffmpeg -i "${this.videoPath}" -ss 1 -vframes 1 "${framePath}" -y`);
console.log('β
Fallback frame extracted');
console.log(`π Frame saved to: ${framePath}`);
// Create basic output structure
const summary = {
status: 'partial_success',
frame_extracted: true,
frame_path: framePath,
message: 'Frame extracted successfully. Ready for manual puppet pipeline processing.',
next_steps: [
'1. Use the extracted frame as reference image',
'2. Run puppet pipeline with the frame',
'3. Check automated_output folder for results'
]
};
fs.writeFileSync(
path.join(this.outputBase, 'fallback_summary.json'),
JSON.stringify(summary, null, 2)
);
console.log('\nπ Fallback Summary:');
console.log(JSON.stringify(summary, null, 2));
} catch (error) {
console.error('Fallback also failed:', error);
}
}
}
// Auto-run the system
if (require.main === module) {
const system = new FullAutomationSystem();
system.run().catch(console.error);
}
module.exports = FullAutomationSystem;