@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
JavaScript
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