Environment Variables
Comprehensive guide for configuring your application's environment with the `.env` file. This document is your one-stop resource for understanding and customizing the environment variables that will shape your application's behavior in different contexts.
Welcome to the comprehensive guide for configuring your application's environment with the .env file. This document is your one-stop resource for understanding and customizing the environment variables that will shape your application's behavior in different contexts.
While the default settings provide a solid foundation for a standard docker installation, delving into this guide will unveil the full potential of LibreChat. This guide empowers you to tailor LibreChat to your precise needs. Discover how to adjust language model availability, integrate social logins, manage the automatic moderation system, and much more. It's all about giving you the control to fine-tune LibreChat for an optimal user experience.
Reminder: Please restart LibreChat for the configuration changes to take effect
Alternatively, you can create a new file named docker-compose.override.yml in the same directory as your main docker-compose.yml file for LibreChat, where you can set your .env variables as needed under environment, or modify the default configuration provided by the main docker-compose.yml, without the need to directly edit or duplicate the whole file.
For more info see:
-
Our quick guide:
-
The official docker documentation:
-
You can also view an example of an override file for LibreChat in your LibreChat folder and on GitHub:
Server Configuration
Port
- The server listens on a specific port.
- The
PORTenvironment variable sets the port where the server listens. By default, it is set to3080.
| Key | Type | Description | Example |
|---|---|---|---|
| HOST | string | Specifies the host. | HOST=localhost |
| PORT | number | Specifies the port. | PORT=3080 |
HTTP Server Timeouts
These optional values configure the Node.js HTTP server. Leave them unset to retain Node's defaults. A value of 0 disables that timeout.
| Key | Type | Description | Example |
|---|---|---|---|
| HTTP_KEEP_ALIVE_TIMEOUT_MS | integer | Idle keep-alive timeout in milliseconds. Set this above the load balancer idle timeout to avoid reused connections racing server closure. Node default: 5000. | # HTTP_KEEP_ALIVE_TIMEOUT_MS=70000 |
| HTTP_KEEP_ALIVE_TIMEOUT_BUFFER_MS | integer | Additional socket timeout buffer in milliseconds. Node default: 1000. | # HTTP_KEEP_ALIVE_TIMEOUT_BUFFER_MS=5000 |
| HTTP_HEADERS_TIMEOUT_MS | integer | Time allowed to receive complete request headers. Node default: 60000. | # HTTP_HEADERS_TIMEOUT_MS=80000 |
| HTTP_REQUEST_TIMEOUT_MS | integer | Time allowed to receive the complete request. Node default: 300000. | # HTTP_REQUEST_TIMEOUT_MS=300000 |
Values must be non-negative safe integers; invalid values are ignored. When both header and request timeouts are enabled, LibreChat clamps the header timeout to the request timeout if it is higher. Node checks header and request expiry on a 30-second connection sweep, so values below 30000 are not enforced at exact millisecond precision. Bun currently accepts these settings but does not enforce them; LibreChat logs a warning when the API server runs under Bun.
NODE_MAX_OLD_SPACE_SIZE in .env.example is a Docker build argument and does not change the heap size at runtime. To set the Node.js heap limit, use NODE_OPTIONS, for example NODE_OPTIONS="--max-old-space-size=6144".
Trust proxy
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.
The TRUST_PROXY environment variable default is set to 1.
Refer to Express.js - trust proxy for more information about this.
| Key | Type | Description | Example |
|---|---|---|---|
| TRUST_PROXY | number | Specifies the number of hops. | TRUST_PROXY=1 |
Trusted Tenant Header
TRUST_TENANT_HEADER controls whether LibreChat accepts X-Tenant-Id before authentication on the /oauth, /api/auth, /api/share, and admin authentication route trees. It is disabled by default; while disabled, those routes ignore the header.
| Key | Type | Description | Example |
|---|---|---|---|
| TRUST_TENANT_HEADER | boolean | Trust X-Tenant-Id on pre-authentication routes. Enable only behind a trusted proxy that replaces client-supplied values. | TRUST_TENANT_HEADER=false |
Do not trust client-supplied tenant headers
Enable this setting only when a trusted reverse proxy strips every incoming X-Tenant-Id value
and sets the authoritative tenant ID itself. Otherwise, an untrusted client could choose the
tenant context used before authentication. LibreChat logs a security warning when the setting is
enabled.
When TENANT_ISOLATION_STRICT is enabled but TRUST_TENANT_HEADER is disabled, LibreChat warns at startup that pre-authentication tenant headers will be ignored. With strict isolation, guarded pre-authentication requests need real tenant context before account lookup. Missing context returns 403 with TENANT_CONTEXT_REQUIRED; OAuth callbacks redirect to the authentication error page. Ensure trusted tenant resolution covers sign-in, callbacks, refresh, and email verification. See the upgrade guide.
Credentials Configuration
LibreChat uses CREDS_KEY and CREDS_IV to encrypt supported credentials stored in the database. Configure fixed, unique values for production and share the same values across every replica.
| Key | Type | Description | Example |
|---|---|---|---|
| CREDS_KEY | string | 32-byte key (64 hexadecimal characters) for securely storing credentials. | CREDS_KEY= |
| CREDS_IV | string | 16-byte IV (32 hexadecimal characters) for securely storing credentials. | CREDS_IV= |
| LIBRECHAT_TEMP_CREDENTIALS_PATH | string | Path used to persist automatically generated temporary credentials. Defaults to `.env.temp` in the process working directory. | # LIBRECHAT_TEMP_CREDENTIALS_PATH=/app/data/.env.temp |
When any of CREDS_KEY, CREDS_IV, JWT_SECRET, or JWT_REFRESH_SECRET is blank, LibreChat first reuses a valid value from the temporary credentials file. If none exists, it generates a cryptographically random value and writes the file with owner-only permissions. Explicit environment values always take precedence. LibreChat refuses to use .env or .env.example as the generated file path, preventing accidental replacement of either configuration file.
LibreChat also refuses to start when JWT_SECRET or JWT_REFRESH_SECRET still uses one of the retired published defaults, whether the value comes from the environment or the temporary credentials file. Generate unique replacements rather than carrying old sample secrets into a deployment.
The bundled Docker Compose files persist /app/data/.env.temp in the librechat-data volume, so a single Compose deployment can restart without changing these generated values. If the file cannot be persisted, the values are process-local and sessions or encrypted records may become inaccessible after restart.
Set permanent values for production
Temporary generation is a bootstrap convenience, not a credential-rotation system. Before production use, generate permanent values with the Credentials Generator, store them in your secret manager, and provide the same values to every replica. Changing an established key does not re-encrypt existing records. LibreChat records credential fingerprints in the database and warns when active values drift; do not overwrite that marker instead of performing a controlled migration.
Security Headers and Content Security Policy
LibreChat sends baseline HSTS, framing, content-type, opener, resource, and referrer headers by default. SECURITY_HEADERS=false disables all of them and is also the global CSP kill switch.
Nonce-based CSP is separately opt-in with CSP_ENABLED=true and defaults to report-only mode. Start with CSP_REPORT_ONLY=true, inspect violations, and add only the origins your deployment requires before enforcing. When CSP is active, the SPA shell is always sent with Cache-Control: no-store so its per-response nonce cannot be reused from cache.
See HTTP Security Headers for every baseline and CSP variable, accepted values, defaults, source-list overrides, and rollout guidance.
Static File Handling
| Key | Type | Description | Example |
|---|---|---|---|
| STATIC_CACHE_MAX_AGE | string | Cache-Control max-age in seconds | STATIC_CACHE_MAX_AGE=172800 |
| STATIC_CACHE_S_MAX_AGE | string | Cache-Control s-maxage in seconds for shared caches (CDNs and proxies) | STATIC_CACHE_S_MAX_AGE="86400" |
| DISABLE_COMPRESSION | boolean | Disables compression for static files. | DISABLE_COMPRESSION=false |
| ENABLE_IMAGE_OUTPUT_GZIP_SCAN | boolean | Enables serving gzipped versions of uploaded images if present in the same folder. | ENABLE_IMAGE_OUTPUT_GZIP_SCAN=true |
| ENABLE_STATIC_ASSET_BROTLI | boolean | Enables serving precompressed Brotli versions of static app assets when available. | ENABLE_STATIC_ASSET_BROTLI=true |
Behaviour:
Sets the Cache-Control headers for static files. These configurations only trigger when the NODE_ENV is set to production.
- Uncomment
STATIC_CACHE_MAX_AGEto change the localmax-agefor static files. By default this is set to 2 days (172800 seconds). - Uncomment
STATIC_CACHE_S_MAX_AGEto set thes-maxagefor shared caches (CDNs and proxies). By default this is set to 1 day (86400 seconds). - Uncomment
DISABLE_COMPRESSIONto disable compression for static files. By default, compression is enabled. - Uncomment
ENABLE_IMAGE_OUTPUT_GZIP_SCANto enable scanning and serving of gzipped version of images if they have been pre-compressed in the same folder, with the same name and a .gz extension. By default, gzip scan for uploaded images is disabled. - Uncomment
ENABLE_STATIC_ASSET_BROTLIto serve precompressed.brversions of static app assets when they exist. When enabled, Brotli is preferred before gzip for API-served static files.
Warning
- This only affects static files served by the API server and is not applicable to Firebase, NGINX, or any other configurations.
Index HTML Cache Control
| Key | Type | Description | Example |
|---|---|---|---|
| INDEX_CACHE_CONTROL | string | Cache-Control header for index.html | INDEX_CACHE_CONTROL=no-cache, no-store, must-revalidate |
| INDEX_PRAGMA | string | Pragma header for index.html | INDEX_PRAGMA=no-cache |
| INDEX_EXPIRES | string | Expires header for index.html | INDEX_EXPIRES=0 |
Behaviour:
Controls caching headers specifically for the index.html response. By default, these settings prevent caching to ensure users always get the latest version of the application.
Note
Unlike static assets which are cached for performance, the index.html file's cache headers are configured separately to ensure users always get the latest application shell.
MongoDB Database
| Key | Type | Description | Example |
|---|---|---|---|
| MONGO_URI | string | Specifies the MongoDB URI. | MONGO_URI=mongodb://127.0.0.1:27017/LibreChat |
Change this to your MongoDB URI if different. You should add LibreChat or your own APP_TITLE as the database name in the URI.
If you are using an online database, the URI format is mongodb+srv://<username>:<password>@<host>/<database>?<options>. Your MONGO_URI should look like this:
mongodb+srv://username:[email protected]/LibreChat?retryWrites=true(retryWritesis the only option you need when using the online database.)
MongoDB Connection Pool Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| MONGO_MAX_POOL_SIZE | number | The maximum number of connections in the connection pool. | # MONGO_MAX_POOL_SIZE= |
| MONGO_MIN_POOL_SIZE | number | The minimum number of connections in the connection pool. | # MONGO_MIN_POOL_SIZE= |
| MONGO_MAX_CONNECTING | number | The maximum number of connections that may be in the process of being established concurrently by the connection pool. | # MONGO_MAX_CONNECTING= |
| MONGO_MAX_IDLE_TIME_MS | number | The maximum number of milliseconds that a connection can remain idle in the pool before being removed and closed. | # MONGO_MAX_IDLE_TIME_MS= |
| MONGO_WAIT_QUEUE_TIMEOUT_MS | number | The maximum time in milliseconds that a thread can wait for a connection to become available. | # MONGO_WAIT_QUEUE_TIMEOUT_MS= |
MongoDB Schema Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| MONGO_AUTO_INDEX | boolean | Set to false to disable automatic index creation for all models associated with this connection. When omitted, empty, or whitespace-only, uses Mongoose default behavior. | # MONGO_AUTO_INDEX= |
| MONGO_AUTO_CREATE | boolean | Set to false to disable Mongoose automatically calling createCollection() on every model created on this connection. When omitted, empty, or whitespace-only, uses Mongoose default behavior. | # MONGO_AUTO_CREATE= |
Amazon DocumentDB 5.0+ instance-based clusters are a supported target. DocumentDB requires retryWrites=false and TLS with the AWS CA bundle; elastic clusters are unsupported because they do not provide unique indexes. A typical URI has this form:
mongodb://username:password@cluster:27017/librechat?tls=true&tlsCAFile=/path-to-ca/global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
DocumentDB 4.0 can run with reduced partial-unique-index enforcement. See Amazon DocumentDB Compatibility for the supported target and caveats.
See also:
- MongoDB Atlas for instructions on how to create an online MongoDB Atlas database (useful for use without Docker)
- MongoDB Community Server for instructions on how to create a local MongoDB database (without Docker)
- MongoDB Authentication To enable explicit authentication for MongoDB in Docker.
- Manage your database with Mongo Express for securely accessing your Docker MongoDB database
Application Domains
To configure LibreChat for local use or custom domain deployment, set the following environment variables:
| Key | Type | Description | Example |
|---|---|---|---|
| DOMAIN_CLIENT | string | Specifies the client-side domain. | DOMAIN_CLIENT=http://localhost:3080 |
| DOMAIN_SERVER | string | Specifies the server-side domain. | DOMAIN_SERVER=http://localhost:3080 |
| ADMIN_PANEL_URL | string | External admin panel base URL used for admin OAuth/SSO redirects and the admin-only Settings > General link. Do not include a trailing slash. | ADMIN_PANEL_URL=https://admin.example.com/admin |
| ADMIN_PANEL_SESSION_SECRET | string | Required session encryption key for the bundled admin panel (min 32 characters). The docker-compose and deploy-compose admin-panel services read it as their SESSION_SECRET. Generate with `openssl rand -hex 32` before starting the stack. | ADMIN_PANEL_SESSION_SECRET=<your-32-char-random-string> |
| ADMIN_PANEL_PORT | number | Host port for the bundled admin panel in the default docker-compose. In deploy-compose the panel is served at http://admin.localhost via nginx instead. | ADMIN_PANEL_PORT=3000 |
When deploying LibreChat to a custom domain, replace http://localhost:3080 with your deployed URL
- e.g.
https://librechat.example.com.
Prevent Public Search Engines Indexing
By default, your website will not be indexed by public search engines (e.g. Google, Bing, …). This means that people will not be able to find your website through these search engines. If you want to make your website more visible and searchable, you can change the following setting to false
| Key | Type | Description | Example |
|---|---|---|---|
| NO_INDEX | boolean | Prevents public search engines from indexing your website. | NO_INDEX=true |
❗Note: This method is not guaranteed to work for all search engines, and some search engines may still index your website or web page for other purposes, such as caching or archiving. Therefore, you should not rely solely on this method to protect sensitive or confidential information on your website or web page.
Logging
LibreChat has built-in central logging, see Logging System for more info.
Log Files
- Debug log files are written only when
DEBUG_LOGGING=true, which is recommended for development and when reporting issues. - To report issues, reproduce the error and submit logs from
./api/logs/debug-%DATE%.logat: LibreChat GitHub Issues - Error logs are stored in the same location.
Environment Variables
| Key | Type | Description | Example |
|---|---|---|---|
| DEBUG_LOGGING | boolean | Write debug logs to file. Debug log files are created only when this is true. | DEBUG_LOGGING=true |
| DEBUG_CONSOLE | boolean | Enable verbose console/stdout logs in the same format as file debug logs. | DEBUG_CONSOLE=false |
| CONSOLE_LOG_LEVEL | string | Set console verbosity to error, warn, info, http, verbose, debug, activity, silly, or silent. Defaults to info, or debug when DEBUG_CONSOLE=true; an explicit value takes precedence. | # CONSOLE_LOG_LEVEL=info |
| LOG_TO_FILE | boolean | Set to false to disable file-backed Winston transports while keeping console logging available. | LOG_TO_FILE=true |
| CONSOLE_JSON | boolean | Enable verbose JSON console/stdout logs suitable for cloud deployments like GCP/AWS. | CONSOLE_JSON=false |
| CONSOLE_JSON_STRING_LENGTH | number | Configure the truncation size for string values in JSON console/stdout logs. Default: 255. | # CONSOLE_JSON_STRING_LENGTH=255 |
| DEBUG_MESSAGE_LENGTH | number | Maximum length of a debug log message before it is truncated. Default: 150. | # DEBUG_MESSAGE_LENGTH=150 |
| LOG_REDACTION_MAX_NODES | number | Maximum number of values (objects, and strings weighted by length) that one log record may redact before the remainder is replaced, so very wide payloads cannot stall logging. Default: 5000. | # LOG_REDACTION_MAX_NODES=5000 |
| LIBRECHAT_LOG_DIR | string | Custom directory for log files. Defaults to /app/logs (Docker) or api/logs (local dev). | # LIBRECHAT_LOG_DIR=/custom/log/path |
| MEM_DIAG | boolean | Enable memory diagnostics — logs heap/RSS snapshots every 60 seconds. Auto-enabled when running with --inspect. | # MEM_DIAG=true |
| AGENT_DEBUG_LOGGING | boolean | Enables verbose debug logging in the agent controller (token counts, context pruning diagnostics). | # AGENT_DEBUG_LOGGING=true |
Note:
DEBUG_LOGGINGcan be used with eitherDEBUG_CONSOLEorCONSOLE_JSONbut not both.DEBUG_CONSOLEandCONSOLE_JSONare mutually exclusive.CONSOLE_LOG_LEVEL=silentdisables console output without disabling file logging. Invalid values fall back to the normal default and emit a warning.CONSOLE_JSON: When handling console logs in cloud deployments (such as GCP or AWS), enabling this will dump the logs with a UTC timestamp and format them as JSON.
Note: DEBUG_CONSOLE is not recommended, as the outputs can be quite verbose, and so it's disabled by default.
Permission
UID and GID are numbers assigned by Linux to each user and group on the system. If you have permission problems, set here the UID and GID of the user running the Docker Compose command. The applications in the container will run with these UID/GID.
| Key | Type | Description | Example |
|---|---|---|---|
| UID | number | The user ID. | # UID=1000 |
| GID | number | The group ID. | # GID=1000 |
Langfuse Tracing and Tenant Fanout
Use the standard Langfuse variables for one central observability project. The optional fanout deployment can additionally route tenant traces, media, and feedback scores to tenant-specific Langfuse projects. See Langfuse Tracing for setup, in-app connection management, and architecture.
| Key | Type | Description | Example |
|---|---|---|---|
| LANGFUSE_PUBLIC_KEY | string | Public key for the central Langfuse project. | # LANGFUSE_PUBLIC_KEY= |
| LANGFUSE_SECRET_KEY | string | Secret key for the central Langfuse project. | # LANGFUSE_SECRET_KEY= |
| LANGFUSE_BASE_URL | string | Base URL for central tracing and feedback scores. | # LANGFUSE_BASE_URL=https://cloud.langfuse.com |
| LANGFUSE_PROJECT_ID | string | Stable central Langfuse project ID. When omitted, LibreChat discovers and caches it in the background for feedback routing. | # LANGFUSE_PROJECT_ID= |
| LANGFUSE_TRACING_ENABLED | boolean | Set to false to disable Langfuse traces and feedback scores. Default: true. | # LANGFUSE_TRACING_ENABLED=true |
| LANGFUSE_SAMPLE_RATE | number | Deterministic trace-level sample rate from 0 to 1. Sampled-out traces do not receive feedback scores. Default: 1. | # LANGFUSE_SAMPLE_RATE=1 |
| LANGFUSE_FANOUT_ENABLED | boolean | Enable routing through the optional fanout gateway. | # LANGFUSE_FANOUT_ENABLED=false |
| LANGFUSE_FANOUT_COLLECTOR_URL | string | Gateway URL used by the LibreChat API. | # LANGFUSE_FANOUT_COLLECTOR_URL=http://langfuse-fanout-collector:4318 |
| LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED | boolean | Prevent the LibreChat SDK from creating media uploads for central or fallback collector traces. Tenant-routed media uploads are unchanged. | # LANGFUSE_FANOUT_CENTRAL_MEDIA_UPLOAD_DISABLED=false |
| LANGFUSE_FANOUT_LISTEN_ADDR | string | Gateway HTTP listen address. Default: :4318. | # LANGFUSE_FANOUT_LISTEN_ADDR=:4318 |
| LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED | boolean | Emergency switch that disables tenant trace and score export while retaining central export. | # LANGFUSE_FANOUT_TENANT_EXPORT_DISABLED=false |
| LANGFUSE_FANOUT_CENTRAL_BASE_URL | string | Central Langfuse base URL used by the gateway. | # LANGFUSE_FANOUT_CENTRAL_BASE_URL=https://cloud.langfuse.com |
| LANGFUSE_FANOUT_CENTRAL_AUTH_HEADER | string | Full Basic authorization header for central trace and media export. | # LANGFUSE_FANOUT_CENTRAL_AUTH_HEADER=Basic <base64-public-colon-secret> |
| LANGFUSE_FANOUT_CENTRAL_MEDIA_EXPORT_DISABLED | boolean | Disable central media fanout without disabling central traces. | # LANGFUSE_FANOUT_CENTRAL_MEDIA_EXPORT_DISABLED=false |
| LANGFUSE_FANOUT_TENANT_DESTINATIONS | string | Comma-separated destination key and base URL mappings allowed at startup. | # LANGFUSE_FANOUT_TENANT_DESTINATIONS=eu=https://cloud.langfuse.com,us=https://us.cloud.langfuse.com,jp=https://jp.cloud.langfuse.com |
| LANGFUSE_FANOUT_TRACE_DESTINATION_KEYS | string | Destination keys supported by the collector routing configuration. | # LANGFUSE_FANOUT_TRACE_DESTINATION_KEYS=eu,us,jp |
| LANGFUSE_FANOUT_PUBLIC_URL | string | Gateway base URL used to create one-time media upload URLs. | # LANGFUSE_FANOUT_PUBLIC_URL=http://langfuse-fanout-collector:4318 |
| LANGFUSE_FANOUT_TRACE_COLLECTOR_URL | string | Internal gateway-to-collector trace endpoint. | # LANGFUSE_FANOUT_TRACE_COLLECTOR_URL=http://langfuse-fanout-otel:4319 |
| LANGFUSE_FANOUT_REDIS_URI | string | Redis URI for one-time media upload plans. | # LANGFUSE_FANOUT_REDIS_URI=redis://langfuse-fanout-redis:6379 |
| LANGFUSE_FANOUT_REDIS_USERNAME | string | Optional Redis username for the fanout gateway. | # LANGFUSE_FANOUT_REDIS_USERNAME= |
| LANGFUSE_FANOUT_REDIS_PASSWORD | string | Optional Redis password for the fanout gateway. | # LANGFUSE_FANOUT_REDIS_PASSWORD= |
| LANGFUSE_FANOUT_REDIS_KEY_PREFIX | string | Redis key prefix for fanout media plans. | # LANGFUSE_FANOUT_REDIS_KEY_PREFIX=langfuse-fanout |
| LANGFUSE_FANOUT_OTEL_RECEIVER_ENDPOINT | string | Internal collector receiver bind address. | # LANGFUSE_FANOUT_OTEL_RECEIVER_ENDPOINT=0.0.0.0:4319 |
| LANGFUSE_FANOUT_TENANT_EU_BASE_URL | string | Static EU destination URL for the included Compose collector. | # LANGFUSE_FANOUT_TENANT_EU_BASE_URL=https://cloud.langfuse.com |
| LANGFUSE_FANOUT_TENANT_US_BASE_URL | string | Static US destination URL for the included Compose collector. | # LANGFUSE_FANOUT_TENANT_US_BASE_URL=https://us.cloud.langfuse.com |
| LANGFUSE_FANOUT_TENANT_JP_BASE_URL | string | Static JP destination URL for the included Compose collector. | # LANGFUSE_FANOUT_TENANT_JP_BASE_URL=https://jp.cloud.langfuse.com |
| LANGFUSE_FANOUT_UPSTREAM_TIMEOUT | duration | Timeout for gateway requests to Langfuse and media upload URLs. | # LANGFUSE_FANOUT_UPSTREAM_TIMEOUT=30s |
| LANGFUSE_FANOUT_METRICS_SECRET | string | Bearer token required to scrape the gateway metrics endpoint. | # LANGFUSE_FANOUT_METRICS_SECRET= |
| LANGFUSE_FANOUT_MEMORY_LIMIT_MIB | number | Collector memory limit in MiB. | # LANGFUSE_FANOUT_MEMORY_LIMIT_MIB=256 |
| LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB | number | Collector memory spike allowance in MiB. | # LANGFUSE_FANOUT_MEMORY_SPIKE_LIMIT_MIB=64 |
| LANGFUSE_FANOUT_BATCH_TIMEOUT | duration | Collector batch flush timeout. | # LANGFUSE_FANOUT_BATCH_TIMEOUT=1s |
| LANGFUSE_FANOUT_BATCH_SEND_SIZE | number | Collector batch send size. | # LANGFUSE_FANOUT_BATCH_SEND_SIZE=128 |
| LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT | number | Collector metadata cardinality limit. | # LANGFUSE_FANOUT_METADATA_CARDINALITY_LIMIT=1000 |
In a single-tenant deployment without complete LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY environment credentials, an authorized administrator can configure one encrypted connection under Settings → Langfuse. Complete environment credentials take precedence and hide that setting. Fanout deployments use the same setting for the tenant connection when fanout and tenant export are enabled.
LANGFUSE_BASE_URL is canonical. LANGFUSE_HOST and LANGFUSE_BASEURL remain compatibility aliases and are consulted in that order only when the canonical setting is absent.
OpenTelemetry Traces and Logs
LibreChat can emit backend OpenTelemetry traces for general API, HTTP, MongoDB, Mongoose, Redis, and outbound request visibility, and can export its Winston application logs as correlated OpenTelemetry log records. Traces and logs are independently opt-in; enabling logs alone does not install tracing instrumentation. Use Langfuse for GenAI-specific prompt/model observability.
| Key | Type | Description | Example |
|---|---|---|---|
| OTEL_TRACING_ENABLED | boolean | Enable backend OpenTelemetry tracing. Tracing remains disabled when OTEL_SDK_DISABLED=true. | # OTEL_TRACING_ENABLED=false |
| OTEL_LOGS_ENABLED | boolean | Export application logs through OpenTelemetry. Logs can be enabled with or without tracing and remain disabled when OTEL_SDK_DISABLED=true. | # OTEL_LOGS_ENABLED=false |
| OTEL_LOGS_LEVEL | string | Minimum Winston level exported as OpenTelemetry logs. Defaults to info; unknown levels warn and fall back to info. | # OTEL_LOGS_LEVEL=info |
| OTEL_SERVICE_NAME | string | Service name reported to OpenTelemetry. Default: librechat. | # OTEL_SERVICE_NAME=librechat |
| OTEL_SERVICE_VERSION | string | Service version reported to OpenTelemetry. Defaults to the package version when unset. | # OTEL_SERVICE_VERSION= |
| OTEL_EXPORTER_OTLP_ENDPOINT | string | Base OTLP exporter endpoint. | # OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 |
| OTEL_EXPORTER_OTLP_PROTOCOL | string | Default protocol for every OTLP signal: http/protobuf or grpc. Per-signal protocol variables override it. | # OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf |
| OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | string | Trace-specific OTLP endpoint. Overrides the base endpoint for traces when set. | # OTEL_EXPORTER_OTLP_TRACES_ENDPOINT= |
| OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | string | Log-specific OTLP endpoint. Overrides the base endpoint for logs when set. | # OTEL_EXPORTER_OTLP_LOGS_ENDPOINT= |
| OTEL_EXPORTER_OTLP_HEADERS | string | Comma-separated OTLP exporter headers, such as authorization metadata. | # OTEL_EXPORTER_OTLP_HEADERS= |
| OTEL_TRACES_EXPORTER | string | Trace exporter selection. | # OTEL_TRACES_EXPORTER=otlp |
| OTEL_LOGS_EXPORTER | string | Log exporter selection. | # OTEL_LOGS_EXPORTER=otlp |
| OTEL_TRACES_SAMPLER | string | OpenTelemetry trace sampler. Default example: parentbased_always_on. | # OTEL_TRACES_SAMPLER=parentbased_always_on |
| OTEL_LOG_LEVEL | string | OpenTelemetry SDK log level. | # OTEL_LOG_LEVEL=INFO |
| OTEL_SDK_DISABLED | boolean | Disable the OpenTelemetry SDK even if tracing is enabled. | # OTEL_SDK_DISABLED=false |
| OTEL_IOREDIS_TRACING_ENABLED | boolean | Enable Redis command-level spans. Disabled by default to keep backend traces high-level. | # OTEL_IOREDIS_TRACING_ENABLED=false |
Real User Monitoring (Browser)
LibreChat can publish browser Real User Monitoring (RUM) telemetry to HyperDX-compatible OTLP collectors. RUM is disabled by default.
| Key | Type | Description | Example |
|---|---|---|---|
| RUM_ENABLED | boolean | Enable browser Real User Monitoring. Default: false. | # RUM_ENABLED=false |
| RUM_PROVIDER | string | Browser RUM provider. Currently supports `hyperdx`. | # RUM_PROVIDER=hyperdx |
| RUM_URL | string | Public collector URL used by public-token mode. | # RUM_URL=http://localhost:4318 |
| RUM_SERVICE_NAME | string | Service name reported by the browser SDK. Default: librechat-web. | # RUM_SERVICE_NAME=librechat-web |
| RUM_ENVIRONMENT | string | Environment label reported with browser telemetry. | # RUM_ENVIRONMENT=development |
| RUM_AUTH_MODE | string | Authentication mode for browser telemetry. Use `publicToken` or `proxy`. | # RUM_AUTH_MODE=publicToken |
| RUM_PUBLIC_TOKEN | string | Public browser token for public-token mode. Treat this as public and restrict ingestion at the collector. | # RUM_PUBLIC_TOKEN= |
| RUM_PROXY_TARGET_URL | string | Collector base URL used by authenticated proxy mode. Required when `RUM_AUTH_MODE=proxy`. | # RUM_PROXY_TARGET_URL=http://otel-collector:4318 |
| RUM_PROXY_AUTHORIZATION | string | Optional server-only Authorization header forwarded by authenticated proxy mode. Provide the complete header value expected by the collector. | # RUM_PROXY_AUTHORIZATION= |
| RUM_PROXY_TIMEOUT_MS | number | Proxy request timeout in milliseconds. Default: 10000. | # RUM_PROXY_TIMEOUT_MS=10000 |
| RUM_PROXY_BODY_LIMIT | string | Maximum request body size accepted by the proxy, parsed only after authentication and rate limiting. Default: 3mb. | # RUM_PROXY_BODY_LIMIT=3mb |
| RUM_PROXY_USER_MAX | number | Maximum telemetry requests per authenticated user in RUM_PROXY_USER_WINDOW. Default: 240. | # RUM_PROXY_USER_MAX=240 |
| RUM_PROXY_USER_WINDOW | number | Window in minutes for RUM_PROXY_USER_MAX. Default: 1. | # RUM_PROXY_USER_WINDOW=1 |
| RUM_TRACE_PROPAGATION_TARGETS | string | Comma-separated first-party HTTPS origins or URLs that should receive traceparent headers. | # RUM_TRACE_PROPAGATION_TARGETS=https://api.example.com |
| RUM_SESSION_REPLAY_ENABLED | boolean | Enable browser session replay. Replay may collect sensitive prompts, responses, or payloads. A value set for telemetry.rum.sessionReplay.enabled in librechat.yaml takes precedence. Default: false. | # RUM_SESSION_REPLAY_ENABLED=false |
| RUM_DISABLE_REPLAY | boolean | Legacy switch for browser session replay, used only when RUM_SESSION_REPLAY_ENABLED is unset. Replay stays off unless this is explicitly set to false. Prefer RUM_SESSION_REPLAY_ENABLED. | # RUM_DISABLE_REPLAY=true |
| RUM_CLIENT_LOGS | boolean | Export browser client logger warnings and errors as OTLP logs. Applies only in proxy mode. Default: false. | # RUM_CLIENT_LOGS=false |
| RUM_CONSOLE_CAPTURE | boolean | Capture browser console logs. May collect sensitive prompts, responses, or payloads. | # RUM_CONSOLE_CAPTURE=false |
| RUM_ADVANCED_NETWORK_CAPTURE | boolean | Capture detailed network payloads. May collect sensitive prompts, responses, or payloads. | # RUM_ADVANCED_NETWORK_CAPTURE=false |
| RUM_SAMPLE_RATE | number | Browser telemetry sample rate from 0 to 1. Default: 1. | # RUM_SAMPLE_RATE=1 |
In publicToken mode, the browser sends telemetry directly to RUM_URL with RUM_PUBLIC_TOKEN. In proxy mode, the browser sends telemetry through LibreChat; the backend validates the user session, strips app authentication headers, and forwards telemetry to RUM_PROXY_TARGET_URL. RUM_PROXY_AUTHORIZATION can add a server-only credential to those exports; configure the final collector URL because authenticated redirects are rejected. Invalid or expired sessions are dropped with a 204 response so browser telemetry failures do not surface normal API authentication errors. Proxy outcomes are counted in rum_proxy_requests_total with endpoint and result labels on the LibreChat API /metrics endpoint.
For sampled page loads, LibreChat emits one page-load-diagnostics action when First Contentful Paint is observed. It includes navigation timing attribution such as time to first byte, first-byte-to-FCP time, service-worker timing, navigation type, and a normalized route instead of raw conversation IDs. RUM also records early page lifecycle, service-worker, stale-asset recovery, and single-page-app route-change events. Diagnostics are best-effort and never delay startup or trigger recovery behavior; early events are discarded when the page is not sampled.
Configuration Path - librechat.yaml
Specify an alternative location for the LibreChat configuration file.
You may specify an absolute path, a relative path, or a URL. The filename in the path is flexible and does not have to be librechat.yaml; any valid configuration file will work.
Note: If you prefer LibreChat to search for the configuration file in the root directory (which is the default behavior), simply leave this option commented out.
| Key | Type | Description | Example |
|---|---|---|---|
| CONFIG_PATH | string | An alternative location for the LibreChat configuration file. | # CONFIG_PATH=https://raw.githubusercontent.com/LibreChat-AI/LibreChat/main/librechat.example.yaml |
Deployment Skills
Deployment Skills are loaded read-only at startup from the filesystem and exposed to users who have the Skills capability enabled.
| Key | Type | Description | Example |
|---|---|---|---|
| DEPLOYMENT_SKILLS_DIR | string | Directory containing deployment-provided Skills. Defaults to `./skill` at the project root. | # DEPLOYMENT_SKILLS_DIR=./skill |
Restart LibreChat after changing this directory or any files inside it. Deployment-provided Skills take precedence over persisted Skills with the same name.
Agent Plugins (Experimental)
LibreChat can load experimental Agent Plugins from immediate child directories at startup. A plugin can bundle deployment Skills, MCP servers, and optional command hooks.
| Key | Type | Description | Example |
|---|---|---|---|
| DEPLOYMENT_PLUGINS_DIR | string | Directory containing Agent Plugin packages. Defaults to `./plugin` at the project root. | # DEPLOYMENT_PLUGINS_DIR=./plugin |
| DEPLOYMENT_PLUGIN_DATA_DIR | string | Persistent data root for Agent Plugins. Defaults to `./data/plugins` at the project root. | # DEPLOYMENT_PLUGIN_DATA_DIR=./data/plugins |
| DEPLOYMENT_PLUGIN_HOOKS | boolean | Runs trusted `command` handlers declared in `ai.librechat/hooks/hooks.json`. Disabled by default. Commands execute as child processes on the API host. | # DEPLOYMENT_PLUGIN_HOOKS=true |
See Agent Plugins for package layout, schema versions, supported components, precedence, and current limitations.
Configuration Validation
By default, LibreChat will exit with an error (exit code 1) if the librechat.yaml configuration file contains validation errors. This fail-fast behavior helps catch configuration issues early in deployment pipelines and prevents running with unintended default settings.
| Key | Type | Description | Example |
|---|---|---|---|
| CONFIG_BYPASS_VALIDATION | boolean | When set to `true`, the server will log a warning and continue starting with default configuration even if `librechat.yaml` has validation errors. This preserves the legacy behavior. | # CONFIG_BYPASS_VALIDATION=true |
Warning
Using CONFIG_BYPASS_VALIDATION=true is not recommended for production environments. It is
intended as a temporary workaround while debugging configuration issues. Always fix validation
errors in your configuration file.
Uncaught Exception Handling
By default, LibreChat will exit the process when an uncaught exception occurs, which is the standard Node.js behavior. You can override this to keep the app running after uncaught exceptions.
| Key | Type | Description | Example |
|---|---|---|---|
| CONTINUE_ON_UNCAUGHT_EXCEPTION | boolean | When set to `true`, the app will continue running after encountering uncaught exceptions instead of exiting the process. | # CONTINUE_ON_UNCAUGHT_EXCEPTION=false |
Warning
Not recommended for production unless necessary. Uncaught exceptions may leave the application in an unpredictable state.
Endpoints
In this section, you can configure the endpoints and models selection, their API keys, and the proxy and reverse proxy settings for the endpoints that support it.
General Config
Uncomment ENDPOINTS to customize the available endpoints in LibreChat.
| Key | Type | Description | Example |
|---|---|---|---|
| ENDPOINTS | string | Comma-separated list of available endpoints. | # ENDPOINTS=openAI,assistants,azureOpenAI,google,anthropic |
| PROXY | string | Outbound proxy for supported server-side clients. Applies to both HTTP and HTTPS targets. | PROXY= |
| HTTP_PROXY | string | HTTP proxy fallback used by supported server-side clients when PROXY is unset. | # HTTP_PROXY= |
| HTTPS_PROXY | string | HTTPS proxy fallback used by supported server-side clients when PROXY is unset. | # HTTPS_PROXY= |
| NO_PROXY | string | Comma-separated hosts, domains, or IP ranges that supported server-side clients should bypass. The lowercase no_proxy variant is also honored. | # NO_PROXY= |
| TITLE_CONVO | boolean | Enable titling for all endpoints. | TITLE_CONVO=true |
Known Endpoints - librechat.yaml
- see also: Custom Endpoints & Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| ANYSCALE_API_KEY | string | API key for Anyscale. | # ANYSCALE_API_KEY= |
| APIPIE_API_KEY | string | API key for Apipie. | # APIPIE_API_KEY= |
| COHERE_API_KEY | string | API key for Cohere. | # COHERE_API_KEY= |
| FIREWORKS_API_KEY | string | API key for Fireworks. | # FIREWORKS_API_KEY= |
| GROQ_API_KEY | string | API key for Groq. | # GROQ_API_KEY= |
| MISTRAL_API_KEY | string | API key for Mistral. | # MISTRAL_API_KEY= |
| OPENROUTER_KEY | string | API key for OpenRouter. | # OPENROUTER_KEY= |
| PERPLEXITY_API_KEY | string | API key for Perplexity. | # PERPLEXITY_API_KEY= |
| SHUTTLEAI_API_KEY | string | API key for ShuttleAI. | # SHUTTLEAI_API_KEY= |
| TOGETHERAI_API_KEY | string | API key for TogetherAI. | # TOGETHERAI_API_KEY= |
| DEEPSEEK_API_KEY | string | API key for Deepseek API | # DEEPSEEK_API_KEY= |
Web Search
The web search feature enables internet search capabilities within LibreChat.
Important: The exact environment variable names shown below are default references and can be customized through the librechat.yaml configuration file to use any variable names you prefer.
For detailed configuration and customization options, see: Web Search Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| SERPER_API_KEY | string | API key for Serper search provider. Get your key from https://serper.dev/api-keys | # SERPER_API_KEY= |
| SEARXNG_INSTANCE_URL | string | URL of your SearXNG instance, as a base URL such as http://searxng:8080, not a bare hostname. | # SEARXNG_INSTANCE_URL= |
| SEARXNG_API_KEY | string | API key for your SearXNG instance. Only needed if the instance requires authentication. | # SEARXNG_API_KEY= |
| TAVILY_API_KEY | string | API key for Tavily search and scraper provider. Get your key from https://app.tavily.com/home | # TAVILY_API_KEY= |
| TAVILY_SEARCH_URL | string | Custom Tavily Search API URL (optional), as a full endpoint URL. Only needed for custom or proxy Tavily-compatible search endpoints. | # TAVILY_SEARCH_URL= |
| TAVILY_EXTRACT_URL | string | Custom Tavily Extract API URL (optional), as a full endpoint URL. Only needed for custom or proxy Tavily-compatible extract endpoints. | # TAVILY_EXTRACT_URL= |
| KEENABLE_API_KEY | string | Optional Keenable API key for search and page fetch. Public endpoints work keyless; a key raises their rate limits. | # KEENABLE_API_KEY= |
| KEENABLE_API_URL | string | Optional custom Keenable search API URL, as a full endpoint URL. | # KEENABLE_API_URL= |
| KEENABLE_FETCH_URL | string | Optional custom Keenable page-fetch API URL used when scraperProvider is keenable, as a full endpoint URL. | # KEENABLE_FETCH_URL= |
| FIRECRAWL_API_KEY | string | API key for Firecrawl scraper service. Get your key from https://docs.firecrawl.dev/introduction#api-key | # FIRECRAWL_API_KEY= |
| FIRECRAWL_API_URL | string | Custom Firecrawl API URL (optional), as a base URL without the version, such as http://firecrawl:3002. Only needed for custom Firecrawl instances. | # FIRECRAWL_API_URL= |
| FIRECRAWL_VERSION | string | Firecrawl API version, used as a path segment of the request URL. Defaults to v2 when unset. | # FIRECRAWL_VERSION=v2 |
| JINA_API_KEY | string | API key for Jina reranker service. Get your key from https://jina.ai/api-dashboard/ | # JINA_API_KEY= |
| JINA_API_URL | string | Custom Jina API URL (optional), as a full endpoint URL. Only needed for custom Jina instances. | # JINA_API_URL= |
| COHERE_API_KEY | string | API key for Cohere reranker service. Get your key from https://dashboard.cohere.com/welcome/login | # COHERE_API_KEY= |
| COHERE_API_URL | string | Custom Cohere rerank API URL (optional), as a full endpoint URL. Environment only. | # COHERE_API_URL= |
Note: Most variable names can be customized in your librechat.yaml configuration file. For example, you could use CUSTOM_SERPER_KEY instead of SERPER_API_KEY by configuring it in the web search settings. KEENABLE_FETCH_URL and COHERE_API_URL are environment-only. See the Web Search Configuration documentation for details, and URL Formats for what each URL variable expects.
Anthropic
see: Anthropic Endpoint
- You can request an access key from https://platform.claude.com/
- Leave
ANTHROPIC_API_KEY=blank to disable this endpoint - Set
ANTHROPIC_API_KEY=to "user_provided" to allow users to provide their own API key from the WebUI - If you have access to a reverse proxy for
Anthropic, you can set it withANTHROPIC_REVERSE_PROXY=- leave blank or comment it out to use default base url
| Key | Type | Description | Example |
|---|---|---|---|
| ANTHROPIC_API_KEY | string | Anthropic API key or "user_provided" to allow users to provide their own API key. | Defaults to an empty string. |
| ANTHROPIC_MODELS | string | Comma-separated list of Anthropic models to use. | # ANTHROPIC_MODELS=claude-fable-5-1,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 | string | Reverse proxy for Anthropic. | # ANTHROPIC_REVERSE_PROXY= |
| ANTHROPIC_VERSION | string | Value of the anthropic-version header sent when fetching the Anthropic model list. Default: 2023-06-01. | # ANTHROPIC_VERSION=2023-06-01 |
Claude Fable 5.1 and Fable 5 are included in the default Anthropic model list. Fable/Mythos-class
models use the modern Anthropic behavior in LibreChat: 1M context, adaptive thinking
support, prompt caching support, and thinkingDisplay handling for summarized or
omitted reasoning output.
Anthropic via Vertex AI
You can also use Anthropic Claude models through Google Cloud Vertex AI. For detailed YAML configuration options, see: Anthropic Vertex AI Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| ANTHROPIC_USE_VERTEX | boolean | Set to true to use Anthropic models through Google Vertex AI instead of direct API. | ANTHROPIC_USE_VERTEX=true |
| ANTHROPIC_VERTEX_REGION | string | The Google Cloud location for Vertex AI. Default: us-east5. Use global, us, or eu for Opus 4.7+, Opus 5, Sonnet 5, and Fable/Mythos 5. | ANTHROPIC_VERTEX_REGION=global |
Note: When using Vertex AI, you must also configure
GOOGLE_SERVICE_KEY_FILE(see Google Configuration) with a service account that has theVertex AI Userrole.
AWS Bedrock
See: AWS Bedrock Setup
| Key | Type | Description | Example |
|---|---|---|---|
| BEDROCK_AWS_DEFAULT_REGION | string | A default AWS region must be provided for Bedrock. | BEDROCK_AWS_DEFAULT_REGION=us-east-1 |
| BEDROCK_AWS_ACCESS_KEY_ID | string | AWS access key ID for Bedrock. Optional if using default AWS credentials chain. | # BEDROCK_AWS_ACCESS_KEY_ID=your_access_key_id |
| BEDROCK_AWS_SECRET_ACCESS_KEY | string | AWS secret access key for Bedrock. Optional if using default AWS credentials chain. | # BEDROCK_AWS_SECRET_ACCESS_KEY=your_secret_access_key |
| BEDROCK_AWS_SESSION_TOKEN | string | AWS session token for temporary credentials. Optional. | # BEDROCK_AWS_SESSION_TOKEN=your_session_token |
| BEDROCK_AWS_PROFILE | string | AWS shared config profile name for Bedrock. Optional if using the default AWS credentials chain. | # BEDROCK_AWS_PROFILE=your-profile-name |
| BEDROCK_AWS_BEARER_TOKEN | string | Amazon Bedrock API key for bearer auth, or user_provided to let users enter their own Bedrock API key in the UI. | # BEDROCK_AWS_BEARER_TOKEN=your_bedrock_api_key |
| BEDROCK_REVERSE_PROXY | string | Host of a reverse proxy for Bedrock API calls, without the https:// scheme. Works with or without PROXY. | # BEDROCK_REVERSE_PROXY=bedrock-proxy.example.com |
| BEDROCK_AWS_MODELS | string | Comma-separated list of Bedrock model IDs. If omitted, all known supported models are included. | # BEDROCK_AWS_MODELS=global.anthropic.claude-fable-5-1,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 |
Note: You can omit the access keys to use the default AWS credentials chain (environment variables, SSO credentials, shared credentials files, or EC2/ECS Instance Metadata Service). See AWS Bedrock Setup for more details.
Claude Fable/Mythos-class models on Bedrock are inference-profile only. Use a profile
ID such as global.anthropic.claude-fable-5-1, and enable the required Anthropic data
sharing setting in the Bedrock console or Data Retention API before invoking them.
Follow these instructions to setup the Google Endpoint
| Key | Type | Description | Example |
|---|---|---|---|
| GOOGLE_KEY | string | Google API key. Set to "user_provided" to allow users to provide their own API key from the WebUI. | GOOGLE_KEY=user_provided |
| GOOGLE_SERVICE_KEY_FILE | string | Path to Google service account JSON key file, URL to fetch it from, or stringified JSON. Used for Vertex AI authentication (e.g., OCR features). | GOOGLE_SERVICE_KEY_FILE=/path/to/service-account.json |
| GOOGLE_CLOUD_PROJECT | string | Google Cloud project ID for Vertex AI. Checked after VERTEX_PROJECT_ID; GCLOUD_PROJECT and GOOGLE_PROJECT_ID are used as further fallbacks, in that order. | # GOOGLE_CLOUD_PROJECT=your-project-id |
| GOOGLE_REVERSE_PROXY | string | Google reverse proxy URL. | GOOGLE_REVERSE_PROXY= |
| GOOGLE_AUTH_HEADER | boolean | Use Authorization header instead of X-goog-api-key. Some reverse proxies require this. | # GOOGLE_AUTH_HEADER=true |
| GOOGLE_MODELS | string | Available Gemini API Google models, separated by commas. | GOOGLE_MODELS=gemini-4-argon,gemini-3.8-flash,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 |
| GOOGLE_MODELS | string | Available Vertex AI Google models, separated by commas. | GOOGLE_MODELS=gemini-4-argon,gemini-3.8-flash,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 | string | DEPRECATED: The model used for titling with Google. | GOOGLE_TITLE_MODEL=gemini-2.0-flash-lite-001 |
| GOOGLE_LOC | string | Specifies the Google Cloud location for processing API requests | GOOGLE_LOC=us-central1 |
| GOOGLE_CLOUD_LOCATION | string | Alternative region for Gemini Image Generation (e.g., global). | # GOOGLE_CLOUD_LOCATION=global |
| GOOGLE_EXCLUDE_SAFETY_SETTINGS | string | Completely omit the safety settings that are included by default, which will use provider defaults | GOOGLE_EXCLUDE_SAFETY_SETTINGS=true |
| GOOGLE_SAFETY_SEXUALLY_EXPLICIT | string | Safety setting for sexually explicit content. Options are BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, and BLOCK_LOW_AND_ABOVE. | GOOGLE_SAFETY_SEXUALLY_EXPLICIT=BLOCK_ONLY_HIGH |
| GOOGLE_SAFETY_HATE_SPEECH | string | Safety setting for hate speech content. Options are BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, and BLOCK_LOW_AND_ABOVE. | GOOGLE_SAFETY_HATE_SPEECH=BLOCK_ONLY_HIGH |
| GOOGLE_SAFETY_HARASSMENT | string | Safety setting for harassment content. Options are BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, and BLOCK_LOW_AND_ABOVE. | GOOGLE_SAFETY_HARASSMENT=BLOCK_ONLY_HIGH |
| GOOGLE_SAFETY_DANGEROUS_CONTENT | string | Safety setting for dangerous content. Options are BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, and BLOCK_LOW_AND_ABOVE. | GOOGLE_SAFETY_DANGEROUS_CONTENT=BLOCK_ONLY_HIGH |
| GOOGLE_SAFETY_CIVIC_INTEGRITY | string | Safety setting for civic integrity content. Options are BLOCK_NONE, BLOCK_ONLY_HIGH, BLOCK_MEDIUM_AND_ABOVE, and BLOCK_LOW_AND_ABOVE. | # GOOGLE_SAFETY_CIVIC_INTEGRITY=BLOCK_ONLY_HIGH |
Customize the available models, separated by commas, without spaces. The first will be default. Leave it blank or commented out to use internal settings.
When a GOOGLE_SAFETY_* variable is unset, the provider default is used (BLOCK_NONE for civic integrity), and Gemini 2.0, gemini-1.5-flash-8b, experimental, and LearnLM models receive BLOCK_NONE. Set GOOGLE_EXCLUDE_SAFETY_SETTINGS=true to omit safety settings entirely.
GOOGLE_TITLE_MODELis now deprecated and will be removed in future versions. Use thetitleModelEndpoint Setting instead in thelibrechat.yamlconfig instead.
Note: For the Vertex AI GOOGLE_SAFETY variables, you do not have access to the BLOCK_NONE setting by default. To use this restricted HarmBlockThreshold setting, you will need to either:
- (a) Get access through an allowlist via your Google account team
- (b) Switch your account type to monthly invoiced billing following this instruction: https://cloud.google.com/billing/docs/how-to/invoiced-billing
Gemini Image Generation
Gemini Image Generation is a tool for Agents that supports both the Gemini API and Vertex AI. See: Gemini Image Generation
| Key | Type | Description | Example |
|---|---|---|---|
| GEMINI_API_KEY | string | Dedicated Gemini API key for image generation. Falls back to GOOGLE_KEY if not set. | # GEMINI_API_KEY=your_gemini_api_key |
| GEMINI_IMAGE_MODEL | string | Gemini model for image generation. Default: gemini-2.5-flash-image. | # GEMINI_IMAGE_MODEL=gemini-2.5-flash-image |
Note: When no API key is configured, the tool automatically falls back to Vertex AI using the service account from
GOOGLE_SERVICE_KEY_FILE. The service account must have theVertex AI Userrole.
OpenAI
See: OpenAI Setup
| Key | Type | Description | Example |
|---|---|---|---|
| OPENAI_API_KEY | string | Your OpenAI API key. Leave blank to disable this endpoint or set to "user_provided" to allow users to provide their own API key from the WebUI. | OPENAI_API_KEY=user_provided |
| OPENAI_MODELS | string | Customize the available models, separated by commas, without spaces. The first will be default. Leave commented out to use internal settings. | # OPENAI_MODELS=gpt-6-astra,gpt-6.1-sol,gpt-6-sol,gpt-6-luna,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 | boolean | Enable debug mode for the OpenAI endpoint. | DEBUG_OPENAI=false |
| OPENAI_SUMMARIZE | boolean | Enable message summarization. False by default | # OPENAI_SUMMARIZE=true |
| OPENAI_SUMMARY_MODEL | string | The model used for OpenAI summarization. | # OPENAI_SUMMARY_MODEL=gpt-4o-mini |
| OPENAI_FORCE_PROMPT | boolean | Force the API to be called with a prompt payload instead of a messages payload. | # OPENAI_FORCE_PROMPT=false |
| OPENAI_ORGANIZATION | string | Specify which organization to use for each API request to OpenAI. Optional | # OPENAI_ORGANIZATION= |
| OPENAI_REVERSE_PROXY | string | DEPRECATED: Reverse proxy settings for OpenAI. | # OPENAI_REVERSE_PROXY= |
| OPENAI_TITLE_MODEL | string | DEPRECATED: The model used for OpenAI titling. | # OPENAI_TITLE_MODEL=gpt-4o-mini |
OPENAI_TITLE_MODELis now deprecated and will be removed in future versions. Use thetitleModelEndpoint Setting instead in thelibrechat.yamlconfig instead.OPENAI_REVERSE_PROXYis now deprecated and will be removed in future versions. Use a custom endpoint instead.
Assistants
See: Assistants Setup
| Key | Type | Description | Example |
|---|---|---|---|
| ASSISTANTS_API_KEY | string | Your OpenAI API key for Assistants API. Leave blank to disable this endpoint or set to "user_provided" to allow users to provide their own API key from the WebUI. | ASSISTANTS_API_KEY=user_provided |
| ASSISTANTS_MODELS | string | Customize the available models, separated by commas, without spaces. The first will be default. Leave blank to use internal settings. | # 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 |
| ASSISTANTS_BASE_URL | string | Alternate base URL for Assistants API. | # ASSISTANTS_BASE_URL= |
Note: You can customize the available models, separated by commas, without spaces. The first will be default. Leave it blank or commented out to use internal settings.
Legacy Azure OpenAI Variables (deprecated)
These variables configure a single Azure OpenAI deployment without librechat.yaml. They are deprecated. Use the Azure OpenAI configuration in librechat.yaml instead, which supports multiple groups, models, and deployments.
| Key | Type | Description | Example |
|---|---|---|---|
| AZURE_API_KEY | string | Azure OpenAI API key. AZURE_OPENAI_API_KEY is read when this is unset. Set to user_provided to let users enter their own key. | # AZURE_API_KEY= |
| AZURE_OPENAI_API_INSTANCE_NAME | string | Azure OpenAI resource (instance) name. | # AZURE_OPENAI_API_INSTANCE_NAME= |
| AZURE_OPENAI_API_DEPLOYMENT_NAME | string | Azure OpenAI deployment name. | # AZURE_OPENAI_API_DEPLOYMENT_NAME= |
| AZURE_OPENAI_API_VERSION | string | Azure OpenAI API version. | # AZURE_OPENAI_API_VERSION= |
| AZURE_OPENAI_BASEURL | string | Custom base URL for the Azure OpenAI endpoint. | # AZURE_OPENAI_BASEURL= |
| AZURE_OPENAI_DEFAULT_MODEL | string | Default model for the Azure OpenAI endpoint. | # AZURE_OPENAI_DEFAULT_MODEL=gpt-3.5-turbo |
| AZURE_USE_MODEL_AS_DEPLOYMENT_NAME | boolean | Use the selected model name as the deployment name. | # AZURE_USE_MODEL_AS_DEPLOYMENT_NAME=TRUE |
| AZURE_OPENAI_MODELS | string | Comma-separated list of Azure OpenAI models, without spaces. | # AZURE_OPENAI_MODELS=gpt-3.5-turbo,gpt-4 |
| AZURE_ASSISTANTS_API_KEY | string | API key for the Azure Assistants endpoint. Set to user_provided to let users enter their own key. | # AZURE_ASSISTANTS_API_KEY= |
| AZURE_ASSISTANTS_BASE_URL | string | Base URL for the Azure Assistants endpoint. | # AZURE_ASSISTANTS_BASE_URL= |
Tavily
Get your API key here: https://tavily.com/#api
Environment Variables:
| Key | Type | Description | Example |
|---|---|---|---|
| TAVILY_API_KEY | string | Tavily API key. | TAVILY_API_KEY= |
Traversaal
Description: LLM-enhanced search tool.
Get API key here: https://api.traversaal.ai/dashboard
Environment Variables:
| Key | Type | Description | Example |
|---|---|---|---|
| TRAVERSAAL_API_KEY | string | Traversaal API key. | TRAVERSAAL_API_KEY= |
WolframAlpha
See detailed instructions here: Wolfram Alpha
Environment Variables:
| Key | Type | Description | Example |
|---|---|---|---|
| WOLFRAM_APP_ID | string | Wolfram Alpha App ID. | WOLFRAM_APP_ID= |
Zapier
Description: - You need a Zapier account. Get your API key from here: Zapier
- Create allowed actions - Follow step 3 in this getting start guide from Zapier
Note: Zapier is known to be finicky with certain actions. Writing email drafts is probably the best use of it.
Environment Variables:
| Key | Type | Description | Example |
|---|---|---|---|
| ZAPIER_NLA_API_KEY | string | Zapier NLA API key. | ZAPIER_NLA_API_KEY= |
OpenWeather
See detailed instructions here: OpenWeather
| Key | Type | Description | Example |
|---|---|---|---|
| OPENWEATHER_API_KEY | string | OpenWeather API key for the One Call API 3.0. | OPENWEATHER_API_KEY= |
File Uploads
| Key | Type | Description | Example |
|---|---|---|---|
| FILE_UPLOAD_SSE_ENABLED | boolean | Stream upload responses with heartbeat events during long-running file processing. Default: false. | # FILE_UPLOAD_SSE_ENABLED=false |
| REMOTE_FILE_FETCH_TIMEOUT_MS | number | Timeout in milliseconds for server-side remote file downloads. Default: 15000. | # REMOTE_FILE_FETCH_TIMEOUT_MS=15000 |
| REMOTE_FILE_FETCH_MAX_BYTES | number | Maximum size in bytes for server-side remote file downloads. Default: 536870912 (512 MiB). | # REMOTE_FILE_FETCH_MAX_BYTES=536870912 |
| FILE_RETENTION_SWEEP_INTERVAL_MS | number | Interval in milliseconds between sweeps that delete expired files. Set to 0 to disable the sweep. Default: 3600000 (1 hour). | # FILE_RETENTION_SWEEP_INTERVAL_MS=3600000 |
| FILE_RETENTION_SWEEP_MAX_ATTEMPTS | number | Consecutive failed deletions after which an expired file is parked for 30 days instead of retried on the normal backoff. Lower it when working through a large backlog. Default: 10. | # FILE_RETENTION_SWEEP_MAX_ATTEMPTS=10 |
With FILE_UPLOAD_SSE_ENABLED=true, clients that request text/event-stream receive one-second heartbeat events while upload processing is still running, followed by a data or error event and a final close event. Clients that do not request SSE continue to receive the normal JSON response. This is useful when a reverse proxy would otherwise close an idle connection during long OCR, parsing, or RAG work.
The remote fetch controls apply when LibreChat ingests an HTTP or HTTPS file URL into local, Firebase, Azure, or S3/CloudFront storage. LibreChat checks both a declared Content-Length and the bytes actually streamed, so the limit still applies when the remote server omits or misstates its length. These controls are independent of the per-upload limits in fileConfig.
Code Interpreter
The Code Interpreter API provides a secure environment for executing code and managing files. See: Code Interpreter API. For setup, see Code Interpreter configuration.
| Key | Type | Description | Example |
|---|---|---|---|
| LIBRECHAT_CODE_API_KEY | string | API key for the Code Interpreter service. When set globally, provides access to all users. | LIBRECHAT_CODE_API_KEY=your-api-key |
| CODE_ENVIRONMENT_DECISION_VERSION | number | Controls the immutable, conversation-owned Code-environment decision protocol (version 1), which is advertised by default and which per-chat machine choice depends on. Set to 0 to keep the legacy path, for example while API replicas that predate protocol version 1 are still running. 0 also turns off per-chat machine choice, so every agent stays on its fixed machine. | # CODE_ENVIRONMENT_DECISION_VERSION=0 |
| LIBRECHAT_CODE_BASEURL | string | Base URL for the normal stateless Code Interpreter service. | # LIBRECHAT_CODE_BASEURL=https://your-custom-domain.com |
| LIBRECHAT_CODE_BASEURL_STATEFUL | string | Default Code Interpreter base URL for highly experimental stateful Agent sessions when no named statefulCodeSessions environment is selected. The service must advertise the stateful profile. | # LIBRECHAT_CODE_BASEURL_STATEFUL=https://your-stateful-code-domain.com |
| CODE_SANDBOX_PREWARM | boolean | Prewarm selected stateful sandboxes in parallel with model generation. Set to false to disable. Default: true. | # CODE_SANDBOX_PREWARM=true |
| CODE_SANDBOX_COLD_AFTER_MS | number | Time in milliseconds before LibreChat treats a tracked sandbox as cold. Default: 2100000 (35 minutes). | # CODE_SANDBOX_COLD_AFTER_MS=2100000 |
| LIBRECHAT_CODE_SANDBOX_OUTPUT_MAX_SIZE | number | Sandbox stdout budget in bytes used to derive image-read window sizes. Match the runner's SANDBOX_OUTPUT_MAX_SIZE to minimize execution round trips. Default: 65536. | # LIBRECHAT_CODE_SANDBOX_OUTPUT_MAX_SIZE=65536 |
| LIBRECHAT_CODE_IMAGE_CHUNK_BYTES | number | Exact bytes read per sandbox image window. Overrides the size derived from LIBRECHAT_CODE_SANDBOX_OUTPUT_MAX_SIZE; leave unset unless an exact override is required. | # LIBRECHAT_CODE_IMAGE_CHUNK_BYTES= |
| CODE_ENVIRONMENT_PAIRING_USER_MAX | number | Maximum self-service code-worker pairing requests per user during one rate-limit window. Default: 5. | # CODE_ENVIRONMENT_PAIRING_USER_MAX=5 |
| CODE_ENVIRONMENT_PAIRING_USER_WINDOW | number | Self-service code-worker pairing rate-limit window in minutes. Default: 60. | # CODE_ENVIRONMENT_PAIRING_USER_WINDOW=60 |
| CODE_ENVIRONMENT_STATUS_USER_MAX | number | Maximum code environment status requests per user in CODE_ENVIRONMENT_STATUS_USER_WINDOW. Default: 120. | # CODE_ENVIRONMENT_STATUS_USER_MAX=120 |
| CODE_ENVIRONMENT_STATUS_USER_WINDOW | number | Window in minutes for CODE_ENVIRONMENT_STATUS_USER_MAX. Default: 1. | # CODE_ENVIRONMENT_STATUS_USER_WINDOW=1 |
| CODE_ENVIRONMENT_STATUS_IP_MAX | number | Maximum code environment status requests per IP in CODE_ENVIRONMENT_STATUS_IP_WINDOW. Default: 300. | # CODE_ENVIRONMENT_STATUS_IP_MAX=300 |
| CODE_ENVIRONMENT_STATUS_IP_WINDOW | number | Window in minutes for CODE_ENVIRONMENT_STATUS_IP_MAX. Default: 1. | # CODE_ENVIRONMENT_STATUS_IP_WINDOW=1 |
If a worker has a smaller stdout cap than configured, LibreChat narrows and remembers the image window for that Code Interpreter base URL after a failed read. Matching the two budgets avoids that discarded discovery request and reduces pressure on the Code Interpreter execution rate limit.
Code Interpreter JWT Authentication
The current self-hosted ClickHouse/code-interpreter service verifies short-lived LibreChat bearer tokens outside local mode. Set CODEAPI_AUTH_PROVIDER=librechat-jwt to enable token minting, then give Code Interpreter the public key that matches LibreChat's private signer. See Self-hosted JWT authentication for the paired service configuration and key-generation helper.
| Key | Type | Description | Example |
|---|---|---|---|
| CODEAPI_AUTH_PROVIDER | string | Set to librechat-jwt to mint per-user Code Interpreter bearer tokens. The compatibility value both also enables minting, but ClickHouse/code-interpreter expects librechat-jwt. | # CODEAPI_AUTH_PROVIDER=librechat-jwt |
| CODEAPI_JWT_ENABLED | boolean | Explicitly enables Code Interpreter JWT minting when CODEAPI_AUTH_PROVIDER is not librechat-jwt or both. Default: false. | # CODEAPI_JWT_ENABLED=true |
| CODEAPI_JWT_PRIVATE_KEY | string | Ed25519 or RSA private signing key in PEM format. Escaped \n sequences are converted to newlines. | # CODEAPI_JWT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..." |
| CODEAPI_JWT_PRIVATE_KEY_BASE64 | string | Base64-encoded PEM private key. Used when CODEAPI_JWT_PRIVATE_KEY is unset. | # CODEAPI_JWT_PRIVATE_KEY_BASE64= |
| CODEAPI_JWT_PRIVATE_JWK_JSON | string | Private signing key as JWK JSON. Used when both PEM settings are unset. | # CODEAPI_JWT_PRIVATE_JWK_JSON={"kty":"OKP",...} |
| CODEAPI_JWT_ALGORITHM | string | Signing algorithm: EdDSA or RS256. Default: EdDSA. | # CODEAPI_JWT_ALGORITHM=EdDSA |
| CODEAPI_JWT_KID | string | Signing-key ID included in the token header. Must identify the matching Code Interpreter verifier key. Default: lc-codeapi-2026-05. | # CODEAPI_JWT_KID=lc-codeapi-2026-05 |
| CODEAPI_JWT_ISSUER | string | Token issuer; must match Code Interpreter. Default: librechat. | # CODEAPI_JWT_ISSUER=librechat |
| CODEAPI_JWT_AUDIENCE | string | Token audience; must match Code Interpreter. Default: codeapi. | # CODEAPI_JWT_AUDIENCE=codeapi |
| CODEAPI_JWT_TTL_SECONDS | number | Bearer-token lifetime in seconds. Invalid or larger values resolve to the 300-second default and maximum. | # CODEAPI_JWT_TTL_SECONDS=300 |
| CODEAPI_JWT_MINT_CACHE_SECONDS | number | How long LibreChat can reuse a token for the same authenticated context. Default and maximum: 30 seconds. | # CODEAPI_JWT_MINT_CACHE_SECONDS=30 |
| CODEAPI_JWT_SINGLE_TENANT_ID | string | Fallback tenant ID when strict tenant isolation is disabled and no tenant context is available. Must match Code Interpreter. Default: legacy. | # CODEAPI_JWT_SINGLE_TENANT_ID=legacy |
At least one private-key source is required when JWT minting is enabled. If more than one is set, LibreChat checks CODEAPI_JWT_PRIVATE_KEY, then CODEAPI_JWT_PRIVATE_KEY_BASE64, then CODEAPI_JWT_PRIVATE_JWK_JSON. CODEAPI_JWT_KEY_ID remains a compatibility alias for CODEAPI_JWT_KID.
For a multi-tenant deployment, enable TENANT_ISOLATION_STRICT=true in LibreChat and CODEAPI_TENANT_ISOLATION_STRICT=true in Code Interpreter. Requests without authenticated tenant context then fail instead of using CODEAPI_JWT_SINGLE_TENANT_ID.
Stateful Code Interpreter Endpoint
stateful_code_sessions is highly experimental and requires a separate Code Interpreter route. Configure the default route with LIBRECHAT_CODE_BASEURL_STATEFUL, or define named managed or attached backends under endpoints.agents.statefulCodeSessions.environments. The selected service must run the stateful profile; LibreChat sends X-CodeAPI-Expected-Profile: stateful with stateful requests.
Stateful requests never fall back to LIBRECHAT_CODE_BASEURL. If the selected named environment is unavailable, or neither a named default nor LIBRECHAT_CODE_BASEURL_STATEFUL is configured, LibreChat stops the Agent run with a configuration error. Stateless agents continue using LIBRECHAT_CODE_BASEURL, and the two execution profiles do not share a live workspace.
Each Agent can scope its stateful workspace to the signed-in user, the user and Agent together, or the user and conversation. See Stateful Code Sessions for setup and persistence limitations.
Named attached environments can also expose a self-service pairing control plane with pairing.allowPrincipalWorkers: true. Authorized users manage those owner-bound workers under Settings > Code environments; pairing-only entries do not replace LIBRECHAT_CODE_BASEURL_STATEFUL and cannot serve as the deployment default.
Conversation Pull Requests
Settings for showing a conversation's pull request from GitHub, GitLab or Bitbucket Cloud. See Conversation Pull Requests and endpoints.agents.pullRequests.
The fallback variables are used only when pullRequests.token is not set, and only those of the configured provider are read, in the order listed. Set them on the LibreChat server.
| Key | Type | Description | Example |
|---|---|---|---|
| GITHUB_PULL_REQUEST_TOKEN | string | Fallback read-only GitHub token. Tried first on GitHub. | # GITHUB_PULL_REQUEST_TOKEN=your-read-only-token |
| GITHUB_TOKEN | string | Fallback GitHub token, tried second. It is a common name: if your deployment already uses it for something else, the fallback starts using it here as soon as a repository scope is set. | # GITHUB_TOKEN=your-read-only-token |
| GH_TOKEN | string | Fallback GitHub token, tried third. | # GH_TOKEN=your-read-only-token |
| GITLAB_PULL_REQUEST_TOKEN | string | Fallback GitLab token with the `read_api` scope. Tried first on GitLab. | # GITLAB_PULL_REQUEST_TOKEN=your-read-api-token |
| GITLAB_TOKEN | string | Fallback GitLab token, tried second. Also a common name; see `GITHUB_TOKEN`. | # GITLAB_TOKEN=your-read-api-token |
| BITBUCKET_PULL_REQUEST_TOKEN | string | Fallback Bitbucket Cloud repository, project or workspace access token with read access to pull requests and repositories. | # BITBUCKET_PULL_REQUEST_TOKEN=your-read-only-token |
| Any name you choose | string | The variable that `pullRequests.token: "${NAME}"` refers to. Also used for `pullRequests.oauth.clientId` and `clientSecret`, which are references too. | # GITHUB_PR_OAUTH_CLIENT_ID=your-client-id |
| CODEAPI_BRIDGE_LANE_GIT | boolean | Set on the Code API, not on LibreChat. Makes attached workers report their git branch and head. Required for any pull request to be found. | CODEAPI_BRIDGE_LANE_GIT=true |
Users connecting their own account need JWT_SECRET, which signs the connection flow, and DOMAIN_SERVER, which forms the callback URL <DOMAIN_SERVER>/api/pull-requests/oauth/callback. pullRequests.sharedCache takes effect only with USE_REDIS=true.
Provider requests use the deployment's proxy settings (PROXY, HTTP_PROXY, HTTPS_PROXY, NO_PROXY, and their lowercase forms), and NO_PROXY is honored. These are shared with other LibreChat outbound traffic and are not specific to this feature.
Artifacts
Artifacts leverage the CodeSandbox library for secure rendering of HTML/JS code. By default, the public CDN hosted by CodeSandbox is used. See Artifacts configuration for setup.
Fortunately, for those with internal network requirements, you can self-host the bundler that compiles the frontend code and specify a custom bundler URL for Sandpack.
For more info, including pre-made container images for self-hosting with metric requests removed, see: https://github.com/LibreChat-AI/codesandbox-client
| Key | Type | Description | Example |
|---|---|---|---|
| SANDPACK_BUNDLER_URL | string | Specifies a custom bundler URL for Sandpack, used by Artifacts | SANDPACK_BUNDLER_URL=your-bundler-url |
| SANDPACK_STATIC_BUNDLER_URL | string | Custom bundler URL used for static artifact templates (HTML, Markdown, code, text, and office previews). When self-hosting, set it alongside SANDPACK_BUNDLER_URL. | SANDPACK_STATIC_BUNDLER_URL=your-static-bundler-url |
Search (Meilisearch)
Search is disabled by default. Enable it only after configuring Meilisearch with a unique master key:
| Key | Type | Description | Example |
|---|---|---|---|
| SEARCH | boolean | Enables search in messages and conversations. Default: false. | SEARCH=true |
Note: If you're not using docker, it requires the installation of the free self-hosted Meilisearch or a paid remote plan
To disable anonymized telemetry analytics for MeiliSearch for absolute privacy, set to true:
| Key | Type | Description | Example |
|---|---|---|---|
| MEILI_NO_ANALYTICS | boolean | Disables anonymized telemetry analytics for MeiliSearch. | MEILI_NO_ANALYTICS=true |
For the API server to connect to the search server. Replace '0.0.0.0' with 'meilisearch' if serving MeiliSearch with docker-compose.
| Key | Type | Description | Example |
|---|---|---|---|
| MEILI_HOST | string | The API server connection to the search server. | MEILI_HOST=http://0.0.0.0:7700 |
This master key must be at least 16 bytes of valid UTF-8. Generate a unique value and give the same key to LibreChat and the Meilisearch service. Search requires both SEARCH=true and a configured MEILI_MASTER_KEY.
| Key | Type | Description | Example |
|---|---|---|---|
| MEILI_MASTER_KEY | string | The master key for MeiliSearch. | MEILI_MASTER_KEY= |
To prevent LibreChat from attempting a database indexing sync with Meilisearch, you can set the following environment variable to true. This is useful in a node cluster, or multi-node setup, where only one instance should be responsible for indexing.
| Key | Type | Description | Example |
|---|---|---|---|
| MEILI_NO_SYNC | string | Toggle for disabling Mellisearch index sync | MEILI_NO_SYNC=true |
RAG API
Configure Retrieval-Augmented Generation for document indexing and context-aware responses. See: RAG API Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| RAG_API_URL | string | URL of the RAG API service. | RAG_API_URL=http://host.docker.internal:8000 |
| RAG_OPENAI_API_KEY | string | OpenAI API key for RAG embeddings. Overrides OPENAI_API_KEY for RAG. | # RAG_OPENAI_API_KEY=sk-your-openai-api-key |
| RAG_OPENAI_BASEURL | string | Custom OpenAI base URL for RAG embeddings. | # RAG_OPENAI_BASEURL= |
| RAG_USE_FULL_CONTEXT | boolean | Fetch entire file context instead of top 4 results. Default: false. | # RAG_USE_FULL_CONTEXT=true |
| EMBEDDINGS_PROVIDER | string | Embeddings provider: openai, azure, huggingface, huggingfacetei, or ollama. Default: openai. | # EMBEDDINGS_PROVIDER=openai |
| EMBEDDINGS_MODEL | string | Embeddings model to use. Default depends on provider. | # EMBEDDINGS_MODEL=text-embedding-3-small |
Note: When using the default Docker setup, the
.envfile is shared between LibreChat and the RAG API. For complete configuration options, see the RAG API documentation.
Speech to Text & Text to Speech
Configure Speech-to-Text (STT) and Text-to-Speech (TTS) services. See: Speech Settings
| Key | Type | Description | Example |
|---|---|---|---|
| STT_API_KEY | string | API key for Speech-to-Text service (e.g., OpenAI Whisper). | # STT_API_KEY= |
| TTS_API_KEY | string | API key for Text-to-Speech service (e.g., OpenAI TTS). | # TTS_API_KEY= |
Note: STT and TTS are primarily configured through the
speech:section inlibrechat.yaml. These environment variables are referenced in that configuration. See Speech Settings for full YAML configuration options.
Shared Links
Configure shared conversation links functionality.
| Key | Type | Description | Example |
|---|---|---|---|
| ALLOW_SHARED_LINKS | boolean | Enable or disable shared conversation links. Default: true. | ALLOW_SHARED_LINKS=true |
| ALLOW_SHARED_LINKS_PUBLIC | boolean | Allow shared links to be publicly accessible without authentication. Default: false. | ALLOW_SHARED_LINKS_PUBLIC=false |
| SHARED_LINKS_SNAPSHOT_FILES | boolean | Snapshot files referenced by a shared chat so viewers can preview or download them through the shared link. Overrides interface.sharedLinks.snapshotFiles when set. | SHARED_LINKS_SNAPSHOT_FILES=true |
| SHARED_LINKS_AUTO_MIGRATE | boolean | Fallback that migrates legacy shared links missed by the explicit shared-link permissions migration when they are first accessed. Enabled when unset; set to false to disable. | # SHARED_LINKS_AUTO_MIGRATE=true |
| SHARE_IP_MAX | number | Maximum shared-link retrievals per IP during the IP window. Default: 100. | # SHARE_IP_MAX=100 |
| SHARE_IP_WINDOW | number | Shared-link IP rate-limit window in minutes. Default: 1. | # SHARE_IP_WINDOW=1 |
| SHARE_USER_MAX | number | Maximum shared-link retrievals per authenticated user during the user window. Default: 60. | # SHARE_USER_MAX=60 |
| SHARE_USER_WINDOW | number | Shared-link user rate-limit window in minutes. Default: 1. | # SHARE_USER_WINDOW=1 |
| SHARE_VIOLATION_SCORE | number | Violation score added when a shared-link retrieval limit is exceeded. Default: 0. | # SHARE_VIOLATION_SCORE=0 |
ALLOW_SHARED_LINKS is the feature-wide switch. Role permissions now control who can create shared links, share them with authenticated users, or make them visible to everyone; see interface.sharedLinks. ALLOW_SHARED_LINKS_PUBLIC only controls whether publicly shared links can be viewed without authentication. SHARED_LINKS_SNAPSHOT_FILES is a global override for shared-link file snapshots and can disable snapshot serving for every link when set to false.
Every shared-link read uses the IP bucket because public links are reachable without authentication. Signed-in viewers also use the user bucket. Exceeding either limit returns HTTP 429; a nonzero SHARE_VIOLATION_SCORE records the event in the existing violation system.
Scheduled Chats
| Key | Type | Description | Example |
|---|---|---|---|
| SCHEDULES_SINGLE_PROCESS | boolean | Allows Scheduled Chats without Redis only when exactly one LibreChat process is running. Never enable this for multiple processes or replicas. | SCHEDULES_SINGLE_PROCESS=true |
| SCHEDULES_DISABLED | boolean | Emergency global stop for automatic Scheduled Chat occurrences and Run now. Definitions remain stored. Default: false. | SCHEDULES_DISABLED=true |
Scheduled Chats are experimental and disabled until interface.schedules is configured. Multi-replica deployments require USE_REDIS_STREAMS=true; a deployment without shared Redis streams fails schedule writes closed unless it explicitly declares a truly single-process topology with SCHEDULES_SINGLE_PROCESS=true. A scheduled Agent that can pause for Ask User or tool approval always requires USE_REDIS_STREAMS=true plus a durable shared checkpointer; the built-in default is MongoDB. See Scheduled Chats for setup and runtime behavior.
Agent Event Runtime
| Key | Type | Description | Example |
|---|---|---|---|
| AGENT_TRIGGERS_SELF_URL | string | Compatibility fallback for endpoints.agents.eventDriven.selfUrl. Base URL used by the Agent event host to re-enter fire, continue, and steer admission. | # AGENT_TRIGGERS_SELF_URL=http://127.0.0.1:3080 |
| AGENT_EVENT_USER_MAX | number | Compatibility fallback for rateLimits.agentEvents.userMax. Maximum Agent Event requests per API-key principal in the configured window. Default: 40. | AGENT_EVENT_USER_MAX=40 |
| AGENT_EVENT_USER_WINDOW | number | Compatibility fallback for rateLimits.agentEvents.userWindowInMinutes. Agent Event rate-limit window in minutes. Default: 1. | AGENT_EVENT_USER_WINDOW=1 |
Prefer endpoints.agents.eventDriven.selfUrl and rateLimits.agentEvents in librechat.yaml. AGENT_TRIGGERS_SELF_URL and the rate-limit variables remain compatibility fallbacks; an explicitly configured YAML value takes precedence.
Bound child continuations, detached Subagent parent continuations, and Event Actor detached Action completion are automatic. The retired ENABLE_AGENT_EVENT_CHILD_TURNS, ENABLE_SUBAGENT_COMPLETION_WAKEUPS, and AGENT_TRIGGERS_DETACHED_ACTIONS_PRODUCER_ENABLED variables are no longer read.
The in-memory generation store supports process-local Event Actor detached completion while the process remains alive. Redis generation streams add durable restart recovery and replica handoff. See Generation Protocol Compatibility before a mixed-version deployment.
Leave AGENT_TRIGGERS_SELF_URL unset for the normal bound-listener path. Set it only when internal event admission must traverse another HTTP origin, such as a TLS front door. The value must be an HTTP or HTTPS URL without embedded credentials.
LibreChat exposes an authenticated Agent Events API; it does not expose an unauthenticated webhook. API-key identity, Remote Agents permissions, target access, idempotency, and the dedicated Agent Event rate limit protect ingress. MongoDB-backed ordering lanes, actor mailboxes, receipts, leases, retries, and dead letters support workers across replicas. See Agent Event Delivery and Agents API - Agent Events for behavior and examples.
User System
This section contains the configuration for:
Admin Insights
| Key | Type | Description | Example |
|---|---|---|---|
| ENABLE_INSIGHTS | boolean | Enables the MongoDB-backed Insights dashboard. Default: false. | ENABLE_INSIGHTS=false |
When enabled, administrators and accounts with the read:insights capability can review every Agent, and other users only the Agents they were granted View insights on. Queries are tenant-scoped and expose persisted activity metrics and recent conversation metadata. See Admin Insights for metric definitions and access details.
Audit Log
| Key | Type | Description | Example |
|---|---|---|---|
| AUDIT_LOG_FAIL_CLOSED | boolean | System grants and resource sharing are audited before they take effect. When true, a grant or widening permission change that cannot be audited fails and nothing changes. Revocations are never blocked by an audit outage. Set to false to apply every change anyway and only log audit failures. Default: true for system grants, resource sharing, audit log exports and code pairing. Admin config override, group, and role changes only fail closed when this is set to exactly true; when unset they apply and log the audit failure. | # AUDIT_LOG_FAIL_CLOSED=true |
Config Override Environment References
Config overrides written through the admin API (role, group, and user profiles and the Base profile) may reference only the ${ENV_VAR} names that librechat.yaml already references, the built-in endpoint credentials (such as OPENAI_API_KEY and ANTHROPIC_API_KEY), and the names listed below. Any other reference is rejected on write and resolves to nothing at runtime. References are not checked in the interface and modelSpecs sections or in these prompt fields, which are used as written: each endpoint's titlePrompt, titlePromptTemplate, activityPrompt, activityPhasePrompt and reasoningLabelPrompt, summarization.prompt and summarization.updatePrompt, memory.agent.instructions, and webSearch.firecrawlOptions.changeTrackingOptions.prompt. Prompt keys anywhere else are checked. See Admin Panel for how overrides are layered.
| Key | Type | Description | Example |
|---|---|---|---|
| CONFIG_OVERRIDE_ENV_ALLOWLIST | string | Comma or space separated list of extra environment variable names that admin config overrides may reference. | # CONFIG_OVERRIDE_ENV_ALLOWLIST=MY_GATEWAY_KEY,MY_GATEWAY_URL |
Agent Conversation Controls
| Key | Type | Description | Example |
|---|---|---|---|
| STEER_MAX_LENGTH | number | Maximum characters allowed in one mid-run Agent steering message. Default: 16000. | # STEER_MAX_LENGTH=16000 |
Moderation
The Automated Moderation System uses a scoring mechanism to track user violations. As users commit actions like excessive logins, registrations, or messaging, they accumulate violation scores. Upon reaching a set threshold, the user and their IP are temporarily banned. This system ensures platform security by monitoring and penalizing rapid or suspicious activities.
see: Automated Moderation
Basic Moderation Settings
| Key | Type | Description | Example |
|---|---|---|---|
| OPENAI_MODERATION | boolean | Whether or not to enable OpenAI moderation on the **OpenAI** and **Plugins** endpoints. | OPENAI_MODERATION=false |
| OPENAI_MODERATION_API_KEY | string | Your OpenAI API key. | OPENAI_MODERATION_API_KEY= |
| OPENAI_MODERATION_REVERSE_PROXY | string | Note: Commented out by default, this is not working with all reverse proxys. | # OPENAI_MODERATION_REVERSE_PROXY= |
Banning Settings
| Key | Type | Description | Example |
|---|---|---|---|
| BAN_VIOLATIONS | boolean | Whether or not to enable banning users for violations (they will still be logged). | BAN_VIOLATIONS=true |
| BAN_DURATION | integer | How long the user and associated IP are banned for (in milliseconds). | BAN_DURATION=1000 * 60 * 60 * 2 |
| BAN_INTERVAL | integer | The user will be banned every time their score reaches/crosses over the interval threshold. | BAN_INTERVAL=20 |
| VIOLATION_SCORE_TTL | integer | How long a violation score lives without new violations (in milliseconds). Each new violation restarts the countdown, so scores decay after a quiet period instead of accumulating forever. Set to 0 to never expire scores (legacy behavior). | VIOLATION_SCORE_TTL=1000 * 60 * 60 |
Login and registration rate limiting
Prevents brute force attacks and spam registrations by limiting login attempts and new account registrations.
| Key | Type | Description | Example |
|---|---|---|---|
| LOGIN_MAX | integer | The max amount of logins allowed per IP per LOGIN_WINDOW. | LOGIN_MAX=7 |
| LOGIN_WINDOW | integer | In minutes, determines the window of time for LOGIN_MAX logins. | LOGIN_WINDOW=5 |
| REGISTER_MAX | integer | The max amount of registrations allowed per IP per REGISTER_WINDOW. | REGISTER_MAX=5 |
| REGISTER_WINDOW | integer | In minutes, determines the window of time for REGISTER_MAX registrations. | REGISTER_WINDOW=60 |
The login-attempt budget is shared by the local login API and top-level social or federated OAuth navigations from the same IP. A rejected API login receives the existing JSON 429 response. A rate-limited or banned /oauth/* browser navigation returns to /login?redirect=false with a localized error code instead of rendering a JSON document; redirect=false prevents an automatic OpenID redirect from immediately entering the limiter again.
Two-factor authentication rate limiting
| Key | Type | Description | Example |
|---|---|---|---|
| TWO_FACTOR_TEMP_MAX | integer | Two-factor code attempts (sign-in challenge and enrollment confirmation) per TWO_FACTOR_TEMP_WINDOW. Defaults to LOGIN_MAX. | # TWO_FACTOR_TEMP_MAX=7 |
| TWO_FACTOR_TEMP_WINDOW | integer | Window in minutes for TWO_FACTOR_TEMP_MAX. Defaults to LOGIN_WINDOW. | # TWO_FACTOR_TEMP_WINDOW=5 |
| TWO_FACTOR_SETUP_MAX | integer | Two-factor enrollment steps that check no guessable code, kept separate so wrong codes cannot strand an enrollment. Default: 20. | # TWO_FACTOR_SETUP_MAX=20 |
| TWO_FACTOR_SETUP_WINDOW | integer | Window in minutes for TWO_FACTOR_SETUP_MAX. Defaults to TWO_FACTOR_TEMP_WINDOW. | # TWO_FACTOR_SETUP_WINDOW=5 |
These are process-wide settings that apply before request or tenant configuration is available. See Required Two-Factor Authentication.
Passkey rate limiting
| Key | Type | Description | Example |
|---|---|---|---|
| PASSKEY_STEPUP_MAX | integer | Password-confirmed passkey add or remove attempts per user in PASSKEY_STEPUP_WINDOW. Not logged as a violation. Default: 20. | PASSKEY_STEPUP_MAX=20 |
| PASSKEY_STEPUP_WINDOW | integer | Window in minutes for PASSKEY_STEPUP_MAX. Default: 15. | PASSKEY_STEPUP_WINDOW=15 |
| PASSKEY_MAX | integer | Passkey sign-in requests per IP in PASSKEY_WINDOW (one sign-in uses two requests). Requests over the limit get HTTP 429; they are not scored as violations because no user is signed in yet. Default: 20. | # PASSKEY_MAX=20 |
| PASSKEY_WINDOW | integer | Window in minutes for PASSKEY_MAX. Default: 5. | # PASSKEY_WINDOW=5 |
Password reset and email verification rate limiting
LibreChat applies separate IP-based limits to requesting an email and submitting the token from that email. This prevents repeated token guesses without forcing deployments to use the same limit for email delivery and token validation.
| Key | Type | Description | Example |
|---|---|---|---|
| RESET_PASSWORD_MAX | integer | Maximum password-reset email requests per IP in RESET_PASSWORD_WINDOW. Default: 2. | # RESET_PASSWORD_MAX=2 |
| RESET_PASSWORD_WINDOW | integer | Password-reset email request window in minutes. Default: 2. | # RESET_PASSWORD_WINDOW=2 |
| RESET_PASSWORD_SUBMISSION_MAX | integer | Maximum password-reset token submissions per IP. Defaults to RESET_PASSWORD_MAX, then 2. | # RESET_PASSWORD_SUBMISSION_MAX=2 |
| RESET_PASSWORD_SUBMISSION_WINDOW | integer | Password-reset token submission window in minutes. Defaults to RESET_PASSWORD_WINDOW, then 2. | # RESET_PASSWORD_SUBMISSION_WINDOW=2 |
| VERIFY_EMAIL_MAX | integer | Maximum verification-email resend requests per IP in VERIFY_EMAIL_WINDOW. Default: 2. | # VERIFY_EMAIL_MAX=2 |
| VERIFY_EMAIL_WINDOW | integer | Verification-email resend window in minutes. Default: 2. | # VERIFY_EMAIL_WINDOW=2 |
| VERIFY_EMAIL_SUBMISSION_MAX | integer | Maximum email-verification token submissions per IP. Defaults to VERIFY_EMAIL_MAX, then 2. | # VERIFY_EMAIL_SUBMISSION_MAX=2 |
| VERIFY_EMAIL_SUBMISSION_WINDOW | integer | Email-verification token submission window in minutes. Defaults to VERIFY_EMAIL_WINDOW, then 2. | # VERIFY_EMAIL_SUBMISSION_WINDOW=2 |
Email change rate limiting
Limits email address change requests per signed-in user, and verification link openings per IP and per account.
Note: These can also be configured via
librechat.yamlin therateLimits.emailChangeandrateLimits.emailChangeConfirmsections. A value set inlibrechat.yamltakes precedence over the environment variable.
| Key | Type | Description | Example |
|---|---|---|---|
| EMAIL_CHANGE_USER_MAX | integer | Email change requests per user in EMAIL_CHANGE_USER_WINDOW. Default: 3. | # EMAIL_CHANGE_USER_MAX=3 |
| EMAIL_CHANGE_USER_WINDOW | integer | Window in minutes for EMAIL_CHANGE_USER_MAX. Default: 2. | # EMAIL_CHANGE_USER_WINDOW=2 |
| EMAIL_CHANGE_CONFIRM_IP_MAX | integer | Verification link openings per IP in EMAIL_CHANGE_CONFIRM_IP_WINDOW. Default: 20. | # EMAIL_CHANGE_CONFIRM_IP_MAX=20 |
| EMAIL_CHANGE_CONFIRM_IP_WINDOW | integer | Window in minutes for EMAIL_CHANGE_CONFIRM_IP_MAX. Default: 2. | # EMAIL_CHANGE_CONFIRM_IP_WINDOW=2 |
| EMAIL_CHANGE_CONFIRM_USER_MAX | integer | Verification link openings per IP and account in EMAIL_CHANGE_CONFIRM_USER_WINDOW. Defaults to VERIFY_EMAIL_MAX, then 2. | # EMAIL_CHANGE_CONFIRM_USER_MAX=2 |
| EMAIL_CHANGE_CONFIRM_USER_WINDOW | integer | Window in minutes for EMAIL_CHANGE_CONFIRM_USER_MAX. Defaults to VERIFY_EMAIL_WINDOW, then 2. | # EMAIL_CHANGE_CONFIRM_USER_WINDOW=2 |
Score for each violation
| Key | Type | Description | Example |
|---|---|---|---|
| LOGIN_VIOLATION_SCORE | integer | Score for login violations. | LOGIN_VIOLATION_SCORE=1 |
| REGISTRATION_VIOLATION_SCORE | integer | Score for registration violations. | REGISTRATION_VIOLATION_SCORE=1 |
| CONCURRENT_VIOLATION_SCORE | integer | Score for concurrent violations. | CONCURRENT_VIOLATION_SCORE=1 |
| MESSAGE_VIOLATION_SCORE | integer | Score for message violations. | MESSAGE_VIOLATION_SCORE=1 |
| NON_BROWSER_VIOLATION_SCORE | integer | Score for non-browser violations. | NON_BROWSER_VIOLATION_SCORE=20 |
| ILLEGAL_MODEL_REQ_SCORE | integer | Score for illegal model requests. | ILLEGAL_MODEL_REQ_SCORE=5 |
| IMPORT_VIOLATION_SCORE | integer | Score for import conversation violations. | IMPORT_VIOLATION_SCORE=1 |
| FORK_VIOLATION_SCORE | integer | Score for conversation fork violations. | FORK_VIOLATION_SCORE=1 |
| TTS_VIOLATION_SCORE | integer | Score for text-to-speech violations. | TTS_VIOLATION_SCORE=0 |
| STT_VIOLATION_SCORE | integer | Score for speech-to-text violations. | STT_VIOLATION_SCORE=0 |
| FILE_UPLOAD_VIOLATION_SCORE | integer | Score for file upload violations. | FILE_UPLOAD_VIOLATION_SCORE=0 |
| RESET_PASSWORD_VIOLATION_SCORE | integer | Score for password-reset email request violations. Default: 1. | # RESET_PASSWORD_VIOLATION_SCORE=1 |
| VERIFY_EMAIL_VIOLATION_SCORE | integer | Score for verification-email resend violations. Default: 1. | # VERIFY_EMAIL_VIOLATION_SCORE=1 |
| RESET_PASSWORD_SUBMISSION_VIOLATION_SCORE | integer | Score for password-reset token submission violations. Default: 1. | # RESET_PASSWORD_SUBMISSION_VIOLATION_SCORE=1 |
| VERIFY_EMAIL_SUBMISSION_VIOLATION_SCORE | integer | Score for email-verification token submission violations. Default: 1. | # VERIFY_EMAIL_SUBMISSION_VIOLATION_SCORE=1 |
| EMAIL_CHANGE_VIOLATION_SCORE | integer | Score for exceeding the email change request limit. Default: 1. | # EMAIL_CHANGE_VIOLATION_SCORE=1 |
| EMAIL_CHANGE_SUBMISSION_IP_VIOLATION_SCORE | integer | Score for exceeding the per-IP limit on email change verification link openings. Default: 1. | # EMAIL_CHANGE_SUBMISSION_IP_VIOLATION_SCORE=1 |
| TWO_FACTOR_TEMP_VIOLATION_SCORE | integer | Score for exceeding the two-factor code attempt limit. Defaults to LOGIN_VIOLATION_SCORE. | # TWO_FACTOR_TEMP_VIOLATION_SCORE=1 |
| TWO_FACTOR_SETUP_VIOLATION_SCORE | integer | Score for exceeding the two-factor setup limit. Defaults to TWO_FACTOR_TEMP_VIOLATION_SCORE, then LOGIN_VIOLATION_SCORE. | # TWO_FACTOR_SETUP_VIOLATION_SCORE=1 |
| TOOL_CALL_VIOLATION_SCORE | integer | Score for tool call violations. | TOOL_CALL_VIOLATION_SCORE=0 |
| CONVO_ACCESS_VIOLATION_SCORE | integer | Score for conversation access violations. | CONVO_ACCESS_VIOLATION_SCORE=0 |
Note: Non-browser access and Illegal model requests are almost always nefarious as it means a 3rd party is attempting to access the server through an automated script.
Message rate limiting (per user & IP)
| Key | Type | Description | Example |
|---|---|---|---|
| LIMIT_CONCURRENT_MESSAGES | boolean | Whether to limit the amount of messages a user can send per request. | LIMIT_CONCURRENT_MESSAGES=true |
| CONCURRENT_MESSAGE_MAX | integer | The max amount of messages a user can send per request. | CONCURRENT_MESSAGE_MAX=2 |
Limiters
Note: You can utilize both limiters, but default is to limit by IP only.
IP Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| LIMIT_MESSAGE_IP | boolean | Whether to limit the amount of messages an IP can send per `MESSAGE_IP_WINDOW`. | LIMIT_MESSAGE_IP=true |
| MESSAGE_IP_MAX | integer | The max amount of messages an IP can send per `MESSAGE_IP_WINDOW`. | MESSAGE_IP_MAX=40 |
| MESSAGE_IP_WINDOW | integer | In minutes, determines the window of time for `MESSAGE_IP_MAX` messages. | MESSAGE_IP_WINDOW=1 |
User Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| LIMIT_MESSAGE_USER | boolean | Whether to limit the amount of messages an user can send per `MESSAGE_USER_WINDOW`. | LIMIT_MESSAGE_USER=false |
| MESSAGE_USER_MAX | integer | The max amount of messages an user can send per `MESSAGE_USER_WINDOW`. | MESSAGE_USER_MAX=40 |
| MESSAGE_USER_WINDOW | integer | In minutes, determines the window of time for `MESSAGE_USER_MAX` messages. | MESSAGE_USER_WINDOW=1 |
Confirmed idempotent Agent-generation retries bypass ordinary per-user message admission so recovery can proceed, but they still pass through the shared IP limiter when LIMIT_MESSAGE_IP is enabled. Trusted Agent-trigger deliveries remain exempt from that browser-facing IP boundary.
Queued Attachment TTL Limiter:
The /files/usage endpoint renews a bounded TTL hold for attachments waiting in queued Agent messages. It has a separate per-user limiter so metadata renewals do not consume the upload quota.
| Key | Type | Description | Example |
|---|---|---|---|
| FILE_USAGE_USER_MAX | integer | Maximum queued-attachment TTL renewal requests per user and window. Default: 120. | # FILE_USAGE_USER_MAX=120 |
| FILE_USAGE_USER_WINDOW | integer | Window in minutes for FILE_USAGE_USER_MAX. Default: 15. | # FILE_USAGE_USER_WINDOW=15 |
Import conversation rate limiting
Limits how often users can import conversations to prevent abuse.
Note: These can also be configured via
librechat.yamlin therateLimits.conversationsImportsection. A value set inlibrechat.yamltakes precedence over the environment variable.
Note: Both the IP and user limiters are always active. Tune them with the
MAXandWINDOWvariables below.
IP Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| IMPORT_IP_MAX | integer | The max amount of conversation imports an IP can perform per `IMPORT_IP_WINDOW`. | IMPORT_IP_MAX=100 |
| IMPORT_IP_WINDOW | integer | In minutes, determines the window of time for `IMPORT_IP_MAX` imports. | IMPORT_IP_WINDOW=15 |
User Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| IMPORT_USER_MAX | integer | The max amount of conversation imports a user can perform per `IMPORT_USER_WINDOW`. | IMPORT_USER_MAX=50 |
| IMPORT_USER_WINDOW | integer | In minutes, determines the window of time for `IMPORT_USER_MAX` imports. | IMPORT_USER_WINDOW=15 |
Conversation forking rate limiting
Limits how often users can fork conversations to prevent abuse.
Note: Both the IP and user limiters are always active. Tune them with the
MAXandWINDOWvariables below.
IP Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| FORK_IP_MAX | integer | The max amount of conversation forks an IP can create per `FORK_IP_WINDOW`. | FORK_IP_MAX=30 |
| FORK_IP_WINDOW | integer | In minutes, determines the window of time for `FORK_IP_MAX` forks. | FORK_IP_WINDOW=1 |
User Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| FORK_USER_MAX | integer | The max amount of conversation forks a user can create per `FORK_USER_WINDOW`. | FORK_USER_MAX=7 |
| FORK_USER_WINDOW | integer | In minutes, determines the window of time for `FORK_USER_MAX` forks. | FORK_USER_WINDOW=1 |
File upload rate limiting
Limits how often users can upload files to prevent abuse.
Note: These can also be configured via
librechat.yamlin therateLimits.fileUploadssection. A value set inlibrechat.yamltakes precedence over the environment variable.
IP Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| FILE_UPLOAD_IP_MAX | integer | Max file uploads per IP per `FILE_UPLOAD_IP_WINDOW`. Default: 100. | # FILE_UPLOAD_IP_MAX=100 |
| FILE_UPLOAD_IP_WINDOW | integer | In minutes, determines the window of time for `FILE_UPLOAD_IP_MAX`. Default: 15. | # FILE_UPLOAD_IP_WINDOW=15 |
User Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| FILE_UPLOAD_USER_MAX | integer | Max file uploads per user per `FILE_UPLOAD_USER_WINDOW`. Default: 50. | # FILE_UPLOAD_USER_MAX=50 |
| FILE_UPLOAD_USER_WINDOW | integer | In minutes, determines the window of time for `FILE_UPLOAD_USER_MAX`. Default: 15. | # FILE_UPLOAD_USER_WINDOW=15 |
TTS (Text-to-Speech) rate limiting
Limits how often users can use Text-to-Speech to prevent abuse.
Note: These can also be configured via
librechat.yamlin therateLimits.ttssection. A value set inlibrechat.yamltakes precedence over the environment variable.
IP Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| TTS_IP_MAX | integer | Max TTS requests per IP per `TTS_IP_WINDOW`. Default: 100. | # TTS_IP_MAX=100 |
| TTS_IP_WINDOW | integer | In minutes, determines the window of time for `TTS_IP_MAX`. Default: 1. | # TTS_IP_WINDOW=1 |
User Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| TTS_USER_MAX | integer | Max TTS requests per user per `TTS_USER_WINDOW`. Default: 50. | # TTS_USER_MAX=50 |
| TTS_USER_WINDOW | integer | In minutes, determines the window of time for `TTS_USER_MAX`. Default: 1. | # TTS_USER_WINDOW=1 |
STT (Speech-to-Text) rate limiting
Limits how often users can use Speech-to-Text to prevent abuse.
Note: These can also be configured via
librechat.yamlin therateLimits.sttsection. A value set inlibrechat.yamltakes precedence over the environment variable.
IP Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| STT_IP_MAX | integer | Max STT requests per IP per `STT_IP_WINDOW`. Default: 100. | # STT_IP_MAX=100 |
| STT_IP_WINDOW | integer | In minutes, determines the window of time for `STT_IP_MAX`. Default: 1. | # STT_IP_WINDOW=1 |
User Limiter:
| Key | Type | Description | Example |
|---|---|---|---|
| STT_USER_MAX | integer | Max STT requests per user per `STT_USER_WINDOW`. Default: 50. | # STT_USER_MAX=50 |
| STT_USER_WINDOW | integer | In minutes, determines the window of time for `STT_USER_MAX`. Default: 1. | # STT_USER_WINDOW=1 |
Balance
The following feature allows for the management of user balances within the system's endpoints. You have the option to add balances manually, or you may choose to implement a system that accumulates balances automatically for users. If a specific initial balance is defined in the configuration, tokens will be credited to the user's balance automatically when they register.
see: Token Usage
| Key | Type | Description | Example |
|---|---|---|---|
| CHECK_BALANCE | boolean | Enable token credit balances for the OpenAI/Plugins endpoints. | CHECK_BALANCE=false |
| START_BALANCE | integer | If the value is set, tokens will be credited to the user's balance after registration. | START_BALANCE=20000 |
Managing Balances
- Run
npm run add-balanceto manually add balances.- You can also specify the email and token credit amount to add, e.g.:
npm run add-balance [email protected] 1000
- You can also specify the email and token credit amount to add, e.g.:
- Run
npm run set-balanceto manually set balances, similar toadd-balance. - Run
npm run list-balancesto list the balance of every user.
Note: 1000 credits = $0.001 (1 mill USD)
Registration and Login
Configuration File Clarification
All authentication settings in this section should be configured in your .env file, not in the
librechat.yaml file or docker-compose.override.yml. The docker-compose.override.yml file is
only used to mount volumes and set environment variables for Docker, while the librechat.yaml
file is used for custom endpoints and other application settings. The exceptions are
ALLOW_EMAIL_CHANGE and MAX_PASSKEYS_PER_USER, which emailChange and passkeys in
librechat.yaml override when set.
- General Settings:
| Key | Type | Description | Example |
|---|---|---|---|
| ALLOW_EMAIL_LOGIN | boolean | Enable or disable ONLY email login. | ALLOW_EMAIL_LOGIN=true |
| ALLOW_EMAIL_LOGIN_OVERRIDE | boolean | Permit direct API email login while ALLOW_EMAIL_LOGIN=false. Each use is logged. Default: false. | # ALLOW_EMAIL_LOGIN_OVERRIDE=false |
| ALLOW_REGISTRATION | boolean | Enable or disable Email registration of new users. | ALLOW_REGISTRATION=true |
| ALLOW_SOCIAL_LOGIN | boolean | Allow users to connect to LibreChat with various social networks. | ALLOW_SOCIAL_LOGIN=false |
| ALLOW_SOCIAL_REGISTRATION | boolean | Enable or disable registration of new users using various social networks. | ALLOW_SOCIAL_REGISTRATION=false |
| ALLOW_PASSWORD_RESET | boolean | Enable or disable the ability for users to reset their password by themselves | ALLOW_PASSWORD_RESET=false |
| ALLOW_ACCOUNT_DELETION | boolean | Enable or disable the ability for users to delete their account by themselves. Enabled by default if omitted/commented out | ALLOW_ACCOUNT_DELETION=true |
| ALLOW_UNVERIFIED_EMAIL_LOGIN | boolean | Set to true to allow users to log in without verifying their email address. If set to false, users will be required to verify their email before logging in. | ALLOW_UNVERIFIED_EMAIL_LOGIN=true |
| ALLOW_EMAIL_CHANGE | boolean | Allow local-account users to change their email address from Settings > Account. Requires email delivery. Enabled by default if omitted. emailChange.enabled in librechat.yaml takes precedence. Keep it false during multi-node rollouts until every node supports it. | # ALLOW_EMAIL_CHANGE=true |
| ENFORCE_TWO_FACTOR_AUTHENTICATION | boolean | Require local and LDAP accounts to enroll in 2FA before a full session is issued. Federated identity providers keep their own MFA policies. | ENFORCE_TWO_FACTOR_AUTHENTICATION=false |
| TWO_FACTOR_BACKUP_CODE_FORMAT | string | Format of newly issued two-factor recovery codes: strong (128-bit, salted) or legacy (32-bit, unsalted). Default: strong. Use legacy only during a rolling upgrade, on every replica, while older backends that cannot read strong codes are still running. Existing legacy codes keep working until the user regenerates them. | # TWO_FACTOR_BACKUP_CODE_FORMAT=strong |
| MIN_PASSWORD_LENGTH | number | Minimum password length for user authentication. 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 |
See Email Address Change for ALLOW_EMAIL_CHANGE and Required Two-Factor Authentication for ENFORCE_TWO_FACTOR_AUTHENTICATION.
Quick Tip: Even with registration disabled, add users directly to the database using
npm run create-user. Quick Tip: With registration disabled, you can delete a user withnpm run delete-user [email protected].
- Session and Refresh Token Settings:
| Key | Type | Description | Example |
|---|---|---|---|
| SESSION_EXPIRY | integer (milliseconds) | Session expiry time. | SESSION_EXPIRY=1000 * 60 * 15 |
| REFRESH_TOKEN_EXPIRY | integer (milliseconds) | Refresh token expiry time. | REFRESH_TOKEN_EXPIRY=(1000 * 60 * 60 * 24) * 7 |
| SESSION_COOKIE_SECURE | boolean | Overrides the Secure attribute for session/auth cookies. Leave unset to use the default NODE_ENV/DOMAIN_SERVER heuristic. | # SESSION_COOKIE_SECURE=false |
-
For more information: Refresh Token
-
Passkey Settings:
Passkey (WebAuthn) sign-in for local accounts. Requires HTTPS in production; localhost is exempt. See Passkeys.
| Key | Type | Description | Example |
|---|---|---|---|
| ALLOW_PASSKEY_LOGIN | boolean | Enable passkey sign-in and passkey management in account settings. | ALLOW_PASSKEY_LOGIN=false |
| MAX_PASSKEYS_PER_USER | integer | Passkeys each account may enroll (1-100). passkeys.perUserMax in librechat.yaml overrides this. Default: 20. | # MAX_PASSKEYS_PER_USER=20 |
| PASSKEY_RP_ID | string | Relying party ID passkeys are bound to. Defaults to the hostname of DOMAIN_CLIENT. Pin it if DOMAIN_CLIENT may change: existing passkeys stop working when the RP ID changes. Must be a domain, not an IP address. | # PASSKEY_RP_ID= |
| PASSKEY_RP_NAME | string | Name shown by the authenticator. Defaults to APP_TITLE. | # PASSKEY_RP_NAME= |
| PASSKEY_ORIGINS | string | Comma-separated allowed origins. Defaults to DOMAIN_CLIENT and DOMAIN_SERVER. | # PASSKEY_ORIGINS= |
- JWT Settings:
Use unique values of at least 32 bytes. Generate permanent values for production with the Credentials Generator.
| Key | Type | Description | Example |
|---|---|---|---|
| JWT_SECRET | string (hex) | JWT secret key. | JWT_SECRET= |
| JWT_REFRESH_SECRET | string (hex) | JWT refresh secret key. | JWT_REFRESH_SECRET= |
Blank JWT secrets use the same temporary-credential bootstrap described under Credentials Configuration. In production and horizontally scaled deployments, set permanent values and share them across replicas so issued sessions remain valid.
Social Logins
For more details: OAuth2-OIDC
Apple Authentication
For more information: Apple Authentication
| Key | Type | Description | Example |
|---|---|---|---|
| APPLE_CLIENT_ID | string | Your Apple Services ID (e.g., com.yourdomain.librechat.services). | APPLE_CLIENT_ID=com.yourdomain.librechat.services |
| APPLE_TEAM_ID | string | Your Apple Developer Team ID. | APPLE_TEAM_ID=YOUR_TEAM_ID |
| APPLE_KEY_ID | string | Your Apple Key ID from the downloaded key. | APPLE_KEY_ID=YOUR_KEY_ID |
| APPLE_PRIVATE_KEY_PATH | string | Absolute path to your downloaded .p8 file. | APPLE_PRIVATE_KEY_PATH=/path/to/AuthKey.p8 |
| APPLE_CALLBACK_URL | string | The callback URL for Apple authentication. | APPLE_CALLBACK_URL=/oauth/apple/callback |
Discord Authentication
For more information: Discord
| Key | Type | Description | Example |
|---|---|---|---|
| DISCORD_CLIENT_ID | string | Your Discord client ID. | DISCORD_CLIENT_ID= |
| DISCORD_CLIENT_SECRET | string | Your Discord client secret. | DISCORD_CLIENT_SECRET= |
| DISCORD_CALLBACK_URL | string | The callback URL for Discord authentication. | DISCORD_CALLBACK_URL=/oauth/discord/callback |
Facebook Authentication
For more information: Facebook Authentication
| Key | Type | Description | Example |
|---|---|---|---|
| FACEBOOK_CLIENT_ID | string | Your Facebook client ID. | FACEBOOK_CLIENT_ID= |
| FACEBOOK_CLIENT_SECRET | string | Your Facebook client secret. | FACEBOOK_CLIENT_SECRET= |
| FACEBOOK_CALLBACK_URL | string | The callback URL for Facebook authentication. | FACEBOOK_CALLBACK_URL=/oauth/facebook/callback |
GitHub Authentication
For more information: GitHub Authentication
| Key | Type | Description | Example |
|---|---|---|---|
| GITHUB_CLIENT_ID | string | Your GitHub client ID. | GITHUB_CLIENT_ID= |
| GITHUB_CLIENT_SECRET | string | Your GitHub client secret. | GITHUB_CLIENT_SECRET= |
| GITHUB_CALLBACK_URL | string | The callback URL for GitHub authentication. | GITHUB_CALLBACK_URL=/oauth/github/callback |
| GITHUB_ENTERPRISE_BASE_URL | string | Optional: The base URL for your GitHub Enterprise instance. | GITHUB_ENTERPRISE_BASE_URL= |
| GITHUB_ENTERPRISE_USER_AGENT | string | Optional: The user agent for GitHub Enterprise requests. | GITHUB_ENTERPRISE_USER_AGENT= |
Google Authentication
For more information: Google Authentication
| Key | Type | Description | Example |
|---|---|---|---|
| GOOGLE_CLIENT_ID | string | Your Google client ID. | GOOGLE_CLIENT_ID= |
| GOOGLE_CLIENT_SECRET | string | Your Google client secret. | GOOGLE_CLIENT_SECRET= |
| GOOGLE_CALLBACK_URL | string | The callback URL for Google authentication. | GOOGLE_CALLBACK_URL=/oauth/google/callback |
OpenID Connect
For more information:
| Key | Type | Description | Example |
|---|---|---|---|
| OPENID_CLIENT_ID | string | Your OpenID client ID. | OPENID_CLIENT_ID= |
| OPENID_CLIENT_SECRET | string | Your OpenID client secret. | OPENID_CLIENT_SECRET= |
| OPENID_ISSUER | string | The OpenID issuer URL. | OPENID_ISSUER= |
| OPENID_SESSION_SECRET | string | The secret for OpenID session storage. | OPENID_SESSION_SECRET= |
| OPENID_SCOPE | string | The OpenID scope. | OPENID_SCOPE="openid profile email" |
| OPENID_CALLBACK_URL | string | The callback URL for OpenID authentication. | OPENID_CALLBACK_URL=/oauth/openid/callback |
| OPENID_AUDIENCE | string | Audience value for OpenID JWT validation and authorization requests. Comma-separated values are accepted for JWT validation; authorization requests use the first non-empty value. Required for Auth0 when using OPENID_REUSE_TOKENS=true to receive JWT access tokens instead of opaque tokens. | OPENID_AUDIENCE=https://api.librechat.com |
| OPENID_REFRESH_AUDIENCE | string | Audience parameter for OpenID refresh token requests. Some providers, such as Auth0 custom APIs, require it to preserve the intended access-token audience during refresh. Usually matches OPENID_AUDIENCE. | OPENID_REFRESH_AUDIENCE= |
| OPENID_AVATAR_AUTHORIZED_ORIGINS | string | Additional origins, separated by commas or whitespace, to which LibreChat sends the user access token when fetching the profile picture. The issuer and userinfo endpoint origins are always authorized. | # OPENID_AVATAR_AUTHORIZED_ORIGINS=https://avatars.example.com |
| OPENID_DISCOVERY_RETRY_ATTEMPTS | number | Discovery attempts during startup, from 0 to 100. Set to 0 to use background retries only. Default: 1. registration.openidDiscovery.startupAttempts in librechat.yaml takes precedence. | # OPENID_DISCOVERY_RETRY_ATTEMPTS=1 |
| OPENID_DISCOVERY_RETRY_DELAY_MS | number | Delay in milliseconds between startup and background discovery retries, from 100 to 3600000. Default: 5000. registration.openidDiscovery.retryDelayMs in librechat.yaml takes precedence. | # OPENID_DISCOVERY_RETRY_DELAY_MS=5000 |
| OPENID_REQUIRED_ROLE | string | The required role(s) for validation. Supports a single role or multiple comma-separated roles. When multiple roles are specified, the user needs ANY of the specified roles (OR logic). | OPENID_REQUIRED_ROLE=admin or OPENID_REQUIRED_ROLE=role1,role2,admin |
| OPENID_REQUIRED_ROLE_TOKEN_KIND | string | The token kind for required role validation. | OPENID_REQUIRED_ROLE_TOKEN_KIND= |
| OPENID_REQUIRED_ROLE_PARAMETER_PATH | string | The parameter path for required role validation. | OPENID_REQUIRED_ROLE_PARAMETER_PATH= |
| OPENID_ADMIN_ROLE | string | The role the user should have in order to be an admin in LibreChat. | OPENID_ADMIN_ROLE= |
| OPENID_ADMIN_ROLE_TOKEN_KIND | string | The source of the information for admin role verification. Possible values are: access, id or userinfo. | OPENID_ADMIN_ROLE_TOKEN_KIND= |
| OPENID_ADMIN_ROLE_PARAMETER_PATH | string | The parameter path for required role validation. | OPENID_ADMIN_ROLE_PARAMETER_PATH= |
| OPENID_ROLE_SYNC_ENABLED | boolean | Enable generic OpenID role sync for non-admin roles. ADMIN cannot be assigned by role sync; use OPENID_ADMIN_ROLE for admin elevation. | OPENID_ROLE_SYNC_ENABLED=false |
| OPENID_ROLE_SYNC_API_ENABLED | boolean | Enable API-based role sync helpers. Requires OPENID_ROLE_SYNC_ENABLED=true. | OPENID_ROLE_SYNC_API_ENABLED=false |
| OPENID_ROLE_SYNC_SOURCE | string | Token source for the role claim. Must be one of: access, id, userinfo. Default: id. | OPENID_ROLE_SYNC_SOURCE=id |
| OPENID_ROLE_SYNC_CLAIM | string | Claim path that contains the provider roles or groups. Required when role sync is enabled. | OPENID_ROLE_SYNC_CLAIM= |
| OPENID_ROLE_SYNC_ROLE_PRIORITY | string | Comma-separated LibreChat roles ordered from most important to least important. The first matching role is assigned. | OPENID_ROLE_SYNC_ROLE_PRIORITY=Support,User |
| OPENID_ROLE_SYNC_FALLBACK_ROLE | string | LibreChat role assigned when no priority role matches. The fallback is authoritative when configured. Remote Agents API authentication treats an unresolved Entra group-overage list as empty, so this fallback applies there as well. | OPENID_ROLE_SYNC_FALLBACK_ROLE=USER |
| OPENID_BUTTON_LABEL | string | The label for the OpenID login button. | OPENID_BUTTON_LABEL= |
| OPENID_IMAGE_URL | string | The URL of the OpenID login button image. | OPENID_IMAGE_URL= |
| OPENID_USE_END_SESSION_ENDPOINT | string | Whether to use the Issuer End Session Endpoint as a Logout Redirect | OPENID_USE_END_SESSION_ENDPOINT=TRUE |
| OPENID_MAX_LOGOUT_URL_LENGTH | number | Maximum logout URL length before using logout_hint instead of id_token_hint. Default: 2000. | # OPENID_MAX_LOGOUT_URL_LENGTH=2000 |
| OPENID_AUTO_REDIRECT | boolean | Whether to automatically redirect to the OpenID provider. | OPENID_AUTO_REDIRECT=true |
| OPENID_USE_PKCE | boolean | Use PKCE (Proof Key for Code Exchange) for OpenID authentication. For public clients without a client secret, leave OPENID_CLIENT_SECRET empty and set this to true. | # OPENID_USE_PKCE=true |
| OPENID_POST_LOGOUT_REDIRECT_URI | string | Redirect URI after OpenID logout. Defaults to ${DOMAIN_CLIENT}/login. | # OPENID_POST_LOGOUT_REDIRECT_URI= |
| OPENID_CLOCK_TOLERANCE | number | Clock tolerance in seconds for token validation. Default: 300. | # OPENID_CLOCK_TOLERANCE=300 |
| OPENID_GENERATE_NONCE | boolean | Force the OpenID client to generate a nonce parameter. Required by some identity providers like AWS Cognito (especially with federation) and Authentik. | OPENID_GENERATE_NONCE=true |
| DEBUG_OPENID_REQUESTS | boolean | Enable detailed logging of OpenID request headers. When disabled (default), only request URLs are logged at debug level. When enabled, request headers are also logged (with sensitive data masked) for deeper debugging of authentication issues. | DEBUG_OPENID_REQUESTS=false |
| OPENID_USERNAME_CLAIM | string | The user info property from the OpenID provider to store as the user's username. | OPENID_USERNAME_CLAIM= |
| OPENID_NAME_CLAIM | string | The user info property from the OpenID provider to store as the user's display name. | OPENID_NAME_CLAIM= |
| OPENID_EMAIL_CLAIM | string | The 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= |
OpenID role sync
OPENID_ROLE_SYNC_CLAIM is required when role sync is enabled.
OPENID_ROLE_SYNC_API_ENABLED=true also requires OPENID_ROLE_SYNC_ENABLED=true. Generic role
sync cannot assign ADMIN; use OPENID_ADMIN_ROLE for admin elevation.
OpenID Connect Token Reuse
LibreChat supports reusing access and refresh tokens issued by your OpenID Connect provider (like Azure Entra ID or Auth0) to manage user authentication state. When this feature is active, the refresh token passed to the user as a cookie is issued by your OpenID provider instead of LibreChat.
| Key | Type | Description | Example |
|---|---|---|---|
| OPENID_REUSE_TOKENS | boolean | Enable reuse of OpenID provider tokens for session management. | OPENID_REUSE_TOKENS=false |
| OPENID_SCOPE | string | Space-separated list of OpenID scopes. Must include offline_access for token reuse. | OPENID_SCOPE=api://librechat/.default openid profile email offline_access |
| OPENID_AUDIENCE | string | Audience value for OpenID JWT validation and authorization requests. Comma-separated values are accepted for JWT validation; authorization requests use the first non-empty value. Required for Auth0 when OPENID_REUSE_TOKENS=true. See the note in the main OpenID section above. | OPENID_AUDIENCE=https://api.librechat.com |
| OPENID_REUSE_MAX_SESSION_AGE_MS | number | Maximum age a reused OpenID session token is served before LibreChat forces an IdP refresh. Default: 900000 ms / 15 minutes. | OPENID_REUSE_MAX_SESSION_AGE_MS=900000 |
| OPENID_REFRESH_BRIDGE_GRACE_MS | number | Short recovery window for a rotated refresh token while LibreChat publishes the refreshed OpenID session. Default: 60000 ms / 1 minute. | OPENID_REFRESH_BRIDGE_GRACE_MS=60000 |
| OPENID_JWKS_URL_CACHE_ENABLED | boolean | Enable caching of signing key verification results. Enabled when unset; any value other than true disables it. | OPENID_JWKS_URL_CACHE_ENABLED=true |
| OPENID_JWKS_URL_CACHE_TIME | number | Cache duration in milliseconds. Default: 60000 (1 minute). | OPENID_JWKS_URL_CACHE_TIME=60000 |
| OPENID_ON_BEHALF_FLOW_FOR_USERINFO_REQUIRED | boolean | Enable on-behalf-of flow for user info. | OPENID_ON_BEHALF_FLOW_FOR_USERINFO_REQUIRED=true |
| OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE | string | Scope for user info in on-behalf-of flow. | OPENID_ON_BEHALF_FLOW_USERINFO_SCOPE=user.read |
| OPENID_USE_END_SESSION_ENDPOINT | boolean | Enable use of the end session endpoint for logout. | OPENID_USE_END_SESSION_ENDPOINT=true |
| OPENID_MAX_LOGOUT_URL_LENGTH | number | Maximum logout URL length in characters before switching to logout_hint. Useful to prevent URI too long errors when id_token_hint exceeds server limits. Default: 2000. | OPENID_MAX_LOGOUT_URL_LENGTH=2000 |
OPENID_REUSE_MAX_SESSION_AGE_MS and OPENID_REFRESH_BRIDGE_GRACE_MS accept arithmetic expressions like SESSION_EXPIRY. Increase the session age toward the IdP access-token lifetime when your provider revokes the previous access token on refresh, so downstream consumers such as MCP servers can finish using a still-valid bearer token. Increase the bridge grace period only when slow session persistence or cross-replica publication needs more than the default minute to publish a rotated token.
Note
For detailed configuration steps and prerequisites, see Re-use OpenID Tokens for Login Session.
Microsoft Graph API / Entra ID Integration
When using Azure Entra ID (formerly Azure AD) as your OpenID provider, you can enable additional Microsoft Graph API features for enhanced people and group search capabilities within the permissions and sharing system.
| Key | Type | Description | Example |
|---|---|---|---|
| USE_ENTRA_ID_FOR_PEOPLE_SEARCH | boolean | 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 |
| ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS | boolean | When enabled, Entra ID group owners will be considered as members of the group. | ENTRA_ID_INCLUDE_OWNERS_AS_MEMBERS=false |
| OPENID_GRAPH_SCOPES | string | 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,User.ReadBasic.All |
| GRAPH_API_SCOPES | string | Space-separated Microsoft Graph scopes requested by the OBO exchange for {{LIBRECHAT_GRAPH_ACCESS_TOKEN}} placeholders in YAML-defined MCP servers. Default: https://graph.microsoft.com/.default. | # GRAPH_API_SCOPES=https://graph.microsoft.com/.default |
GRAPH_API_SCOPES is separate from OPENID_GRAPH_SCOPES: the former controls Graph tokens resolved into MCP configuration, while the latter controls Entra ID people and group search.
Important Prerequisites
- You must have Azure Entra ID configured as your OpenID provider - OpenID token reuse MUST be
enabled (
OPENID_REUSE_TOKENS=true) - this feature will not work without it - Your Azure app registration must have the appropriate Microsoft Graph API permissions - For group search functionality, admin consent may be required for certain Graph API scopes
SharePoint Integration
LibreChat supports direct integration with SharePoint Online and OneDrive for Business, allowing users to select and attach files from their SharePoint libraries directly within conversations. This enterprise feature leverages the existing Azure Entra ID authentication. When enabled, From SharePoint appears in the Attach section of the composer + menu.
| Key | Type | Description | Example |
|---|---|---|---|
| ENABLE_SHAREPOINT_FILEPICKER | boolean | Enable SharePoint file picker in chat and agent panels. When enabled, adds a "From SharePoint" option to the Attach section of the composer "+" menu. | ENABLE_SHAREPOINT_FILEPICKER=true |
| SHAREPOINT_BASE_URL | string | SharePoint tenant base URL. Required when SharePoint integration is enabled. | SHAREPOINT_BASE_URL=https://yourtenant.sharepoint.com |
| SHAREPOINT_PICKER_SHAREPOINT_SCOPE | string | SharePoint-specific OAuth scope for the file picker. Used for authentication when opening the SharePoint file picker interface. | SHAREPOINT_PICKER_SHAREPOINT_SCOPE=https://yourtenant.sharepoint.com/AllSites.Read |
| SHAREPOINT_PICKER_GRAPH_SCOPE | string | Microsoft Graph API scope for file downloads. Used for downloading files from SharePoint after selection. | SHAREPOINT_PICKER_GRAPH_SCOPE=Files.Read.All |
Critical Requirements
All of the following must be configured for SharePoint integration to work:
- Azure Entra ID authentication must be fully configured
OPENID_REUSE_TOKENS=trueis mandatory (uses on-behalf-of token flow)OPENID_SCOPEmust include your LibreChat app API scope, for exampleapi://<client-id>/access_as_userOPENID_ON_BEHALF_FLOW_FOR_USERINFO_REQUIRED=trueis required when using that app-audience scope with Azure Entra ID- Your Azure app registration must have SharePoint and Graph API permissions
- Your Azure app registration must expose the LibreChat API scope used in
OPENID_SCOPE - All four SharePoint environment variables must be set
- HTTPS is required in production environments
Feature Capabilities
When enabled, users can: - Access files from SharePoint document libraries and OneDrive for Business - Select multiple files at once (default max: 10 files) - See real-time download progress
- Files are downloaded and attached to the conversation like regular uploads
For detailed SharePoint configuration instructions, see: SharePoint Integration Guide
SAML
For more information:
Mutual Exclusion of OpenID and SAML
If OpenID is enabled, SAML authentication will be automatically disabled.
Only one authentication method can be active at a time.
| Key | Type | Description | Example |
|---|---|---|---|
| SAML_ENTRY_POINT | string | The SAML identity provider (IdP) entry point URL. | SAML_ENTRY_POINT= |
| SAML_ISSUER | string | The SAML service provider (SP) entity ID. | SAML_ISSUER= |
| SAML_CERT | string | The SAML signing certificate, provided as a file path or a one-line PEM string. | SAML_CERT= |
| SAML_CALLBACK_URL | string | The callback URL for SAML authentication. | SAML_CALLBACK_URL=/oauth/saml/callback |
| SAML_SESSION_SECRET | string | The secret for SAML session storage. | SAML_SESSION_SECRET= |
| SAML_NAME_ID_FORMAT | string | Stable NameID format requested from the IdP. Persistent identifiers are recommended; transient identifiers are rejected. | # SAML_NAME_ID_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent |
| SAML_IDP_ISSUER | string | Expected IdP entity ID. When set, assertions with a missing or different issuer are rejected. | SAML_IDP_ISSUER= |
| SAML_EMAIL_CLAIM | string | <Optional>: The attribute in the SAML assertion containing the user email. (default: email) | SAML_EMAIL_CLAIM= |
| SAML_USERNAME_CLAIM | string | <Optional>: The attribute in the SAML assertion containing the username. (default: username) | SAML_USERNAME_CLAIM= |
| SAML_GIVEN_NAME_CLAIM | string | <Optional>: The attribute in the SAML assertion containing the given name. (default: given_name) | SAML_GIVEN_NAME_CLAIM= |
| SAML_FAMILY_NAME_CLAIM | string | <Optional>: The attribute in the SAML assertion containing the family name. (default: family_name) | SAML_FAMILY_NAME_CLAIM= |
| SAML_PICTURE_CLAIM | string | <Optional>: The attribute in the SAML assertion containing the profile picture URL. (default: picture) | SAML_PICTURE_CLAIM= |
| SAML_NAME_CLAIM | string | <Optional>: The attribute in the SAML assertion containing the full name. | SAML_NAME_CLAIM= |
| SAML_BUTTON_LABEL | string | <Optional>: The label for the SAML login button. | SAML_BUTTON_LABEL= |
| SAML_IMAGE_URL | string | <Optional>: The URL of the SAML login button image. | SAML_IMAGE_URL= |
| SAML_USE_AUTHN_RESPONSE_SIGNED | boolean | <Optional>: If "true", signs the entire SAML Response. Otherwise, only the Assertion is signed (default). | SAML_USE_AUTHN_RESPONSE_SIGNED= |
LDAP/AD Authentication
For more information: LDAP/AD Authentication
| Key | Type | Description | Example |
|---|---|---|---|
| LDAP_URL | string | LDAP server URL. | LDAP_URL=ldap://localhost:389 |
| LDAP_BIND_DN | string | Bind DN | LDAP_BIND_DN=cn=root |
| LDAP_BIND_CREDENTIALS | string | Password for bindDN | LDAP_BIND_CREDENTIALS=password |
| LDAP_USER_SEARCH_BASE | string | LDAP user search base | LDAP_USER_SEARCH_BASE=o=users,o=example.com |
| LDAP_SEARCH_FILTER | string | LDAP search filter | LDAP_SEARCH_FILTER=mail={{username}} |
| LDAP_CA_CERT_PATH | string | CA certificate path. | LDAP_CA_CERT_PATH=/path/to/root_ca_cert.crt |
| LDAP_TLS_REJECT_UNAUTHORIZED | boolean | Whether to verify the LDAP server certificate against LDAP_CA_CERT_PATH. Applies only when LDAP_CA_CERT_PATH is set: in that case, leaving it unset disables certificate verification, so set it to true. Without LDAP_CA_CERT_PATH, the Node.js default verification applies. | LDAP_TLS_REJECT_UNAUTHORIZED=true |
| LDAP_STARTTLS | string | Enable LDAP StartTLS for upgrading the connection to TLS. Set to true to enable this feature. | LDAP_STARTTLS=true |
| LDAP_LOGIN_USES_USERNAME | boolean | Use username instead of email for LDAP login. | # LDAP_LOGIN_USES_USERNAME=true |
| LDAP_ID | string | LDAP attribute for unique user ID. Default: uid or sAMAccountName, mail. | # LDAP_ID=uid |
| LDAP_USERNAME | string | LDAP attribute for username. Default: givenName or mail. | # LDAP_USERNAME=givenName |
| LDAP_EMAIL | string | LDAP attribute for email. Default: mail. | # LDAP_EMAIL=userPrincipalName |
| LDAP_FULL_NAME | string | LDAP attribute(s) for full name. Can be comma-separated. Default: givenName + surname. | # LDAP_FULL_NAME=givenName,surname |
Password Reset
Email is used for account verification and password reset. LibreChat supports both Mailgun API and traditional SMTP services. See: Email setup
Important Note: You must configure either Mailgun (recommended for servers that block SMTP) or SMTP for email to work.
Warning: Failing to set valid values for either Mailgun or SMTP will result in LibreChat using the unsecured password reset!
Mailgun Configuration (Recommended)
Mailgun is particularly useful for deployments on servers that block SMTP ports. When both MAILGUN_API_KEY and MAILGUN_DOMAIN are set, LibreChat will use Mailgun instead of SMTP.
| Key | Type | Description | Example |
|---|---|---|---|
| MAILGUN_API_KEY | string | Your Mailgun API key (required for Mailgun). | MAILGUN_API_KEY= |
| MAILGUN_DOMAIN | string | Your Mailgun domain (required for Mailgun). | MAILGUN_DOMAIN=mg.yourdomain.com |
| MAILGUN_HOST | string | Custom Mailgun API host (optional). Use https://api.eu.mailgun.net for EU region. | MAILGUN_HOST=https://api.mailgun.net |
| EMAIL_FROM | string | From email address. Required. | [email protected] |
| EMAIL_FROM_NAME | string | From name (defaults to APP_TITLE if not set). | EMAIL_FROM_NAME= |
SMTP Configuration
If Mailgun is not configured, LibreChat will fall back to SMTP settings.
Warning: If using
EMAIL_SERVICE, do NOT set the extended connection parameters: HOST, PORT, ENCRYPTION, ENCRYPTION_HOSTNAME, ALLOW_SELFSIGNED.
See: nodemailer well-known-services
| Key | Type | Description | Example |
|---|---|---|---|
| EMAIL_SERVICE | string | Email service (e.g., Gmail, Outlook). | EMAIL_SERVICE= |
| EMAIL_HOST | string | Mail server host. | EMAIL_HOST= |
| EMAIL_PORT | number | Mail server port. | EMAIL_PORT=25 |
| EMAIL_ENCRYPTION | string | Encryption method (starttls, tls, etc.). | EMAIL_ENCRYPTION= |
| EMAIL_ENCRYPTION_HOSTNAME | string | Hostname for encryption. | EMAIL_ENCRYPTION_HOSTNAME= |
| EMAIL_ALLOW_SELFSIGNED | boolean | Allow self-signed certificates. | EMAIL_ALLOW_SELFSIGNED= |
| EMAIL_USERNAME | string | Username for authentication. | EMAIL_USERNAME= |
| EMAIL_PASSWORD | string | Password for authentication. | EMAIL_PASSWORD= |
| EMAIL_FROM_NAME | string | From name. | EMAIL_FROM_NAME= |
| EMAIL_FROM | string | From email address. Required. | [email protected] |
Firebase CDN
See: Firebase CDN Configuration
Important
- If you are using Firebase as your file storage strategy, set
fileStrategyorfileStrategiestofirebasein yourlibrechat.yamlconfiguration file. For more information on configuring thelibrechat.yamlfile, please refer to the YAML Configuration Guide: Custom Endpoints & Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| FIREBASE_API_KEY | string | The API key for your Firebase project. | FIREBASE_API_KEY= |
| FIREBASE_AUTH_DOMAIN | string | The Firebase Auth domain for your project. | FIREBASE_AUTH_DOMAIN= |
| FIREBASE_PROJECT_ID | string | The ID of your Firebase project. | FIREBASE_PROJECT_ID= |
| FIREBASE_STORAGE_BUCKET | string | The Firebase Storage bucket for your project. | FIREBASE_STORAGE_BUCKET= |
| FIREBASE_MESSAGING_SENDER_ID | string | The Firebase Cloud Messaging sender ID. | FIREBASE_MESSAGING_SENDER_ID= |
| FIREBASE_APP_ID | string | The Firebase App ID for your project. | FIREBASE_APP_ID= |
Amazon S3 and CloudFront
See: Amazon S3 Configuration and CloudFront with S3
Important
If you are using S3 as your file storage strategy, set fileStrategy or fileStrategies in your
librechat.yaml configuration file. If you use CloudFront, S3 is still required as the storage
origin.
| Key | Type | Description | Example |
|---|---|---|---|
| AWS_ACCESS_KEY_ID | string | Your IAM user access key ID. Optional if using IRSA. | AWS_ACCESS_KEY_ID=your_access_key_id |
| AWS_SECRET_ACCESS_KEY | string | Your IAM user secret access key. Optional if using IRSA. | AWS_SECRET_ACCESS_KEY=your_secret_access_key |
| AWS_REGION | string | The AWS region where your S3 bucket is located. | AWS_REGION=us-east-1 |
| AWS_BUCKET_NAME | string | The name of the S3 bucket for file storage. | AWS_BUCKET_NAME=your_bucket_name |
| AWS_ENDPOINT_URL | string | Custom AWS endpoint URL (optional). For S3-compatible services. Include the URL scheme, such as https://a7g8.da.idrivee2-32.com. | # AWS_ENDPOINT_URL=https://your_endpoint_url |
| AWS_FORCE_PATH_STYLE | boolean | Set to true for S3-compatible providers that require path-style URLs (e.g. MinIO, Hetzner, Backblaze B2). Not needed for AWS S3. Default: false. | # AWS_FORCE_PATH_STYLE=false |
| CLOUDFRONT_KEY_PAIR_ID | string | CloudFront public key pair ID. Required for signed cookies and signed CloudFront download URLs. | # CLOUDFRONT_KEY_PAIR_ID=K1234567890ABC |
| CLOUDFRONT_PRIVATE_KEY | string | CloudFront private key PEM. Required for signed cookies and signed CloudFront download URLs. Preserve PEM newlines when injecting this secret. | # CLOUDFRONT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----" |
Note: For Kubernetes deployments (e.g., on EKS), you can use IRSA (IAM Roles for Service Accounts) instead of providing explicit credentials. In that case, only
AWS_REGIONandAWS_BUCKET_NAMEare required.
Azure Blob Storage CDN
See: Azure Blob Storage CDN Configuration
Important
If you are using Azure Blob Storage as your file storage strategy, set fileStrategy or
fileStrategies to azure_blob in your librechat.yaml configuration file.
| Key | Type | Description | Example |
|---|---|---|---|
| AZURE_STORAGE_CONNECTION_STRING | string | Azure Blob Storage connection string. Use this OR AZURE_STORAGE_ACCOUNT_NAME for Managed Identity. | AZURE_STORAGE_CONNECTION_STRING=DefaultEndpointsProtocol=https;AccountName=... |
| AZURE_STORAGE_ACCOUNT_NAME | string | Azure Storage account name. Use for Managed Identity authentication (do not set connection string). | # AZURE_STORAGE_ACCOUNT_NAME=yourAccountName |
| AZURE_STORAGE_PUBLIC_ACCESS | boolean | Make uploaded blobs publicly readable. Default: true; set it to false to keep blobs private. | AZURE_STORAGE_PUBLIC_ACCESS=false |
| AZURE_CONTAINER_NAME | string | Container name for file storage. Default: files. | AZURE_CONTAINER_NAME=files |
Note: Use either
AZURE_STORAGE_CONNECTION_STRING(Option A) orAZURE_STORAGE_ACCOUNT_NAMEwith Managed Identity (Option B), not both.
UI
Help and FAQ Button
| Key | Type | Description | Example |
|---|---|---|---|
| HELP_AND_FAQ_URL | string | Help and FAQ URL. If empty or commented, the button is enabled. To disable the Help and FAQ button, set to "/". | HELP_AND_FAQ_URL=https://librechat.ai |
Behaviour:
Sets the Cache-Control headers for static files. These configurations only trigger when the NODE_ENV is set to production.
Properly setting cache headers is crucial for optimizing the performance and efficiency of your web application. By controlling how long browsers and CDNs store copies of your static files, you can significantly reduce server load, decrease page load times, and improve the overall user experience.
- Uncomment
STATIC_CACHE_MAX_AGEto change themax-agefor static files. By default this is set to 4 weeks. - Uncomment
STATIC_CACHE_S_MAX_AGEto change thes-maxagefor static files. By default this is set to 1 week.- This is for the shared cache, which is used by CDNs and proxies.
App Title and Footer
| Key | Type | Description | Example |
|---|---|---|---|
| APP_TITLE | string | App title. | APP_TITLE=LibreChat |
| CUSTOM_FOOTER | string | Custom footer. | # CUSTOM_FOOTER="My custom footer" |
| TEMP_CHAT_RETENTION_HOURS | number | **Deprecated:** Use `interface.temporaryChatRetention` in librechat.yaml instead. Hours to retain temporary chats. Default: 720 (30 days). | # TEMP_CHAT_RETENTION_HOURS=168 |
Behaviour:
- Uncomment
CUSTOM_FOOTERto add a custom footer. - Uncomment and leave
CUSTOM_FOOTERempty to remove the footer. - You can now add one or more links in the CUSTOM_FOOTER value using the following format:
[Anchor text](URL). Each link should be delineated with a pipe (|).
Markdown example:
CUSTOM_FOOTER=[Link 1](http://example1.com) | [Link 2](http://example2.com)
Theme Colors
| Key | Type | Description | Example |
|---|---|---|---|
| REACT_APP_THEME_<TOKEN> | string | Overrides one theme color token at build time. The value is a space-separated `R G B` triplet. | # REACT_APP_THEME_SURFACE_SUBMIT=4 120 87 |
Behaviour:
- Every color token in the theme engine can be set this way: drop the
rgb-prefix from the token name and upper-snake-case the rest, sorgb-surface-submitbecomesREACT_APP_THEME_SURFACE_SUBMITandrgb-status-error-borderbecomesREACT_APP_THEME_STATUS_ERROR_BORDER. The token list is theIThemeRGBinterface inpackages/client/src/theme/types/index.ts. - Values are inlined into the client when it is built, so the client has to be rebuilt after changing them. Setting them on a prebuilt Docker image has no effect.
- The same colors apply in light and dark mode, and they only change colors, not shape.
interface.themeinlibrechat.yamloutranks these colors, and the high-contrast modes outrank both.interface.themealso needs no rebuild and can change shape, so prefer it for new deployments.
Birthday Hat
| Key | Type | Description | Example |
|---|---|---|---|
| SHOW_BIRTHDAY_ICON | boolean | Show the birthday hat icon. | # SHOW_BIRTHDAY_ICON=true |
Behaviour:
- The birthday hat icon will show automatically on February 11th (LibreChat's birthday).
- Set
SHOW_BIRTHDAY_ICONtofalseto disable the birthday hat. - Set
SHOW_BIRTHDAY_ICONtotrueto enable the birthday hat all the time.
Analytics
Google Tag Manager
LibreChat supports Google Tag Manager for analytics. You will need a Google Tag Manager ID to enable it in LibreChat. Follow this guide to generate a Google Tag Manager ID and configure Google Analytics. Then set the ANALYTICS_GTM_ID environment variable to your Google Tag Manager ID.
Note: If ANALYTICS_GTM_ID is not set, Google Tag Manager will not be enabled. If it is set incorrectly, you will see failing requests to gtm.js
Google Tag Manager loads only after a user accepts the analytics consent banner, and users can change their answer later in Settings > Data. Deployments that handle consent themselves can skip the banner with interface.analyticsConsent: false.
| Key | Type | Description | Example |
|---|---|---|---|
| ANALYTICS_GTM_ID | string | Google Tag Manager ID. | ANALYTICS_GTM_ID= |
Conversation Import
Configure limits for conversation file imports to prevent memory issues.
| Key | Type | Description | Example |
|---|---|---|---|
| CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES | number | Maximum file size in bytes for conversation imports. Default: 0 (no limit enforced). Example: 262144000 (250 MiB). | # CONVERSATION_IMPORT_MAX_FILE_SIZE_BYTES=262144000 |
Inline File Previews
Control how large generated files can be before LibreChat skips inline preview extraction and leaves them download-only.
| Key | Type | Description | Example |
|---|---|---|---|
| FILE_PREVIEW_MAX_EXTRACT_BYTES | number | Maximum source file size in bytes for code-execution artifact inline previews, including DOCX, XLSX, CSV, PPTX, POTX, text, and PDF-like files. Default: 2097152 (2 MiB). Rendered HTML previews are still capped separately, so very rich files may skip preview even below this value. | # FILE_PREVIEW_MAX_EXTRACT_BYTES=2097152 |
| OFFICE_PREVIEW_DISABLE_CDN | boolean | Render DOCX previews on the server instead of loading a renderer from cdn.jsdelivr.net. Set to true on air-gapped or filtered networks. Accepts true, 1, or yes. Default: false. | # OFFICE_PREVIEW_DISABLE_CDN=true |
MCP (Model Context Protocol)
Configure Model Context Protocol settings for enhanced server management and OAuth support.
MCP Server Configuration
| Key | Type | Description | Example |
|---|---|---|---|
| MCP_OAUTH_ON_AUTH_ERROR | boolean | Treat 401/403 responses as OAuth requirement when no oauth metadata found. | MCP_OAUTH_ON_AUTH_ERROR=true |
| MCP_OAUTH_DETECTION_TIMEOUT | number | Timeout for OAuth detection requests in milliseconds. | MCP_OAUTH_DETECTION_TIMEOUT=5000 |
| MCP_OAUTH_HANDLING_TIMEOUT | number | How long LibreChat waits for a user to complete an MCP OAuth flow before timing out. Default: 600000 ms (10 minutes). | MCP_OAUTH_HANDLING_TIMEOUT=600000 |
| MCP_OAUTH_FLOW_TTL | number | How long MCP OAuth flow state is retained. LibreChat clamps this above MCP_OAUTH_HANDLING_TIMEOUT so callbacks near the deadline can still complete. Default: 900000 ms (15 minutes). | MCP_OAUTH_FLOW_TTL=900000 |
| MCP_CONNECTION_CHECK_TTL | number | Cache connection status checks for this many milliseconds to avoid expensive verification. Default: 60000. | MCP_CONNECTION_CHECK_TTL=60000 |
| MCP_TOOLS_LIST_MAX_PAGES | number | Maximum number of tools/list pages to request when an MCP server paginates its tool list (cursor pagination). Bounds the pagination loop so a misbehaving server cannot stall tool discovery. Clamped to a minimum of 1. Default: 50. | MCP_TOOLS_LIST_MAX_PAGES=50 |
| MCP_SKIP_CODE_CHALLENGE_CHECK | boolean | Skip code challenge method validation. When set to true, forces S256 code challenge even if not advertised in .well-known/openid-configuration | MCP_SKIP_CODE_CHALLENGE_CHECK=false |
| MCP_STREAMABLE_HTTP_MAX_RESPONSE_BYTES | number | Maximum 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 |
| MCP_STREAMABLE_HTTP_MAX_LINE_BYTES | number | Maximum bytes allowed in one 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 |
| MCP_TOOLS_LIST_MAX_TOOLS | number | Maximum total tools retained from paginated tools/list responses. Clamped to a minimum of 1. Default: 1000. | # MCP_TOOLS_LIST_MAX_TOOLS=1000 |
| MCP_TOOLS_LIST_MAX_BYTES | number | Maximum approximate JSON bytes retained from paginated tools/list responses. Clamped to a minimum of 1. Default: 5242880 (5 MiB). | # MCP_TOOLS_LIST_MAX_BYTES=5242880 |
| MCP_TOOLS_LIST_TIMEOUT_MS | number | Maximum elapsed time in milliseconds for paginated tools/list discovery. Clamped to a minimum of 1. Default: 30000. | # MCP_TOOLS_LIST_TIMEOUT_MS=30000 |
| MCP_USER_CONNECTION_IDLE_TIMEOUT | number | Idle time in milliseconds after which per-user MCP connections are disconnected. Default: 900000 (15 minutes). | # MCP_USER_CONNECTION_IDLE_TIMEOUT=900000 |
| MCP_REGISTRY_CACHE_TTL | number | TTL in milliseconds for the MCP server registry caches. With multiple instances, cross-instance staleness can reach twice this value. Set to 0 to disable the local snapshot so every read goes to Redis. Default: 5000. | # MCP_REGISTRY_CACHE_TTL=5000 |
| MCP_INIT_TIMEOUT_MS | number | Time in milliseconds allowed for MCP servers to initialize at startup. Default: 30000. | # MCP_INIT_TIMEOUT_MS=30000 |
| MCP_INIT_FOLLOWER_RETRY_MS | number | In multi-instance deployments, how often non-leader instances check whether the leader finished initializing MCP servers, in milliseconds. Default: 3000. | # MCP_INIT_FOLLOWER_RETRY_MS=3000 |
| MCP_INIT_FOLLOWER_MAX_WAIT_MS | number | Maximum time in milliseconds a non-leader instance waits for the leader to finish MCP initialization. Set to 0 for no wait. Default: MCP_INIT_TIMEOUT_MS plus MCP_INIT_FOLLOWER_RETRY_MS. | # MCP_INIT_FOLLOWER_MAX_WAIT_MS=33000 |
| MCP_IMAGE_DATA_MAX_BYTES | number | Maximum size in bytes of inline image data in an MCP tool result. Larger results are rejected; remote image URLs are not counted. Default: 10485760 (10 MiB). | # MCP_IMAGE_DATA_MAX_BYTES=10485760 |
| MCP_SANDBOX_FRAME_ANCESTORS | string | Comma-separated origins allowed to embed the MCP app sandbox frame. When unset, embedding is denied (frame-ancestors none). | # MCP_SANDBOX_FRAME_ANCESTORS=https://chat.example.com |
MCP Connection Circuit Breaker
LibreChat limits how often it reconnects to an MCP server so a failing or flapping server cannot trigger a reconnect storm. Two independent checks apply. The cycle breaker trips after MCP_CB_MAX_CYCLES connect and disconnect cycles within MCP_CB_CYCLE_WINDOW_MS, then refuses new connection attempts for MCP_CB_CYCLE_COOLDOWN_MS. The failure backoff starts once MCP_CB_MAX_FAILED_ROUNDS consecutive failed connection rounds occur within MCP_CB_FAILED_WINDOW_MS; retries then wait an exponentially growing delay that starts at MCP_CB_BASE_BACKOFF_MS and is capped at MCP_CB_MAX_BACKOFF_MS.
| Key | Type | Description | Example |
|---|---|---|---|
| MCP_CB_MAX_CYCLES | number | Connect and disconnect cycles allowed within the cycle window before the breaker trips. Default: 7. | # MCP_CB_MAX_CYCLES=7 |
| MCP_CB_CYCLE_WINDOW_MS | number | Sliding window in milliseconds for counting cycles. Default: 45000. | # MCP_CB_CYCLE_WINDOW_MS=45000 |
| MCP_CB_CYCLE_COOLDOWN_MS | number | Cooldown in milliseconds after the cycle breaker trips. Default: 15000. | # MCP_CB_CYCLE_COOLDOWN_MS=15000 |
| MCP_CB_MAX_FAILED_ROUNDS | number | Consecutive failed connection rounds allowed before backoff begins. Default: 3. | # MCP_CB_MAX_FAILED_ROUNDS=3 |
| MCP_CB_FAILED_WINDOW_MS | number | Sliding window in milliseconds for counting failed rounds. Default: 120000. | # MCP_CB_FAILED_WINDOW_MS=120000 |
| MCP_CB_BASE_BACKOFF_MS | number | Base backoff in milliseconds once the failed round threshold is reached. Default: 30000. | # MCP_CB_BASE_BACKOFF_MS=30000 |
| MCP_CB_MAX_BACKOFF_MS | number | Maximum backoff in milliseconds for exponential backoff. Default: 300000. | # MCP_CB_MAX_BACKOFF_MS=300000 |
Other
Redis
Redis provides significant performance improvements and enables horizontal scaling capabilities for LibreChat.
Note: Redis support is experimental, and you may encounter some problems when using it.
Important: If using Redis, you should flush the cache after changing any LibreChat settings.
For detailed configuration and examples, see: Redis Configuration Guide
| Key | Type | Description | Example |
|---|---|---|---|
| USE_REDIS | boolean | Enable Redis for caching and session storage. When true, REDIS_URI must be provided. | USE_REDIS=true |
| USE_REDIS_STREAMS | boolean | Enable Redis for resumable LLM streams. Defaults to USE_REDIS value if not set. Set to false to use in-memory storage for streams. | # USE_REDIS_STREAMS=true |
| STREAM_DELTA_COALESCE_MS | integer | Batch Redis stream delta publications within this many milliseconds. Default: 25. Set to 0 to publish every delta on its own. Values are capped at 1000. In-memory streams are not affected. | # STREAM_DELTA_COALESCE_MS=25 |
| REDIS_URI | string | Redis connection URI. For single instance: `redis://host:port`. For cluster: comma-separated URIs. | REDIS_URI=redis://127.0.0.1:6379 |
| USE_REDIS_CLUSTER | boolean | Enable Redis cluster mode when using a single URI | # USE_REDIS_CLUSTER="true" |
| REDIS_CLUSTER_SAFE_DELETE | boolean | Delete Redis cache keys individually to avoid CROSSSLOT errors on single-endpoint managed Redis services that shard keys internally. | # REDIS_CLUSTER_SAFE_DELETE=true |
| REDIS_USERNAME | string | Redis username for authentication. Used only when REDIS_URI has no username; a username in the URI wins. | # REDIS_USERNAME=your_redis_username |
| REDIS_PASSWORD | string | Redis password for authentication. Used only when REDIS_URI has no password; a password in the URI wins. | # REDIS_PASSWORD=your_redis_password |
| REDIS_CA | string | Path to CA certificate for TLS verification when using rediss:// protocol. | # REDIS_CA=/path/to/ca-cert.pem |
| REDIS_KEY_PREFIX | string | Static prefix for all Redis keys to prevent cross-deployment contamination. | # REDIS_KEY_PREFIX=librechat-prod-v2 |
| REDIS_KEY_PREFIX_VAR | string | Environment variable name containing dynamic prefix (e.g., K_REVISION for Cloud Run). Cannot be used with REDIS_KEY_PREFIX. | # REDIS_KEY_PREFIX_VAR=K_REVISION |
| REDIS_MAX_LISTENERS | number | Maximum event listeners per Redis client. Prevents memory leaks. Default: 40. | # REDIS_MAX_LISTENERS=40 |
| REDIS_READONLY_RECOVERY_INTERVAL | number | Minimum milliseconds between forced Keyv reconnect attempts after READONLY replies during standalone or Sentinel failover. Default: 5000. | # REDIS_READONLY_RECOVERY_INTERVAL=5000 |
| REDIS_PING_INTERVAL | number | Ping interval in seconds to maintain connections. Default: 0 (disabled). Only set if experiencing timeouts. | # REDIS_PING_INTERVAL=300 |
| REDIS_PING_TIMEOUT | number | Milliseconds an enabled heartbeat PING may remain unanswered before LibreChat reconnects the socket. Default: 5000. | # REDIS_PING_TIMEOUT=5000 |
| REDIS_SUBSCRIBER_PING_INTERVAL | number | Heartbeat interval in seconds for dedicated pub/sub subscriber connections. Default: 15; set to 0 to disable. | # REDIS_SUBSCRIBER_PING_INTERVAL=15 |
| REDIS_KEEP_ALIVE | number | TCP keepalive idle delay in milliseconds for ioredis sockets. Default: 10000; set to 0 for the kernel default. | # REDIS_KEEP_ALIVE=10000 |
| REDIS_CONNECT_TIMEOUT | number | Connection timeout in milliseconds. Default: 10000. | # REDIS_CONNECT_TIMEOUT=10000 |
| REDIS_RETRY_MAX_ATTEMPTS | number | Maximum number of reconnection attempts. Set to 0 for unlimited attempts. Default: 10. | # REDIS_RETRY_MAX_ATTEMPTS=10 |
| REDIS_RETRY_MAX_DELAY | number | Maximum delay between reconnection attempts in milliseconds. Default: 3000. | # REDIS_RETRY_MAX_DELAY=3000 |
| REDIS_ENABLE_OFFLINE_QUEUE | boolean | Queue commands while the connection is down instead of failing them immediately. Default: true. | # REDIS_ENABLE_OFFLINE_QUEUE=true |
| REDIS_SCAN_COUNT | number | COUNT hint for Redis SCAN operations when scanning keys by pattern. Higher values reduce round trips but increase per-call memory and latency. Default: 1000. | # REDIS_SCAN_COUNT=1000 |
| REDIS_DELETE_CHUNK_SIZE | number | Number of keys deleted per batch in Redis DEL operations. In cluster mode, keys are deleted individually in parallel chunks of this size. Lower values reduce memory use but increase round trips. Default: 1000. | # REDIS_DELETE_CHUNK_SIZE=1000 |
| STREAM_KEEP_COMPLETED_JOBS | boolean | Keep completed generation stream jobs instead of removing them when generation finishes. Default: false. | # STREAM_KEEP_COMPLETED_JOBS=false |
| FORCED_IN_MEMORY_CACHE_NAMESPACES | string | Comma-separated cache keys to force in-memory storage even when Redis is enabled. | # FORCED_IN_MEMORY_CACHE_NAMESPACES=ROLES,MESSAGES |
| AUTH_USER_CACHE_MODE | string | Set exactly to `on` to cache authenticated user documents during request bursts. Requires Redis and a Redis-backed AUTH_USER_DOC namespace. Default: off. | # AUTH_USER_CACHE_MODE=off |
| USER_PRINCIPALS_CACHE_TTL_MS | number | TTL in milliseconds for cached group memberships used in ACL checks. Set to 0 to disable. Default: 300000. | # USER_PRINCIPALS_CACHE_TTL_MS=300000 |
| USER_PRINCIPALS_LOCK_TTL_MS | number | Redis lock TTL in milliseconds for cross-container principal-cache builds. Set to 0 to disable build locking. Default: 5000. | # USER_PRINCIPALS_LOCK_TTL_MS=5000 |
| USER_PRINCIPALS_LOCK_WAIT_MS | number | Maximum time to wait for another container to fill the principal cache before reading the database directly. Defaults to USER_PRINCIPALS_LOCK_TTL_MS. | # USER_PRINCIPALS_LOCK_WAIT_MS=5000 |
| REDIS_USE_ALTERNATIVE_DNS_LOOKUP | boolean | Enable alternate dnsLookup for TLS connections with AWS Elasticache. Required for Elasticache clusters with TLS. | # REDIS_USE_ALTERNATIVE_DNS_LOOKUP=true |
Notes:
- When
USE_REDIS=true, you must provideREDIS_URIor the application will throw an error. - Current LibreChat clients negotiate generation protocol v2 automatically. The retired
GENERATION_PROTOCOL_VERSIONvariable is no longer read. See Generation Protocol Compatibility before mixing release versions or rolling back. - Redis streams coalesce deltas in a 25 ms window by default, and each event is still published as an individually sequenced chunk frame, so subscribers from earlier releases keep working. Set
STREAM_DELTA_COALESCE_MS=0to publish every delta on its own. See Stream Delta Coalescing. - For Redis Cluster mode, provide multiple URIs:
redis://node1:7001,redis://node2:7002,redis://node3:7003(cluster mode is auto-detected). - For single-endpoint managed Redis services that shard keys internally, keep
USE_REDIS_CLUSTER=falseand setREDIS_CLUSTER_SAFE_DELETE=trueif cache clears fail withCROSSSLOTerrors. REDIS_READONLY_RECOVERY_INTERVALdebounces Keyv reconnect attempts after a failover leaves an open socket attached to a demoted read-only replica. Redis Cluster clients use their native topology handling instead.REDIS_PING_INTERVALcontrols the optional heartbeat on the main ioredis client; dedicated pub/sub subscribers useREDIS_SUBSCRIBER_PING_INTERVALso an otherwise idle dead socket is detected. Both useREDIS_PING_TIMEOUTas the response deadline and reconnect when it expires.- Use
rediss://protocol for TLS connections and setREDIS_CAif your CA is not publicly trusted. REDIS_KEY_PREFIX_VARandREDIS_KEY_PREFIXare mutually exclusive.- AWS Elasticache with TLS: Elasticache may need to use an alternate dnsLookup for TLS connections. Set
REDIS_USE_ALTERNATIVE_DNS_LOOKUP=trueif using Elasticache with TLS. See ioredis documentation for more details.
Leader Election
Configure distributed leader election for multi-instance deployments with Redis. Leader election ensures only one instance performs certain operations like scheduled tasks.
| Key | Type | Description | Example |
|---|---|---|---|
| LEADER_LEASE_DURATION | number | Duration in seconds that the leader lease is valid before it expires. Default: 25. | LEADER_LEASE_DURATION=25 |
| LEADER_RENEW_INTERVAL | number | Interval in seconds at which the leader renews its lease. Default: 10. | LEADER_RENEW_INTERVAL=10 |
| LEADER_RENEW_ATTEMPTS | number | Maximum number of retry attempts when renewing the lease fails. Default: 3. | LEADER_RENEW_ATTEMPTS=3 |
| LEADER_RENEW_RETRY_DELAY | number | Delay in seconds between retry attempts when renewing the lease. Default: 0.5. | LEADER_RENEW_RETRY_DELAY=0.5 |
Notes:
- Leader election requires Redis to be enabled (
USE_REDIS=true). - These settings are only relevant for multi-instance deployments.
- The leader lease must be renewed before expiration to maintain leadership.
- If lease renewal fails after max attempts, the instance will relinquish leadership.
Config Endpoint Re-derivation
CONFIG_REDERIVE_ENDPOINTS defaults to off. Set it to true to re-derive served Azure groups, Anthropic Vertex AI settings, and the Azure Assistants switch from configuration profiles. Without it, these profile overrides remain stored but inert. Check startup diagnostics before enabling the feature; /api/admin/config/meta exposes the effective features.endpointRederive flag.
Vertex AI overrides can reference only environment names already referenced by deployment YAML's own endpoints.anthropic.vertex settings. CONFIG_OVERRIDE_ENV_ALLOWLIST does not widen that boundary.
Langfuse Prompt Catalog Controls
| Variable | Default | Purpose |
|---|---|---|
LANGFUSE_PROMPT_SYNC_AVAILABLE | false | Offers prompt-sync settings to authorized administrators. The stored Base langfuse.promptSync.enabled switch must also be enabled. |
LANGFUSE_PROMPT_SYNC_TIMEOUT_MS | 10000 | Milliseconds per upstream prompt API request, not per whole sync. Finite values are rounded and clamped to 1000–60000; unset or non-numeric values use the default. |
See prompt catalog setup for connection selection, permissions, source identity, and read-only imports.
How is this guide?