mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-05-13 16:07:30 +00:00
* 🪟 feat: Add allowedAddresses Exemption List For SSRF-Guarded Targets LibreChat already blocks SSRF-prone targets (private IPs, loopback, link-local, .internal/.local TLDs) at every server-side fetch site that consumes user-controllable URLs — custom-endpoint baseURLs, MCP servers, OpenAPI Actions, and OAuth endpoints. The only existing escape hatch is `allowedDomains`, but that flips the field into a strict whitelist: adding `127.0.0.1` to permit a self-hosted Ollama also blocks every public destination that isn't in the list. Introduce `allowedAddresses` as the orthogonal primitive: a private- IP-space exemption list. When a hostname or its resolved IP appears in the list, the SSRF block is bypassed for that target. Public destinations remain reachable. Operators can now run self-hosted LLMs / MCP servers / Action endpoints on private addresses without weakening the default-deny posture for everything else. Schema additions in `packages/data-provider/src/config.ts`: - `endpoints.allowedAddresses` (new — gates `validateEndpointURL`) - `mcpSettings.allowedAddresses` (parallel to `allowedDomains`) - `actions.allowedAddresses` (parallel to `allowedDomains`) Core changes in `packages/api/src/auth/`: - New `isAddressAllowed(hostnameOrIP, allowedAddresses)` — pure, case-insensitive, bracket-stripped literal match. - Threaded the list through `isSSRFTarget`, `resolveHostnameSSRF`, `isDomainAllowedCore`, `isActionDomainAllowed`, `isMCPDomainAllowed`, `isOAuthUrlAllowed`, and `validateEndpointURL`. - Extended `createSSRFSafeAgents` and `createSSRFSafeUndiciConnect` to accept the list, building an SSRF-safe DNS lookup that exempts matching hostnames/IPs at TCP connect time (TOCTOU-safe). Wiring: - Custom and OpenAI endpoint initialize sites pass `endpoints.allowedAddresses` to `validateEndpointURL`. - `MCPServersRegistry` stores `allowedAddresses` and exposes it via `getAllowedAddresses()`. The factory, connection class, manager, `UserConnectionManager`, and `ConnectionsRepository` all thread it through to the SSRF utilities. - `MCPOAuthHandler.initiateOAuthFlow`, `refreshOAuthTokens`, and `validateOAuthUrl` accept the list and consult it on every URL validation along the OAuth chain. - `ToolService`, `ActionService`, and the assistants/agents action routes pass `actions.allowedAddresses` to `isActionDomainAllowed` and to `createSSRFSafeAgents` for runtime action calls. - `initializeMCPs.js` reads `mcpSettings.allowedAddresses` from the app config and forwards it to the registry constructor. Documentation: - `librechat.example.yaml` shows the new field next to each existing `allowedDomains` block, with a note clarifying that `allowedAddresses` is an exemption list (not a whitelist). Tests: - Unit tests for `isAddressAllowed` covering literal IPs, hostnames, IPv6 brackets, case insensitivity, and partial-match rejection. - Exemption tests for every entry point: `isSSRFTarget`, `resolveHostnameSSRF`, `validateEndpointURL`, `isActionDomainAllowed`, `isMCPDomainAllowed`, `isOAuthUrlAllowed`. - Existing tests updated to reflect the new optional parameter. Default behavior is unchanged: omitted = empty list = no exemptions. * 🩹 fix: Plumb allowedAddresses Through AppConfig endpoints Type The initial PR added `endpoints.allowedAddresses` to the data-provider config schema and consumed it in the endpoint initialize sites, but the runtime `AppConfig.endpoints` shape in `@librechat/data-schemas` was a hand-maintained subset that didn't include the new field — so `tsc` rejected `appConfig.endpoints.allowedAddresses`. Add the field to `AppConfig['endpoints']` in `packages/data-schemas/src/types/app.ts` and forward it from the loaded config in `packages/data-schemas/src/app/endpoints.ts` so the runtime config carries the value. Update `initializeMCPs.spec.js` to expect the third positional argument (`allowedAddresses`) on the `createMCPServersRegistry` call. * 🩹 fix: Enforce allowedDomains Before allowedAddresses In isOAuthUrlAllowed The initial implementation checked the address exemption first, so a URL whose hostname appeared in `allowedAddresses` would return true even when the admin had configured `allowedDomains` as a strict bound on OAuth endpoints. A malicious MCP server could advertise OAuth metadata, token, or revocation URLs at any address the admin had permitted for an unrelated reason (a self-hosted LLM at `127.0.0.1`, for example) and pass validation, expanding SSRF reach beyond the configured domain whitelist. Reorder: when `allowedDomains` is set, treat it as authoritative — return true only if the URL matches a domain entry, otherwise fall through to false. The address exemption only applies when no `allowedDomains` is configured (mirrors how the downstream SSRF check in `validateOAuthUrl` consults `allowedAddresses`). Add a regression test asserting that an `allowedAddresses` entry does not broaden a configured `allowedDomains` list. Reported by chatgpt-codex-connector on PR #12933. * 🩹 fix: Forward allowedAddresses To Remaining OAuth Callers Two `MCPOAuthHandler` callers still used the pre-feature signatures and were silently dropping the new `allowedAddresses` argument: - `api/server/routes/mcp.js` invoked `initiateOAuthFlow` with the old 5-argument shape, so OAuth flows initiated through the route handler ignored the registry's `getAllowedAddresses()` and would reject any metadata/authorization/token URL on a permitted private host. - `api/server/controllers/UserController.js#maybeUninstallOAuthMCP` invoked `revokeOAuthToken` without the address exemption, so uninstalling an OAuth-backed MCP server on a permitted private host would fail at the revocation step even though the rest of the MCP connection path now permits it. Both sites now read `allowedAddresses` from the registry alongside `allowedDomains` and forward it. Reported by Copilot on PR #12933. * 🩹 fix: Update Test Mocks And Assertions For OAuth allowedAddresses The previous commit started passing `allowedAddresses` to `MCPOAuthHandler.initiateOAuthFlow` from `api/server/routes/mcp.js` and to `MCPOAuthHandler.revokeOAuthToken` from `api/server/controllers/UserController.js`, but the corresponding test files mocked the registry without `getAllowedAddresses` (causing `TypeError`s) and asserted the old positional shape on `toHaveBeenCalledWith`. Update the mocks and assertions to match the new arity: - `api/server/routes/__tests__/mcp.spec.js`: add `getAllowedDomains`/`getAllowedAddresses` to the registry mock and expect the additional positional args on `initiateOAuthFlow`. - `api/server/controllers/__tests__/maybeUninstallOAuthMCP.spec.js`: add a `getAllowedAddresses` mock alongside the existing `getAllowedDomains` and seed it in `setupOAuthServerFound`. - `api/server/controllers/__tests__/UserController.mcpOAuth.spec.js`: add `getAllowedAddresses` to the registry mock and expect the trailing `null` arg on the three `revokeOAuthToken` assertions. * 🛡️ fix: Address Comprehensive Review — Scope allowedAddresses To Private IP Space Major findings from the comprehensive PR review (severity → fix): **CRITICAL — `validateOAuthUrl` SSRF fallback bypass.** When `allowedDomains` is configured and a URL fails the whitelist, the SSRF fallback in `validateOAuthUrl` was still passing `allowedAddresses` to `isSSRFTarget` / `resolveHostnameSSRF`, letting a malicious MCP server advertise OAuth endpoints at any address the admin had permitted for an unrelated reason. Suppress `allowedAddresses` in the fallback when `allowedDomains` is active — the address exemption is opt-in for the no-whitelist mode only. **MAJOR — WebSocket transport SSRF check ignored exemptions.** The `constructTransport` WebSocket branch called `resolveHostnameSSRF(wsHostname)` without `this.allowedAddresses`, so a permitted private MCP server would pass `isMCPDomainAllowed` but be blocked at transport creation. Forward the exemption. **Scope `allowedAddresses` to private IP space only (operator directive).** The exemption list is for permitting private/internal targets; it must not be a back-door to broaden trust to public destinations. - Schema (`packages/data-provider/src/config.ts`): new `allowedAddressesSchema` rejects URLs (`://`), paths/CIDR (`/`), whitespace, and public IPv4/IPv6 literals at config-load time. Wired into `endpoints`, `mcpSettings`, and `actions`. - Runtime (`packages/api/src/auth/domain.ts`): `isAddressAllowed` now drops public-IP candidates and public-IP entries on the match path — defense in depth so a misconfigured runtime list never grants exemption. - Hot path (`packages/api/src/auth/agent.ts`): `buildSSRFSafeLookup` pre-normalizes the list into a `Set<string>` once at construction and applies the same scoping filter, so the connect-time DNS lookup is an O(1) Set membership check instead of a full re-iterate-and-normalize on every outbound request. **Test coverage for the connect-time and OAuth-fallback paths.** - `agent.spec.ts`: new describe block exercising `buildSSRFSafeLookup` and `createSSRFSafe*` with `allowedAddresses` — hostname-literal exemption, resolved-IP exemption, public-IP scoping, URL/CIDR/whitespace rejection, and the default no-list block. - `handler.allowedAddresses.test.ts` (new): integration tests for `validateOAuthUrl` — covers both the no-domains-set "permit private" path and the strict-bound regression where `allowedAddresses` must NOT bypass `allowedDomains`. **Documentation & cleanup.** - `connection.ts` redirect SSRF check: explicit comment that `allowedAddresses` is intentionally NOT consulted for redirect targets (server-controlled, must not inherit the admin's exemption). - `MCPConnectionFactory.test.ts`: replaced an `eslint-disable` with a proper `import { getTenantId } from '@librechat/data-schemas'`. The disable was added to make a pre-existing `require()` quiet — the cleaner fix is to use the existing top-level import. Updated `MCPConnectionSSRF.test.ts` WebSocket SSRF assertions to match the new two-argument call shape (`hostname, allowedAddresses`). * 🩹 fix: Require Absolute URL Before allowedAddresses Trust Bypass In isOAuthUrlAllowed `parseDomainSpec` is lenient — it silently prepends `https://` to schemeless inputs so it can match patterns like bare `example.com`. That leniency leaked into `isOAuthUrlAllowed`'s new `allowedAddresses` short-circuit: a value like `10.0.0.5/oauth` (no scheme) would parse successfully via the prepended default, hit the address-exemption path, return `true`, and skip `validateOAuthUrl`'s strict `new URL(url)` parse-or-throw — only to fail later in OAuth discovery with a less clear runtime error. Add a strict `new URL(url)` gate at the top of `isOAuthUrlAllowed`. Schemeless inputs now fall through to `validateOAuthUrl`'s explicit "Invalid OAuth <field>" rejection. Tests added in both `auth/domain.spec.ts` (unit) and the OAuth handler integration spec (end-to-end). Reported by chatgpt-codex-connector (P2) on PR #12933. * 🛡️ fix: Address Follow-Up Comprehensive Review — Schema Tests, Shared Normalization, host:port Auditing the second comprehensive review: **F1 MAJOR — schema validation untested.** `allowedAddressesSchema` had zero coverage, so a regression in the three refinement stages or the three wiring locations (`endpoints` / `mcpSettings` / `actions`) would silently let invalid entries reach the runtime. Added a dedicated `describe('allowedAddressesSchema')` block in `config.spec.ts` covering: valid private IPs (v4 + v6, including the previously-missed 192.0.0.0/24 range), accepted hostnames, all rejection categories (URLs, CIDR, paths, whitespace tabs/newlines, host:port, public IP literals), and full `configSchema.parse()` integration at each of the three nesting points. **F2 MINOR — `isPrivateIPv4Literal` divergence.** The schema reimpl in `packages/data-provider` was discarding the `c` octet, so the `192.0.0.0/24` (RFC 5736 IETF protocol assignments) range that the authoritative `isPrivateIPv4` accepts was being rejected with a misleading "public IP" error. Destructure `c` and add the missing range check; covered by the new schema tests. **F3 MINOR — DRY violation across `domain.ts` and `agent.ts`.** Both files had independent normalization implementations with a subtle whitespace-check divergence (`/\s/` vs `.includes(' ')`). Extracted the shared logic into a new `packages/api/src/auth/allowedAddresses.ts` module that both consumers import: - `normalizeAddressEntry(entry)` — single-entry shape check - `looksLikeHostPort(entry)` — host:port detector (used by F4) - `normalizeAllowedAddressesSet(list)` — pre-normalized Set for the connect-time hot path - `isAddressInAllowedSet(candidate, set)` — membership check that enforces private-IP scoping on the candidate Both `isAddressAllowed` (preflight) and `buildSSRFSafeLookup` (connect) now go through the same primitives; the whitespace divergence is gone. To break the import cycle (`allowedAddresses` needs `isPrivateIP`, `domain` previously owned it), extracted IP private-range detection into a leaf `auth/ip.ts` module. `domain.ts` re-exports `isPrivateIP` for backward compatibility with existing call sites. **F4 MINOR — `host:port` silently misclassified.** Entries like `localhost:8080` previously slipped through the URL/path guard, were mis-detected as IPv6, failed `isPrivateIP`, and were silently dropped with a misleading "public IP" schema error. Added an explicit `looksLikeHostPort` check with a clear error: "allowedAddresses entries must not include a port — list the bare hostname or IP only." Bare `::1`, `[::1]`, and other valid IPv6 literals are intentionally not matched (regex distinguishes by colon count and the bracketed `[ipv6]:port` form). **F5 MINOR — hostname-trust documentation gap.** Hostname entries short-circuit `resolveHostnameSSRF` before any DNS lookup — that's a deliberate design (admin trusts the name) but it means the exemption follows whatever the name resolves to at runtime. Added an explicit note in `librechat.example.yaml` for both `mcpSettings.allowedAddresses` and `endpoints.allowedAddresses`: "a hostname entry trusts whatever IP that name resolves to. Only list hostnames whose DNS you control. Prefer literal IPs when you can." **F6** (8 positional params) is flagged for follow-up; refactor to an options object is a breaking-API change deferred to a separate PR. **F7** (redirect/WebSocket asymmetry, NIT, conf 40) — skipping; the existing inline comment is sufficient. * 🧹 chore: Address Follow-Up NITs — Import Order And Mirror-Function Naming Three NITs from the latest comprehensive review: **NIT #1 (conf 85) — local import order.** AGENTS.md requires local imports sorted longest-to-shortest. Both `domain.ts` and `agent.ts` had `./ip` (shorter) before `./allowedAddresses` (longer). Swapped. **NIT #2 (conf 60) — missing cross-reference.** The schema-side `isHostPortShape` in `packages/data-provider/src/config.ts` had no note pointing at the canonical runtime mirror. Added a JSDoc paragraph explaining the mirror relationship and why a local copy exists (the data-provider package can't import from `@librechat/api` without creating a circular dependency). **NIT #3 (conf 50) — naming inconsistency.** Renamed `isHostPortShape` → `looksLikeHostPort` so the schema mirror matches the runtime helper exactly. Kept as a separate function (not a shared import) for the same circular-dependency reason; the matching name makes it obvious they should stay in lockstep.
658 lines
29 KiB
YAML
658 lines
29 KiB
YAML
# For more information, see the Configuration Guide:
|
|
# https://www.librechat.ai/docs/configuration/librechat_yaml
|
|
|
|
# Configuration version (required)
|
|
version: 1.3.9
|
|
|
|
# Cache settings: Set to true to enable caching
|
|
cache: true
|
|
|
|
# File storage configuration
|
|
# Single strategy for all file types (legacy format, still supported)
|
|
# fileStrategy: "s3"
|
|
|
|
# Granular file storage strategies (new format - recommended)
|
|
# Allows different storage strategies for different file types
|
|
# fileStrategy:
|
|
# avatar: "s3" # Storage for user/agent avatar images
|
|
# image: "firebase" # Storage for uploaded images in chats
|
|
# document: "local" # Storage for document uploads (PDFs, text files, etc.)
|
|
|
|
# Available strategies: "local", "s3", "firebase"
|
|
# If not specified, defaults to "local" for all file types
|
|
# You can mix and match strategies based on your needs:
|
|
# - Use S3 for avatars for fast global access
|
|
# - Use Firebase for images with automatic optimization
|
|
# - Use local storage for documents for privacy/compliance
|
|
|
|
# Custom interface configuration
|
|
interface:
|
|
customWelcome: 'Welcome to LibreChat! Enjoy your experience.'
|
|
# Enable/disable file search as a chatarea selection (default: true)
|
|
# Note: This setting does not disable the Agents File Search Capability.
|
|
# To disable the Agents Capability, see the Agents Endpoint configuration instead.
|
|
fileSearch: true
|
|
# Privacy policy settings
|
|
privacyPolicy:
|
|
externalUrl: 'https://librechat.ai/privacy-policy'
|
|
openNewTab: true
|
|
|
|
# Terms of service
|
|
termsOfService:
|
|
externalUrl: 'https://librechat.ai/tos'
|
|
openNewTab: true
|
|
modalAcceptance: true
|
|
modalTitle: 'Terms of Service for LibreChat'
|
|
modalContent: |
|
|
# Terms and Conditions for LibreChat
|
|
|
|
*Effective Date: February 18, 2024*
|
|
|
|
Welcome to LibreChat, the informational website for the open-source AI chat platform, available at https://librechat.ai. These Terms of Service ("Terms") govern your use of our website and the services we offer. By accessing or using the Website, you agree to be bound by these Terms and our Privacy Policy, accessible at https://librechat.ai//privacy.
|
|
|
|
## 1. Ownership
|
|
|
|
Upon purchasing a package from LibreChat, you are granted the right to download and use the code for accessing an admin panel for LibreChat. While you own the downloaded code, you are expressly prohibited from reselling, redistributing, or otherwise transferring the code to third parties without explicit permission from LibreChat.
|
|
|
|
## 2. User Data
|
|
|
|
We collect personal data, such as your name, email address, and payment information, as described in our Privacy Policy. This information is collected to provide and improve our services, process transactions, and communicate with you.
|
|
|
|
## 3. Non-Personal Data Collection
|
|
|
|
The Website uses cookies to enhance user experience, analyze site usage, and facilitate certain functionalities. By using the Website, you consent to the use of cookies in accordance with our Privacy Policy.
|
|
|
|
## 4. Use of the Website
|
|
|
|
You agree to use the Website only for lawful purposes and in a manner that does not infringe the rights of, restrict, or inhibit anyone else's use and enjoyment of the Website. Prohibited behavior includes harassing or causing distress or inconvenience to any person, transmitting obscene or offensive content, or disrupting the normal flow of dialogue within the Website.
|
|
|
|
## 5. Governing Law
|
|
|
|
These Terms shall be governed by and construed in accordance with the laws of the United States, without giving effect to any principles of conflicts of law.
|
|
|
|
## 6. Changes to the Terms
|
|
|
|
We reserve the right to modify these Terms at any time. We will notify users of any changes by email. Your continued use of the Website after such changes have been notified will constitute your consent to such changes.
|
|
|
|
## 7. Contact Information
|
|
|
|
If you have any questions about these Terms, please contact us at contact@librechat.ai.
|
|
|
|
By using the Website, you acknowledge that you have read these Terms of Service and agree to be bound by them.
|
|
|
|
modelSelect: true
|
|
parameters: true
|
|
presets: true
|
|
prompts:
|
|
use: true
|
|
create: true
|
|
share: false
|
|
public: false
|
|
bookmarks: true
|
|
multiConvo: true
|
|
agents:
|
|
use: true
|
|
create: true
|
|
share: false
|
|
public: false
|
|
peoplePicker:
|
|
users: true
|
|
groups: true
|
|
roles: true
|
|
marketplace:
|
|
use: false
|
|
fileCitations: true
|
|
# Remote Agents configuration
|
|
# Controls user permissions for remote agents with external API support
|
|
# remoteAgents:
|
|
# use: false
|
|
# create: false
|
|
# share: false
|
|
# public: false
|
|
# MCP Servers configuration example
|
|
# mcpServers:
|
|
# Controls user permissions for MCP (Model Context Protocol) server management
|
|
# - use: Allow users to use configured MCP servers
|
|
# - create: Allow users to create and manage new MCP servers
|
|
# - share: Allow users to share MCP servers with other users
|
|
# - public: Allow users to share MCP servers publicly (with everyone)
|
|
|
|
# Creation / edit MCP server config Dialog config example
|
|
# trustCheckbox:
|
|
# label:
|
|
# en: 'I understand and I want to continue'
|
|
# de: 'Ich verstehe und möchte fortfahren'
|
|
# de-DE: 'Ich verstehe und möchte fortfahren' # You can narrow translation to regions like (de-DE or de-CH)
|
|
# subLabel:
|
|
# en: |
|
|
# Librechat hasn't reviewed this MCP server. Attackers may attempt to steal your data or trick the model into taking unintended actions, including destroying data. <a href="https://google.de" target="_blank"><strong>Learn more.</strong></a>
|
|
# de: |
|
|
# LibreChat hat diesen MCP-Server nicht überprüft. Angreifer könnten versuchen, Ihre Daten zu stehlen oder das Modell zu unbeabsichtigten Aktionen zu verleiten, einschließlich der Zerstörung von Daten. <a href="https://google.de" target="_blank"><strong>Mehr erfahren.</strong></a>
|
|
|
|
# Temporary chat retention period in hours (default: 720, min: 1, max: 8760)
|
|
# temporaryChatRetention: 1
|
|
|
|
# Example Cloudflare turnstile (optional)
|
|
#turnstile:
|
|
# siteKey: "your-site-key-here"
|
|
# options:
|
|
# language: "auto" # "auto" or an ISO 639-1 language code (e.g. en)
|
|
# size: "normal" # Options: "normal", "compact", "flexible", or "invisible"
|
|
|
|
# Example Registration Object Structure (optional)
|
|
registration:
|
|
socialLogins: ['github', 'google', 'discord', 'openid', 'facebook', 'apple', 'saml']
|
|
# allowedDomains:
|
|
# - "gmail.com"
|
|
|
|
# Example Balance settings
|
|
# balance:
|
|
# enabled: false
|
|
# startBalance: 20000
|
|
# autoRefillEnabled: false
|
|
# refillIntervalValue: 30
|
|
# refillIntervalUnit: 'days'
|
|
# refillAmount: 10000
|
|
|
|
# Example Transactions settings
|
|
# Controls whether to save transaction records to the database
|
|
# Default is true (enabled)
|
|
#transactions:
|
|
# enabled: false
|
|
# Note: If balance.enabled is true, transactions will always be enabled
|
|
# regardless of this setting to ensure balance tracking works correctly
|
|
|
|
# speech:
|
|
# tts:
|
|
# openai:
|
|
# url: ''
|
|
# apiKey: '${TTS_API_KEY}'
|
|
# model: ''
|
|
# voices: ['']
|
|
|
|
#
|
|
# stt:
|
|
# openai:
|
|
# url: ''
|
|
# apiKey: '${STT_API_KEY}'
|
|
# model: ''
|
|
|
|
# rateLimits:
|
|
# fileUploads:
|
|
# ipMax: 100
|
|
# ipWindowInMinutes: 60 # Rate limit window for file uploads per IP
|
|
# userMax: 50
|
|
# userWindowInMinutes: 60 # Rate limit window for file uploads per user
|
|
# conversationsImport:
|
|
# ipMax: 100
|
|
# ipWindowInMinutes: 60 # Rate limit window for conversation imports per IP
|
|
# userMax: 50
|
|
# userWindowInMinutes: 60 # Rate limit window for conversation imports per user
|
|
|
|
# Agent Actions domain restrictions (OpenAPI spec validation)
|
|
# SECURITY: If not configured, SSRF targets are blocked (localhost, private IPs, .internal/.local TLDs).
|
|
# Prefer `allowedAddresses` for permitting internal targets — adding a private IP to
|
|
# `allowedDomains` switches the field into strict-whitelist mode and blocks every
|
|
# public destination not also listed.
|
|
# Supports wildcards: '*.example.com' and protocol/port restrictions: 'https://api.example.com:8443'
|
|
actions:
|
|
allowedDomains:
|
|
- 'swapi.dev'
|
|
- 'librechat.ai'
|
|
- 'google.com'
|
|
# - 'http://10.225.26.25:7894' # Internal IP with protocol/port (uncomment if needed)
|
|
# `allowedAddresses` is an SSRF exemption list, NOT a strict whitelist.
|
|
# Hostnames or IPs listed here bypass the default-deny block on private/loopback/
|
|
# link-local destinations. Public domains continue to work normally — listing
|
|
# private targets here does not restrict access to anything else.
|
|
#
|
|
# Entries must be bare hostnames or private IP literals only — no URLs, paths,
|
|
# CIDR ranges, ports, or public IPs. Public IP literals are rejected at config
|
|
# load (the field is scoped to private IP space; public IPs aren't SSRF targets).
|
|
#
|
|
# NOTE on hostnames: a hostname entry trusts whatever IP that name resolves to.
|
|
# If DNS for that name is hijacked or rotated to a different private IP, the
|
|
# exemption follows. Only list hostnames whose DNS you control. Prefer literal
|
|
# IPs when you can.
|
|
# allowedAddresses:
|
|
# - 'host.docker.internal'
|
|
# - '127.0.0.1'
|
|
# - '10.0.0.5'
|
|
|
|
# Custom endpoint baseURL exemption list
|
|
# SECURITY: User-provided baseURLs (`baseURL: 'user_provided'`) are validated against
|
|
# the same SSRF block as Actions and MCP. If your users legitimately point at private
|
|
# services (self-hosted Ollama, internal LLM gateway, etc.), list those hostnames or
|
|
# IPs here so the validator allows them through. Public destinations are unaffected.
|
|
#
|
|
# Entries must be bare hostnames or private IP literals (no URLs, paths, CIDR,
|
|
# ports, or public IPs). Hostname entries trust whatever IP they resolve to —
|
|
# only list names whose DNS you control.
|
|
# endpoints:
|
|
# allowedAddresses:
|
|
# - 'localhost'
|
|
# - '127.0.0.1'
|
|
# - 'ollama'
|
|
# - '10.0.0.5'
|
|
|
|
# MCP Server domain restrictions for remote transports (SSE, WebSocket, HTTP)
|
|
# SECURITY: If not configured, SSRF targets are blocked (localhost, private IPs, .internal/.local TLDs).
|
|
# Prefer `allowedAddresses` for permitting internal targets — adding a private host to
|
|
# `allowedDomains` switches the field into strict-whitelist mode and blocks every
|
|
# public destination not also listed.
|
|
# Supports wildcards: '*.example.com' matches 'api.example.com', 'staging.example.com', etc.
|
|
# Supports protocol/port restrictions: 'https://api.example.com:8443' restricts to specific protocol/port.
|
|
# mcpSettings:
|
|
# allowedDomains:
|
|
# - 'host.docker.internal' # Docker host access (required for Docker setups)
|
|
# - 'localhost' # Local development
|
|
# - '*.example.com' # Wildcard subdomain
|
|
# - 'https://secure.api.com' # Protocol-restricted
|
|
# - 'http://internal:8080' # Protocol and port restricted
|
|
# # allowedAddresses is an SSRF exemption list (private-IP-space only).
|
|
# # Hostnames/IPs listed here bypass the default-deny block; public destinations
|
|
# # remain reachable. Useful when you want default SSRF protection AND specific
|
|
# # internal MCP servers. Entries must be bare hostnames or private IP literals
|
|
# # (no URLs, paths, CIDR, ports, or public IPs). Hostname entries trust
|
|
# # whatever IP they resolve to — only list names whose DNS you control.
|
|
# allowedAddresses:
|
|
# - 'host.docker.internal'
|
|
# - '127.0.0.1'
|
|
|
|
# Example MCP Servers Object Structure
|
|
# mcpServers:
|
|
# everything:
|
|
# # type: sse # type can optionally be omitted
|
|
# url: http://localhost:3001/sse
|
|
# timeout: 60000 # 1 minute timeout for this server, this is the default timeout for MCP servers.
|
|
# puppeteer:
|
|
# type: stdio
|
|
# command: npx
|
|
# args:
|
|
# - -y
|
|
# - "@modelcontextprotocol/server-puppeteer"
|
|
# timeout: 300000 # 5 minutes timeout for this server
|
|
# filesystem:
|
|
# # type: stdio
|
|
# command: npx
|
|
# args:
|
|
# - -y
|
|
# - "@modelcontextprotocol/server-filesystem"
|
|
# - /home/user/LibreChat/
|
|
# iconPath: /home/user/LibreChat/client/public/assets/logo.svg
|
|
# mcp-obsidian:
|
|
# command: npx
|
|
# args:
|
|
# - -y
|
|
# - "mcp-obsidian"
|
|
# - /path/to/obsidian/vault
|
|
|
|
# Definition of custom endpoints
|
|
endpoints:
|
|
# assistants:
|
|
# disableBuilder: false # Disable Assistants Builder Interface by setting to `true`
|
|
# pollIntervalMs: 3000 # Polling interval for checking assistant updates
|
|
# timeoutMs: 180000 # Timeout for assistant operations
|
|
# # Should only be one or the other, either `supportedIds` or `excludedIds`
|
|
# supportedIds: ["asst_supportedAssistantId1", "asst_supportedAssistantId2"]
|
|
# # excludedIds: ["asst_excludedAssistantId"]
|
|
# # Only show assistants that the user created or that were created externally (e.g. in Assistants playground).
|
|
# # privateAssistants: false # Does not work with `supportedIds` or `excludedIds`
|
|
# # (optional) Models that support retrieval, will default to latest known OpenAI models that support the feature
|
|
# retrievalModels: ["gpt-4-turbo-preview"]
|
|
# # (optional) Assistant Capabilities available to all users. Omit the ones you wish to exclude. Defaults to list below.
|
|
# capabilities: ["code_interpreter", "retrieval", "actions", "tools", "image_vision"]
|
|
# agents:
|
|
# # (optional) Default recursion depth for agents, defaults to 25
|
|
# recursionLimit: 50
|
|
# # (optional) Max recursion depth for agents, defaults to 25
|
|
# maxRecursionLimit: 100
|
|
# # (optional) Disable the builder interface for agents
|
|
# disableBuilder: false
|
|
# # (optional) Maximum total citations to include in agent responses, defaults to 30
|
|
# maxCitations: 30
|
|
# # (optional) Maximum citations per file to include in agent responses, defaults to 7
|
|
# maxCitationsPerFile: 7
|
|
# # (optional) Minimum relevance score for sources to be included in responses, defaults to 0.45 (45% relevance threshold)
|
|
# # Set to 0.0 to show all sources (no filtering), or higher like 0.7 for stricter filtering
|
|
# minRelevanceScore: 0.45
|
|
# # (optional) Agent Capabilities available to all users. Omit the ones you wish to exclude. Defaults to list below.
|
|
# capabilities: ["deferred_tools", "execute_code", "file_search", "actions", "tools"]
|
|
|
|
# Anthropic endpoint configuration with Vertex AI support
|
|
# Use this to run Anthropic Claude models through Google Cloud Vertex AI
|
|
# anthropic:
|
|
# # (optional) Stream rate limiting in milliseconds
|
|
# streamRate: 20
|
|
# # (optional) Title model for conversation titles
|
|
# titleModel: claude-3.5-haiku # Use the visible model name (key from models config)
|
|
#
|
|
# # Vertex AI Configuration - enables running Claude models via Google Cloud
|
|
# # This is similar to Azure OpenAI but for Anthropic models on Google Cloud
|
|
# # Vertex AI is automatically enabled when this config section is present
|
|
# vertex:
|
|
# # Vertex AI region (optional, defaults to 'us-east5')
|
|
# # Available regions: us-east5, us-central1, europe-west1, europe-west4, asia-southeast1
|
|
# region: "us-east5"
|
|
# # Path to Google service account key file (optional)
|
|
# # If not specified, uses GOOGLE_SERVICE_KEY_FILE env var or default path (api/data/auth.json)
|
|
# # The project_id is automatically extracted from the service key file
|
|
# # serviceKeyFile: "/path/to/service-account.json"
|
|
# # Google Cloud Project ID (optional) - auto-detected from service key file
|
|
# # Only specify if you need to override the project_id in your service key
|
|
# # projectId: "${VERTEX_PROJECT_ID}"
|
|
#
|
|
# # ============================================================================
|
|
# # Model Configuration - Set Visible Model Names and Deployment Mappings
|
|
# # Similar to Azure OpenAI model naming pattern
|
|
# # ============================================================================
|
|
#
|
|
# # Option 1: Simple array (legacy format - model name = deployment name)
|
|
# # Use this if you want the technical model IDs to show in the UI
|
|
# # models:
|
|
# # - "claude-sonnet-4-6"
|
|
# # - "claude-3-7-sonnet-20250219"
|
|
# # - "claude-3-5-sonnet-v2@20241022"
|
|
# # - "claude-3-5-haiku@20241022"
|
|
#
|
|
# # Option 2: Object format with custom visible names (RECOMMENDED)
|
|
# # The key is the visible model name shown in the UI (can be any name you want)
|
|
# # The deploymentName is the actual Vertex AI model ID used for API calls
|
|
# # You can use friendly names (avoid spaces for cleaner YAML) or technical IDs as keys
|
|
# models:
|
|
# claude-opus-4.5:
|
|
# deploymentName: claude-opus-4-5@20251101
|
|
# claude-sonnet-4:
|
|
# deploymentName: claude-sonnet-4-6
|
|
# claude-3.7-sonnet:
|
|
# deploymentName: claude-3-7-sonnet-20250219
|
|
# claude-3.5-sonnet:
|
|
# deploymentName: claude-3-5-sonnet-v2@20241022
|
|
# claude-3.5-haiku:
|
|
# deploymentName: claude-3-5-haiku@20241022
|
|
#
|
|
# # Option 3: Mixed format with default deploymentName
|
|
# # Set a default deploymentName and use boolean values for models
|
|
# # deploymentName: claude-sonnet-4-6
|
|
# # models:
|
|
# # claude-sonnet-4: true # Will use the default deploymentName
|
|
# # claude-3.5-haiku:
|
|
# # deploymentName: claude-3-5-haiku@20241022 # Override for this model
|
|
|
|
custom:
|
|
# Groq Example
|
|
- name: 'groq'
|
|
apiKey: '${GROQ_API_KEY}'
|
|
baseURL: 'https://api.groq.com/openai/v1/'
|
|
models:
|
|
default:
|
|
- 'llama3-70b-8192'
|
|
- 'llama3-8b-8192'
|
|
- 'llama2-70b-4096'
|
|
- 'mixtral-8x7b-32768'
|
|
- 'gemma-7b-it'
|
|
fetch: false
|
|
titleConvo: true
|
|
titleModel: 'mixtral-8x7b-32768'
|
|
modelDisplayLabel: 'groq'
|
|
|
|
# Mistral AI Example
|
|
- name: 'Mistral' # Unique name for the endpoint
|
|
# For `apiKey` and `baseURL`, you can use environment variables that you define.
|
|
# recommended environment variables:
|
|
apiKey: '${MISTRAL_API_KEY}'
|
|
baseURL: 'https://api.mistral.ai/v1'
|
|
|
|
# Models configuration
|
|
models:
|
|
# List of default models to use. At least one value is required.
|
|
default: ['mistral-tiny', 'mistral-small', 'mistral-medium']
|
|
# Fetch option: Set to true to fetch models from API.
|
|
fetch: true # Defaults to false.
|
|
|
|
# Optional configurations
|
|
|
|
# Title Conversation setting
|
|
titleConvo: true # Set to true to enable title conversation
|
|
|
|
# Title Method: Choose between "completion" or "functions".
|
|
# titleMethod: "completion" # Defaults to "completion" if omitted.
|
|
|
|
# Title Model: Specify the model to use for titles.
|
|
titleModel: 'mistral-tiny' # Defaults to "gpt-3.5-turbo" if omitted.
|
|
|
|
# Summarize setting: Set to true to enable summarization.
|
|
# summarize: false
|
|
|
|
# Summary Model: Specify the model to use if summarization is enabled.
|
|
# summaryModel: "mistral-tiny" # Defaults to "gpt-3.5-turbo" if omitted.
|
|
|
|
# The label displayed for the AI model in messages.
|
|
modelDisplayLabel: 'Mistral' # Default is "AI" when not set.
|
|
|
|
# Add additional parameters to the request. Default params will be overwritten.
|
|
# addParams:
|
|
# safe_prompt: true # This field is specific to Mistral AI: https://docs.mistral.ai/api/
|
|
|
|
# Drop Default params parameters from the request. See default params in guide linked below.
|
|
# NOTE: For Mistral, it is necessary to drop the following parameters or you will encounter a 422 Error:
|
|
dropParams: ['stop', 'user', 'frequency_penalty', 'presence_penalty']
|
|
|
|
# OpenRouter Example
|
|
- name: 'OpenRouter'
|
|
# For `apiKey` and `baseURL`, you can use environment variables that you define.
|
|
# recommended environment variables:
|
|
apiKey: '${OPENROUTER_KEY}'
|
|
baseURL: 'https://openrouter.ai/api/v1'
|
|
headers:
|
|
x-librechat-body-parentmessageid: '{{LIBRECHAT_BODY_PARENTMESSAGEID}}'
|
|
models:
|
|
default: ['meta-llama/llama-3-70b-instruct']
|
|
fetch: true
|
|
titleConvo: true
|
|
titleModel: 'meta-llama/llama-3-70b-instruct'
|
|
# Recommended: Drop the stop parameter from the request as Openrouter models use a variety of stop tokens.
|
|
dropParams: ['stop']
|
|
modelDisplayLabel: 'OpenRouter'
|
|
|
|
# Helicone Example
|
|
- name: 'Helicone'
|
|
# For `apiKey` and `baseURL`, you can use environment variables that you define.
|
|
# recommended environment variables:
|
|
apiKey: '${HELICONE_KEY}'
|
|
baseURL: 'https://ai-gateway.helicone.ai'
|
|
headers:
|
|
x-librechat-body-parentmessageid: '{{LIBRECHAT_BODY_PARENTMESSAGEID}}'
|
|
models:
|
|
default:
|
|
['gpt-4o-mini', 'claude-4.5-sonnet', 'llama-3.1-8b-instruct', 'gemini-2.5-flash-lite']
|
|
fetch: true
|
|
titleConvo: true
|
|
titleModel: 'gpt-4o-mini'
|
|
modelDisplayLabel: 'Helicone'
|
|
iconURL: https://marketing-assets-helicone.s3.us-west-2.amazonaws.com/helicone.png
|
|
|
|
# Portkey AI Example
|
|
- name: 'Portkey'
|
|
apiKey: 'dummy'
|
|
baseURL: 'https://api.portkey.ai/v1'
|
|
headers:
|
|
x-portkey-api-key: '${PORTKEY_API_KEY}'
|
|
x-portkey-virtual-key: '${PORTKEY_OPENAI_VIRTUAL_KEY}'
|
|
models:
|
|
default: ['gpt-4o-mini', 'gpt-4o', 'chatgpt-4o-latest']
|
|
fetch: true
|
|
titleConvo: true
|
|
titleModel: 'current_model'
|
|
summarize: false
|
|
summaryModel: 'current_model'
|
|
modelDisplayLabel: 'Portkey'
|
|
iconURL: https://images.crunchbase.com/image/upload/c_pad,f_auto,q_auto:eco,dpr_1/rjqy7ghvjoiu4cd1xjbf
|
|
|
|
# AWS Bedrock Example
|
|
# Note: Bedrock endpoint is configured via environment variables
|
|
# bedrock:
|
|
# # Models Configuration
|
|
# # Specify which models are available (equivalent to BEDROCK_AWS_MODELS env variable)
|
|
# models:
|
|
# - "anthropic.claude-3-7-sonnet-20250219-v1:0"
|
|
# - "anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
#
|
|
# # Inference Profiles Configuration
|
|
# # Maps model IDs to their inference profile ARNs
|
|
# # IMPORTANT: The model ID (key) MUST be a valid AWS Bedrock model ID that you've added to the models list above
|
|
# # The ARN (value) is the inference profile you wish to map to for that model
|
|
# # Both the model ID and ARN are sent to AWS - the model ID for validation/metadata, the ARN for routing
|
|
# inferenceProfiles:
|
|
# "us.anthropic.claude-sonnet-4-6": "${BEDROCK_INFERENCE_PROFILE_CLAUDE_SONNET}"
|
|
# "anthropic.claude-3-7-sonnet-20250219-v1:0": "arn:aws:bedrock:us-west-2:123456789012:application-inference-profile/abc123"
|
|
#
|
|
# # Guardrail Configuration
|
|
# guardrailConfig:
|
|
# guardrailIdentifier: "your-guardrail-id"
|
|
# guardrailVersion: "1"
|
|
#
|
|
# # Trace behavior for debugging (optional)
|
|
# # - "enabled": Include basic trace information about guardrail assessments
|
|
# # - "enabled_full": Include comprehensive trace details (recommended for debugging)
|
|
# # - "disabled": No trace information (default)
|
|
# # Trace output is logged to application log files for compliance auditing
|
|
# trace: "enabled"
|
|
# Example modelSpecs configuration showing grouping options
|
|
# The 'group' field organizes model specs in the UI selector:
|
|
# - If 'group' matches an endpoint name (e.g., "openAI", "groq"), the spec appears nested under that endpoint
|
|
# - If 'group' is a custom name (doesn't match any endpoint), it creates a separate collapsible section
|
|
# - If 'group' is omitted, the spec appears as a standalone item at the top level
|
|
#
|
|
# The 'groupIcon' field sets an icon for custom groups:
|
|
# - Only needs to be set on one spec per group (first one is used)
|
|
# - Can be a URL or a built-in endpoint key (e.g., "openAI", "anthropic", "groq")
|
|
# modelSpecs:
|
|
# list:
|
|
# # Example 1: Nested under an endpoint (grouped with openAI endpoint)
|
|
# - name: "gpt-4o"
|
|
# label: "GPT-4 Optimized"
|
|
# description: "Most capable GPT-4 model with multimodal support"
|
|
# group: "openAI" # String value matching the endpoint name
|
|
# preset:
|
|
# endpoint: "openAI"
|
|
# model: "gpt-4o"
|
|
#
|
|
# # Example 2: Nested under a custom endpoint (grouped with groq endpoint)
|
|
# - name: "llama3-70b-8192"
|
|
# label: "Llama 3 70B"
|
|
# description: "Fastest inference available - great for quick responses"
|
|
# group: "groq" # String value matching your custom endpoint name from endpoints.custom
|
|
# preset:
|
|
# endpoint: "groq"
|
|
# model: "llama3-70b-8192"
|
|
#
|
|
# # Example 3: Custom group with icon (creates a separate collapsible section)
|
|
# - name: "coding-assistant"
|
|
# label: "Coding Assistant"
|
|
# description: "Specialized for coding tasks"
|
|
# group: "my-assistants" # Custom string - doesn't match any endpoint, so creates its own group
|
|
# groupIcon: "https://example.com/icons/assistants.png" # Icon URL for the group
|
|
# preset:
|
|
# endpoint: "openAI"
|
|
# model: "gpt-4o"
|
|
# instructions: "You are an expert coding assistant..."
|
|
# temperature: 0.3
|
|
#
|
|
# - name: "writing-assistant"
|
|
# label: "Writing Assistant"
|
|
# description: "Specialized for creative writing"
|
|
# group: "my-assistants" # Same custom group name - both specs appear in same section
|
|
# # No need to set groupIcon again - the first spec's icon is used
|
|
# preset:
|
|
# endpoint: "anthropic"
|
|
# model: "claude-sonnet-4"
|
|
# instructions: "You are a creative writing expert..."
|
|
#
|
|
# # Example 4: Custom group using built-in icon key
|
|
# - name: "fast-models"
|
|
# label: "Fast Response Model"
|
|
# group: "Fast Models"
|
|
# groupIcon: "groq" # Uses the built-in Groq icon
|
|
# preset:
|
|
# endpoint: "groq"
|
|
# model: "llama3-8b-8192"
|
|
#
|
|
# # Example 5: Standalone (no group - appears at top level)
|
|
# - name: "general-assistant"
|
|
# label: "General Assistant"
|
|
# description: "General purpose assistant"
|
|
# # No 'group' field - appears as standalone item at top level (not nested)
|
|
# preset:
|
|
# endpoint: "openAI"
|
|
# model: "gpt-4o-mini"
|
|
|
|
# fileConfig:
|
|
# endpoints:
|
|
# assistants:
|
|
# fileLimit: 5
|
|
# fileSizeLimit: 10 # Maximum size for an individual file in MB
|
|
# totalSizeLimit: 50 # Maximum total size for all files in a single request in MB
|
|
# supportedMimeTypes:
|
|
# - "image/.*"
|
|
# - "application/pdf"
|
|
# openAI:
|
|
# disabled: true # Disables file uploading to the OpenAI endpoint
|
|
# default:
|
|
# totalSizeLimit: 20
|
|
# YourCustomEndpointName:
|
|
# fileLimit: 2
|
|
# fileSizeLimit: 5
|
|
# serverFileSizeLimit: 100 # Global server file size limit in MB
|
|
# avatarSizeLimit: 2 # Limit for user avatar image size in MB
|
|
# imageGeneration: # Image Gen settings, either percentage or px
|
|
# percentage: 100
|
|
# px: 1024
|
|
# # Client-side image resizing to prevent upload errors
|
|
# clientImageResize:
|
|
# enabled: false # Enable/disable client-side image resizing (default: false)
|
|
# maxWidth: 1900 # Maximum width for resized images (default: 1900)
|
|
# maxHeight: 1900 # Maximum height for resized images (default: 1900)
|
|
# quality: 0.92 # JPEG quality for compression (0.0-1.0, default: 0.92)
|
|
# # See the Custom Configuration Guide for more information on Assistants Config:
|
|
# # https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/assistants_endpoint
|
|
|
|
# Web Search Configuration (optional)
|
|
# webSearch:
|
|
# # Jina Reranking Configuration
|
|
# jinaApiKey: '${JINA_API_KEY}' # Your Jina API key
|
|
# jinaApiUrl: '${JINA_API_URL}' # Custom Jina API URL (optional, defaults to https://api.jina.ai/v1/rerank)
|
|
# # Other rerankers
|
|
# cohereApiKey: '${COHERE_API_KEY}'
|
|
# # Search providers
|
|
# serperApiKey: '${SERPER_API_KEY}'
|
|
# searxngInstanceUrl: '${SEARXNG_INSTANCE_URL}'
|
|
# searxngApiKey: '${SEARXNG_API_KEY}'
|
|
# # Content scrapers
|
|
# firecrawlApiKey: '${FIRECRAWL_API_KEY}'
|
|
# firecrawlApiUrl: '${FIRECRAWL_API_URL}'
|
|
|
|
# Memory configuration for user memories
|
|
# memory:
|
|
# # (optional) Disable memory functionality
|
|
# disabled: false
|
|
# # (optional) Restrict memory keys to specific values to limit memory storage and improve consistency
|
|
# validKeys: ["preferences", "work_info", "personal_info", "skills", "interests", "context"]
|
|
# # (optional) Maximum token limit for memory storage (not yet implemented for token counting)
|
|
# tokenLimit: 10000
|
|
# # (optional) Enable personalization features (defaults to true if memory is configured)
|
|
# # When false, users will not see the Personalization tab in settings
|
|
# personalize: true
|
|
# # (optional) Memory agent configuration for automatic memory updates from chat messages.
|
|
# # If omitted, users can still create, edit, delete, and reference memories manually.
|
|
# agent:
|
|
# # Explicitly enables automatic memory updates from chat messages.
|
|
# enabled: true
|
|
# # Option 1: Use existing agent by ID
|
|
# id: "your-memory-agent-id"
|
|
# # Option 2: Define agent inline
|
|
# # provider: "openai"
|
|
# # model: "gpt-4o-mini"
|
|
# # instructions: "You are a memory management assistant. Store and manage user information accurately."
|
|
# # model_parameters:
|
|
# # temperature: 0.1
|