import { readFileSync } from "node:fs"; /** * Read a configuration value from the environment, with `_FILE` * indirection: if `_FILE` is set, the value is read from that file * (trailing whitespace stripped). This keeps secrets out of process * environments and lets systemd credentials / agenix-managed files be used * directly. */ export function envOrFile(name: string): string | undefined { const direct = process.env[name]; const file = process.env[`${name}_FILE`]; if (direct && file) { throw new Error(`Both ${name} and ${name}_FILE are set; use only one.`); } if (file) { try { return readFileSync(file, "utf8").replace(/\s+$/, ""); } catch (err) { const message = err instanceof Error ? err.message : String(err); throw new Error(`Could not read ${name}_FILE (${file}): ${message}`); } } return direct || undefined; } /** Like envOrFile, but exits with a helpful message when unset. */ export function requireEnvOrFile(name: string, hint: string): string { const value = envOrFile(name); if (!value) { console.error(`[jortt-mcp] Missing required configuration: ${name}\n${hint}`); process.exit(1); } return value; } export function envFlag(name: string): boolean { const value = process.env[name]?.toLowerCase(); return value === "1" || value === "true" || value === "yes"; } /** Parse a comma- or whitespace-separated env list. */ export function envList(name: string): string[] { const value = process.env[name]; if (!value) return []; return value .split(/[,\s]+/) .map((s) => s.trim()) .filter(Boolean); }