Skip to main content
Glama
preferences.ts3.91 kB
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "fs"; import { join, dirname } from "path"; import { homedir } from "os"; import { UserPreferences, CostPreference } from "./types.js"; // Determine preferences file location function getPreferencesPath(): string { // Try user config directory first const userConfigDir = process.platform === "win32" ? join(process.env.APPDATA || homedir(), "cross-llm-mcp") : join(homedir(), ".cross-llm-mcp"); // Fallback to project directory if user config doesn't exist const projectDir = process.cwd(); const projectConfigPath = join( projectDir, ".cross-llm-mcp", "preferences.json", ); // Prefer user config directory, but use project directory as fallback const userConfigPath = join(userConfigDir, "preferences.json"); // Check if user config directory exists or can be created try { if (!existsSync(userConfigDir)) { mkdirSync(userConfigDir, { recursive: true }); } return userConfigPath; } catch { // If we can't use user config, try project directory try { const projectConfigDir = dirname(projectConfigPath); if (!existsSync(projectConfigDir)) { mkdirSync(projectConfigDir, { recursive: true }); } return projectConfigPath; } catch { // Last resort: use user config path anyway (might fail on write) return userConfigPath; } } } // Load preferences from file or environment variables export function loadPreferences(): UserPreferences { const prefs: UserPreferences = {}; // First, try to load from file const prefsPath = getPreferencesPath(); if (existsSync(prefsPath)) { try { const fileContent = readFileSync(prefsPath, "utf-8"); const filePrefs = JSON.parse(fileContent) as UserPreferences; if (filePrefs.defaultModel) { prefs.defaultModel = filePrefs.defaultModel; } if (filePrefs.costPreference) { prefs.costPreference = filePrefs.costPreference; } if (filePrefs.tagPreferences) { prefs.tagPreferences = filePrefs.tagPreferences; } } catch (error) { // If file read fails, continue to env var fallback console.error("Error reading preferences file:", error); } } // Environment variable fallback/override const envDefaultModel = process.env.CROSS_LLM_DEFAULT_MODEL; const envCostPreference = process.env.CROSS_LLM_COST_PREFERENCE; if (envDefaultModel) { prefs.defaultModel = envDefaultModel; } if (envCostPreference === "flagship" || envCostPreference === "cheaper") { prefs.costPreference = envCostPreference as CostPreference; } return prefs; } // Save preferences to file export function savePreferences(prefs: UserPreferences): void { const prefsPath = getPreferencesPath(); const prefsDir = dirname(prefsPath); // Ensure directory exists if (!existsSync(prefsDir)) { mkdirSync(prefsDir, { recursive: true }); } // Read existing preferences to merge let existingPrefs: UserPreferences = {}; if (existsSync(prefsPath)) { try { const fileContent = readFileSync(prefsPath, "utf-8"); existingPrefs = JSON.parse(fileContent) as UserPreferences; } catch { // If read fails, start fresh existingPrefs = {}; } } // Merge preferences (new values override existing) const mergedPrefs: UserPreferences = { ...existingPrefs, ...prefs, // Deep merge tagPreferences tagPreferences: { ...existingPrefs.tagPreferences, ...prefs.tagPreferences, }, }; // Write to file try { writeFileSync(prefsPath, JSON.stringify(mergedPrefs, null, 2), "utf-8"); } catch (error) { throw new Error(`Failed to save preferences: ${error}`); } } // Get preferences file path (for informational purposes) export function getPreferencesFilePath(): string { return getPreferencesPath(); }

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/JamesANZ/cross-llm-mcp'

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