Skip to main content
Glama

firewalla-mcp-server

config.ts5.63 kB
import * as dotenv from 'dotenv'; import type { FirewallaConfig } from '../types'; import { getRequiredEnvVar, getOptionalEnvVar, getOptionalEnvInt, parseTransportConfig, } from '../utils/env.js'; // Configure dotenv to load environment variables dotenv.config(); export interface ProductionConfig extends FirewallaConfig { environment: 'production' | 'staging' | 'development'; logLevel: 'error' | 'warn' | 'info' | 'debug'; enableMetrics: boolean; enableHealthChecks: boolean; corsOrigins: string[]; trustedProxies: string[]; maxConcurrentRequests: number; gracefulShutdownTimeout: number; } export function getProductionConfig(): ProductionConfig { // Check if running in test mode const testMode = getOptionalEnvVar('MCP_TEST_MODE', 'false').toLowerCase() === 'true'; const mspId = testMode ? 'test.firewalla.net' : getRequiredEnvVar('FIREWALLA_MSP_ID'); const baseConfig = { mspToken: testMode ? 'test-token' : getRequiredEnvVar('FIREWALLA_MSP_TOKEN'), mspId, mspBaseUrl: `https://${mspId}`, boxId: testMode ? 'test-box-id' : process.env.FIREWALLA_BOX_ID || undefined, apiTimeout: getOptionalEnvInt('API_TIMEOUT', 30000, 1000, 300000), // 1s to 5min rateLimit: getOptionalEnvInt('API_RATE_LIMIT', 100, 1, 1000), // 1 to 1000 requests per minute cacheTtl: getOptionalEnvInt('CACHE_TTL', 300, 0, 3600), // 0s to 1 hour defaultPageSize: getOptionalEnvInt('DEFAULT_PAGE_SIZE', 100, 1, 10000), // 1 to 10000 items per page maxPageSize: getOptionalEnvInt('MAX_PAGE_SIZE', 10000, 100, 100000), // 100 to 100000 items per page transport: parseTransportConfig(), }; return { ...baseConfig, environment: getOptionalEnvVar( 'NODE_ENV', 'development' ) as ProductionConfig['environment'], logLevel: getOptionalEnvVar( 'LOG_LEVEL', 'info' ) as ProductionConfig['logLevel'], enableMetrics: getOptionalEnvVar('ENABLE_METRICS', 'true') === 'true', enableHealthChecks: getOptionalEnvVar('ENABLE_HEALTH_CHECKS', 'true') === 'true', corsOrigins: getOptionalEnvVar( 'CORS_ORIGINS', 'https://claude.ai,https://anthropic.com' ).split(','), trustedProxies: getOptionalEnvVar('TRUSTED_PROXIES', '') .split(',') .filter(Boolean), maxConcurrentRequests: getOptionalEnvInt( 'MAX_CONCURRENT_REQUESTS', 50, 1, 1000 ), // 1 to 1000 concurrent requests gracefulShutdownTimeout: getOptionalEnvInt( 'GRACEFUL_SHUTDOWN_TIMEOUT', 30000, 1000, 60000 ), // 1s to 60s }; } export class ProductionConfigValidator { static validate(config: ProductionConfig): { valid: boolean; errors: string[]; warnings: string[]; } { const errors: string[] = []; const warnings: string[] = []; // Validate environment if ( !['production', 'staging', 'development'].includes(config.environment) ) { errors.push( 'Invalid environment. Must be production, staging, or development' ); } // Validate log level if (!['error', 'warn', 'info', 'debug'].includes(config.logLevel)) { errors.push('Invalid log level. Must be error, warn, info, or debug'); } // Production-specific validations if (config.environment === 'production') { if (config.logLevel === 'debug') { warnings.push( 'Debug logging enabled in production may impact performance' ); } // MSP ID validation for production - no HTTP check needed as URL is constructed if (config.apiTimeout < 10000) { warnings.push('API timeout may be too low for production workloads'); } if (config.cacheTtl > 3600) { warnings.push( 'Cache TTL over 1 hour may cause stale data in production' ); } if (config.corsOrigins.includes('*')) { errors.push('Wildcard CORS origins not allowed in production'); } if (config.maxConcurrentRequests > 200) { warnings.push( 'High concurrent request limit may impact system stability' ); } } // Validate CORS origins config.corsOrigins.forEach((origin, index) => { if (origin !== '*' && !isValidUrl(origin)) { errors.push(`Invalid CORS origin at index ${index}: ${origin}`); } }); // Validate trusted proxies config.trustedProxies.forEach((proxy, index) => { if (!isValidIpOrCidr(proxy)) { errors.push(`Invalid trusted proxy at index ${index}: ${proxy}`); } }); // Validate numeric ranges if ( config.maxConcurrentRequests < 1 || config.maxConcurrentRequests > 1000 ) { errors.push('Max concurrent requests must be between 1 and 1000'); } if ( config.gracefulShutdownTimeout < 1000 || config.gracefulShutdownTimeout > 60000 ) { errors.push( 'Graceful shutdown timeout must be between 1000ms and 60000ms' ); } return { valid: errors.length === 0, errors, warnings, }; } } function isValidUrl(urlString: string): boolean { try { const url = new URL(urlString); return url.protocol === 'http:' || url.protocol === 'https:'; } catch { return false; } } function isValidIpOrCidr(value: string): boolean { // Basic IP/CIDR validation const ipRegex = /^(\d{1,3}\.){3}\d{1,3}(\/\d{1,2})?$/; const ipv6Regex = /^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}(\/\d{1,3})?$/; return ipRegex.test(value) || ipv6Regex.test(value); } export const productionConfig = getProductionConfig();

Latest Blog Posts

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/amittell/firewalla-mcp-server'

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