UNPKG

@kinetixarts/server-craft-it

Version:

Craft IT - Model Context Protocol (MCP) compliant Server for AI-Powered Asset Generation using Gemini

173 lines 7.4 kB
#!/usr/bin/env node import startServer from "./server/server.js"; import { fileURLToPath } from 'url'; import path from 'path'; import fs from 'fs'; import dotenv from 'dotenv'; // Get the current file's directory path const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); // Try to load environment variables from .env files, but don't fail if they don't exist // This is optional since environment variables can also be set directly try { // Check for a local .env file first const localEnvPath = path.join(process.cwd(), '.env'); if (fs.existsSync(localEnvPath)) { dotenv.config({ path: localEnvPath }); // Only log in verbose mode if (process.argv.includes('--verbose')) { console.error(`Loading environment from: ${localEnvPath}`); } } else { // Try package .env as fallback const packageEnvPath = path.join(__dirname, '../.env'); if (fs.existsSync(packageEnvPath)) { dotenv.config({ path: packageEnvPath }); if (process.argv.includes('--verbose')) { console.error(`Loading environment from: ${packageEnvPath}`); } } } } catch (error) { // Non-critical error, continue using environment variables if (process.argv.includes('--verbose')) { console.error('Could not load .env file:', error); } } /** * Validate required environment variables and exit with helpful message if missing */ /** * Check for required environment variables and provide helpful messages * @returns True if all required variables are present */ function validateEnvironment() { // First check for environment variables - they may be set through npx config // even if no .env file exists if (process.env.GEMINI_API_KEY) { return true; } // If GEMINI_API_KEY is missing, show detailed help message console.error('\n\x1b[31m%s\x1b[0m', '⛔ Error: GEMINI_API_KEY is missing!'); console.error('\n\x1b[33m%s\x1b[0m', '📋 Setup Instructions:'); console.error('1. Create a .env file in the current directory with:'); console.error('\x1b[36m%s\x1b[0m', ' GEMINI_API_KEY=your_key_here'); console.error('\n Or'); console.error('2. Set the environment variable in your command:'); console.error('\x1b[36m%s\x1b[0m', ' GEMINI_API_KEY=your_key npx @kinetixarts/server-craft-it'); console.error('\n Or'); console.error('3. Configure in your Claude MCP configuration:'); console.error('\x1b[36m%s\x1b[0m', ' "env": { "GEMINI_API_KEY": "your_key_here" }'); console.error('\n\x1b[33m%s\x1b[0m', '🔑 Get API Keys:'); console.error('- Gemini API key: https://makersuite.google.com/app/apikey'); console.error(' Your API key must have access to the gemini-2.0-flash-preview-image-generation model\n'); return false; } // Parse command line arguments function parseArgs() { const args = { stdio: process.argv.includes('--stdio'), outputPath: null, help: process.argv.includes('--help') || process.argv.includes('-h'), }; // Parse --output-path const outputPathIndex = process.argv.findIndex(arg => arg === '--output-path' || arg === '-o'); if (outputPathIndex !== -1 && outputPathIndex < process.argv.length - 1) { args.outputPath = process.argv[outputPathIndex + 1]; } return args; } // Print help information function printHelp() { console.error('\x1b[36m%s\x1b[0m', '🎨 Craft-IT MCP Asset Generator - Help'); console.error('\nUsage:'); console.error(' npx @kinetixarts/server-craft-it [options]'); console.error('\nOptions:'); console.error(' --stdio Run in stdio mode for direct integration with AI assistants'); console.error(' --output-path, -o Specify path where generated images will be saved'); console.error(' (defaults to CRAFT_IT_IMAGE_PATH or "assets/images")'); console.error(' --help, -h Show this help message'); console.error('\nEnvironment Variables:'); console.error(' GEMINI_API_KEY Required. Your Gemini API key'); console.error(' PORT Optional. HTTP server port (default: 3001)'); console.error(' HOST Optional. HTTP server host (default: 0.0.0.0)'); console.error(' CRAFT_IT_IMAGE_PATH Optional. Path to store generated images'); process.exit(0); } // Print a welcome message console.error('\x1b[36m%s\x1b[0m', '🚀 Starting Craft-IT MCP Asset Generator Server'); // Start the server async function main() { try { const args = parseArgs(); // Validate environment variables if (!validateEnvironment()) { process.exit(1); } // Show help if requested if (args.help) { printHelp(); return; } // Validate output path if provided if (args.outputPath) { try { // Check if path is valid const pathTestResult = path.resolve(args.outputPath); console.error(`Image output path set to: ${args.outputPath}`); } catch (error) { console.error('\x1b[31m%s\x1b[0m', `Error: Invalid output path: ${args.outputPath}`); process.exit(1); } } const server = await startServer({ outputPath: args.outputPath, }); const PORT = Number(process.env.PORT) || 3001; const HOST = process.env.HOST || '0.0.0.0'; const TRANSPORT_TYPE = args.stdio ? 'stdio' : 'httpStream'; if (TRANSPORT_TYPE === 'stdio') { server.start({ transportType: "stdio", }); console.error('\x1b[32m%s\x1b[0m', 'MCP Server running in stdio mode'); console.error('\x1b[33m%s\x1b[0m', 'This mode is designed for direct integration with AI assistants'); } else { server.start({ transportType: "httpStream", httpStream: { port: PORT, endpoint: "/stream", } }); console.error('\x1b[32m%s\x1b[0m', `MCP Server running at http://${HOST}:${PORT}`); console.error('\x1b[33m%s\x1b[0m', `HTTP Stream endpoint: http://${HOST}:${PORT}/stream`); console.error(''); console.error('\x1b[36m%s\x1b[0m', 'To connect, use the URL above in your MCP client configuration'); console.error(''); console.error('To use stdio mode instead, run with --stdio flag:'); console.error('\x1b[33m%s\x1b[0m', 'npx @kinetixarts/server-craft-it --stdio'); console.error(''); console.error('For more options, run with --help flag:'); console.error('\x1b[33m%s\x1b[0m', 'npx @kinetixarts/server-craft-it --help'); } } catch (error) { console.error('\x1b[31m%s\x1b[0m', "Error starting MCP server:", error); process.exit(1); } } // Handle ctrl+c gracefully process.on('SIGINT', () => { console.error('\n\x1b[33m%s\x1b[0m', 'Shutting down Craft-IT MCP server...'); process.exit(0); }); main().catch((error) => { console.error('\x1b[31m%s\x1b[0m', "Fatal error in main():", error); process.exit(1); }); //# sourceMappingURL=cli.js.map