UNPKG

sap-b1-mcp-server

Version:

SAP Business One Service Layer MCP Server

195 lines 6.7 kB
import { z } from 'zod'; // Configuration schema validation const configSchema = z.object({ serverUrl: z.string().url('Invalid SAP B1 Service Layer URL'), database: z.string().min(1, 'Database name is required'), username: z.string().min(1, 'Username is required'), password: z.string().min(1, 'Password is required'), sessionTimeout: z.number().min(1).max(1440).optional() // 1-1440 minutes }); // Environment variables schema const envSchema = z.object({ SAP_B1_SERVER_URL: z.string().optional(), SAP_B1_DATABASE: z.string().optional(), SAP_B1_USERNAME: z.string().optional(), SAP_B1_PASSWORD: z.string().optional(), SAP_B1_SESSION_TIMEOUT: z.string().optional(), MCP_TRANSPORT: z.enum(['stdio', 'http', 'streaming-http']).optional().default('stdio'), MCP_HTTP_PORT: z.string().optional(), MCP_HTTP_HOST: z.string().optional(), MCP_API_KEY: z.string().optional(), MCP_REQUIRE_API_KEY: z.string().optional(), MCP_HTTP_CORS: z.string().optional(), NODE_ENV: z.enum(['development', 'production', 'test']).optional().default('development') }); export class ConfigManager { config = null; /** * Load configuration from environment variables and config file */ async loadConfig(configPath) { // Parse environment variables const env = envSchema.parse(process.env); let sapConfig; // Try to load from config file if provided if (configPath) { try { const fileConfig = await this.loadConfigFromFile(configPath); sapConfig = fileConfig; } catch (error) { console.warn(`Failed to load config from file: ${configPath}. Using environment variables.`); sapConfig = this.loadConfigFromEnv(env); } } else { sapConfig = this.loadConfigFromEnv(env); } // Validate SAP configuration const validatedSapConfig = configSchema.parse(sapConfig); // Build complete configuration this.config = { sap: validatedSapConfig, transport: { type: env.MCP_TRANSPORT, http: (env.MCP_TRANSPORT === 'http' || env.MCP_TRANSPORT === 'streaming-http') ? { port: env.MCP_HTTP_PORT ? parseInt(env.MCP_HTTP_PORT) : 3000, host: env.MCP_HTTP_HOST || 'localhost', apiKey: env.MCP_API_KEY, requireApiKey: env.MCP_REQUIRE_API_KEY ? env.MCP_REQUIRE_API_KEY.toLowerCase() === 'true' : true, cors: env.MCP_HTTP_CORS ? env.MCP_HTTP_CORS.toLowerCase() === 'true' : true } : undefined }, environment: env.NODE_ENV }; return this.config; } /** * Get current configuration */ getConfig() { if (!this.config) { throw new Error('Configuration not loaded. Call loadConfig() first.'); } return this.config; } /** * Get SAP B1 configuration */ getSAPConfig() { return this.getConfig().sap; } /** * Validate configuration without loading */ static validateConfig(config) { try { configSchema.parse(config); return { valid: true, errors: [] }; } catch (error) { if (error instanceof z.ZodError) { return { valid: false, errors: error.errors.map(e => `${e.path.join('.')}: ${e.message}`) }; } return { valid: false, errors: [error instanceof Error ? error.message : 'Unknown validation error'] }; } } /** * Create example configuration file */ static createExampleConfig() { return { serverUrl: 'https://your-sap-server:50000/b1s/v1', database: 'YOUR_COMPANY_DB', username: 'manager', password: 'your-password', sessionTimeout: 30 }; } /** * Load configuration from JSON file */ async loadConfigFromFile(filePath) { const fs = await import('fs/promises'); const fileContent = await fs.readFile(filePath, 'utf-8'); const config = JSON.parse(fileContent); return config; } /** * Load configuration from environment variables */ loadConfigFromEnv(env) { if (!env.SAP_B1_SERVER_URL || !env.SAP_B1_DATABASE || !env.SAP_B1_USERNAME || !env.SAP_B1_PASSWORD) { throw new Error('Missing required environment variables: SAP_B1_SERVER_URL, SAP_B1_DATABASE, SAP_B1_USERNAME, SAP_B1_PASSWORD'); } return { serverUrl: env.SAP_B1_SERVER_URL, database: env.SAP_B1_DATABASE, username: env.SAP_B1_USERNAME, password: env.SAP_B1_PASSWORD, sessionTimeout: env.SAP_B1_SESSION_TIMEOUT ? parseInt(env.SAP_B1_SESSION_TIMEOUT) : 30 }; } /** * Mask sensitive information in configuration for logging */ static maskSensitiveConfig(config) { return { serverUrl: config.serverUrl, database: config.database, username: config.username, password: '***masked***', sessionTimeout: config.sessionTimeout }; } /** * Get configuration summary for display */ getConfigSummary() { const config = this.getConfig(); return { sap: ConfigManager.maskSensitiveConfig(config.sap), transport: config.transport, environment: config.environment }; } /** * Check if configuration is for production */ isProduction() { return this.getConfig().environment === 'production'; } /** * Check if configuration is for development */ isDevelopment() { return this.getConfig().environment === 'development'; } /** * Check if HTTP transport is enabled */ isHttpTransport() { const type = this.getConfig().transport.type; return type === 'http' || type === 'streaming-http'; } /** * Check if streaming HTTP transport is enabled */ isStreamingHttpTransport() { return this.getConfig().transport.type === 'streaming-http'; } /** * Get HTTP configuration if enabled */ getHttpConfig() { const config = this.getConfig(); return config.transport.type === 'http' && config.transport.http ? config.transport.http : null; } } //# sourceMappingURL=config.js.map