Skip to main content
Glama
auth.ts3.49 kB
import { config } from 'dotenv'; import path from 'path'; import fs from 'fs'; import { AuthConfig } from '../types'; export function loadAuthConfig(specsPath: string): AuthConfig { // Load .env file from specs directory const envPath = path.join(specsPath, '.env'); if (fs.existsSync(envPath)) { config({ path: envPath }); } const authConfig: AuthConfig = {}; // Parse environment variables with naming convention {API_NAME}_API_KEY, etc. for (const [key, value] of Object.entries(process.env)) { if (!value) continue; // Match patterns like PETSTORE_API_KEY, GITHUB_TOKEN, etc. const apiKeyMatch = key.match(/^(.+)_API_KEY$/); const tokenMatch = key.match(/^(.+)_TOKEN$/); const bearerMatch = key.match(/^(.+)_BEARER_TOKEN$/); const basicUserMatch = key.match(/^(.+)_USERNAME$/); const basicPassMatch = key.match(/^(.+)_PASSWORD$/); let apiName: string | undefined; let authType: 'bearer' | 'apiKey' | 'basic' | undefined; let configKey: string | undefined; if (bearerMatch) { apiName = bearerMatch[1].toLowerCase(); authType = 'bearer'; configKey = 'token'; } else if (apiKeyMatch) { apiName = apiKeyMatch[1].toLowerCase(); authType = 'apiKey'; configKey = 'token'; } else if (tokenMatch && !key.includes('BEARER')) { apiName = tokenMatch[1].toLowerCase(); authType = 'bearer'; configKey = 'token'; } else if (basicUserMatch) { apiName = basicUserMatch[1].toLowerCase(); authType = 'basic'; configKey = 'username'; } else if (basicPassMatch) { apiName = basicPassMatch[1].toLowerCase(); authType = 'basic'; configKey = 'password'; } if (apiName && authType && configKey) { if (!authConfig[apiName]) { authConfig[apiName] = { type: authType }; } // Override type if more specific auth found if (authType === 'bearer' && authConfig[apiName].type !== 'bearer') { authConfig[apiName].type = authType; } (authConfig[apiName] as any)[configKey] = value; // Set default header name for API keys if (authType === 'apiKey' && !authConfig[apiName].headerName) { authConfig[apiName].headerName = 'X-API-Key'; } } } return authConfig; } export function applyAuthentication( headers: Record<string, string>, authConfig?: AuthConfig[string] ): Record<string, string> { if (!authConfig) return headers; const result = { ...headers }; switch (authConfig.type) { case 'bearer': if (authConfig.token) { result['Authorization'] = `Bearer ${authConfig.token}`; } break; case 'apiKey': if (authConfig.token && authConfig.headerName) { result[authConfig.headerName] = authConfig.token; } break; case 'basic': if (authConfig.username && authConfig.password) { const credentials = Buffer.from(`${authConfig.username}:${authConfig.password}`).toString('base64'); result['Authorization'] = `Basic ${credentials}`; } break; } return result; } export function getApiNameFromFile(filePath: string): string { const fileName = path.basename(filePath, path.extname(filePath)); // Convert kebab-case and snake_case to lowercase return fileName.toLowerCase().replace(/[-_]/g, ''); }

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/TBosak/specbridge'

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