mcpgen
Version:
Zero-friction MCP Server Generator
1,020 lines (871 loc) • 30.6 kB
JavaScript
#!/usr/bin/env node
/**
* mcpgen - Minimal MCP Server Generator
*
* A state-of-the-art tool that creates custom MCP servers with zero friction.
*
* Features:
* - Interactive CLI workflow
* - Multiple data source options (in-memory, file, database, API)
* - Advanced AI capabilities (vector embeddings, document processing, image analysis)
* - One-click cloud deployment (AWS, GCP, Azure, Vercel, Heroku, Docker)
* - Schema inference and TypeScript interface generation
* - Ready-to-use tool templates optimized for Claude
* - Custom tools creation with standardized templates
* - Zero configuration deployment
* - Built for performance and extensibility
*
* Created by @plawlost (Yaz Celebi)
*/
console.log("MCPGen v1.0.4 - Minimal MCP Server Generator");
console.log("Created by @plawlost (Yaz Celebi)");
async function startGenerator() {
const fs = await import('fs/promises');
const path = await import('path');
const { execSync } = await import('child_process');
const readline = await import('readline');
const { fileURLToPath } = await import('url');
// Set up readline interface
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
// ANSI colors for terminal output
const colors = {
reset: "\x1b[0m",
bright: "\x1b[1m",
dim: "\x1b[2m",
blue: "\x1b[34m",
green: "\x1b[32m",
red: "\x1b[31m",
yellow: "\x1b[33m",
cyan: "\x1b[36m",
gray: "\x1b[90m",
magenta: "\x1b[35m"
};
// Project configuration
const config = {
projectName: '',
projectPath: '',
description: '',
dataSource: '',
tools: [],
customTools: [],
deployment: '',
useConfigFile: false,
configFile: ''
};
// Helper function to ask questions
const askQuestion = (question, defaultValue = '') => {
return new Promise((resolve) => {
const defaultText = defaultValue ? ` (${defaultValue})` : '';
rl.question(`? ${question}${defaultText}: `, (answer) => {
resolve(answer || defaultValue);
});
});
};
// Check if the user wants to use a config file
const checkForConfigFile = async () => {
const useConfigFile = await askQuestion("Do you want to use a configuration file (y/n)", "n");
if (useConfigFile.toLowerCase() === 'y') {
config.useConfigFile = true;
config.configFile = await askQuestion("Enter path to config file", "mcpgen.config.json");
try {
const configContent = await fs.readFile(config.configFile, 'utf8');
const configData = JSON.parse(configContent);
// Apply configuration from file
Object.assign(config, configData);
console.log(`\n${colors.green}✅ Loaded configuration from ${config.configFile}${colors.reset}`);
console.log(`${colors.dim}Project: ${config.projectName}${colors.reset}`);
console.log(`${colors.dim}Data source: ${config.dataSource}${colors.reset}`);
console.log(`${colors.dim}Tools: ${config.tools.join(', ')}${colors.reset}`);
if (config.customTools && config.customTools.length > 0) {
console.log(`${colors.dim}Custom tools: ${config.customTools.map(t => t.name).join(', ')}${colors.reset}`);
}
if (config.deployment && config.deployment !== 'none') {
console.log(`${colors.dim}Deployment: ${config.deployment}${colors.reset}`);
}
return true;
} catch (error) {
console.error(`\n${colors.red}Error loading config file: ${error.message}${colors.reset}`);
const createNew = await askQuestion("Would you like to create a new configuration interactively (y/n)", "y");
if (createNew.toLowerCase() !== 'y') {
console.log("Exiting...");
process.exit(0);
}
config.useConfigFile = false;
}
}
return false;
};
// Helper to save the current configuration to a file
const saveConfiguration = async () => {
const saveConfig = await askQuestion("Would you like to save this configuration for future use (y/n)", "y");
if (saveConfig.toLowerCase() === 'y') {
const configFileName = await askQuestion("Enter config file name", "mcpgen.config.json");
const configToSave = {
projectName: config.projectName,
projectPath: config.projectPath,
description: config.description,
dataSource: config.dataSource,
tools: config.tools,
customTools: config.customTools,
deployment: config.deployment
};
await fs.writeFile(configFileName, JSON.stringify(configToSave, null, 2));
console.log(`\n${colors.green}✅ Configuration saved to ${configFileName}${colors.reset}`);
console.log(`${colors.dim}You can use this configuration in the future with:${colors.reset}`);
console.log(`${colors.dim}mcpgen --config ${configFileName}${colors.reset}`);
}
};
console.log("\nWelcome to MCPGen!");
console.log("This tool helps you create custom MCP servers for Claude and other AI assistants.");
// Check for config file
const configLoaded = await checkForConfigFile();
if (!configLoaded) {
// Project setup
console.log("\nProject Setup");
config.projectName = await askQuestion("Project name", "my-mcp");
config.projectPath = await askQuestion("Project path", `./${config.projectName}`);
config.description = await askQuestion("Description", "Custom MCP server");
// Data source selection
console.log("\nData Source Selection");
console.log("1. Mock Data (in-memory)");
console.log("2. JSON File");
console.log("3. External API");
console.log("4. PostgreSQL");
console.log("5. MongoDB");
console.log("6. MySQL/MariaDB");
console.log("7. Supabase");
const dataSourceChoice = await askQuestion("Select data source (1-7)", "1");
switch(dataSourceChoice) {
case "1": config.dataSource = "mock"; break;
case "2": config.dataSource = "jsonFile"; break;
case "3": config.dataSource = "api"; break;
case "4": config.dataSource = "postgres"; break;
case "5": config.dataSource = "mongodb"; break;
case "6": config.dataSource = "mysql"; break;
case "7": config.dataSource = "supabase"; break;
default: config.dataSource = "mock";
}
// Tool selection
console.log("\nTool Selection");
console.log("1. search - Search for information");
console.log("2. getItem - Get detailed information about a specific item");
console.log("3. createItem - Create a new item");
console.log("4. getWeather - Get weather information for a location");
console.log("5. vectorEmbed - Generate vector embeddings for semantic search");
console.log("6. analyzeImage - Analyze and extract information from images");
console.log("7. processDocument - Extract and process information from documents");
console.log("8. visualizeData - Create data visualizations from datasets");
console.log("9. Custom tool - Define your own tool");
const toolsInput = await askQuestion("Select tools (comma-separated numbers, or 'a' for all)", "1,2");
// Process tool selection
const toolMap = {
"1": "search",
"2": "getItem",
"3": "createItem",
"4": "getWeather",
"5": "vectorEmbed",
"6": "analyzeImage",
"7": "processDocument",
"8": "visualizeData"
};
if (toolsInput.toLowerCase() === 'a') {
config.tools = Object.values(toolMap);
// Custom tools will be handled separately
} else {
// Parse tool selection, separating custom tools (option 9)
const toolSelections = toolsInput
.split(',')
.map(num => num.trim());
// Standard tools
config.tools = toolSelections
.filter(num => num !== '9' && toolMap[num])
.map(num => toolMap[num]);
// Check for custom tools
if (toolSelections.includes('9')) {
await defineCustomTools();
}
}
// Ask if user wants to add custom tools even if not initially selected
if (!toolsInput.includes('9') && toolsInput.toLowerCase() !== 'a') {
const addCustom = await askQuestion("Would you like to add custom tools (y/n)", "n");
if (addCustom.toLowerCase() === 'y') {
await defineCustomTools();
}
}
// Cloud deployment selection
console.log("\nCloud Deployment");
console.log("1. None (local only)");
console.log("2. AWS Lambda");
console.log("3. Google Cloud Functions");
console.log("4. Azure Functions");
console.log("5. Vercel");
console.log("6. Heroku");
console.log("7. Docker");
const deploymentChoice = await askQuestion("Select deployment target (1-7)", "1");
switch(deploymentChoice) {
case "1": config.deployment = "none"; break;
case "2": config.deployment = "aws"; break;
case "3": config.deployment = "gcp"; break;
case "4": config.deployment = "azure"; break;
case "5": config.deployment = "vercel"; break;
case "6": config.deployment = "heroku"; break;
case "7": config.deployment = "docker"; break;
default: config.deployment = "none";
}
// Save configuration if desired
await saveConfiguration();
}
// Function to define custom tools interactively
async function defineCustomTools() {
let addingTools = true;
while (addingTools) {
console.log(`\n${colors.blue}Custom Tool Definition${colors.reset}`);
const customTool = {
name: await askQuestion("Tool name (camelCase, e.g. myCustomTool)"),
description: await askQuestion("Tool description"),
params: []
};
// Parameter definition
console.log("\nParameter Definition");
console.log("Define parameters for your tool (leave name empty when done)");
let addingParams = true;
while (addingParams) {
const paramName = await askQuestion("Parameter name");
if (!paramName) {
addingParams = false;
continue;
}
console.log("Parameter type options:");
console.log("1. string");
console.log("2. number");
console.log("3. boolean");
console.log("4. array");
console.log("5. object");
const typeChoice = await askQuestion("Select parameter type (1-5)", "1");
let paramType;
switch(typeChoice) {
case "1": paramType = "string"; break;
case "2": paramType = "number"; break;
case "3": paramType = "boolean"; break;
case "4": paramType = "array"; break;
case "5": paramType = "object"; break;
default: paramType = "string";
}
const isRequired = await askQuestion("Is this parameter required (y/n)", "y");
if (isRequired.toLowerCase() !== 'y') {
paramType += '?';
}
customTool.params.push({
name: paramName,
type: paramType
});
}
// Implementation template
console.log("\nImplementation Template");
console.log("Choose an implementation template:");
console.log("1. Basic (returns static response)");
console.log("2. Database (queries the data source)");
console.log("3. API (makes external API request)");
console.log("4. Custom (enter your own implementation)");
const templateChoice = await askQuestion("Select template (1-4)", "1");
let implementationTemplate = '';
switch(templateChoice) {
case "1":
implementationTemplate = `
// Basic implementation for ${customTool.name}
${customTool.params.map(p => `const ${p.name} = args.${p.name};`).join('\n')}
return {
content: [
{ type: "text", text: "This is a response from your custom tool: ${customTool.name}" },
{ type: "text", text: "Add your implementation logic here" }
]
};`;
break;
case "2":
implementationTemplate = `
// Database implementation for ${customTool.name}
${customTool.params.map(p => `const ${p.name} = args.${p.name};`).join('\n')}
// Query the data source
const results = await fetchData("Your query here"); // Modify as needed
return {
content: [
{ type: "text", text: "Results from database:" },
...results.map(r => ({ type: "text", text: JSON.stringify(r) }))
]
};`;
break;
case "3":
implementationTemplate = `
// API implementation for ${customTool.name}
${customTool.params.map(p => `const ${p.name} = args.${p.name};`).join('\n')}
// Make API request
const response = await fetch("https://api.example.com/endpoint", {
method: "GET",
headers: {
"Content-Type": "application/json"
}
});
const data = await response.json();
return {
content: [
{ type: "text", text: "API Response:" },
{ type: "text", text: JSON.stringify(data) }
]
};`;
break;
case "4":
console.log("Enter your custom implementation below (type 'END' on a new line when finished):");
let customImpl = '';
let line = '';
while (true) {
line = await askQuestion("");
if (line === 'END') break;
customImpl += line + '\n';
}
implementationTemplate = customImpl;
break;
}
customTool.implementation = implementationTemplate;
// Add the custom tool to the configuration
if (!config.customTools) {
config.customTools = [];
}
config.customTools.push(customTool);
console.log(`\n${colors.green}✅ Custom tool "${customTool.name}" defined!${colors.reset}`);
const defineAnother = await askQuestion("Would you like to define another custom tool (y/n)", "n");
if (defineAnother.toLowerCase() !== 'y') {
addingTools = false;
}
}
}
// Generate project
console.log("\nGenerating MCP Server...");
try {
// Create project directory
await fs.mkdir(config.projectPath, { recursive: true });
// Create a simple README.md
const readmeContent = `# ${config.projectName}
${config.description}
## Features
- Custom MCP server for Claude and other MCP-compatible clients
- Data source: ${config.dataSource}
- Tools: ${config.tools.join(', ')}
${config.customTools && config.customTools.length > 0 ? `- Custom tools: ${config.customTools.map(t => t.name).join(', ')}` : ''}
${config.deployment !== 'none' ? `- Deployment: ${config.deployment}` : ''}
## Getting Started
\`\`\`bash
npm install
npm run build
npm start
\`\`\`
${config.deployment !== 'none' ? `
## Deployment
This project is configured for deployment to ${config.deployment.toUpperCase()}.
\`\`\`bash
npm run deploy
\`\`\`
` : ''}
## Custom Tools
${config.customTools && config.customTools.length > 0 ?
config.customTools.map(tool => `### ${tool.name}\n${tool.description}\n\nParameters:\n${tool.params.map(p => `- ${p.name}: ${p.type}`).join('\n')}\n`).join('\n')
: 'No custom tools defined.'}
Created with MCPGen by @plawlost (Yaz Celebi)
`;
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'README.md'),
readmeContent
);
// Create package.json with deployment script if needed
const packageJson = {
name: config.projectName,
version: "1.0.0",
description: config.description,
main: "dist/main.js",
type: "module",
scripts: {
build: "tsc",
start: "node dist/main.js",
dev: "tsc && node dist/main.js"
},
dependencies: {
"@modelcontextprotocol/sdk": "latest",
"zod": "^3.21.4"
},
devDependencies: {
"@types/node": "^20.10.0",
"typescript": "^5.2.2"
}
};
// Add deployment-specific dependencies and scripts
switch(config.deployment) {
case "aws":
packageJson.scripts.deploy = "serverless deploy";
packageJson.devDependencies.serverless = "^3.34.0";
break;
case "gcp":
packageJson.scripts.deploy = "gcloud functions deploy";
break;
case "azure":
packageJson.scripts.deploy = "func azure functionapp publish";
break;
case "vercel":
packageJson.scripts.deploy = "vercel --prod";
packageJson.devDependencies.vercel = "^31.0.0";
break;
case "heroku":
packageJson.scripts.deploy = "git push heroku main";
break;
case "docker":
packageJson.scripts.deploy = "docker build -t ${config.projectName} . && docker run -p 3000:3000 ${config.projectName}";
break;
}
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'package.json'),
JSON.stringify(packageJson, null, 2)
);
// Create src directory
await fs.mkdir(path.join(path.resolve(config.projectPath), 'src'), { recursive: true });
// Create main.ts with implementation
let mainTsContent = `// Generated by MCPGen v1.0.4
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
// Create the MCP server
const server = new McpServer({
name: "${config.projectName}",
version: "1.0.0",
description: "${config.description}"
});
// Mock data source
const mockData = [
{ id: "1", title: "Item 1", description: "Description for item 1" },
{ id: "2", title: "Item 2", description: "Description for item 2" },
{ id: "3", title: "Item 3", description: "Description for item 3" }
];
// Basic data access functions
async function searchItems(query) {
return mockData.filter(item =>
item.title.toLowerCase().includes(query.toLowerCase()) ||
item.description.toLowerCase().includes(query.toLowerCase())
);
}
async function getItemById(id) {
return mockData.find(item => item.id === id);
}
${config.tools.includes('search') ? `
// Search tool
server.tool(
"search",
"Search for information",
{
query: z.string().describe("query"),
limit: z.number().optional().describe("limit")
},
async (args, _extra) => {
const { query, limit = 5 } = args;
const results = await searchItems(query);
const limitedResults = results.slice(0, limit);
return {
content: [
{ type: "text", text: "Results for '" + query + "':" },
...limitedResults.map(r => ({
type: "text",
text: "- " + r.title + ": " + (r.description || '')
}))
]
};
}
);` : ''}
${config.tools.includes('getItem') ? `
// GetItem tool
server.tool(
"getItem",
"Get detailed information about a specific item",
{
id: z.string().describe("id")
},
async (args, _extra) => {
const { id } = args;
const item = await getItemById(id);
if (!item) {
return {
content: [{ type: "text", text: "No item found with ID: " + id }]
};
}
return {
content: [
{ type: "text", text: "Item " + id + ": " + item.title },
{ type: "text", text: item.description || 'No description available' }
]
};
}
);` : ''}
${config.customTools && config.customTools.length > 0 ?
config.customTools.map(tool => `
// Custom tool: ${tool.name}
server.tool(
"${tool.name}",
"${tool.description}",
{
${tool.params.map(param => {
const isOptional = param.type.endsWith('?');
const baseType = isOptional ? param.type.slice(0, -1) : param.type;
let zodType;
switch(baseType) {
case 'string': zodType = 'z.string()'; break;
case 'number': zodType = 'z.number()'; break;
case 'boolean': zodType = 'z.boolean()'; break;
case 'array': zodType = 'z.array(z.any())'; break;
case 'object': zodType = 'z.record(z.string(), z.any())'; break;
default: zodType = 'z.any()';
}
if (isOptional) {
zodType += '.optional()';
}
return ` ${param.name}: ${zodType}.describe("${param.name}")`;
}).join(',\n')}
},
async (args, _extra) => {
try {
${tool.implementation}
} catch (error) {
return {
content: [
{ type: "text", text: "Error in ${tool.name}: " + error.message }
]
};
}
}
);`).join('\n\n') : ''}
// Main function
async function main() {
try {
// Register transport
server.registerTransport(
new StdioServerTransport({
input: process.stdin,
output: process.stdout,
})
);
console.error('MCP Server started');
console.error('Server name: ' + server.serverInfo.name);
// Keep the process running
process.stdin.resume();
} catch (error) {
console.error('Error starting server: ' + error.message);
process.exit(1);
}
}
// Start the application
main();
`;
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'src', 'main.ts'),
mainTsContent
);
// Create deployment configuration files
if (config.deployment !== 'none') {
switch(config.deployment) {
case "aws":
// Create serverless.yml
const serverlessYml = `
service: ${config.projectName}
provider:
name: aws
runtime: nodejs18.x
region: us-east-1
memorySize: 256
timeout: 30
functions:
mcp:
handler: dist/lambda.handler
events:
- http:
path: /
method: post
`;
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'serverless.yml'),
serverlessYml
);
// Create Lambda handler wrapper
const lambdaWrapper = `
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { handler as mcpHandler } from "./main.js";
export const handler = async (event, context) => {
// Parse API Gateway event
const body = JSON.parse(event.body || '{}');
try {
const response = await mcpHandler(body);
return {
statusCode: 200,
body: JSON.stringify(response)
};
} catch (error) {
return {
statusCode: 500,
body: JSON.stringify({ error: error.message })
};
}
};
`;
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'src', 'lambda.ts'),
lambdaWrapper
);
break;
case "vercel":
// Create vercel.json
const vercelJson = `{
"version": 2,
"builds": [
{
"src": "dist/vercel.js",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "dist/vercel.js"
}
]
}`;
// Create Vercel handler wrapper
const vercelWrapper = `
import { handler as mcpHandler } from "./main.js";
export default async (req, res) => {
if (req.method === 'OPTIONS') {
res.status(200).end();
return;
}
try {
const body = req.body || {};
const response = await mcpHandler(body);
res.status(200).json(response);
} catch (error) {
res.status(500).json({ error: error.message });
}
};
`;
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'vercel.json'),
vercelJson
);
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'src', 'vercel.ts'),
vercelWrapper
);
break;
case "docker":
// Create Dockerfile
const dockerfile = `FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY dist ./dist
EXPOSE 3000
CMD ["node", "dist/docker.js"]
`;
// Create Docker wrapper
const dockerWrapper = `
import express from 'express';
import { handler as mcpHandler } from "./main.js";
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
app.post('/', async (req, res) => {
try {
const body = req.body || {};
const response = await mcpHandler(body);
res.status(200).json(response);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(port, () => {
console.log(\`MCP server listening on port \${port}\`);
});
`;
// Create docker-compose.yml
const dockerCompose = `version: '3'
services:
mcp-server:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
`;
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'Dockerfile'),
dockerfile
);
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'docker-compose.yml'),
dockerCompose
);
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'src', 'docker.ts'),
dockerWrapper
);
// Add express to package.json
const dockerPackageJsonPath = path.join(path.resolve(config.projectPath), 'package.json');
const dockerPackageJson = JSON.parse(await fs.readFile(dockerPackageJsonPath, 'utf8'));
dockerPackageJson.dependencies = dockerPackageJson.dependencies || {};
dockerPackageJson.dependencies.express = '^4.18.2';
await fs.writeFile(dockerPackageJsonPath, JSON.stringify(dockerPackageJson, null, 2));
break;
}
}
// Create tsconfig.json
const tsconfig = {
compilerOptions: {
target: "ES2022",
module: "NodeNext",
moduleResolution: "NodeNext",
esModuleInterop: true,
outDir: "dist",
rootDir: "src",
strict: true,
skipLibCheck: true
},
include: ["src/**/*"],
exclude: ["node_modules", "dist"]
};
await fs.writeFile(
path.join(path.resolve(config.projectPath), 'tsconfig.json'),
JSON.stringify(tsconfig, null, 2)
);
// Create a template for custom tools
const customToolTemplate = `/*
* MCPGen Custom Tool Template
*
* Use this template to create new custom tools for your MCP server.
* Copy this file, modify it, and add it to your project.
*/
// Import the tool to your main.ts file
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
/**
* Register a custom tool with the MCP server
*
* @param server - The MCP server instance
*/
export function registerCustomTool(server: McpServer) {
server.tool(
"customToolName", // Tool name in camelCase
"Description of what this tool does", // Tool description
{
// Define parameters with their types and descriptions
param1: z.string().describe("Description of param1"),
param2: z.number().optional().describe("Optional numeric parameter"),
// Add more parameters as needed
},
async (args, _extra) => {
try {
// Extract parameters
const { param1, param2 = 42 } = args;
// Implement your tool's logic here
// For example, call an API, query a database, etc.
const result = "This is a result: " + param1;
// Return response with content
return {
content: [
{ type: "text", text: "Custom tool response:" },
{ type: "text", text: result }
]
};
} catch (error) {
// Handle errors gracefully
return {
content: [
{ type: "text", text: "Error in custom tool: " + error.message }
]
};
}
}
);
}
`;
// Create a templates directory for custom tools
const templatesDir = path.join(path.resolve(config.projectPath), 'templates');
await fs.mkdir(templatesDir, { recursive: true });
await fs.writeFile(
path.join(templatesDir, 'custom-tool-template.ts'),
customToolTemplate
);
console.log("\n" + colors.green + "✅ MCP Server generated successfully!" + colors.reset);
console.log("\nNext steps:");
console.log(`1. cd ${config.projectPath}`);
console.log("2. npm install");
console.log("3. npm run build");
console.log("4. npm start");
if (config.deployment !== 'none') {
console.log("\nTo deploy to the cloud:");
console.log("5. npm run deploy");
}
if (config.customTools && config.customTools.length > 0) {
console.log("\nCustom tools are available in your server:");
config.customTools.forEach(tool => {
console.log(`- ${tool.name}: ${tool.description}`);
});
}
console.log("\nTo add more custom tools, use the template at:");
console.log(`${config.projectPath}/templates/custom-tool-template.ts`);
console.log("\nTo integrate with Claude Desktop:");
console.log("Add to your Claude Desktop configuration:");
console.log(" macOS: ~/Library/Application Support/Claude/claude_desktop_config.json");
console.log(" Windows: %APPDATA%\\Claude\\claude_desktop_config.json");
} catch (error) {
console.error("\n" + colors.red + "❌ Error generating MCP Server: " + error.message + colors.reset);
}
// Close readline interface
rl.close();
}
// Process command line arguments
async function processArgs() {
const args = process.argv.slice(2);
// Handle --config flag
const configIndex = args.indexOf('--config');
if (configIndex !== -1 && configIndex + 1 < args.length) {
// This will be handled in the startGenerator function
// Just acknowledge it here
console.log(`\nUsing configuration file: ${args[configIndex + 1]}`);
}
// Handle --version flag
if (args.includes('--version') || args.includes('-v')) {
console.log("v1.0.4");
return true;
}
// Handle --help flag
if (args.includes('--help') || args.includes('-h')) {
console.log(`
MCPGen v1.0.4 - Zero-friction MCP Server Generator
Usage:
mcpgen [options]
Options:
--version, -v Show version number
--help, -h Show help
--config <file> Use configuration file
Examples:
mcpgen Interactive mode
mcpgen --config my.config.json Use configuration file
`);
return true;
}
return false;
}
// Main function
async function main() {
const shouldExit = await processArgs();
if (shouldExit) return;
console.log("\nStarting MCP Server Generator...");
await startGenerator();
console.log("\nThank you for using MCPGen!");
}
// Start the application
main();