Skip to main content
Glama

MCP API Server

by fikri2992
cli-commands.ts8.04 kB
import { Command } from 'commander'; import { CLIOptions, ProgressInfo } from './cli-types.js'; import { CLIError } from './cli-error-handler.js'; import { validateInput, validateOutput } from './cli-validators.js'; import { reportProgress, logInfo, logError, logDebug, logSuccess } from './cli-output.js'; import { CodeGenerator } from '../generator/code-generator.js'; import * as fs from 'fs/promises'; import * as path from 'path'; /** * Generate command implementation */ export const generateCommand = new Command('generate') .description('Generate MCP server from API specification') .argument('<input>', 'Path to API specification markdown file') .argument('<output>', 'Output directory for generated MCP server') .option('-n, --name <name>', 'Name for the generated MCP server') .option('-t, --template <path>', 'Path to custom template directory') .option('--overwrite', 'Overwrite existing files in output directory', false) .option('--no-tests', 'Skip generating test files') .option('--no-docs', 'Skip generating documentation') .option('--backup', 'Create backup of existing files before overwriting', false) .action(async (input: string, output: string, cmdOptions: any, command: Command) => { try { // Merge global and command options const globalOptions = command.parent?.opts() || {}; const options: CLIOptions = { input, output, name: cmdOptions.name, template: cmdOptions.template, debug: globalOptions.debug || process.env.DEBUG === 'true', quiet: globalOptions.quiet || process.env.QUIET === 'true', openaiApiKey: globalOptions.openaiApiKey || process.env.OPENAI_API_KEY, model: globalOptions.model || process.env.OPENAI_MODEL || 'gpt-4', noAi: globalOptions.noAi || process.env.NO_AI === 'true', config: globalOptions.config, overwrite: cmdOptions.overwrite || false, backup: cmdOptions.backup || false, ...cmdOptions }; await executeGenerate(options); } catch (error) { throw error; // Re-throw to be handled by main error handler } }); /** * Execute the generate command */ async function executeGenerate(options: CLIOptions): Promise<void> { logDebug('Starting generate command with options:', options, options.debug); // Step 1: Validate input file reportProgress({ step: 'Validating input', current: 1, total: 6, message: `Checking ${options.input}` }, options.quiet); await validateInput(options.input); logInfo('✓ Input file validated', options.quiet); // Step 2: Validate output directory reportProgress({ step: 'Preparing output', current: 2, total: 6, message: `Setting up ${options.output}` }, options.quiet); await validateOutput(options.output, options); logInfo('✓ Output directory prepared', options.quiet); // Step 3: Parse markdown (placeholder) reportProgress({ step: 'Parsing API specification', current: 3, total: 6, message: 'Extracting API definitions' }, options.quiet); // TODO: This will be implemented in task 3 logInfo('✓ API specification parsed (placeholder)', options.quiet); // Step 4: AI processing (placeholder) if (!options.noAi && options.openaiApiKey) { reportProgress({ step: 'AI-powered optimization', current: 4, total: 6, message: 'Enhancing API specifications' }, options.quiet); // TODO: This will be implemented in task 4 logInfo('✓ AI optimization completed (placeholder)', options.quiet); } else { logInfo('⚠ AI processing skipped (no API key or disabled)', options.quiet); } // Step 5: Code generation reportProgress({ step: 'Generating MCP server', current: 5, total: 6, message: 'Creating server files' }, options.quiet); try { // Create code generator const generator = new CodeGenerator({ outputDir: options.output, overwrite: options.overwrite, backup: options.backup, debug: options.debug, initGit: true, createExamples: true, onProgress: (progress: ProgressInfo) => { if (!options.quiet) { reportProgress(progress, options.quiet); } }, server: { name: options.name || 'Generated MCP Server', description: `MCP server generated from ${path.basename(options.input)}`, version: '1.0.0', license: 'MIT', }, }); // For now, create a placeholder API collection // TODO: Replace with actual parsed API collection from previous steps const placeholderAPICollection = { name: options.name || 'Generated MCP Server', description: `MCP server generated from ${path.basename(options.input)}`, apis: [], // Will be populated by parser curlCommands: [], // Will be populated by parser rawMarkdown: await fs.readFile(options.input, 'utf-8'), metadata: { fileName: path.basename(options.input), parsedAt: new Date().toISOString(), headings: [], codeBlocks: 0, curlCommandsFound: 0, }, }; // Generate complete project const result = await generator.generateProject(placeholderAPICollection); if (!result.scaffoldingResult?.success) { throw new Error(`Project generation failed: ${result.errors.join(', ')}`); } // Log results logDebug('Generation completed', { files: result.scaffoldingResult.metadata.totalFiles, directories: result.scaffoldingResult.metadata.totalDirectories, size: result.scaffoldingResult.metadata.totalSize, duration: result.scaffoldingResult.metadata.duration, }, options.debug); if (result.warnings.length > 0) { result.warnings.forEach(warning => { logInfo(`⚠️ ${warning}`, options.quiet); }); } logInfo('✓ MCP server generated successfully', options.quiet); } catch (error) { throw new CLIError( 'generation_error', `Code generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, { error } ); } // Step 6: Finalization reportProgress({ step: 'Finalizing', current: 6, total: 6, message: 'Completing generation' }, options.quiet); logInfo('✅ MCP server generation completed successfully!', options.quiet); logInfo(`📁 Output directory: ${path.resolve(options.output)}`, options.quiet); if (!options.quiet) { console.log('\nNext steps:'); console.log(` cd ${options.output}`); console.log(' npm install'); console.log(' npm run build'); console.log(' npm start'); } } /** * Create placeholder output files for testing * This will be replaced by actual code generation in later tasks */ async function createPlaceholderOutput(options: CLIOptions): Promise<void> { const serverName = options.name || path.basename(options.input, '.md'); // Create basic package.json const packageJson = { name: `mcp-${serverName}`, version: '1.0.0', description: `Generated MCP server for ${serverName}`, main: 'dist/index.js', scripts: { build: 'tsc', start: 'node dist/index.js', dev: 'tsc --watch' }, dependencies: { '@modelcontextprotocol/sdk': '^0.5.0', 'axios': '^1.6.0', 'zod': '^3.22.0' }, devDependencies: { '@types/node': '^20.0.0', 'typescript': '^5.0.0' } }; await fs.writeFile( path.join(options.output, 'package.json'), JSON.stringify(packageJson, null, 2) ); // Create basic README const readme = `# ${serverName} MCP Server Generated MCP server for ${serverName} API. ## Installation \`\`\`bash npm install npm run build \`\`\` ## Usage \`\`\`bash npm start \`\`\` This is a placeholder generated by MCP Builder CLI. Actual implementation will be added in future tasks. `; await fs.writeFile( path.join(options.output, 'README.md'), readme ); logDebug('Placeholder files created', options.debug); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/fikri2992/mcp0'

If you have feedback or need assistance with the MCP directory API, please join our Discord server