Skip to main content
Glama

Open Search MCP

by flyanima
MIT License
2
  • Apple
  • Linux
config-generator.ts12.8 kB
import { promises as fs } from 'fs'; import { join, dirname } from 'path'; import { homedir } from 'os'; import { defaultLogger as logger } from '../utils/logger.js'; export type PlatformType = 'claude-desktop' | 'cursor' | 'vscode' | 'windsurf' | 'augment-code' | 'cline'; export interface ConfigGeneratorOptions { platform: PlatformType; serverName?: string; serverPath?: string; apiKeys?: Record<string, string>; autoApprove?: string[]; timeout?: number; disabled?: boolean; outputPath?: string; } export interface PlatformConfig { configPath: string; configFormat: 'json' | 'yaml'; configStructure: any; installInstructions: string; } /** * Multi-Platform Configuration Generator * Generates platform-specific configurations for Open-Search-MCP */ export class ConfigGenerator { private static readonly PLATFORM_CONFIGS: Record<PlatformType, PlatformConfig> = { 'claude-desktop': { configPath: process.platform === 'win32' ? join(homedir(), 'AppData', 'Roaming', 'Claude', 'claude_desktop_config.json') : process.platform === 'darwin' ? join(homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json') : join(homedir(), '.config', 'Claude', 'claude_desktop_config.json'), configFormat: 'json', configStructure: { mcpServers: {} }, installInstructions: 'Restart Claude Desktop after configuration update' }, 'cursor': { configPath: process.platform === 'win32' ? join(homedir(), 'AppData', 'Roaming', 'Cursor', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'cline_mcp_settings.json') : process.platform === 'darwin' ? join(homedir(), 'Library', 'Application Support', 'Cursor', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'cline_mcp_settings.json') : join(homedir(), '.config', 'Cursor', 'User', 'globalStorage', 'rooveterinaryinc.roo-cline', 'settings', 'cline_mcp_settings.json'), configFormat: 'json', configStructure: { mcpServers: {} }, installInstructions: 'Install Cline extension and restart Cursor IDE' }, 'vscode': { configPath: process.platform === 'win32' ? join(homedir(), 'AppData', 'Roaming', 'Code', 'User', 'settings.json') : process.platform === 'darwin' ? join(homedir(), 'Library', 'Application Support', 'Code', 'User', 'settings.json') : join(homedir(), '.config', 'Code', 'User', 'settings.json'), configFormat: 'json', configStructure: { 'mcp.servers': {} }, installInstructions: 'Install MCP extension and reload VS Code window' }, 'windsurf': { configPath: join(process.cwd(), 'windsurf-mcp-config.json'), configFormat: 'json', configStructure: { servers: {}, ui: { theme: 'auto', notifications: true, autoStart: true } }, installInstructions: 'Start HTTP server with npm run server:http and import config in Windsurf Settings → MCP Servers' }, 'augment-code': { configPath: join(process.cwd(), 'augment-mcp-config.json'), configFormat: 'json', configStructure: { mcpServers: {} }, installInstructions: 'Import configuration in Augment Code settings' }, 'cline': { configPath: join(process.cwd(), 'cline-mcp-settings.json'), configFormat: 'json', configStructure: { mcpServers: {} }, installInstructions: 'Use with Cline extension in supported editors' } }; /** * Generate configuration for a specific platform */ public static async generateConfig(options: ConfigGeneratorOptions): Promise<string> { const { platform, serverName = 'open-search-mcp', serverPath = 'node', apiKeys = {}, autoApprove = this.getDefaultAutoApproveTools(), timeout = 60, disabled = false, outputPath } = options; const platformConfig = this.PLATFORM_CONFIGS[platform]; if (!platformConfig) { throw new Error(`Unsupported platform: ${platform}`); } // Generate server configuration const serverConfig = this.generateServerConfig({ serverName, serverPath, apiKeys, autoApprove, timeout, disabled, platform }); // Create platform-specific configuration const config = { ...platformConfig.configStructure }; switch (platform) { case 'claude-desktop': case 'cursor': case 'augment-code': case 'cline': config.mcpServers[serverName] = serverConfig; break; case 'vscode': config['mcp.servers'][serverName] = serverConfig; break; case 'windsurf': config.servers[serverName] = serverConfig; break; } // Convert to string const configString = JSON.stringify(config, null, 2); // Write to file if output path is specified if (outputPath) { await this.writeConfigFile(outputPath, configString); } return configString; } /** * Generate server configuration object */ private static generateServerConfig(options: { serverName: string; serverPath: string; apiKeys: Record<string, string>; autoApprove: string[]; timeout: number; disabled: boolean; platform: PlatformType; }) { const { serverPath, apiKeys, autoApprove, timeout, disabled, platform } = options; // Determine script path const scriptPath = process.env.OPEN_SEARCH_MCP_PATH || join(process.cwd(), 'dist', 'expanded-server.js'); // Build environment variables const env: Record<string, string> = { NODE_ENV: 'production', MCP_PLATFORM: platform, ...apiKeys }; // Add common environment variables if available const commonEnvVars = [ 'GITHUB_TOKEN', 'ALPHA_VANTAGE_API_KEY', 'GOOGLE_API_KEY', 'GOOGLE_SEARCH_ENGINE_ID', 'NEWSAPI_KEY', 'OPENWEATHER_API_KEY' ]; commonEnvVars.forEach(key => { if (process.env[key]) { env[key] = process.env[key]!; } }); // Platform-specific configuration const baseConfig = { command: serverPath, args: [scriptPath], env, timeout, disabled }; // Add platform-specific fields switch (platform) { case 'cursor': case 'cline': return { ...baseConfig, autoApprove }; case 'vscode': return { ...baseConfig, autoStart: true, restart: true }; case 'windsurf': return { type: 'mcp', protocol: 'http', endpoint: `http://localhost:8000/mcp`, command: baseConfig.command, args: baseConfig.args, env: { ...baseConfig.env, MCP_TRANSPORT: 'http', MCP_HTTP_PORT: '8000', MCP_HTTP_HOST: 'localhost' }, timeout: baseConfig.timeout, retries: 3, healthCheck: { enabled: true, interval: 30000, endpoint: 'http://localhost:8000/health' } }; case 'augment-code': return { transport: 'websocket', endpoint: 'ws://localhost:8001', command: baseConfig.command, args: baseConfig.args, env: { ...baseConfig.env, MCP_TRANSPORT: 'websocket', MCP_WS_PORT: '8001', MCP_WS_HOST: 'localhost' }, timeout: baseConfig.timeout, reconnect: { enabled: true, maxAttempts: 5, delay: 3000 }, features: { realTimeUpdates: true, analytics: true, collaboration: false } }; default: return baseConfig; } } /** * Get default auto-approve tools */ private static getDefaultAutoApproveTools(): string[] { return [ // Academic search tools 'search_arxiv', 'search_pubmed', 'search_ieee', 'search_semantic_scholar', 'search_iacr', 'search_biorxiv', 'search_medrxiv', // Developer tools 'search_github', 'search_stackoverflow', 'search_gitlab', 'search_bitbucket', // Search engines 'search_searx', 'search_startpage', 'search_brave', 'search_ecosia', // Testing tools 'test_jsonplaceholder', 'test_httpbin', // Web crawling 'crawl_url_content', 'batch_crawl_urls', // Document processing 'analyze_pdf', // Research tools 'intelligent_research', 'deep_research', 'visualize_thinking', 'decompose_thinking', 'check_research_saturation' ]; } /** * Write configuration to file */ private static async writeConfigFile(filePath: string, content: string): Promise<void> { try { const dir = dirname(filePath); await fs.mkdir(dir, { recursive: true }); await fs.writeFile(filePath, content, 'utf-8'); logger.info(`Configuration written to: ${filePath}`); } catch (error) { logger.error(`Failed to write configuration file: ${error}`); throw error; } } /** * Install configuration for a platform */ public static async installConfig(options: ConfigGeneratorOptions): Promise<void> { const { platform } = options; const platformConfig = this.PLATFORM_CONFIGS[platform]; if (!platformConfig) { throw new Error(`Unsupported platform: ${platform}`); } try { // Check if platform is installed const isInstalled = await this.isPlatformInstalled(platform); if (!isInstalled) { logger.warn(`${platform} may not be installed or configuration directory not found`); } // Generate configuration const configString = await this.generateConfig({ ...options, outputPath: platformConfig.configPath }); logger.info(`Configuration installed for ${platform}`); logger.info(`Config path: ${platformConfig.configPath}`); logger.info(`Instructions: ${platformConfig.installInstructions}`); } catch (error) { logger.error(`Failed to install configuration for ${platform}:`, error); throw error; } } /** * Check if a platform is installed */ private static async isPlatformInstalled(platform: PlatformType): Promise<boolean> { try { const platformConfig = this.PLATFORM_CONFIGS[platform]; const configDir = dirname(platformConfig.configPath); await fs.access(configDir); return true; } catch { return false; } } /** * Get installation instructions for a platform */ public static getInstallationInstructions(platform: PlatformType): string { const platformConfig = this.PLATFORM_CONFIGS[platform]; if (!platformConfig) { throw new Error(`Unsupported platform: ${platform}`); } return ` # ${platform.toUpperCase()} Integration Instructions ## Configuration Path ${platformConfig.configPath} ## Installation Steps ${platformConfig.installInstructions} ## Configuration Format ${platformConfig.configFormat.toUpperCase()} ## Auto-Generate Configuration \`\`\`bash npm run config:generate -- --platform ${platform} \`\`\` ## Manual Installation \`\`\`bash npm run install:${platform} \`\`\` `; } /** * Get all supported platforms */ public static getSupportedPlatforms(): PlatformType[] { return Object.keys(this.PLATFORM_CONFIGS) as PlatformType[]; } /** * Validate platform configuration */ public static validatePlatformConfig(platform: PlatformType, config: any): { valid: boolean; errors: string[] } { const errors: string[] = []; const platformConfig = this.PLATFORM_CONFIGS[platform]; if (!platformConfig) { errors.push(`Unsupported platform: ${platform}`); return { valid: false, errors }; } // Platform-specific validation switch (platform) { case 'claude-desktop': case 'cursor': case 'augment-code': case 'cline': if (!config.mcpServers) { errors.push('Missing mcpServers configuration'); } break; case 'vscode': if (!config['mcp.servers']) { errors.push('Missing mcp.servers configuration'); } break; case 'windsurf': if (!config.servers) { errors.push('Missing servers configuration'); } break; } return { valid: errors.length === 0, errors }; } }

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/flyanima/open-search-mcp'

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