UNPKG

bookstack-mcp-server

Version:

MCP server providing comprehensive access to BookStack knowledge management system

183 lines 7.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ConfigManager = exports.ConfigSchema = void 0; const zod_1 = require("zod"); const dotenv_1 = require("dotenv"); const logger_1 = require("../utils/logger"); // Load environment variables (0, dotenv_1.config)(); /** * Configuration schema using Zod for validation */ exports.ConfigSchema = zod_1.z.object({ bookstack: zod_1.z.object({ baseUrl: zod_1.z.string().url('Invalid BookStack base URL').default('http://localhost:8080/api'), apiToken: zod_1.z.string().min(1, 'BookStack API token is required - set BOOKSTACK_API_TOKEN environment variable'), timeout: zod_1.z.number().positive().default(30000), }), server: zod_1.z.object({ name: zod_1.z.string().default('bookstack-mcp-server'), version: zod_1.z.string().default('1.0.0'), port: zod_1.z.number().positive().default(3000), }), rateLimit: zod_1.z.object({ requestsPerMinute: zod_1.z.number().positive().default(60), burstLimit: zod_1.z.number().positive().default(10), }), validation: zod_1.z.object({ enabled: zod_1.z.boolean().default(true), strictMode: zod_1.z.boolean().default(false), }), logging: zod_1.z.object({ level: zod_1.z.enum(['error', 'warn', 'info', 'debug']).default('info'), format: zod_1.z.enum(['json', 'pretty']).default('pretty'), }), context7: zod_1.z.object({ enabled: zod_1.z.boolean().default(true), libraryId: zod_1.z.string().default('/bookstack/bookstack'), cacheTtl: zod_1.z.number().positive().default(3600), }), security: zod_1.z.object({ corsEnabled: zod_1.z.boolean().default(true), corsOrigin: zod_1.z.string().default('*'), helmetEnabled: zod_1.z.boolean().default(true), }), development: zod_1.z.object({ nodeEnv: zod_1.z.enum(['development', 'production', 'test']).default('development'), debug: zod_1.z.boolean().default(false), }), }); /** * Configuration manager singleton */ class ConfigManager { constructor() { this.logger = logger_1.Logger.getInstance(); this.config = this.loadConfig(); } static getInstance() { if (!ConfigManager.instance) { ConfigManager.instance = new ConfigManager(); } return ConfigManager.instance; } /** * Load and validate configuration from environment variables */ loadConfig() { const rawConfig = { bookstack: { baseUrl: process.env.BOOKSTACK_BASE_URL || 'http://localhost:8080/api', apiToken: process.env.BOOKSTACK_API_TOKEN || '', timeout: parseInt(process.env.BOOKSTACK_TIMEOUT || '30000'), }, server: { name: process.env.SERVER_NAME || 'bookstack-mcp-server', version: process.env.SERVER_VERSION || '1.0.0', port: parseInt(process.env.SERVER_PORT || '3000'), }, rateLimit: { requestsPerMinute: parseInt(process.env.RATE_LIMIT_REQUESTS_PER_MINUTE || '60'), burstLimit: parseInt(process.env.RATE_LIMIT_BURST_LIMIT || '10'), }, validation: { enabled: process.env.VALIDATION_ENABLED !== 'false', strictMode: process.env.VALIDATION_STRICT_MODE === 'true', }, logging: { level: process.env.LOG_LEVEL || 'info', format: process.env.LOG_FORMAT || 'pretty', }, context7: { enabled: process.env.CONTEXT7_ENABLED !== 'false', libraryId: process.env.CONTEXT7_LIBRARY_ID || '/bookstack/bookstack', cacheTtl: parseInt(process.env.CONTEXT7_CACHE_TTL || '3600'), }, security: { corsEnabled: process.env.CORS_ENABLED !== 'false', corsOrigin: process.env.CORS_ORIGIN || '*', helmetEnabled: process.env.HELMET_ENABLED !== 'false', }, development: { nodeEnv: process.env.NODE_ENV || 'development', debug: process.env.DEBUG === 'true', }, }; try { const validatedConfig = exports.ConfigSchema.parse(rawConfig); this.logger.info('Configuration loaded and validated successfully'); return validatedConfig; } catch (error) { if (error instanceof zod_1.z.ZodError) { const errorMessages = error.errors.map(err => `${err.path.join('.')}: ${err.message}`); this.logger.error('Configuration validation failed:', errorMessages); throw new Error(`Configuration validation failed: ${errorMessages.join(', ')}`); } throw error; } } /** * Get current configuration */ getConfig() { return this.config; } /** * Reload configuration from environment */ reload() { this.config = this.loadConfig(); return this.config; } /** * Validate if configuration is ready for production */ validateForProduction() { const config = this.getConfig(); const errors = []; // Check required production settings if (!config.bookstack.apiToken) { errors.push('BOOKSTACK_API_TOKEN is required'); } if (config.bookstack.baseUrl.includes('localhost') && config.development.nodeEnv === 'production') { errors.push('Production should not use localhost for BookStack URL'); } if (config.development.debug && config.development.nodeEnv === 'production') { errors.push('Debug mode should be disabled in production'); } if (config.logging.level === 'debug' && config.development.nodeEnv === 'production') { errors.push('Debug logging should be disabled in production'); } if (errors.length > 0) { throw new Error(`Production validation failed: ${errors.join(', ')}`); } this.logger.info('Configuration validated for production'); } /** * Get configuration summary for logging */ getSummary() { const config = this.getConfig(); return { bookstack: { baseUrl: config.bookstack.baseUrl, hasApiToken: !!config.bookstack.apiToken, timeout: config.bookstack.timeout, }, server: config.server, rateLimit: config.rateLimit, validation: config.validation, logging: config.logging, context7: { enabled: config.context7.enabled, libraryId: config.context7.libraryId, cacheTtl: config.context7.cacheTtl, }, development: config.development, }; } } exports.ConfigManager = ConfigManager; exports.default = ConfigManager; //# sourceMappingURL=manager.js.map