UNPKG

@rhofkens/mcp-quotes-server-claude-code

Version:

Model Context Protocol (MCP) server for managing and serving quotes

149 lines 4.44 kB
/** * Configuration Management * * Handles loading and validating environment variables * Provides typed configuration object for the application */ import { config as dotenvConfig } from 'dotenv'; import { z } from 'zod'; // Load environment variables from .env file dotenvConfig(); /** * Log levels supported by the application */ export const LogLevel = z.enum(['debug', 'info', 'warn', 'error']); /** * Node environment types */ export const NodeEnv = z.enum(['development', 'test', 'production']); /** * Transport types supported by the MCP server */ export const TransportType = z.enum(['stdio', 'http']); /** * Configuration schema using Zod for validation */ const ConfigSchema = z.object({ // Required configuration serperApiKey: z.string().min(1, 'SERPER_API_KEY is required'), // Server configuration nodeEnv: NodeEnv.default('development'), logLevel: LogLevel.default('info'), serverPort: z.number().int().positive().default(3000), serverHost: z.string().default('localhost'), // Transport configuration transport: TransportType.default('stdio'), httpPort: z.number().int().positive().default(3000), httpHost: z.string().default('localhost'), httpPath: z.string().default('/mcp'), // API configuration apiTimeout: z.number().int().positive().default(5000), maxRetries: z.number().int().min(0).max(10).default(3), cacheTtl: z.number().int().min(0).default(3600), }); /** * Parse and validate environment variables */ function loadConfig() { try { const rawConfig = { // Required serperApiKey: process.env['SERPER_API_KEY'], // Server nodeEnv: process.env['NODE_ENV'], logLevel: process.env['LOG_LEVEL'], serverPort: process.env['SERVER_PORT'] ? parseInt(process.env['SERVER_PORT'], 10) : undefined, serverHost: process.env['SERVER_HOST'], // Transport transport: process.env['MCP_TRANSPORT'], httpPort: process.env['MCP_HTTP_PORT'] ? parseInt(process.env['MCP_HTTP_PORT'], 10) : undefined, httpHost: process.env['MCP_HTTP_HOST'], httpPath: process.env['MCP_HTTP_PATH'], // API apiTimeout: process.env['API_TIMEOUT'] ? parseInt(process.env['API_TIMEOUT'], 10) : undefined, maxRetries: process.env['MAX_RETRIES'] ? parseInt(process.env['MAX_RETRIES'], 10) : undefined, cacheTtl: process.env['CACHE_TTL'] ? parseInt(process.env['CACHE_TTL'], 10) : undefined, }; // Parse and validate configuration const config = ConfigSchema.parse(rawConfig); return config; } catch (error) { if (error instanceof z.ZodError) { const errorMessages = error.errors .map((err) => { const path = err.path.join('.'); return `${path}: ${err.message}`; }) .join('\n'); throw new Error(`Configuration validation failed:\n${errorMessages}`); } throw error; } } /** * Singleton configuration instance */ let configInstance; /** * Get the configuration instance * @throws {Error} If configuration validation fails */ export function getConfig() { if (!configInstance) { configInstance = loadConfig(); } return configInstance; } /** * Reset configuration (useful for testing) */ export function resetConfig() { configInstance = undefined; } /** * Check if running in production */ export function isProduction() { return getConfig().nodeEnv === 'production'; } /** * Check if running in development */ export function isDevelopment() { return getConfig().nodeEnv === 'development'; } /** * Check if running in test */ export function isTest() { return getConfig().nodeEnv === 'test'; } /** * Get environment-specific configuration */ export function getEnvironmentConfig() { if (isProduction()) { return { logLevel: 'error', maxRetries: 5, apiTimeout: 10000, }; } if (isTest()) { return { logLevel: 'error', maxRetries: 0, apiTimeout: 1000, }; } // Development defaults return { logLevel: 'debug', maxRetries: 3, apiTimeout: 5000, }; } //# sourceMappingURL=config.js.map