@bratcliffe909/mcp-server-segmind
Version:
Model Context Protocol server for Segmind API - Generate images and videos using AI models
118 lines • 4.8 kB
JavaScript
import dotenv from 'dotenv';
import { z } from 'zod';
dotenv.config({ silent: true });
const ConfigSchema = z.object({
apiKey: z.string().regex(/^(sg_|SG_)[a-zA-Z0-9]{12,}$/, 'Invalid Segmind API key format').optional(),
baseUrl: z.string().url().default('https://api.segmind.com/v1'),
nodeEnv: z.enum(['development', 'production', 'test']).default('production'),
logLevel: z.enum(['error', 'warn', 'info', 'debug']).default('info'),
defaultModels: z.object({
text2img: z.string().default('sdxl'),
img2img: z.string().default('sdxl-img2img'),
video: z.string().default('veo-3'),
}),
cache: z.object({
enabled: z.boolean().default(true),
ttl: z.number().min(0).default(3600),
maxSize: z.number().min(0).default(100),
}),
limits: z.object({
maxImageSize: z.number().min(1).default(10 * 1024 * 1024),
maxBatchSize: z.number().min(1).default(5),
requestTimeout: z.number().min(1000).default(120000),
maxConcurrentRequests: z.number().min(1).default(10),
}),
fileOutput: z.object({
saveLocation: z.string().optional(),
}),
security: z.object({
validateInputs: z.boolean().default(true),
sanitizeLogs: z.boolean().default(true),
allowedImageFormats: z.array(z.string()).default(['png', 'jpeg', 'jpg', 'webp']),
}),
});
class ConfigurationLoader {
static instance = null;
static load() {
if (this.instance) {
return this.instance;
}
const rawConfig = {
apiKey: process.env.SEGMIND_API_KEY || '',
baseUrl: process.env.SEGMIND_BASE_URL,
nodeEnv: process.env.NODE_ENV,
logLevel: process.env.LOG_LEVEL,
defaultModels: {
text2img: process.env.DEFAULT_TEXT2IMG_MODEL,
img2img: process.env.DEFAULT_IMG2IMG_MODEL,
video: process.env.DEFAULT_VIDEO_MODEL,
},
cache: {
enabled: process.env.CACHE_ENABLED !== undefined ? process.env.CACHE_ENABLED === 'true' : undefined,
ttl: process.env.CACHE_TTL ? parseInt(process.env.CACHE_TTL, 10) : undefined,
maxSize: process.env.CACHE_MAX_SIZE ? parseInt(process.env.CACHE_MAX_SIZE, 10) : undefined,
},
limits: {
maxImageSize: process.env.MAX_IMAGE_SIZE ? parseInt(process.env.MAX_IMAGE_SIZE, 10) : undefined,
maxBatchSize: process.env.MAX_BATCH_SIZE ? parseInt(process.env.MAX_BATCH_SIZE, 10) : undefined,
requestTimeout: process.env.REQUEST_TIMEOUT ? parseInt(process.env.REQUEST_TIMEOUT, 10) : undefined,
maxConcurrentRequests: process.env.MAX_CONCURRENT_REQUESTS ? parseInt(process.env.MAX_CONCURRENT_REQUESTS, 10) : undefined,
},
security: {
validateInputs: process.env.VALIDATE_INPUTS !== 'false',
sanitizeLogs: process.env.SANITIZE_LOGS !== 'false',
allowedImageFormats: process.env.ALLOWED_IMAGE_FORMATS?.split(','),
},
fileOutput: {
saveLocation: process.env.FILE_OUTPUT_LOCATION,
},
};
try {
if (!rawConfig.apiKey || rawConfig.apiKey === '') {
delete rawConfig.apiKey;
}
this.instance = ConfigSchema.parse(rawConfig);
return this.instance;
}
catch (error) {
if (error instanceof z.ZodError) {
const issues = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`).join(', ');
if (issues.includes('apiKey') && process.env.MCP_MODE === 'true') {
delete rawConfig.apiKey;
this.instance = ConfigSchema.parse(rawConfig);
return this.instance;
}
throw new Error(`Configuration validation failed: ${issues}`);
}
throw error;
}
}
static reset() {
this.instance = null;
}
static getMaskedApiKey(apiKey) {
if (!apiKey || apiKey.length < 10) {
return '[INVALID]';
}
return `${apiKey.substring(0, 6)}...${apiKey.substring(apiKey.length - 4)}`;
}
}
let _config = null;
export function getConfig() {
if (!_config) {
_config = ConfigurationLoader.load();
}
return _config;
}
export const config = new Proxy({}, {
get(_, prop) {
return getConfig()[prop];
}
});
export const getMaskedApiKey = (apiKey) => ConfigurationLoader.getMaskedApiKey(apiKey);
export const resetConfig = () => {
ConfigurationLoader.reset();
_config = null;
};
export { ConfigurationLoader };
//# sourceMappingURL=config.js.map