Skip to main content
Glama
config.ts10.1 kB
import { Router, Request, Response } from 'express'; import { configService } from '../../services/config/index.js'; const router = Router(); /** * GET /api/v1/config/system * Get all system configuration as flat key-value pairs */ router.get('/system', async (req: Request, res: Response) => { try { const pool = (configService as any).pool; const result = await pool.query( 'SELECT key, value FROM system_config WHERE enabled = true ORDER BY key' ); // Convert to flat object const config: Record<string, any> = {}; for (const row of result.rows) { config[row.key] = row.value; } res.json(config); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * PUT /api/v1/config/system/:key * Update a system configuration value */ router.put('/system/:key', async (req: Request, res: Response) => { try { const { key } = req.params; const { value } = req.body; if (value === undefined) { return res.status(400).json({ error: 'value is required' }); } await configService.set(key, value); res.json({ success: true, key, value }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/providers * Get all provider credentials (with partial API keys) */ router.get('/providers', async (req: Request, res: Response) => { try { const pool = (configService as any).pool; const result = await pool.query( `SELECT provider, api_key_encrypted, api_endpoint, enabled, configuration FROM provider_credentials ORDER BY provider` ); // Return with encrypted keys visible (but encrypted, so safe to show) const providers = result.rows.map(row => ({ provider: row.provider, apiKey: row.api_key_encrypted || '', endpoint: row.api_endpoint || '', enabled: row.enabled, configuration: row.configuration || {} })); res.json(providers); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/providers/:provider * Get specific provider configuration */ router.get('/providers/:provider', async (req: Request, res: Response) => { try { const { provider } = req.params; const cred = await configService.getProvider(provider); if (!cred) { return res.status(404).json({ error: 'Provider not found' }); } // Sanitize response res.json({ provider: cred.provider, enabled: cred.enabled, api_endpoint: cred.api_endpoint, configuration: cred.configuration, has_key: !!cred.api_key_encrypted }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * POST /api/v1/config/providers/:provider * Create or update provider credentials */ router.post('/providers/:provider', async (req: Request, res: Response) => { try { const { provider } = req.params; const { apiKey, endpoint, configuration } = req.body; if (!apiKey) { return res.status(400).json({ error: 'apiKey is required' }); } await configService.setProvider( provider, apiKey, endpoint, configuration ); res.json({ success: true, provider }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * DELETE /api/v1/config/providers/:provider * Disable a provider */ router.delete('/providers/:provider', async (req: Request, res: Response) => { try { const { provider } = req.params; const pool = (configService as any).pool; await pool.query( 'UPDATE provider_credentials SET enabled = false WHERE provider = $1', [provider] ); // Clear cache (configService as any).configCache.delete(`provider:${provider}`); res.json({ success: true, provider }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/layers * Get all layer configurations */ router.get('/layers', async (req: Request, res: Response) => { try { const pool = (configService as any).pool; const result = await pool.query( 'SELECT layer_name, models, priority, enabled, configuration FROM layer_config ORDER BY layer_name' ); const layers = result.rows.map(row => ({ layer: row.layer_name, models: row.models || [], priority: row.priority, enabled: row.enabled, description: row.configuration?.description || '' })); res.json(layers); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/layers/:layer * Get specific layer configuration */ router.get('/layers/:layer', async (req: Request, res: Response) => { try { const { layer } = req.params; const config = await configService.getLayer(layer); if (!config) { return res.status(404).json({ error: 'Layer not found' }); } res.json(config); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * PUT /api/v1/config/layers/:layer * Update layer configuration */ router.put('/layers/:layer', async (req: Request, res: Response) => { try { const { layer } = req.params; const { models, priority, enabled, description } = req.body; const pool = (configService as any).pool; const configuration = description ? { description } : {}; await pool.query( `UPDATE layer_config SET models = $1, priority = $2, enabled = $3, configuration = $4 WHERE layer_name = $5`, [models, priority, enabled, JSON.stringify(configuration), layer] ); res.json({ success: true, layer }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/tasks * Get all task configurations */ router.get('/tasks', async (req: Request, res: Response) => { try { const pool = (configService as any).pool; const result = await pool.query( 'SELECT task_type, models, fallback_models, enabled FROM task_config ORDER BY task_type' ); const tasks = result.rows.map(row => ({ task: row.task_type, preferredModel: row.models?.[0] || '', fallbackModels: row.fallback_models || [], enabled: row.enabled })); res.json(tasks); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/tasks/:task * Get specific task configuration */ router.get('/tasks/:task', async (req: Request, res: Response) => { try { const { task } = req.params; const config = await configService.getTask(task); if (!config) { return res.status(404).json({ error: 'Task not found' }); } res.json(config); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * PUT /api/v1/config/tasks/:task * Update task configuration */ router.put('/tasks/:task', async (req: Request, res: Response) => { try { const { task } = req.params; const { preferredModel, fallbackModels, enabled } = req.body; const pool = (configService as any).pool; const models = [preferredModel]; await pool.query( `UPDATE task_config SET models = $1, fallback_models = $2, enabled = $3 WHERE task_type = $4`, [models, fallbackModels || [], enabled, task] ); res.json({ success: true, task }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * GET /api/v1/config/features * Get all feature flags */ router.get('/features', async (req: Request, res: Response) => { try { const pool = (configService as any).pool; const result = await pool.query( 'SELECT flag_key, enabled, description, metadata FROM feature_flags ORDER BY flag_key' ); const features = result.rows.map(row => ({ flag: row.flag_key, enabled: row.enabled, description: row.description || '', metadata: row.metadata || {} })); res.json(features); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * PUT /api/v1/config/features/:flag * Update feature flag */ router.put('/features/:flag', async (req: Request, res: Response) => { try { const { flag } = req.params; const { enabled, description, metadata } = req.body; if (typeof enabled !== 'boolean') { return res.status(400).json({ error: 'enabled must be boolean' }); } const pool = (configService as any).pool; await pool.query( `UPDATE feature_flags SET enabled = $1, description = $2, metadata = $3 WHERE flag_key = $4`, [enabled, description || null, JSON.stringify(metadata || {}), flag] ); res.json({ success: true, flag, enabled }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); /** * POST /api/v1/config/cache/clear * Clear configuration cache */ router.post('/cache/clear', async (req: Request, res: Response) => { try { configService.clearCache(); res.json({ success: true, message: 'Cache cleared' }); } catch (error: any) { res.status(500).json({ error: error.message }); } }); export default router;

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/babasida246/ai-mcp-gateway'

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