Skip to main content
Glama

CodeCompass MCP

config.ts6.6 kB
import { z } from 'zod'; // Configuration schema with validation const ConfigSchema = z.object({ // GitHub Configuration github: z.object({ token: z.string().optional(), apiUrl: z.string().default('https://api.github.com'), maxRetries: z.number().default(3), retryDelay: z.number().default(1000), rateLimitBuffer: z.number().default(10), }), // OpenRouter/AI Configuration openrouter: z.object({ apiKey: z.string().optional(), apiUrl: z.string().default('https://openrouter.ai/api/v1'), defaultModel: z.string().default('anthropic/claude-3.5-sonnet'), maxRetries: z.number().default(3), timeout: z.number().default(30000), }), // Response Management response: z.object({ maxTokens: z.number().default(25000), maxFileContentLength: z.number().default(1000), chunkSizes: z.object({ small: z.object({ tokens: z.number().default(10000), fileContent: z.number().default(500), filesPerChunk: z.number().default(10), }), medium: z.object({ tokens: z.number().default(20000), fileContent: z.number().default(1000), filesPerChunk: z.number().default(20), }), large: z.object({ tokens: z.number().default(40000), fileContent: z.number().default(2000), filesPerChunk: z.number().default(40), }), }), }), // Cache Configuration cache: z.object({ enabled: z.boolean().default(true), ttl: z.number().default(300000), // 5 minutes maxSize: z.number().default(100), }), // Logging Configuration logging: z.object({ level: z.enum(['debug', 'info', 'warn', 'error']).default('info'), enableTimestamps: z.boolean().default(true), enableColors: z.boolean().default(true), }), // Processing Limits limits: z.object({ maxFiles: z.number().default(100), maxFileSize: z.number().default(1024 * 1024), // 1MB maxProcessingTime: z.number().default(60000), // 1 minute maxConcurrentRequests: z.number().default(5), }), }); export type Config = z.infer<typeof ConfigSchema>; // Environment variable mappings const ENV_MAPPINGS = { 'GITHUB_TOKEN': 'github.token', 'GITHUB_API_URL': 'github.apiUrl', 'OPENROUTER_API_KEY': 'openrouter.apiKey', 'OPENROUTER_API_URL': 'openrouter.apiUrl', 'OPENAI_MODEL': 'openrouter.defaultModel', 'MAX_RESPONSE_TOKENS': 'response.maxTokens', 'MAX_FILE_CONTENT_LENGTH': 'response.maxFileContentLength', 'CACHE_ENABLED': 'cache.enabled', 'CACHE_TTL': 'cache.ttl', 'LOG_LEVEL': 'logging.level', 'MAX_FILES': 'limits.maxFiles', 'MAX_FILE_SIZE': 'limits.maxFileSize', 'MAX_PROCESSING_TIME': 'limits.maxProcessingTime', }; // Helper to set nested object property function setNestedProperty(obj: any, path: string, value: any) { const keys = path.split('.'); let current = obj; for (let i = 0; i < keys.length - 1; i++) { const key = keys[i]; if (!(key in current)) { current[key] = {}; } current = current[key]; } const finalKey = keys[keys.length - 1]; current[finalKey] = value; } // Helper to parse environment variable value function parseEnvValue(value: string): any { // Try to parse as number if (/^\d+$/.test(value)) { return parseInt(value, 10); } // Try to parse as boolean if (value.toLowerCase() === 'true') return true; if (value.toLowerCase() === 'false') return false; // Return as string return value; } // Load configuration from environment variables function loadConfigFromEnv(): Partial<Config> { const config: any = {}; for (const [envKey, configPath] of Object.entries(ENV_MAPPINGS)) { const envValue = process.env[envKey]; if (envValue) { setNestedProperty(config, configPath, parseEnvValue(envValue)); } } return config; } // Create and validate configuration export function createConfig(): Config { const envConfig = loadConfigFromEnv(); // Provide defaults for missing configuration sections const configWithDefaults = { github: { token: process.env.GITHUB_TOKEN || '', ...envConfig.github }, openrouter: { apiKey: process.env.OPENROUTER_API_KEY || '', defaultModel: 'anthropic/claude-3.5-sonnet', ...envConfig.openrouter }, response: { maxTokens: 25000, maxFileContentLength: 5000, chunkSizes: { small: { filesPerChunk: 5, fileContent: 1000 }, medium: { filesPerChunk: 10, fileContent: 2000 }, large: { filesPerChunk: 20, fileContent: 5000 } }, ...envConfig.response }, cache: { enabled: true, ttl: 3600, ...envConfig.cache }, logging: { level: 'info', enableTimestamps: true, enableColors: true, ...envConfig.logging }, limits: { maxFiles: 100, maxFileSize: 10 * 1024 * 1024, // 10MB maxProcessingTime: 30000, // 30 seconds maxConcurrentRequests: 10, ...envConfig.limits } }; // Validate the configuration const config = ConfigSchema.parse(configWithDefaults); // Validate required fields for functionality const warnings: string[] = []; if (!config.github.token && !config.openrouter.apiKey) { warnings.push('Warning: Neither GITHUB_TOKEN nor OPENROUTER_API_KEY is set. Some features may be limited.'); } if (warnings.length > 0) { console.warn(warnings.join('\n')); } return config; } // Global configuration instance let globalConfig: Config | null = null; export function getConfig(): Config { if (!globalConfig) { globalConfig = createConfig(); } return globalConfig; } // Configuration validation helper export function validateConfig(config: Partial<Config>): boolean { try { ConfigSchema.parse(config); return true; } catch (error) { console.error('Configuration validation error:', error); return false; } } // Get model aliases for user-friendly names export function getModelAliases(): Record<string, string> { return { 'claude-3-sonnet': 'anthropic/claude-3.5-sonnet', 'claude-3-opus': 'anthropic/claude-3-opus', 'claude-3-haiku': 'anthropic/claude-3-haiku', 'gpt-4': 'openai/gpt-4', 'gpt-4-turbo': 'openai/gpt-4-turbo', 'gpt-4o': 'openai/gpt-4o', 'gpt-4o-mini': 'openai/gpt-4o-mini', 'gemini-pro': 'google/gemini-pro', 'gemini-1.5-pro': 'google/gemini-1.5-pro', }; } // Resolve model alias to full model name export function resolveModelAlias(model: string): string { const aliases = getModelAliases(); return aliases[model] || model; }

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/TheAlchemist6/codecompass-mcp'

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