| const express = require('express'); |
| const { logger } = require('@librechat/data-schemas'); |
| const { isEnabled, getBalanceConfig } = require('@librechat/api'); |
| const { |
| Constants, |
| CacheKeys, |
| removeNullishValues, |
| defaultSocialLogins, |
| } = require('librechat-data-provider'); |
| const { getLdapConfig } = require('~/server/services/Config/ldap'); |
| const { getAppConfig } = require('~/server/services/Config/app'); |
| const { getProjectByName } = require('~/models/Project'); |
| const { getMCPManager } = require('~/config'); |
| const { getLogStores } = require('~/cache'); |
| const { mcpServersRegistry } = require('@librechat/api'); |
|
|
| const router = express.Router(); |
| const emailLoginEnabled = |
| process.env.ALLOW_EMAIL_LOGIN === undefined || isEnabled(process.env.ALLOW_EMAIL_LOGIN); |
| const passwordResetEnabled = isEnabled(process.env.ALLOW_PASSWORD_RESET); |
|
|
| const sharedLinksEnabled = |
| process.env.ALLOW_SHARED_LINKS === undefined || isEnabled(process.env.ALLOW_SHARED_LINKS); |
|
|
| const publicSharedLinksEnabled = |
| sharedLinksEnabled && |
| (process.env.ALLOW_SHARED_LINKS_PUBLIC === undefined || |
| isEnabled(process.env.ALLOW_SHARED_LINKS_PUBLIC)); |
|
|
| const sharePointFilePickerEnabled = isEnabled(process.env.ENABLE_SHAREPOINT_FILEPICKER); |
| const openidReuseTokens = isEnabled(process.env.OPENID_REUSE_TOKENS); |
|
|
| |
| |
| |
| |
| |
| const getMCPServers = async (payload, appConfig) => { |
| try { |
| if (appConfig?.mcpConfig == null) { |
| return; |
| } |
| const mcpManager = getMCPManager(); |
| if (!mcpManager) { |
| return; |
| } |
| const mcpServers = await mcpServersRegistry.getAllServerConfigs(); |
| if (!mcpServers) return; |
| for (const serverName in mcpServers) { |
| if (!payload.mcpServers) { |
| payload.mcpServers = {}; |
| } |
| const serverConfig = mcpServers[serverName]; |
| payload.mcpServers[serverName] = removeNullishValues({ |
| startup: serverConfig?.startup, |
| chatMenu: serverConfig?.chatMenu, |
| isOAuth: serverConfig.requiresOAuth, |
| customUserVars: serverConfig?.customUserVars, |
| }); |
| } |
| } catch (error) { |
| logger.error('Error loading MCP servers', error); |
| } |
| }; |
|
|
| router.get('/', async function (req, res) { |
| const cache = getLogStores(CacheKeys.CONFIG_STORE); |
|
|
| const cachedStartupConfig = await cache.get(CacheKeys.STARTUP_CONFIG); |
| if (cachedStartupConfig) { |
| const appConfig = await getAppConfig({ role: req.user?.role }); |
| await getMCPServers(cachedStartupConfig, appConfig); |
| res.send(cachedStartupConfig); |
| return; |
| } |
|
|
| const isBirthday = () => { |
| const today = new Date(); |
| return today.getMonth() === 1 && today.getDate() === 11; |
| }; |
|
|
| const instanceProject = await getProjectByName(Constants.GLOBAL_PROJECT_NAME, '_id'); |
|
|
| const ldap = getLdapConfig(); |
|
|
| try { |
| const appConfig = await getAppConfig({ role: req.user?.role }); |
|
|
| const isOpenIdEnabled = |
| !!process.env.OPENID_CLIENT_ID && |
| !!process.env.OPENID_CLIENT_SECRET && |
| !!process.env.OPENID_ISSUER && |
| !!process.env.OPENID_SESSION_SECRET; |
|
|
| const isSamlEnabled = |
| !!process.env.SAML_ENTRY_POINT && |
| !!process.env.SAML_ISSUER && |
| !!process.env.SAML_CERT && |
| !!process.env.SAML_SESSION_SECRET; |
|
|
| const balanceConfig = getBalanceConfig(appConfig); |
|
|
| |
| const payload = { |
| appTitle: process.env.APP_TITLE || 'LibreChat', |
| socialLogins: appConfig?.registration?.socialLogins ?? defaultSocialLogins, |
| discordLoginEnabled: !!process.env.DISCORD_CLIENT_ID && !!process.env.DISCORD_CLIENT_SECRET, |
| facebookLoginEnabled: |
| !!process.env.FACEBOOK_CLIENT_ID && !!process.env.FACEBOOK_CLIENT_SECRET, |
| githubLoginEnabled: !!process.env.GITHUB_CLIENT_ID && !!process.env.GITHUB_CLIENT_SECRET, |
| googleLoginEnabled: !!process.env.GOOGLE_CLIENT_ID && !!process.env.GOOGLE_CLIENT_SECRET, |
| appleLoginEnabled: |
| !!process.env.APPLE_CLIENT_ID && |
| !!process.env.APPLE_TEAM_ID && |
| !!process.env.APPLE_KEY_ID && |
| !!process.env.APPLE_PRIVATE_KEY_PATH, |
| openidLoginEnabled: isOpenIdEnabled, |
| openidLabel: process.env.OPENID_BUTTON_LABEL || 'Continue with OpenID', |
| openidImageUrl: process.env.OPENID_IMAGE_URL, |
| openidAutoRedirect: isEnabled(process.env.OPENID_AUTO_REDIRECT), |
| samlLoginEnabled: !isOpenIdEnabled && isSamlEnabled, |
| samlLabel: process.env.SAML_BUTTON_LABEL, |
| samlImageUrl: process.env.SAML_IMAGE_URL, |
| serverDomain: process.env.DOMAIN_SERVER || 'http://localhost:3080', |
| emailLoginEnabled, |
| registrationEnabled: !ldap?.enabled && isEnabled(process.env.ALLOW_REGISTRATION), |
| socialLoginEnabled: isEnabled(process.env.ALLOW_SOCIAL_LOGIN), |
| emailEnabled: |
| (!!process.env.EMAIL_SERVICE || !!process.env.EMAIL_HOST) && |
| !!process.env.EMAIL_USERNAME && |
| !!process.env.EMAIL_PASSWORD && |
| !!process.env.EMAIL_FROM, |
| passwordResetEnabled, |
| showBirthdayIcon: |
| isBirthday() || |
| isEnabled(process.env.SHOW_BIRTHDAY_ICON) || |
| process.env.SHOW_BIRTHDAY_ICON === '', |
| helpAndFaqURL: process.env.HELP_AND_FAQ_URL || 'https://librechat.ai', |
| interface: appConfig?.interfaceConfig, |
| turnstile: appConfig?.turnstileConfig, |
| modelSpecs: appConfig?.modelSpecs, |
| balance: balanceConfig, |
| sharedLinksEnabled, |
| publicSharedLinksEnabled, |
| analyticsGtmId: process.env.ANALYTICS_GTM_ID, |
| instanceProjectId: instanceProject._id.toString(), |
| bundlerURL: process.env.SANDPACK_BUNDLER_URL, |
| staticBundlerURL: process.env.SANDPACK_STATIC_BUNDLER_URL, |
| sharePointFilePickerEnabled, |
| sharePointBaseUrl: process.env.SHAREPOINT_BASE_URL, |
| sharePointPickerGraphScope: process.env.SHAREPOINT_PICKER_GRAPH_SCOPE, |
| sharePointPickerSharePointScope: process.env.SHAREPOINT_PICKER_SHAREPOINT_SCOPE, |
| openidReuseTokens, |
| conversationImportMaxFileSize: process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES |
| ? parseInt(process.env.CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES, 10) |
| : 0, |
| }; |
|
|
| const minPasswordLength = parseInt(process.env.MIN_PASSWORD_LENGTH, 10); |
| if (minPasswordLength && !isNaN(minPasswordLength)) { |
| payload.minPasswordLength = minPasswordLength; |
| } |
|
|
| const webSearchConfig = appConfig?.webSearch; |
| if ( |
| webSearchConfig != null && |
| (webSearchConfig.searchProvider || |
| webSearchConfig.scraperProvider || |
| webSearchConfig.rerankerType) |
| ) { |
| payload.webSearch = {}; |
| } |
|
|
| if (webSearchConfig?.searchProvider) { |
| payload.webSearch.searchProvider = webSearchConfig.searchProvider; |
| } |
| if (webSearchConfig?.scraperProvider) { |
| payload.webSearch.scraperProvider = webSearchConfig.scraperProvider; |
| } |
| if (webSearchConfig?.rerankerType) { |
| payload.webSearch.rerankerType = webSearchConfig.rerankerType; |
| } |
|
|
| if (ldap) { |
| payload.ldap = ldap; |
| } |
|
|
| if (typeof process.env.CUSTOM_FOOTER === 'string') { |
| payload.customFooter = process.env.CUSTOM_FOOTER; |
| } |
|
|
| await cache.set(CacheKeys.STARTUP_CONFIG, payload); |
| await getMCPServers(payload, appConfig); |
| return res.status(200).send(payload); |
| } catch (err) { |
| logger.error('Error in startup config', err); |
| return res.status(500).send({ error: err.message }); |
| } |
| }); |
|
|
| module.exports = router; |
|
|