index.ts.hbs•5.77 kB
#!/usr/bin/env node
import { MCPServer } from './mcp-server.js';
/**
* Configuration interface for command line arguments
* Generated from API specifications
*/
interface ServerOptions {
debug: boolean;
timeout: number;
allowLocalhost: boolean;
allowPrivateIps: boolean;
maxResponseLength: number;
userAgent: string;
}
/**
* Parse command line arguments and environment variables
*/
function parseServerOptions(): ServerOptions {
const args = process.argv.slice(2);
// Parse command line arguments
const options: ServerOptions = {
debug: args.includes('--debug') || process.env.DEBUG === 'true',
timeout: parseInt(process.env.API_TIMEOUT || '{{configuration.timeout}}', 10),
allowLocalhost: args.includes('--allow-localhost') || process.env.ALLOW_LOCALHOST === '{{configuration.allowLocalhost}}',
allowPrivateIps: args.includes('--allow-private-ips') || process.env.ALLOW_PRIVATE_IPS === '{{configuration.allowPrivateIps}}',
maxResponseLength: parseInt(process.env.MAX_RESPONSE_LENGTH || '{{configuration.maxResponseLength}}', 10),
userAgent: process.env.USER_AGENT || '{{configuration.userAgent}}',
};
// Handle help flag
if (args.includes('--help') || args.includes('-h')) {
printUsage();
process.exit(0);
}
// Validate timeout
if (options.timeout < 1000 || options.timeout > 300000) {
console.error('Error: Timeout must be between 1000ms and 300000ms (5 minutes)');
process.exit(1);
}
// Validate max response length
if (options.maxResponseLength < 1000 || options.maxResponseLength > 10000000) {
console.error('Error: Max response length must be between 1000 and 10000000 bytes');
process.exit(1);
}
return options;
}
/**
* Print usage information
*/
function printUsage(): void {
console.log(`
{{server.name}} - {{server.description}}
Usage: {{kebabCase server.name}} [options]
Options:
--debug Enable debug logging
--allow-localhost Allow requests to localhost/127.0.0.1
--allow-private-ips Allow requests to private IP ranges
--help, -h Show this help message
Environment Variables:
DEBUG Enable debug logging (true/false)
API_TIMEOUT Request timeout in milliseconds (default: {{configuration.timeout}})
ALLOW_LOCALHOST Allow localhost requests (true/false)
ALLOW_PRIVATE_IPS Allow private IP requests (true/false)
MAX_RESPONSE_LENGTH Maximum response length in bytes (default: {{configuration.maxResponseLength}})
USER_AGENT Custom user agent string
Available Tools:
{{#each tools}}
- {{name}}: {{description}}
{{/each}}
Examples:
{{kebabCase server.name}} --debug
DEBUG=true {{kebabCase server.name}}
API_TIMEOUT=60000 {{kebabCase server.name}} --allow-localhost
`);
}
/**
* Main entry point for the {{server.name}}
* Initializes and starts the server with stdio transport
*/
async function main() {
try {
// Parse configuration from command line and environment
const options = parseServerOptions();
if (options.debug) {
console.error('Starting {{server.name}} with options:', options);
}
// Create and configure the MCP server
const server = new MCPServer({
name: '{{kebabCase server.name}}',
version: '{{server.version}}',
debug: options.debug,
// Configure components with parsed options
apiClient: {
timeout: options.timeout,
userAgent: options.userAgent,
},
requestValidator: {
allowLocalhost: options.allowLocalhost,
allowPrivateIps: options.allowPrivateIps,
},
responseFormatter: {
includeHeaders: true,
prettyPrintJson: true,
maxResponseLength: options.maxResponseLength,
},
});
// Handle graceful shutdown
let isShuttingDown = false;
const gracefulShutdown = async (signal: string) => {
if (isShuttingDown) {
console.error('Force shutdown requested, exiting immediately...');
process.exit(1);
}
isShuttingDown = true;
console.error(`Received ${signal}, shutting down gracefully...`);
try {
// Set a timeout for graceful shutdown
const shutdownTimeout = setTimeout(() => {
console.error('Shutdown timeout reached, forcing exit...');
process.exit(1);
}, 5000); // 5 second timeout
await server.stop();
clearTimeout(shutdownTimeout);
if (options.debug) {
console.error('Server shutdown completed successfully');
}
process.exit(0);
} catch (error) {
console.error('Error during shutdown:', error);
process.exit(1);
}
};
process.on('SIGINT', () => gracefulShutdown('SIGINT'));
process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
// Handle uncaught exceptions and unhandled rejections
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
if (!isShuttingDown) {
gracefulShutdown('uncaughtException');
}
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
if (!isShuttingDown) {
gracefulShutdown('unhandledRejection');
}
});
// Start the server
await server.start();
// Log successful startup
console.error('{{server.name}} is ready and listening for requests');
} catch (error) {
console.error('Failed to start {{server.name}}:', error);
process.exit(1);
}
}
// Run the main function
main().catch((error) => {
console.error('Unhandled error in main:', error);
process.exit(1);
});