UNPKG

draw-it-mcp

Version:

šŸŽØ A beautiful drawing app with Cursor & Claude Code MCP integration. Draw, save, and let AI analyze your artwork!

282 lines (247 loc) • 9.8 kB
#!/usr/bin/env node import { spawn } from 'child_process'; import { createServer } from 'http'; import path from 'path'; import { fileURLToPath } from 'url'; import fs from 'fs'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const projectRoot = path.resolve(__dirname, '..'); // Read version from package.json const packageJsonPath = path.join(projectRoot, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); const version = packageJson.version; // ASCII Art Banner const banner = ` ╭─────────────────────────────────────────────────────────────╮ │ Draw-it-MCP - MCP-Powered Drawing Assistant for AI Coding │ │ v${version.padEnd(6)} │ │ Features: │ │ • Beautiful canvas drawing interface │ │ • Save & load your artwork │ │ • Cursor & Claude Code MCP integration │ │ • Dark/Light theme support │ │ │ ╰─────────────────────────────────────────────────────────────╯ `; console.log('\x1b[36m%s\x1b[0m', banner); // Find available port async function findAvailablePort(startPort = 3001) { return new Promise((resolve) => { const server = createServer(); server.listen(startPort, () => { const port = server.address().port; server.close(() => { resolve(port); }); }); server.on('error', () => { resolve(findAvailablePort(startPort + 1)); }); }); } // Check if this is first run function isFirstRun() { const flagFile = path.join(projectRoot, '.first-run'); if (!fs.existsSync(flagFile)) { fs.writeFileSync(flagFile, Date.now().toString()); return true; } return false; } // Handle update command if (process.argv.includes('update')) { console.log('šŸ”„ Updating Draw-it-MCP...\n'); const updateProcess = spawn('npm', ['update', '-g', 'draw-it-mcp'], { stdio: 'inherit', shell: true }); updateProcess.on('close', (code) => { if (code === 0) { console.log('\nāœ… Update completed successfully!'); console.log('šŸŽ‰ Draw-it-MCP is now up to date.'); } else { console.log('\nāŒ Update failed. Trying alternative method...'); console.log('šŸ”„ Running: npm install -g draw-it-mcp@latest\n'); const installProcess = spawn('npm', ['install', '-g', 'draw-it-mcp@latest'], { stdio: 'inherit', shell: true }); installProcess.on('close', (installCode) => { if (installCode === 0) { console.log('\nāœ… Installation completed successfully!'); console.log('šŸŽ‰ Draw-it-MCP has been updated to the latest version.'); } else { console.log('\nāŒ Automatic update failed. Please run manually:'); console.log(' npm install -g draw-it-mcp@latest'); } process.exit(installCode); }); } }); process.exit(0); // Don't proceed to main() } // Handle MCP server execution if (process.argv.includes('mcp:server')) { // When called as "draw-it-mcp mcp:server", run the MCP server directly const mcpPath = path.resolve(__dirname, '..', 'src', 'mcp', 'drawing-mcp-server.js'); spawn('node', [mcpPath], { stdio: 'inherit' }); process.exit(0); } // Show MCP configuration for Cursor & Claude Code function showMCPConfiguration() { console.log('\nšŸ“‹ MCP Configuration for Cursor & Claude Code'); console.log('='.repeat(50)); console.log('Copy and paste one of these configurations:\n'); // Get installation paths const globalNodeModulesPath = path.dirname(path.dirname(__dirname)); const mcpServerPath = path.join(projectRoot, 'src', 'mcp', 'drawing-mcp-server.js'); console.log('šŸ”§ Option 1: Using NPX (Recommended)'); console.log('```json'); console.log(JSON.stringify({ mcpServers: { "draw-it-mcp": { command: "npx", args: ["-y", "draw-it-mcp", "mcp:server"] } } }, null, 2)); console.log('```\n'); console.log('šŸ”§ Option 2: Using absolute path'); console.log('```json'); console.log(JSON.stringify({ mcpServers: { "draw-it-mcp": { command: "node", args: [mcpServerPath] } } }, null, 2)); console.log('```\n'); console.log('šŸ’” Setup Instructions:'); console.log('1. Copy one of the JSON configurations above'); console.log('2. In Cursor: Open Settings → Extensions → MCP Settings'); console.log('3. In Claude Code: Use command palette → "Claude Code: Edit MCP Settings"'); console.log('4. Paste the configuration into your MCP settings'); console.log('5. Restart Cursor/Claude Code'); console.log('6. Start drawing and use MCP tools to analyze your artwork!\n'); } // Main function async function main() { try { console.log('šŸš€ Starting Draw-it-MCP...\n'); // Check if we're in development or installed via npm const isDev = fs.existsSync(path.join(projectRoot, 'package-lock.json')); const nodeModulesExists = fs.existsSync(path.join(projectRoot, 'node_modules')); if (!nodeModulesExists) { console.log('šŸ“¦ Installing dependencies... This may take a moment.'); const npmInstall = spawn('npm', ['install'], { cwd: projectRoot, stdio: 'inherit', shell: true }); await new Promise((resolve, reject) => { npmInstall.on('close', (code) => { if (code === 0) { resolve(); } else { reject(new Error(`npm install failed with code ${code}`)); } }); }); } // Find available port const port = await findAvailablePort(3001); console.log(`🌟 Found available port: ${port}`); // Always build on first run or if build doesn't exist const buildDir = path.join(projectRoot, '.next'); if (!fs.existsSync(buildDir) || isFirstRun()) { console.log('šŸ—ļø Building application for the first time...'); const buildProcess = spawn('npx', ['next', 'build'], { cwd: projectRoot, stdio: 'inherit', shell: true }); await new Promise((resolve, reject) => { buildProcess.on('close', (code) => { if (code === 0) { console.log('āœ… Build completed successfully!'); resolve(); } else { reject(new Error(`Build failed with code ${code}`)); } }); }); } // Start the application console.log('šŸŽØ Launching Draw-it-MCP...\n'); const serverProcess = spawn('npx', ['next', 'start', '-p', port.toString()], { cwd: projectRoot, stdio: 'inherit', shell: true, env: { ...process.env, PORT: port.toString() } }); // Show success message setTimeout(() => { console.log('\n' + '='.repeat(60)); console.log('šŸŽ‰ Draw-it-MCP is running!'); console.log(`🌐 Open: \x1b[32mhttp://localhost:${port}\x1b[0m`); console.log(''); console.log('šŸ’” Quick Tips:'); console.log(' • Click colors to change brush color'); console.log(' • Use different brush sizes for varied strokes'); console.log(' • Save your drawings for later'); console.log(' • Toggle dark/light theme'); console.log(''); console.log('šŸ¤– Cursor & Claude Code Integration:'); console.log(' • MCP server available for AI analysis'); console.log(' • See MCP configuration below'); console.log(''); console.log('ā¹ļø Press Ctrl+C to stop'); console.log('='.repeat(60) + '\n'); // Show MCP configuration for Cursor & Claude Code showMCPConfiguration(); // Open browser if first run if (isFirstRun()) { setTimeout(async () => { try { const open = await import('open'); await open.default(`http://localhost:${port}`); console.log('🌐 Browser opened automatically!'); } catch (error) { console.log('šŸ’” Please open your browser and navigate to the URL above'); } }, 2000); } }, 2000); // Handle graceful shutdown process.on('SIGINT', () => { console.log('\nšŸ›‘ Shutting down Draw-it-MCP...'); serverProcess.kill('SIGINT'); setTimeout(() => { console.log('šŸ‘‹ Thanks for using Draw-it-MCP!'); process.exit(0); }, 1000); }); // Handle server process exit serverProcess.on('close', (code) => { if (code !== 0) { console.error(`\nāŒ Server process exited with code ${code}`); console.log('šŸ’” Try running again or check for port conflicts'); } process.exit(code); }); } catch (error) { console.error('\nāŒ Error starting Draw-it-MCP:'); console.error(error.message); console.log('\nšŸ’” Troubleshooting:'); console.log(' • Make sure Node.js 18+ is installed'); console.log(' • Check if port 3001 is available'); console.log(' • Try running: npm install'); console.log(' • If build fails, try: npx create-next-app@latest --typescript'); console.log(' • For MCP setup: https://github.com/Pandoll-AI/draw-it-mcp#ai-powered-art-analysis-optional'); process.exit(1); } } // Run the application main().catch(console.error);