Skip to main content
Glama

OpenAPI MCP Server

by aaker
index.js•7.11 kB
#!/usr/bin/env node import { Command } from 'commander'; import { MCPServer } from './server.js'; import { readFileSync } from 'fs'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Read package.json for version info const packageJsonPath = join(__dirname, '..', 'package.json'); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); const program = new Command(); program .name('openapi-mcp') .description('Pure JavaScript MCP server for OpenAPI specifications') .version(packageJson.version); program .command('serve') .description('Start the MCP server') .requiredOption('-s, --spec <path>', 'Path to OpenAPI specification file') .option('-b, --base-url <url>', 'Base URL for API requests') .option('-t, --token <token>', 'Bearer token for authentication') .option('--timeout <ms>', 'Request timeout in milliseconds', '30000') .option('--transport <type>', 'Transport type (stdio or http)', 'stdio') .option('--http-port <port>', 'HTTP server port (when using http transport)', '3000') .option('--http-host <host>', 'HTTP server host (when using http transport)', 'localhost') .action(async (options) => { try { // Environment variables can override CLI options const config = { specPath: options.spec, baseURL: options.baseUrl || process.env.OPENAPI_BASE_URL || '', bearerToken: options.token || process.env.OPENAPI_BEARER_TOKEN, timeout: parseInt(options.timeout), transport: options.transport, httpPort: parseInt(options.httpPort), httpHost: options.httpHost }; // Validate required options if (!config.specPath) { console.error('Error: OpenAPI specification file is required (--spec)'); process.exit(1); } // Validate transport type if (!['stdio', 'http'].includes(config.transport)) { console.error('Error: Transport must be either "stdio" or "http"'); process.exit(1); } // Create and initialize server const server = new MCPServer(config); // Handle process termination gracefully process.on('SIGINT', async () => { console.error('\n[MCP] Received SIGINT, shutting down gracefully...'); try { await server.close(); process.exit(0); } catch (error) { console.error('[MCP] Error during shutdown:', error.message); process.exit(1); } }); process.on('SIGTERM', async () => { console.error('\n[MCP] Received SIGTERM, shutting down gracefully...'); try { await server.close(); process.exit(0); } catch (error) { console.error('[MCP] Error during shutdown:', error.message); process.exit(1); } }); // Initialize and start server await server.initialize(); await server.run(); } catch (error) { console.error('[MCP] Failed to start server:', error.message); console.error('[MCP] Stack trace:', error.stack); process.exit(1); } }); program .command('validate') .description('Validate OpenAPI specification and show available tools') .requiredOption('-s, --spec <path>', 'Path to OpenAPI specification file') .action(async (options) => { try { const { OpenAPIProcessor } = await import('./openapi-processor.js'); const processor = new OpenAPIProcessor(); console.log('Validating OpenAPI specification...'); await processor.loadSpec(options.spec); console.log('āœ… OpenAPI specification is valid'); console.log(`šŸ“„ Specification: ${options.spec}`); console.log(`šŸ·ļø Title: ${processor.spec.info.title}`); console.log(`šŸ“ Description: ${processor.spec.info.description || 'None'}`); console.log(`šŸ“Š Version: ${processor.spec.info.version}`); const tools = processor.getTools(); console.log(`šŸ”§ Available tools: ${tools.length}`); if (tools.length > 0) { console.log('\nTools:'); tools.forEach((tool, index) => { console.log(` ${index + 1}. ${tool.name}`); console.log(` ${tool.method.toUpperCase()} ${tool.path}`); console.log(` ${tool.description}`); const requiredParams = tool.inputSchema.required || []; if (requiredParams.length > 0) { console.log(` Required parameters: ${requiredParams.join(', ')}`); } console.log(''); }); } // Show security information const securitySchemes = processor.getSecuritySchemes(); if (Object.keys(securitySchemes).length > 0) { console.log('šŸ” Security schemes:'); Object.entries(securitySchemes).forEach(([name, scheme]) => { console.log(` - ${name}: ${scheme.type} (${scheme.scheme || 'N/A'})`); }); } const baseUrl = processor.getBaseUrl(); if (baseUrl) { console.log(`🌐 Default base URL: ${baseUrl}`); } else { console.log('🌐 No default base URL specified in spec'); } } catch (error) { console.error('āŒ Validation failed:', error.message); process.exit(1); } }); program .command('info') .description('Show information about the MCP server') .action(() => { console.log(`${packageJson.name} v${packageJson.version}`); console.log(packageJson.description); console.log(`\nSupported OpenAPI versions: 3.x`); console.log(`Transport protocols: stdio, http`); console.log(`Authentication: Bearer token`); console.log(`HTTP methods: GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD`); console.log('\nEnvironment variables:'); console.log(' OPENAPI_BASE_URL - Default base URL for API requests'); console.log(' OPENAPI_BEARER_TOKEN - Default bearer token for authentication'); console.log('\nExamples:'); console.log(' # Start server with stdio transport (default)'); console.log(` ${packageJson.name} serve -s api.json -b https://api.example.com -t your-token`); console.log(''); console.log(' # Start server with HTTP transport'); console.log(` ${packageJson.name} serve -s api.json --transport http --http-port 3000`); console.log(''); console.log(' # Validate specification'); console.log(` ${packageJson.name} validate -s api.json`); console.log(''); console.log(' # Use environment variables'); console.log(' export OPENAPI_BASE_URL=https://api.example.com'); console.log(' export OPENAPI_BEARER_TOKEN=your-token'); console.log(` ${packageJson.name} serve -s api.json`); }); // Handle unknown commands program.on('command:*', (operands) => { console.error(`Unknown command: ${operands[0]}`); console.error('See --help for available commands'); process.exit(1); }); // Show help if no command provided if (process.argv.length === 2) { program.help(); } program.parse(process.argv);

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/aaker/mini-openapi-mcp'

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