LibreChat/.env.example
Danny Avila 03fa98eb37
🕸️ feat: Complete Keenable Web Search Provider (#15288)
* feat: wire Keenable web-search provider into config, schema, and UI

Keenable landed as a search provider in @librechat/agents (#285, shipped in
3.2.58+), but LibreChat did not yet expose it. This adds the config/schema/UI
glue so it can be selected, mirroring the existing Tavily provider.

- data-provider: add `keenable` to SearchProvider type + SearchProviders enum,
  keenableApiKey/keenableApiUrl schema fields, and a keenableSearchOptions block
  (maxResults, site, attributionTitle, timeout).
- data-schemas: register keenable in webSearchAuth.providers and default the
  key/URL placeholders in loadWebSearchConfig.
- api/web: pass keenableSearchOptions through to the provider and handle
  Keenable's keyless model. Unlike other providers it authenticates with no key
  (the public endpoint), picking up an optional key/URL when set; the URL
  override is SSRF-preflighted like other user-provided URLs.
- client: add Keenable to the provider dropdown with an optional API-key input.
- docs: document KEENABLE_API_KEY/KEENABLE_API_URL in .env.example and a
  webSearch example in librechat.example.yaml.
- tests: keyless + keyed auth resolution, config defaults, and schema parsing.

* fix: ESLint no-unused-vars and clarify Keenable yaml example

- Remove the now-unused RerankerTypes import in data-schemas web.ts (the lint
  job runs with --max-warnings 0 on changed files, so this latent warning failed
  CI once the file was touched).
- Note in the librechat.example.yaml Keenable stanza that a scraper (and
  reranker) is still required for web search to load, and include a Firecrawl
  scraper in the example.

* chore: fix import order drift (sort-imports)

* feat: add Keenable as a keyless scraper and select it without a pinned provider

The Keenable scraper landed in @librechat/agents#337, so wire the scraper
category the same way the search provider already is: `scraperProvider:
keenable` reads pages through Keenable's public fetch endpoint with no key
(a key only lifts rate limits, and the endpoint is overridden with
KEENABLE_FETCH_URL). Paired with `rerankerType: none` this makes a fully
keyless web-search stack possible for the first time.

Also closes the Codex finding on this PR: because none of Keenable's auth
fields are required, the generic auth loop skips it whenever it isn't pinned,
so a key submitted through the API-key dialog (which cannot pin a provider)
left the providers category unauthenticated. Keenable is now selected in that
case, gated on one of its values actually being present so installs that
configured nothing keep their current behavior. The scraper gets the same
fallback, additionally gated on Keenable being the resolved search provider,
so it never silently scrapes for another provider.

* fix: select the Keenable scraper from a supplied key, not only for Keenable search

The API-key dialog submits credentials and cannot pin a provider, so choosing
Keenable as the scraper while search stays on Serper/SearXNG/Tavily had no
effect: the unpinned-scraper fallback required Keenable to also be the resolved
search provider.

A supplied Keenable value now triggers it as well, which is the only signal the
dialog can send. The fallback still runs only when no keyed scraper
authenticated, and with neither trigger the category stays unauthenticated, so
a deployment that never configured Keenable is unaffected.

Note the fully keyless choice still cannot be expressed through the dialog:
Keenable's key is optional, so picking it with no key submits nothing at all.
librechat.example.yaml now documents pinning scraperProvider: keenable for that
case.

* style: Sort Keenable imports

* fix: Harden Keenable auth resolution

* fix: Preserve Keenable selection intent

* fix: Fail closed on invalid web search auth

* fix: close keenable auth gaps

* style: sort web auth imports

* fix: preserve web search selection integrity

* fix: isolate web search auth ordering

* fix: silence expected credential misses

* chore: bump agents sdk

* fix: preserve web search preference ownership

* fix: forward cleared Keenable endpoint

* style: sort web search hook imports

* fix: require intent for credential clears

---------

Co-authored-by: Ilya Bogin <ilya.bogin@keenable.ai>
2026-08-27 14:29:20 -04:00

1373 lines
55 KiB
Text

#=====================================================================#
# LibreChat Configuration #
#=====================================================================#
# Please refer to the reference documentation for assistance #
# with configuring your LibreChat environment. #
# #
# https://www.librechat.ai/docs/configuration/dotenv #
#=====================================================================#
#==================================================#
# Server Configuration #
#==================================================#
HOST=localhost
PORT=3080
# Optional Node.js HTTP server timeouts in milliseconds. When unset, Node.js defaults apply.
# For an ALB, set the application keep-alive timeout above the ALB idle timeout.
# Requires Node.js: Bun accepts these values but does not enforce them.
# Header and request timeout expiry is only detected on a 30s connection sweep, so values
# below 30000 take effect late and are not enforced at the precision configured.
# The header timeout is clamped to the request timeout when the latter is lower, since Node
# does not enforce a request timeout that a longer header timeout sits above.
# Keep-alive is socket-driven and remains exact at any value.
# HTTP_KEEP_ALIVE_TIMEOUT_MS=70000
# HTTP_KEEP_ALIVE_TIMEOUT_BUFFER_MS=5000
# HTTP_HEADERS_TIMEOUT_MS=80000
# HTTP_REQUEST_TIMEOUT_MS=300000
MONGO_URI=mongodb://127.0.0.1:27017/LibreChat
#The maximum number of connections in the connection pool. */
MONGO_MAX_POOL_SIZE=
#The minimum number of connections in the connection pool. */
MONGO_MIN_POOL_SIZE=
#The maximum number of connections that may be in the process of being established concurrently by the connection pool. */
MONGO_MAX_CONNECTING=
#The maximum number of milliseconds that a connection can remain idle in the pool before being removed and closed. */
MONGO_MAX_IDLE_TIME_MS=
#The maximum time in milliseconds that a thread can wait for a connection to become available. */
MONGO_WAIT_QUEUE_TIMEOUT_MS=
# Set to false to disable automatic index creation for all models associated with this connection. */
MONGO_AUTO_INDEX=
# Set to `false` to disable Mongoose automatically calling `createCollection()` on every model created on this connection. */
MONGO_AUTO_CREATE=
DOMAIN_CLIENT=http://localhost:3080
DOMAIN_SERVER=http://localhost:3080
# External admin panel base URL used for admin OAuth/SSO redirects.
# When set, admins also get an Admin Panel link in Settings > General.
# Required when the admin panel is hosted separately from LibreChat.
# May include a path. Do not include a trailing slash.
# Example: https://admin.example.com/admin
ADMIN_PANEL_URL=
# Session encryption key for the bundled admin panel (min 32 characters).
# Required when using the bundled admin panel in docker-compose/deploy-compose.
# Generate a unique value before starting the stack:
# openssl rand -hex 32
ADMIN_PANEL_SESSION_SECRET=
# Host port for the bundled admin panel (default docker-compose only).
# In deploy-compose the panel is served at http://admin.localhost via nginx.
# ADMIN_PANEL_PORT=3000
# Enable the admin-only MongoDB Insights dashboard.
ENABLE_INSIGHTS=false
NO_INDEX=true
# Use the address that is at most n number of hops away from the Express application.
# req.socket.remoteAddress is the first hop, and the rest are looked for in the X-Forwarded-For header from right to left.
# A value of 0 means that the first untrusted address would be req.socket.remoteAddress, i.e. there is no reverse proxy.
# Defaulted to 1.
TRUST_PROXY=1
#===============================#
# Security Headers #
#===============================#
# Baseline HTTP security headers (HSTS, X-Frame-Options, X-Content-Type-Options,
# COOP, CORP, Referrer-Policy) are sent on every response. Content-Security-Policy
# is never set here. Set to false to send no security headers at all.
# SECURITY_HEADERS=true
# Strict-Transport-Security. Only meaningful over HTTPS; browsers ignore it on
# plain HTTP. HSTS_INCLUDE_SUBDOMAINS applies the policy to every subdomain of
# this host for the full max-age, so enable it only if all of them serve HTTPS.
# HSTS_ENABLED=true
# HSTS_MAX_AGE=31536000
# HSTS_INCLUDE_SUBDOMAINS=false
# HSTS_PRELOAD=false
# X-Frame-Options. Set to DENY to block all framing, or to `off` if you embed
# LibreChat in an iframe on another origin.
# X_FRAME_OPTIONS=SAMEORIGIN
# Referrer-Policy. Any standard token, or `off` to omit the header.
# REFERRER_POLICY=no-referrer
# Cross-Origin-Opener-Policy. Use same-origin-allow-popups if a popup-based
# sign-in flow needs to reach back to the window that opened it.
# CROSS_ORIGIN_OPENER_POLICY=same-origin
# Cross-Origin-Resource-Policy. Use cross-origin if other sites need to load
# resources served by LibreChat, such as uploaded images.
# CROSS_ORIGIN_RESOURCE_POLICY=same-origin
#===============================#
# Content Security Policy #
#===============================#
# Nonce-based CSP for the SPA HTML response. Off by default so existing
# deployments are unaffected. Turn it on in report-only mode first, review the
# violations your deployment actually produces, then set CSP_REPORT_ONLY=false.
# Only an explicit false/off/0/no enforces; anything unrecognized warns and stays
# report-only, so a typo cannot silently start blocking scripts.
# CSP_ENABLED=false
# CSP_REPORT_ONLY=true
# CSP_REPORT_URI=
# The default policy accommodates what LibreChat actually loads at runtime:
# script-src 'wasm-unsafe-eval' HEIC image conversion compiles WebAssembly
# worker-src data: Monaco's loader bootstraps workers from data:
# Both are narrower than 'unsafe-eval'. Set these to false to drop them if your
# deployment uses neither HEIC uploads nor the artifact code editor. (The CSP_*_EXTRA
# and CSP_ADDITIONAL_DIRECTIVES variables only add sources; they cannot remove one.)
# CSP_ALLOW_WASM=true
# CSP_ALLOW_DATA_WORKERS=true
# While CSP is enabled the SPA shell is always sent as `no-store` and the
# INDEX_CACHE_CONTROL / INDEX_PRAGMA / INDEX_EXPIRES overrides are ignored for it.
# A cached shell would pin a single nonce across page loads and users, which is
# precisely what a nonce policy exists to prevent.
#
# SECURITY_HEADERS=false disables CSP too; it is the global kill switch.
# Add deployment-specific sources on top of LibreChat's defaults; they are
# appended, never replacing them. Comma- or space-separated. Quote values
# containing spaces.
# CSP_CONNECT_SRC_EXTRA="https://telemetry.example.com wss://stream.example.com"
# CSP_FRAME_SRC_EXTRA="https://tenant.sharepoint.com"
# CSP_IMG_SRC_EXTRA="https://cdn.example.com"
# CSP_STYLE_SRC_EXTRA=
# CSP_FONT_SRC_EXTRA=
# CSP_MEDIA_SRC_EXTRA=
# CSP_WORKER_SRC_EXTRA=
# CSP_FORM_ACTION_EXTRA=
# CSP_DEFAULT_SRC_EXTRA=
# Script hosts get their own note: the default policy uses 'strict-dynamic',
# which makes browsers ignore every host source in script-src. Setting this
# drops 'strict-dynamic' so the hosts you list actually take effect.
# CSP_SCRIPT_SRC_EXTRA="https://trusted-scripts.example.com"
# Who may frame LibreChat. Defaults to 'self'. Replace it if you embed LibreChat
# in a portal on another origin, and set X_FRAME_OPTIONS=off alongside it since
# older browsers honor that header instead.
# CSP_FRAME_ANCESTORS="'self' https://portal.example.com"
# Raw directives appended to the policy, separated by semicolons.
# CSP_ADDITIONAL_DIRECTIVES="upgrade-insecure-requests"
# Trust X-Tenant-Id on unauthenticated routes. Disabled by default.
# Enable only when a trusted reverse proxy strips any client-supplied value and sets its own.
# TRUST_TENANT_HEADER=false
# Minimum password length for user authentication
# Default: 8
# Note: When using LDAP authentication, you may want to set this to 1
# to bypass local password validation, as LDAP servers handle their own
# password policies.
# MIN_PASSWORD_LENGTH=8
# When enabled, the app will continue running after encountering uncaught exceptions
# instead of exiting the process. Not recommended for production unless necessary.
# CONTINUE_ON_UNCAUGHT_EXCEPTION=false
#===============#
# JSON Logging #
#===============#
# Use when process console logs in cloud deployment like GCP/AWS
CONSOLE_JSON=false
# The maximum length of a string in a JSON log object.
# Default: 255
# CONSOLE_JSON_STRING_LENGTH=255
#===============#
# Debug Logging #
#===============#
DEBUG_LOGGING=true
DEBUG_CONSOLE=false
# Set to false to disable file-backed Winston transports.
LOG_TO_FILE=true
# Set to true to enable agent debug logging
AGENT_DEBUG_LOGGING=false
# Enable memory diagnostics (logs heap/RSS snapshots every 60s, auto-enabled with --inspect)
# MEM_DIAG=true
#=============#
# Permissions #
#=============#
# UID=1000
# GID=1000
#==============#
# Node Options #
#==============#
# NOTE: NODE_MAX_OLD_SPACE_SIZE is NOT recognized by Node.js directly.
# This variable is used as a build argument for Docker or CI/CD workflows,
# and is NOT used by Node.js to set the heap size at runtime.
# To configure Node.js memory, use NODE_OPTIONS, e.g.:
# NODE_OPTIONS="--max-old-space-size=6144"
# See: https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib
NODE_MAX_OLD_SPACE_SIZE=6144
#===============#
# Configuration #
#===============#
# Use an absolute path, a relative path, or a URL
# CONFIG_PATH="/alternative/path/to/librechat.yaml"
# Deployment skills are loaded read-only at startup and exposed to all users
# with the Skills capability enabled. Defaults to project root ./skill.
# DEPLOYMENT_SKILLS_DIR=./skill
# Agent Plugins packages (skills + MCP servers + hooks) are loaded at startup
# from this directory; each child directory is one plugin. Defaults to ./plugin.
# DEPLOYMENT_PLUGINS_DIR=./plugin
# DEPLOYMENT_PLUGIN_DATA_DIR=./data/plugins
# Opt-in: execute `command` hook handlers declared by installed plugins
# (ai.librechat/hooks/hooks.json). Commands run as child processes on the API
# host with a minimal environment — only enable for plugins you trust, the
# same trust level as toolApproval hook modules. Off by default: hook
# documents are parsed but never executed.
# DEPLOYMENT_PLUGIN_HOOKS=true
#==================#
# Langfuse Tracing #
#==================#
# Get Langfuse API keys for your project from the project settings page: https://cloud.langfuse.com
# LANGFUSE_PUBLIC_KEY=
# LANGFUSE_SECRET_KEY=
# LANGFUSE_BASE_URL=
# Optional stable project ID. When omitted, LibreChat discovers it from Langfuse in the background.
# LANGFUSE_PROJECT_ID=
# Set false to disable Langfuse traces and feedback scores.
# LANGFUSE_TRACING_ENABLED=true
# Trace-level sample rate from 0 to 1. Sampled-out traces do not receive scores.
# LANGFUSE_SAMPLE_RATE=1
# In single-tenant deployments without environment credentials, an admin can
# configure one encrypted Langfuse connection in the application settings.
# Complete environment credentials take precedence and hide those settings.
# Optional Langfuse fanout for tenant-scoped Langfuse projects.
# The fanout gateway is opt-in: add docker-compose.langfuse-fanout.yml,
# deploy-compose.langfuse-fanout.yml, or enable helm langfuseFanout.
# Tenant public/secret keys and a destination key are managed through
# Settings > Langfuse. Destination keys resolve against known startup URLs;
# credentials can be added or changed at runtime without restarting the gateway.
# See otel/langfuse-fanout/README.md.
# LANGFUSE_FANOUT_ENABLED=false
# LANGFUSE_FANOUT_COLLECTOR_URL=http://langfuse-fanout-collector:4318
# App-side switch: set true to tell the Langfuse SDK not to create media uploads
# for central/fallback collector traces. Tenant-routed media uploads are unchanged.
# LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED=false
# Gateway HTTP listen address (default: :4318).
# LANGFUSE_FANOUT_LISTEN_ADDR=:4318
# Emergency switch: unset/false defaults enabled; set true to keep central fanout export but skip tenant trace/score export.
# LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED=false
# Langfuse Cloud base URL options: https://cloud.langfuse.com (EU),
# https://us.cloud.langfuse.com (US), https://jp.cloud.langfuse.com (JP).
# Gateway-only central trace/media export URL. LibreChat feedback scores use
# LANGFUSE_BASE_URL, so set both URLs to the same non-EU region when applicable.
# LANGFUSE_FANOUT_CENTRAL_BASE_URL=https://cloud.langfuse.com
# Gateway-only Basic auth header for central trace/media export. LibreChat feedback
# scores use LANGFUSE_PUBLIC_KEY/LANGFUSE_SECRET_KEY instead.
# LANGFUSE_FANOUT_CENTRAL_AUTH_HEADER=Basic <base64-public-colon-secret>
# Set true on the gateway to disable central media export while leaving central
# trace export unchanged.
# LANGFUSE_FANOUT_CENTRAL_MEDIA_EXPORT_DISABLED=false
# Compose's included gateway config supports the three listed destination keys.
# Add custom keys only when the gateway is started with matching destination URLs.
# LANGFUSE_FANOUT_TENANT_DESTINATIONS=eu=https://cloud.langfuse.com,us=https://us.cloud.langfuse.com,jp=https://jp.cloud.langfuse.com
# Compose's collector config routes only these destination keys. The gateway
# fails startup when LANGFUSE_FANOUT_TENANT_DESTINATIONS contains another key.
# LANGFUSE_FANOUT_TRACE_DESTINATION_KEYS=eu,us,jp
# Gateway base URL used to build one-time media upload URLs. Compose sets this
# to its private service URL; Helm derives an internal service URL unless set.
# LANGFUSE_FANOUT_PUBLIC_URL=http://langfuse-fanout-collector:4318
# Internal gateway-to-collector trace endpoint. Compose sets this automatically.
# LANGFUSE_FANOUT_TRACE_COLLECTOR_URL=http://langfuse-fanout-otel:4319
# Redis-backed one-time upload plans let multiple gateway pods handle Langfuse
# media create/upload requests. Compose sets this to its private Redis service.
# LANGFUSE_FANOUT_REDIS_URI=redis://langfuse-fanout-redis:6379
# LANGFUSE_FANOUT_REDIS_USERNAME=
# LANGFUSE_FANOUT_REDIS_PASSWORD=
# LANGFUSE_FANOUT_REDIS_KEY_PREFIX=langfuse-fanout
# Internal collector receiver bind address. Helm uses 127.0.0.1 because the
# collector is a sidecar; Compose uses 0.0.0.0 on the private fanout network.
# LANGFUSE_FANOUT_OTEL_RECEIVER_ENDPOINT=0.0.0.0:4319
# Static Compose collector destination URLs. Helm derives these from values.
# LANGFUSE_FANOUT_TENANT_EU_BASE_URL=https://cloud.langfuse.com
# LANGFUSE_FANOUT_TENANT_US_BASE_URL=https://us.cloud.langfuse.com
# LANGFUSE_FANOUT_TENANT_JP_BASE_URL=https://jp.cloud.langfuse.com
# LANGFUSE_FANOUT_UPSTREAM_TIMEOUT=30s
# Optional bearer token for scraping the fanout gateway /metrics endpoint.
# If unset, /metrics returns 401. The gateway also accepts METRICS_SECRET when present.
# LANGFUSE_FANOUT_METRICS_SECRET=
# LANGFUSE_FANOUT_MEMORY_LIMIT_MIB=256
# LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB=64
# LANGFUSE_FANOUT_BATCH_TIMEOUT=1s
# LANGFUSE_FANOUT_BATCH_SEND_SIZE=128
# LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT=1000
#=======================#
# OpenTelemetry Tracing #
#=======================#
# Enables backend OpenTelemetry tracing. General backend visibility only;
# use Langfuse for GenAI-specific prompt/model observability.
# OTEL_TRACING_ENABLED=false
# OTEL_SERVICE_NAME=librechat
# OTEL_SERVICE_VERSION=
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=
# OTEL_EXPORTER_OTLP_HEADERS=
# OTEL_TRACES_EXPORTER=otlp
# OTEL_TRACES_SAMPLER=parentbased_always_on
# OTEL_LOG_LEVEL=INFO
# OTEL_SDK_DISABLED=false
# Enable Redis command-level spans. Disabled by default to keep backend traces high-level.
# OTEL_IOREDIS_TRACING_ENABLED=false
#===============================#
# Real User Monitoring (Browser) #
#===============================#
# Enables browser Real User Monitoring. Disabled by default.
# Currently supports HyperDX via the browser SDK.
# RUM_ENABLED=false
# RUM_PROVIDER=hyperdx
# RUM_URL=http://localhost:4318
# RUM_SERVICE_NAME=librechat-web
# RUM_ENVIRONMENT=development
# Public browser-token mode is suitable for OSS/self-hosted deployments.
# Treat the token as public and restrict/rate-limit ingestion in your RUM backend.
# RUM_AUTH_MODE=publicToken
# RUM_PUBLIC_TOKEN=
# Authenticated proxy mode sends browser telemetry to this LibreChat backend first.
# The backend validates the LibreChat session, strips app auth, and forwards to the collector.
# RUM_AUTH_MODE=proxy
# RUM_PROXY_TARGET_URL=http://otel-collector:4318
# RUM_PROXY_TIMEOUT_MS=10000
# Optional comma-separated first-party HTTPS origins/URLs that should receive traceparent headers.
# Wildcards and non-HTTPS targets are ignored.
# RUM_TRACE_PROPAGATION_TARGETS=https://api.example.com
# Privacy defaults: replay, console capture, and full network body capture stay off.
# Console/network capture may collect sensitive browser logs, prompts, responses, or payloads.
# RUM_DISABLE_REPLAY=true
# RUM_CONSOLE_CAPTURE=false
# RUM_ADVANCED_NETWORK_CAPTURE=false
# RUM_SAMPLE_RATE=1
#===================================================#
# Endpoints #
#===================================================#
# ENDPOINTS=openAI,assistants,azureOpenAI,google,anthropic
# Optional outbound proxy for server-side requests.
# PROXY applies to both HTTP and HTTPS targets. When PROXY is unset, LibreChat honors
# HTTP_PROXY, HTTPS_PROXY, and NO_PROXY/no_proxy for supported server-side clients.
PROXY=
# HTTP_PROXY=
# HTTPS_PROXY=
# NO_PROXY=
#===================================#
# Known Endpoints - librechat.yaml #
#===================================#
# https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints
# ANYSCALE_API_KEY=
# APIPIE_API_KEY=
# COHERE_API_KEY=
# DEEPSEEK_API_KEY=
# DATABRICKS_API_KEY=
# FIREWORKS_API_KEY=
# GROQ_API_KEY=
# HUGGINGFACE_TOKEN=
# MISTRAL_API_KEY=
# OPENROUTER_KEY=
# PERPLEXITY_API_KEY=
# SHUTTLEAI_API_KEY=
# TOGETHERAI_API_KEY=
# UNIFY_API_KEY=
# XAI_API_KEY=
#============#
# Anthropic #
#============#
ANTHROPIC_API_KEY=user_provided
# ANTHROPIC_MODELS=claude-fable-5,claude-opus-5,claude-opus-4-8,claude-opus-4-7,claude-sonnet-5,claude-sonnet-4-6,claude-opus-4-6,claude-opus-4-20250514,claude-3-7-sonnet-20250219,claude-3-5-sonnet-20241022,claude-3-5-haiku-20241022,claude-3-opus-20240229,claude-3-sonnet-20240229,claude-3-haiku-20240307
# ANTHROPIC_REVERSE_PROXY=
# Set to true to use Anthropic models through Google Vertex AI instead of direct API
# ANTHROPIC_USE_VERTEX=
# Supports regional locations like us-east5 and multi-region locations: us, eu, global
# IMPORTANT: specific regional endpoints (us-east5, europe-west1, ...) only serve Claude Sonnet 4.6
# and earlier. Newer models (Opus 4.7+, Opus 5, Sonnet 5, Fable 5) require `global` or a multi-region
# location (`us`/`eu`) and will 404 on a specific region. `global` also avoids the 10% regional premium.
# ANTHROPIC_VERTEX_REGION=us-east5
#============#
# Azure #
#============#
# Note: these variables are DEPRECATED
# Use the `librechat.yaml` configuration for `azureOpenAI` instead
# You may also continue to use them if you opt out of using the `librechat.yaml` configuration
# AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo # Deprecated
# AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 # Deprecated
# AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE # Deprecated
# AZURE_API_KEY= # Deprecated
# AZURE_OPENAI_API_INSTANCE_NAME= # Deprecated
# AZURE_OPENAI_API_DEPLOYMENT_NAME= # Deprecated
# AZURE_OPENAI_API_VERSION= # Deprecated
# AZURE_OPENAI_API_COMPLETIONS_DEPLOYMENT_NAME= # Deprecated
# AZURE_OPENAI_API_EMBEDDINGS_DEPLOYMENT_NAME= # Deprecated
#=================#
# AWS Bedrock #
#=================#
# AWS Bedrock credentials
#
# Preferred for local development: configure an AWS profile in ~/.aws/config or
# ~/.aws/credentials, then set BEDROCK_AWS_PROFILE. LibreChat passes this profile
# to the AWS SDK for JavaScript credential provider chain.
#
# In deployed environments, prefer IAM roles or other short-term credentials
# discoverable by the AWS SDK default credential provider chain. If neither
# BEDROCK_AWS_PROFILE nor Bedrock-specific static credentials are set, the SDK
# uses its default provider chain. AWS-standard environment variables still
# follow AWS SDK precedence.
#
# Profiles can use IAM Identity Center, assume-role settings, or credential_process.
# If you use credential_process, secure the config file and helper command, and do
# not write secret material to stderr.
#
# AWS SDK credential chain:
# https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html
# Shared config/profile settings:
# https://docs.aws.amazon.com/sdkref/latest/guide/settings-reference.html
# credential_process security notes:
# https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html
# BEDROCK_AWS_DEFAULT_REGION=us-east-1 # A default region must be provided
# AWS Profile
# BEDROCK_AWS_PROFILE=your-profile-name
# Static credentials (use only if profiles or IAM roles are not suitable)
# BEDROCK_AWS_ACCESS_KEY_ID=someAccessKey
# BEDROCK_AWS_SECRET_ACCESS_KEY=someSecretAccessKey
# BEDROCK_AWS_SESSION_TOKEN=someSessionToken
# Bedrock API key
# BEDROCK_AWS_BEARER_TOKEN=yourBedrockApiKey
# Note: This example list is not meant to be exhaustive. If omitted, all known, supported model IDs will be included for you.
# Claude 4+ models cannot be invoked on-demand by their bare `anthropic.` foundation-model ID; Bedrock requires a
# cross-region inference profile (`global.` or `us.`) for those. The `global.` profile has no regional pricing premium.
# BEDROCK_AWS_MODELS=global.anthropic.claude-fable-5,global.anthropic.claude-opus-5,global.anthropic.claude-opus-4-8,global.anthropic.claude-opus-4-7,global.anthropic.claude-sonnet-5,global.anthropic.claude-sonnet-4-6,global.anthropic.claude-opus-4-6-v1,global.anthropic.claude-haiku-4-5-20251001-v1:0,meta.llama3-1-8b-instruct-v1:0
# US-only routing alternative: us.anthropic.claude-fable-5,us.anthropic.claude-opus-5,us.anthropic.claude-opus-4-8,us.anthropic.claude-opus-4-7,us.anthropic.claude-sonnet-5,us.anthropic.claude-sonnet-4-6,us.anthropic.claude-opus-4-6-v1
# List the profiles available to your account with: aws bedrock list-inference-profiles --region <your-region>
# See all Bedrock model IDs here: https://docs.aws.amazon.com/bedrock/latest/userguide/model-ids.html#model-ids-arns
# Notes on specific models:
# The following models are not support due to not supporting streaming:
# ai21.j2-mid-v1
# The following models are not support due to not supporting conversation history:
# ai21.j2-ultra-v1, cohere.command-text-v14, cohere.command-light-text-v14
# Claude Mythos-class models (anthropic.claude-fable-5, anthropic.claude-mythos-5) are inference-profile
# only on Bedrock — use a profile ID (e.g. us.anthropic.claude-fable-5) — and require opting into Anthropic
# data sharing via the Bedrock Data Retention API/console before they can be invoked.
#============#
# Google #
#============#
GOOGLE_KEY=user_provided
# GOOGLE_REVERSE_PROXY=
# Some reverse proxies do not support the X-goog-api-key header, uncomment to pass the API key in Authorization header instead.
# GOOGLE_AUTH_HEADER=true
# Gemini API (AI Studio)
# GOOGLE_MODELS=gemini-3.7-flash,gemini-3.6-flash,gemini-3.5-flash,gemini-3.5-flash-lite,gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash,gemini-2.0-flash-lite
# Vertex AI
# GOOGLE_MODELS=gemini-3.7-flash,gemini-3.6-flash,gemini-3.5-flash,gemini-3.5-flash-lite,gemini-3.1-pro-preview,gemini-3.1-pro-preview-customtools,gemini-3.1-flash-lite-preview,gemini-2.5-pro,gemini-2.5-flash,gemini-2.5-flash-lite,gemini-2.0-flash-001,gemini-2.0-flash-lite-001
# GOOGLE_TITLE_MODEL=gemini-2.0-flash-lite-001
# Google Cloud location for Vertex AI (used by both chat and image generation).
# Supports regional locations like us-central1 and multi-region locations: us, eu, global.
# GOOGLE_LOC=us-central1
# Alternative region env var for Gemini Image Generation
# GOOGLE_CLOUD_LOCATION=global
# Vertex AI Service Account Configuration
# Path to your Google Cloud service account JSON file
# GOOGLE_SERVICE_KEY_FILE=/path/to/service-account.json
# Google Safety Settings
# NOTE: These settings apply to both Vertex AI and Gemini API (AI Studio)
#
# For Vertex AI:
# To use the BLOCK_NONE setting, you need either:
# (a) Access through an allowlist via your Google account team, or
# (b) Switch to monthly invoiced billing: https://cloud.google.com/billing/docs/how-to/invoiced-billing
#
# For Gemini API (AI Studio):
# BLOCK_NONE is available by default, no special account requirements.
#
# Available options: BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, BLOCK_LOW_AND_ABOVE
#
# GOOGLE_SAFETY_SEXUALLY_EXPLICIT=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_HATE_SPEECH=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_HARASSMENT=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_DANGEROUS_CONTENT=BLOCK_ONLY_HIGH
# GOOGLE_SAFETY_CIVIC_INTEGRITY=BLOCK_ONLY_HIGH
#========================#
# Gemini Image Generation #
#========================#
# Gemini Image Generation Tool (for Agents)
# Supports multiple authentication methods in priority order:
# 1. User-provided API key (via GUI)
# 2. GEMINI_API_KEY env var (admin-configured)
# 3. GOOGLE_KEY env var (shared with Google chat endpoint)
# 4. Vertex AI service account (via GOOGLE_SERVICE_KEY_FILE)
# Option A: Use dedicated Gemini API key for image generation
# GEMINI_API_KEY=your-gemini-api-key
# Vertex AI model for image generation (defaults to gemini-2.5-flash-image)
# GEMINI_IMAGE_MODEL=gemini-2.5-flash-image
#============#
# OpenAI #
#============#
OPENAI_API_KEY=user_provided
# OPENAI_MODELS=gpt-5.6,gpt-5.6-terra,gpt-5.6-luna,gpt-5.5,gpt-5.5-pro,chat-latest,gpt-5.4,gpt-5.4-pro,gpt-5.4-mini,gpt-5.4-nano,gpt-5.3-codex,gpt-5.2,gpt-5,gpt-5-codex,gpt-5-mini,gpt-5-nano,o3-pro,o3,o4-mini,gpt-4.1,gpt-4.1-mini,gpt-4.1-nano,o3-mini,o1-pro,o1,gpt-4o,gpt-4o-mini
DEBUG_OPENAI=false
# TITLE_CONVO=false
# OPENAI_TITLE_MODEL=gpt-4o-mini
# OPENAI_SUMMARIZE=true
# OPENAI_SUMMARY_MODEL=gpt-4o-mini
# OPENAI_FORCE_PROMPT=true
# OPENAI_REVERSE_PROXY=
# OPENAI_ORGANIZATION=
#====================#
# Assistants API #
#====================#
ASSISTANTS_API_KEY=user_provided
# ASSISTANTS_BASE_URL=
# ASSISTANTS_MODELS=gpt-4o,gpt-4o-mini,gpt-3.5-turbo-0125,gpt-3.5-turbo-16k-0613,gpt-3.5-turbo-16k,gpt-3.5-turbo,gpt-4,gpt-4-0314,gpt-4-32k-0314,gpt-4-0613,gpt-3.5-turbo-0613,gpt-3.5-turbo-1106,gpt-4-0125-preview,gpt-4-turbo-preview,gpt-4-1106-preview
#==========================#
# Azure Assistants API #
#==========================#
# Note: You should map your credentials with custom variables according to your Azure OpenAI Configuration
# The models for Azure Assistants are also determined by your Azure OpenAI configuration.
# More info, including how to enable use of Assistants with Azure here:
# https://www.librechat.ai/docs/configuration/librechat_yaml/ai_endpoints/azure#using-assistants-with-azure
# Leave these blank to let LibreChat generate and persist temporary credentials in .env.temp.
# Configure unique, persistent values before using a production instance.
CREDS_KEY=
CREDS_IV=
# Azure AI Search
#-----------------
AZURE_AI_SEARCH_SERVICE_ENDPOINT=
AZURE_AI_SEARCH_INDEX_NAME=
AZURE_AI_SEARCH_API_KEY=
AZURE_AI_SEARCH_API_VERSION=
AZURE_AI_SEARCH_SEARCH_OPTION_QUERY_TYPE=
AZURE_AI_SEARCH_SEARCH_OPTION_TOP=
AZURE_AI_SEARCH_SEARCH_OPTION_SELECT=
# OpenAI Image Tools Customization
#----------------
# IMAGE_GEN_OAI_API_KEY= # Create or reuse OpenAI API key for image generation tool
# IMAGE_GEN_OAI_BASEURL= # Custom OpenAI base URL for image generation tool
# IMAGE_GEN_OAI_AZURE_API_VERSION= # Custom Azure OpenAI deployments
# IMAGE_GEN_OAI_MODEL=gpt-image-1 # OpenAI image model (e.g., gpt-image-1, gpt-image-1.5)
# IMAGE_GEN_OAI_DESCRIPTION=
# IMAGE_GEN_OAI_DESCRIPTION_WITH_FILES=Custom description for image generation tool when files are present
# IMAGE_GEN_OAI_DESCRIPTION_NO_FILES=Custom description for image generation tool when no files are present
# IMAGE_EDIT_OAI_DESCRIPTION=Custom description for image editing tool
# IMAGE_GEN_OAI_PROMPT_DESCRIPTION=Custom prompt description for image generation tool
# IMAGE_EDIT_OAI_PROMPT_DESCRIPTION=Custom prompt description for image editing tool
# DALL·E
#----------------
# DALLE_API_KEY=
# DALLE3_API_KEY=
# DALLE2_API_KEY=
# DALLE3_SYSTEM_PROMPT=
# DALLE2_SYSTEM_PROMPT=
# DALLE_REVERSE_PROXY=
# DALLE3_BASEURL=
# DALLE2_BASEURL=
# DALL·E (via Azure OpenAI)
# Note: requires some of the variables above to be set
#----------------
# DALLE3_AZURE_API_VERSION=
# DALLE2_AZURE_API_VERSION=
# Flux
#-----------------
FLUX_API_BASE_URL=https://api.us1.bfl.ai
# FLUX_API_BASE_URL = 'https://api.bfl.ml';
# Get your API key at https://api.us1.bfl.ai/auth/profile
# FLUX_API_KEY=
# Google
#-----------------
GOOGLE_SEARCH_API_KEY=
GOOGLE_CSE_ID=
# Stable Diffusion
#-----------------
SD_WEBUI_URL=http://host.docker.internal:7860
# Tavily
#-----------------
TAVILY_API_KEY=
# Traversaal
#-----------------
TRAVERSAAL_API_KEY=
# WolframAlpha
#-----------------
WOLFRAM_APP_ID=
# Zapier
#-----------------
ZAPIER_NLA_API_KEY=
#==================================================#
# Search #
#==================================================#
# Set both SEARCH=true and a unique MEILI_MASTER_KEY to enable search.
SEARCH=false
MEILI_NO_ANALYTICS=true
MEILI_HOST=http://0.0.0.0:7700
# Set a unique value when Meilisearch is enabled; do not reuse a published default.
MEILI_MASTER_KEY=
# Optional: Disable indexing, useful in a multi-node setup
# where only one instance should perform an index sync.
# MEILI_NO_SYNC=true
#==================================================#
# Speech to Text & Text to Speech #
#==================================================#
STT_API_KEY=
TTS_API_KEY=
#==================================================#
# Code Interpreter #
#==================================================#
# LIBRECHAT_CODE_API_KEY=
# LIBRECHAT_CODE_BASEURL=
# Optional dedicated Code API deployment for agents with Stateful code sessions enabled.
# When configured, stateless agents continue using LIBRECHAT_CODE_BASEURL while stateful
# agents fail closed onto this endpoint. The endpoint must advertise the `stateful` profile.
# LIBRECHAT_CODE_BASEURL_STATEFUL=
# Prewarm selected stateful sandboxes in parallel with model generation (default: true).
# CODE_SANDBOX_PREWARM=true
# Time in milliseconds before LibreChat treats a tracked sandbox as cold (default: 2100000 / 35 minutes).
# CODE_SANDBOX_COLD_AFTER_MS=2100000
# Bytes read per sandbox image chunk; lower this if the runner has a small stdout limit (default: 32768).
# LIBRECHAT_CODE_IMAGE_CHUNK_BYTES=32768
#==================================================#
# RAG #
#==================================================#
# More info: https://www.librechat.ai/docs/configuration/rag_api
# RAG_API_URL=http://rag_api:8000
# RAG_OPENAI_BASEURL=
# RAG_OPENAI_API_KEY=
# RAG_USE_FULL_CONTEXT=
# EMBEDDINGS_PROVIDER=openai
# EMBEDDINGS_MODEL=text-embedding-3-small
# Stream upload responses with heartbeats during long-running file processing.
# FILE_UPLOAD_SSE_ENABLED=false
# Timeout in milliseconds for server-side remote file downloads (default: 15000).
# REMOTE_FILE_FETCH_TIMEOUT_MS=15000
# Maximum size in bytes for server-side remote file downloads (default: 536870912 / 512 MiB).
# REMOTE_FILE_FETCH_MAX_BYTES=536870912
#===================================================#
# User System #
#===================================================#
# Maximum characters in one mid-run Agent steering message (default: 16000).
# STEER_MAX_LENGTH=16000
#========================#
# Moderation #
#========================#
OPENAI_MODERATION=false
OPENAI_MODERATION_API_KEY=
# OPENAI_MODERATION_REVERSE_PROXY=
BAN_VIOLATIONS=true
BAN_DURATION=1000 * 60 * 60 * 2
BAN_INTERVAL=20
# Violation scores expire after this long (in ms) without new violations; 0 = never expire
VIOLATION_SCORE_TTL=1000 * 60 * 60
LOGIN_VIOLATION_SCORE=1
REGISTRATION_VIOLATION_SCORE=1
CONCURRENT_VIOLATION_SCORE=1
MESSAGE_VIOLATION_SCORE=1
NON_BROWSER_VIOLATION_SCORE=20
TTS_VIOLATION_SCORE=0
STT_VIOLATION_SCORE=0
FORK_VIOLATION_SCORE=0
IMPORT_VIOLATION_SCORE=0
FILE_UPLOAD_VIOLATION_SCORE=0
# Per-user limiter for metadata-only /files/usage requests that renew the TTL
# of attachments waiting in queued Agent messages (default: 120 per 15 minutes).
# FILE_USAGE_USER_MAX=120
# FILE_USAGE_USER_WINDOW=15
# Password-reset and verification request/submission scores default to 1 when unset.
# RESET_PASSWORD_VIOLATION_SCORE=1
# VERIFY_EMAIL_VIOLATION_SCORE=1
# RESET_PASSWORD_SUBMISSION_VIOLATION_SCORE=1
# VERIFY_EMAIL_SUBMISSION_VIOLATION_SCORE=1
LOGIN_MAX=7
LOGIN_WINDOW=5
REGISTER_MAX=5
REGISTER_WINDOW=60
# Password-reset email requests and token submissions are limited separately.
# Submission values inherit the matching request value when omitted; all default to 2.
# RESET_PASSWORD_MAX=2
# RESET_PASSWORD_WINDOW=2
# RESET_PASSWORD_SUBMISSION_MAX=2
# RESET_PASSWORD_SUBMISSION_WINDOW=2
# VERIFY_EMAIL_MAX=2
# VERIFY_EMAIL_WINDOW=2
# VERIFY_EMAIL_SUBMISSION_MAX=2
# VERIFY_EMAIL_SUBMISSION_WINDOW=2
LIMIT_CONCURRENT_MESSAGES=true
CONCURRENT_MESSAGE_MAX=2
LIMIT_MESSAGE_IP=true
MESSAGE_IP_MAX=40
MESSAGE_IP_WINDOW=1
LIMIT_MESSAGE_USER=false
MESSAGE_USER_MAX=40
MESSAGE_USER_WINDOW=1
ILLEGAL_MODEL_REQ_SCORE=5
#========================#
# Balance #
#========================#
# CHECK_BALANCE=false
# START_BALANCE=20000 # note: the number of tokens that will be credited after registration.
#========================#
# Registration and Login #
#========================#
ALLOW_EMAIL_LOGIN=true
# ALLOW_EMAIL_LOGIN_OVERRIDE=false # note: permits direct API email login while ALLOW_EMAIL_LOGIN=false; each use is logged
ALLOW_REGISTRATION=true
ALLOW_SOCIAL_LOGIN=false
ALLOW_SOCIAL_REGISTRATION=false
ALLOW_PASSWORD_RESET=false
# ALLOW_ACCOUNT_DELETION=true # note: enabled by default if omitted/commented out
ALLOW_UNVERIFIED_EMAIL_LOGIN=true
SESSION_EXPIRY=1000 * 60 * 15
REFRESH_TOKEN_EXPIRY=(1000 * 60 * 60 * 24) * 7
# Overrides the Secure attribute for session/auth cookies when set to true or false;
# leave unset to use the default NODE_ENV/DOMAIN_SERVER heuristic.
# Set to false only for HTTP-only deployments where browsers drop Secure cookies.
# SESSION_COOKIE_SECURE=false
# Leave these blank to use generated temporary secrets from .env.temp.
# Configure unique, persistent values before using a production instance.
JWT_SECRET=
JWT_REFRESH_SECRET=
# Discord
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
DISCORD_CALLBACK_URL=/oauth/discord/callback
# Facebook
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=
FACEBOOK_CALLBACK_URL=/oauth/facebook/callback
# GitHub
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK_URL=/oauth/github/callback
# GitHub Enterprise
# GITHUB_ENTERPRISE_BASE_URL=
# GITHUB_ENTERPRISE_USER_AGENT=
# Google
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_CALLBACK_URL=/oauth/google/callback
# Apple
APPLE_CLIENT_ID=
APPLE_TEAM_ID=
APPLE_KEY_ID=
APPLE_PRIVATE_KEY_PATH=
APPLE_CALLBACK_URL=/oauth/apple/callback
# OpenID
OPENID_CLIENT_ID=
OPENID_CLIENT_SECRET=
OPENID_ISSUER=
OPENID_SESSION_SECRET=
OPENID_SCOPE="openid profile email"
OPENID_CALLBACK_URL=/oauth/openid/callback
# Admin panel SSO uses ${DOMAIN_SERVER}/api/admin/oauth/openid/callback as the
# OpenID provider redirect URI.
OPENID_REQUIRED_ROLE=
OPENID_REQUIRED_ROLE_TOKEN_KIND=
OPENID_REQUIRED_ROLE_PARAMETER_PATH=
OPENID_ADMIN_ROLE=
OPENID_ADMIN_ROLE_PARAMETER_PATH=
OPENID_ADMIN_ROLE_TOKEN_KIND=
# Generic OpenID role sync maps non-admin IdP roles/groups to one LibreChat role.
# ADMIN cannot be assigned by generic role sync; use OPENID_ADMIN_ROLE for admin elevation.
# Role priority is ordered from most important to least important.
OPENID_ROLE_SYNC_ENABLED=false
OPENID_ROLE_SYNC_API_ENABLED=false
OPENID_ROLE_SYNC_SOURCE=id
OPENID_ROLE_SYNC_CLAIM=
OPENID_ROLE_SYNC_ROLE_PRIORITY=
# Fallback is authoritative when configured: if no priority role matches, this role is assigned.
OPENID_ROLE_SYNC_FALLBACK_ROLE=
# Set to determine which user info property returned from OpenID Provider to store as the User's username
OPENID_USERNAME_CLAIM=
# Set to determine which user info property returned from OpenID Provider to store as the User's name
OPENID_NAME_CLAIM=
# Set to determine which user info claim to use as the email/identifier for user matching (e.g., "upn" for Entra ID)
# When not set, defaults to: email -> preferred_username -> upn
OPENID_EMAIL_CLAIM=
# Optional audience parameter for OpenID authorization requests and JWT validation.
# If comma-separated values are provided, JWT validation accepts all values and
# authorization requests use the first non-empty value.
OPENID_AUDIENCE=
# Optional audience parameter for OpenID refresh token requests.
# Some providers, such as Auth0 custom APIs, require this to preserve
# the intended access-token audience during refresh. Usually matches OPENID_AUDIENCE.
OPENID_REFRESH_AUDIENCE=
OPENID_BUTTON_LABEL=
OPENID_IMAGE_URL=
# Set to true to automatically redirect to the OpenID provider when a user visits the login page
# This will bypass the login form completely for users, only use this if OpenID is your only authentication method
OPENID_AUTO_REDIRECT=false
# Set to true to use PKCE (Proof Key for Code Exchange) for OpenID authentication.
# For public clients (no client secret), leave OPENID_CLIENT_SECRET empty and set this to true.
OPENID_USE_PKCE=false
#Set to true to reuse openid tokens for authentication management instead of using the mongodb session and the custom refresh token.
OPENID_REUSE_TOKENS=
#Max age a reused OpenID session token is served before LibreChat forces an IdP refresh. Default 900000 ms (15 min).
#Accepts an arithmetic expression like SESSION_EXPIRY (e.g. 60 * 60 * 24 * 1000 for 24h).
#Raise toward the IdP access-token lifetime when the IdP revokes the previous access token on refresh, so a still-valid token
#is not rotated/revoked out from under downstream consumers (e.g. MCP servers that introspect the bearer).
#When OPENID_REUSE_TOKENS=true, the OpenID session cookie maxAge is extended to at least this value.
OPENID_REUSE_MAX_SESSION_AGE_MS=
#By default, signing key verification results are cached in order to prevent excessive HTTP requests to the JWKS endpoint.
#If a signing key matching the kid is found, this will be cached and the next time this kid is requested the signing key will be served from the cache.
#Default is true.
OPENID_JWKS_URL_CACHE_ENABLED=
OPENID_JWKS_URL_CACHE_TIME= # 600000 ms eq to 10 minutes leave empty to disable caching
#Set to true to trigger token exchange flow to acquire access token for the userinfo endpoint.
OPENID_ON_BEHALF_FLOW_FOR_USERINFO_REQUIRED=
OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE="user.read" # example for Scope Needed for Microsoft Graph API
# Set to true to use the OpenID Connect end session endpoint for logout
OPENID_USE_END_SESSION_ENDPOINT=
# URL to redirect to after OpenID logout (defaults to ${DOMAIN_CLIENT}/login)
OPENID_POST_LOGOUT_REDIRECT_URI=
# Maximum logout URL length before using logout_hint instead of id_token_hint (default: 2000)
OPENID_MAX_LOGOUT_URL_LENGTH=
#========================#
# SharePoint Integration #
#========================#
# Requires Entra ID (OpenID) authentication to be configured
# Enable SharePoint file picker in chat and agent panels
# ENABLE_SHAREPOINT_FILEPICKER=true
# SharePoint tenant base URL (e.g., https://yourtenant.sharepoint.com)
# SHAREPOINT_BASE_URL=https://yourtenant.sharepoint.com
# Microsoft Graph API And SharePoint scopes for file picker
# SHAREPOINT_PICKER_SHAREPOINT_SCOPE==https://yourtenant.sharepoint.com/AllSites.Read
# SHAREPOINT_PICKER_GRAPH_SCOPE=Files.Read.All
#========================#
# SAML
# Note: If OpenID is enabled, SAML authentication will be automatically disabled.
SAML_ENTRY_POINT=
SAML_ISSUER=
SAML_CERT=
SAML_CALLBACK_URL=/oauth/saml/callback
SAML_SESSION_SECRET=
# Stable NameID format requested from the IdP. Transient identifiers are rejected.
# Persistent identifiers are recommended for account binding.
# SAML_NAME_ID_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
# Expected IdP entity ID. When set, assertions from a different or missing issuer are rejected.
SAML_IDP_ISSUER=
# Attribute mappings (optional)
SAML_EMAIL_CLAIM=
SAML_USERNAME_CLAIM=
SAML_GIVEN_NAME_CLAIM=
SAML_FAMILY_NAME_CLAIM=
SAML_PICTURE_CLAIM=
SAML_NAME_CLAIM=
# Logint buttion settings (optional)
SAML_BUTTON_LABEL=
SAML_IMAGE_URL=
# Whether the SAML Response should be signed.
# - If "true", the entire `SAML Response` will be signed.
# - If "false" or unset, only the `SAML Assertion` will be signed (default behavior).
# SAML_USE_AUTHN_RESPONSE_SIGNED=
#===============================================#
# Microsoft Graph API / Entra ID Integration #
#===============================================#
# Enable Entra ID people search integration in permissions/sharing system
# When enabled, the people picker will search both local database and Entra ID
USE_ENTRA_ID_FOR_PEOPLE_SEARCH=false
# When enabled, entra id groups owners will be considered as members of the group
ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS=false
# Microsoft Graph API scopes needed for people/group search
# Default scopes provide access to user profiles and group memberships
OPENID_GRAPH_SCOPES=User.Read,People.Read,GroupMember.Read.All
# LDAP
LDAP_URL=
LDAP_BIND_DN=
LDAP_BIND_CREDENTIALS=
LDAP_USER_SEARCH_BASE=
#LDAP_SEARCH_FILTER="mail="
LDAP_CA_CERT_PATH=
# LDAP_TLS_REJECT_UNAUTHORIZED=
# LDAP_STARTTLS=
# LDAP_LOGIN_USES_USERNAME=true
# LDAP_ID=
# LDAP_USERNAME=
# LDAP_EMAIL=
# LDAP_FULL_NAME=
#========================#
# Email Password Reset #
#========================#
EMAIL_SERVICE=
EMAIL_HOST=
EMAIL_PORT=25
EMAIL_ENCRYPTION=
EMAIL_ENCRYPTION_HOSTNAME=
EMAIL_ALLOW_SELFSIGNED=
# Leave both empty for SMTP servers that do not require authentication
EMAIL_USERNAME=
EMAIL_PASSWORD=
EMAIL_FROM_NAME=
EMAIL_FROM=noreply@librechat.ai
#========================#
# Mailgun API #
#========================#
# MAILGUN_API_KEY=your-mailgun-api-key
# MAILGUN_DOMAIN=mg.yourdomain.com
# EMAIL_FROM=noreply@yourdomain.com
# EMAIL_FROM_NAME="LibreChat"
# # Optional: For EU region
# MAILGUN_HOST=https://api.eu.mailgun.net
#========================#
# Firebase CDN #
#========================#
FIREBASE_API_KEY=
FIREBASE_AUTH_DOMAIN=
FIREBASE_PROJECT_ID=
FIREBASE_STORAGE_BUCKET=
FIREBASE_MESSAGING_SENDER_ID=
FIREBASE_APP_ID=
#========================#
# S3 AWS Bucket #
#========================#
AWS_ENDPOINT_URL=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=
AWS_BUCKET_NAME=
# Required for path-style S3-compatible providers (MinIO, Hetzner, Backblaze B2, etc.)
# that don't support virtual-hosted-style URLs (bucket.endpoint). Not needed for AWS S3.
# AWS_FORCE_PATH_STYLE=false
# Required for CloudFront signed cookies and signed download URLs
# CLOUDFRONT_KEY_PAIR_ID=
# CLOUDFRONT_PRIVATE_KEY=
#========================#
# Azure Blob Storage #
#========================#
AZURE_STORAGE_CONNECTION_STRING=
AZURE_STORAGE_PUBLIC_ACCESS=false
AZURE_CONTAINER_NAME=files
#========================#
# Shared Links #
#========================#
ALLOW_SHARED_LINKS=true
# Allows unauthenticated access to shared links. Defaults to false (auth required) if not set.
ALLOW_SHARED_LINKS_PUBLIC=false
# Snapshot files referenced by a shared chat so viewers can preview/download them through
# the shared link (instead of the owner's file ACL). Enabled by default; overrides the
# `interface.sharedLinks.snapshotFiles` yaml setting when set.
# SHARED_LINKS_SNAPSHOT_FILES=true
#==============================#
# Static File Cache Control #
#==============================#
# Leave commented out to use defaults: 1 day (86400 seconds) for s-maxage and 2 days (172800 seconds) for max-age
# NODE_ENV must be set to production for these to take effect
# STATIC_CACHE_MAX_AGE=172800
# STATIC_CACHE_S_MAX_AGE=86400
# If you have another service in front of your LibreChat doing compression, disable express based compression here
# DISABLE_COMPRESSION=true
# Serve precompressed Brotli versions of static app assets when available.
# ENABLE_STATIC_ASSET_BROTLI=true
# If you have gzipped version of uploaded image images in the same folder, this will enable gzip scan and serving of these images
# Note: The images folder will be scanned on startup and a ma kept in memory. Be careful for large number of images.
# ENABLE_IMAGE_OUTPUT_GZIP_SCAN=true
#===================================================#
# UI #
#===================================================#
APP_TITLE=LibreChat
# CUSTOM_FOOTER="My custom footer"
HELP_AND_FAQ_URL=https://librechat.ai
# SHOW_BIRTHDAY_ICON=true
# Google tag manager id
#ANALYTICS_GTM_ID=user provided google tag manager id
# limit conversation file imports to a certain number of bytes in size to avoid the container
# maxing out memory limitations by unremarking this line and supplying a file size in bytes
# such as the below example of 250 mib
# CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES=262144000
# Max size (bytes) of a code-execution artifact (docx/xlsx/csv/pptx/potx/text/pdf) rendered as an
# inline preview. Larger files fall back to download-only. Default: 2 MB (2097152). Note the
# rendered HTML is independently capped at 512 KB, so very rich files may still skip preview.
# FILE_PREVIEW_MAX_EXTRACT_BYTES=2097152
#===============#
# REDIS Options #
#===============#
# Enable Redis for caching and session storage
# USE_REDIS=true
# Enable Redis for resumable LLM streams (defaults to USE_REDIS value if not set)
# Set to false to use in-memory storage for streams while keeping Redis for other caches
# USE_REDIS_STREAMS=true
# Scheduled chats require shared Redis streams in multi-replica deployments.
# Set this only when the deployment truly runs one LibreChat process without Redis.
# Scheduled agents that can pause for approval or ask_user_question require both
# Redis streams for shared action state and a durable shared checkpointer.
# MongoDB is currently the built-in durable checkpointer (and the default).
# SCHEDULES_SINGLE_PROCESS=true
# Emergency global stop for both automatic and manual scheduled runs.
# SCHEDULES_DISABLED=true
# Generation stream wire/state protocol. Redis-backed deployments default to the
# rolling-upgrade-safe v1 protocol when this is unset; in-memory deployments use v2.
# After EVERY replica is running a v2-capable LibreChat build and all v1-owned active
# generations have drained, set this to 2 in a second rollout. Do not roll back to a
# pre-v2 build while v2 generations remain active in Redis.
# GENERATION_PROTOCOL_VERSION=2
# Coalesce streamed model/tool-argument deltas into windowed Redis publications (ms).
# Unset or 0 (default) publishes per delta. 25 is recommended: it batches the publish
# EVAL and the durable append across the window (fewer Redis round trips and lower
# Redis CPU at high token rates) at the cost of up to one window of added delivery
# latency. Enable only after EVERY replica runs a build with batch-frame support;
# older subscribers drop coalesced frames. Values are capped at 1000.
# Keep the window <= the stream-smoothing cadence (`streamRate`, default 25ms):
# each smoothing tick emits its pieces in one burst, so a tick-sized window
# captures exactly one batch per tick; a larger window re-batches the paced
# deltas and quantizes the smoothed cadence at delivery. With smoothing
# disabled (`streamRate: 0`) there is no cadence to preserve — the window is
# then purely the Redis-cost vs delivery-latency tradeoff described above.
# STREAM_DELTA_COALESCE_MS=25
# Single Redis instance
# REDIS_URI=redis://127.0.0.1:6379
# Redis cluster (multiple nodes)
# REDIS_URI=redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003
# Enable Redis cluster mode when connecting to a cluster through a single URI
# USE_REDIS_CLUSTER=true
# Managed Redis services with a single endpoint may shard keys internally and reject multi-key DEL
# Set to true to delete keys individually and avoid CROSSSLOT errors while keeping single-node mode
# REDIS_CLUSTER_SAFE_DELETE=true
# Redis with TLS/SSL encryption and CA certificate
# REDIS_URI=rediss://127.0.0.1:6380
# REDIS_CA=/path/to/ca-cert.pem
# Elasticache may need to use an alternate dnsLookup for TLS connections. see "Special Note: Aws Elasticache Clusters with TLS" on this webpage: https://www.npmjs.com/package/ioredis
# Enable alternative dnsLookup for redis
# REDIS_USE_ALTERNATIVE_DNS_LOOKUP=true
# Redis authentication (if required)
# REDIS_USERNAME=your_redis_username
# REDIS_PASSWORD=your_redis_password
# Redis key prefix configuration
# Use environment variable name for dynamic prefix (recommended for cloud deployments)
# REDIS_KEY_PREFIX_VAR=K_REVISION
# Or use static prefix directly
# REDIS_KEY_PREFIX=librechat
# Redis connection limits
# REDIS_MAX_LISTENERS=40
# Redis ping interval in seconds (0 = disabled, >0 = enabled)
# When set to a positive integer, Redis clients will ping the server at this interval to keep connections alive
# When unset or 0, no pinging is performed (recommended for most use cases)
# REDIS_PING_INTERVAL=300
# Force specific cache namespaces to use in-memory storage even when Redis is enabled
# Comma-separated list of CacheKeys
# Defaults to CONFIG_STORE,APP_CONFIG so YAML-derived config stays per-container (safe for blue/green deployments)
# Set to empty string to force all namespaces through Redis: FORCED_IN_MEMORY_CACHE_NAMESPACES=
# FORCED_IN_MEMORY_CACHE_NAMESPACES=CONFIG_STORE,APP_CONFIG
# Opt-in cache for authenticated user documents during request bursts. Requires Redis and
# the AUTH_USER_DOC namespace to remain Redis-backed (default: off; set exactly to "on").
# AUTH_USER_CACHE_MODE=off
# TTL in milliseconds for cached group memberships used in ACL permission checks (default: 300000 / 5 minutes; 0 disables)
# Membership changes invalidate affected entries immediately; the TTL bounds staleness from cross-process races.
# USER_PRINCIPALS_CACHE_TTL_MS=300000
# Redis lock TTL in milliseconds for cross-container cache builds (default: 5000)
# 0 disables build locking only; the delayed stale-rewrite eviction pass still runs on Redis-backed stores.
# Only used when the USER_PRINCIPALS namespace is Redis-backed; non-Redis deployments use in-process deduplication.
# USER_PRINCIPALS_LOCK_TTL_MS=5000
# Maximum time in milliseconds to wait for another container holding the lock to fill the cache
# before falling back to a direct database read (default: USER_PRINCIPALS_LOCK_TTL_MS)
# USER_PRINCIPALS_LOCK_WAIT_MS=5000
# Leader Election Configuration (for multi-instance deployments with Redis)
# Duration in seconds that the leader lease is valid before it expires (default: 25)
# LEADER_LEASE_DURATION=25
# Interval in seconds at which the leader renews its lease (default: 10)
# LEADER_RENEW_INTERVAL=10
# Maximum number of retry attempts when renewing the lease fails (default: 3)
# LEADER_RENEW_ATTEMPTS=3
# Delay in seconds between retry attempts when renewing the lease (default: 0.5)
# LEADER_RENEW_RETRY_DELAY=0.5
#==================================================#
# Others #
#==================================================#
# You should leave the following commented out #
# NODE_ENV=
# E2E_USER_EMAIL=
# E2E_USER_PASSWORD=
#=====================================================#
# Cache Headers #
#=====================================================#
# Headers that control caching of the index.html #
# Default configuration prevents caching to ensure #
# users always get the latest version. Customize #
# only if you understand caching implications. #
# INDEX_CACHE_CONTROL=no-cache, no-store, must-revalidate
# INDEX_PRAGMA=no-cache
# INDEX_EXPIRES=0
# no-cache: Forces validation with server before using cached version
# no-store: Prevents storing the response entirely
# must-revalidate: Prevents using stale content when offline
#=====================================================#
# OpenWeather #
#=====================================================#
OPENWEATHER_API_KEY=
#======================#
# Web Search #
#======================#
# Note: All of the following variable names can be customized.
# Omit values to allow user to provide them.
# For more information on configuration values, see:
# https://librechat.ai/docs/features/web_search
# Search Provider (Required)
# SERPER_API_KEY=your_serper_api_key
# Tavily (Search Provider and/or Scraper)
# TAVILY_API_KEY=your_tavily_api_key
# Keenable (Search Provider and/or Scraper; keyless by default, a key only lifts
# rate limits and covers both search and page fetch)
# KEENABLE_API_KEY=your_keenable_api_key
# Optional: Custom Keenable search API URL
# KEENABLE_API_URL=your_keenable_api_url
# Optional: Custom Keenable fetch API URL (used when scraperProvider is keenable)
# KEENABLE_FETCH_URL=your_keenable_fetch_api_url
# Scraper (Required)
# FIRECRAWL_API_KEY=your_firecrawl_api_key
# Optional: Custom Firecrawl API URL
# FIRECRAWL_API_URL=your_firecrawl_api_url
# Reranker (Required)
# JINA_API_KEY=your_jina_api_key
# or
# COHERE_API_KEY=your_cohere_api_key
#======================#
# MCP Configuration #
#======================#
# Treat 401/403 responses as OAuth requirement when no oauth metadata found
# MCP_OAUTH_ON_AUTH_ERROR=true
# Timeout for OAuth detection requests in milliseconds
# MCP_OAUTH_DETECTION_TIMEOUT=5000
# How long to wait (ms) for a user to complete the OAuth flow before timing out (default: 10 minutes)
# MCP_OAUTH_HANDLING_TIMEOUT=600000
# TTL (ms) for OAuth flow state; must outlive MCP_OAUTH_HANDLING_TIMEOUT (default: 15 minutes)
# MCP_OAUTH_FLOW_TTL=900000
# Cache connection status checks for this many milliseconds to avoid expensive verification
# MCP_CONNECTION_CHECK_TTL=60000
# Max bytes allowed in a non-GET streamable HTTP MCP response before rejecting it.
# Set to 0 to disable. Default: 16777216 (16 MiB)
# MCP_STREAMABLE_HTTP_MAX_RESPONSE_BYTES=16777216
# Max bytes allowed in a single SSE line for non-GET streamable HTTP MCP responses.
# Set to 0 to disable. Default: 5242880 (5 MiB)
# MCP_STREAMABLE_HTTP_MAX_LINE_BYTES=5242880
# Skip code challenge method validation (e.g., for AWS Cognito that supports S256 but doesn't advertise it)
# When set to true, forces S256 code challenge even if not advertised in .well-known/openid-configuration
# MCP_SKIP_CODE_CHALLENGE_CHECK=false
# Circuit breaker: max connect/disconnect cycles before tripping (per server)
# MCP_CB_MAX_CYCLES=7
# Circuit breaker: sliding window (ms) for counting cycles
# MCP_CB_CYCLE_WINDOW_MS=45000
# Circuit breaker: cooldown (ms) after the cycle breaker trips
# MCP_CB_CYCLE_COOLDOWN_MS=15000
# Circuit breaker: max consecutive failed connection rounds before backoff
# MCP_CB_MAX_FAILED_ROUNDS=3
# Circuit breaker: sliding window (ms) for counting failed rounds
# MCP_CB_FAILED_WINDOW_MS=120000
# Circuit breaker: base backoff (ms) after failed round threshold is reached
# MCP_CB_BASE_BACKOFF_MS=30000
# Circuit breaker: max backoff cap (ms) for exponential backoff
# MCP_CB_MAX_BACKOFF_MS=300000