Skip to main content
LibreChat is joining ClickHouse to power the open-source Agentic Data Stack 🎉 Learn more
LibreChat

MCP Settings Object Structure

Overview

The mcpSettings configuration provides global settings for MCP (Model Context Protocol) server security and behavior. This configuration is separate from mcpServers and controls how MCP servers can connect to certain domains and IP addresses.

Example

# Example MCP Settings Configuration
mcpSettings:
  # Strict whitelist mode:
  # allowedDomains:
  #   - "example.com"                    # Specific domain
  #   - "*.example.com"                  # All subdomains using wildcard
  #   - "https://api.example.com:8443"   # With protocol and port
  #   - "http://mcp-server:3000"         # Internal service, explicitly whitelisted

  # Default SSRF mode with private service exemptions:
  allowedAddresses:
    - "host.docker.internal:8080"        # Permit one private host on one port
    - "10.0.0.5:8000"                    # Permit one private IP on one port

  # Optional MCP OAuth catalog-recovery tuning; defaults are shown.
  catalogRecovery:
    discoveryBackoffMs: [300000, 600000, 1200000, 1800000]
    discoveryTimeoutMs: 3000
    reauthRetryMs: 1800000
    maxStateEntries: 10000
    generationReadTimeoutMs: 500
    authorizationFenceRetryMs: [0, 50, 200]
    authorizationFenceTimeoutMs: 1000
    authorizationFenceRetryIntervalMs: 30000
    authorizationFenceRetryBatchSize: 100

Configuration

Subkeys

KeyTypeDescriptionExample
allowedDomainsArray of StringsA list specifying allowed domains for MCP server connections.When configured, only listed domains are allowed. When not configured, SSRF targets are blocked but all other domains are allowed.
allowedAddressesArray of StringsAn SSRF exemption list, scoped to private IP space. Hostname/IP + port pairs listed here bypass the default-deny SSRF block when `allowedDomains` is not configured.Use when you want default SSRF protection AND specific internal MCP servers, without flipping `allowedDomains` into strict-whitelist mode.
appsBooleanControls MCP Apps. When true, MCP Apps are enabled and MCP servers are connected with Apps support. When unset, only legacy HTML UI resources are rendered. When false, legacy HTML UI resources are disabled as well.Apps render in a sandbox configured by mcpAppSandbox.
catalogRecoveryObjectOptional bounds for passive MCP discovery, OAuth reauthentication recovery, and cross-replica authorization fencing.Uses the defaults shown in the example.

apps

apps turns on MCP Apps, the interactive interfaces that MCP servers return with tool results. The setting is read on the server and also reported to the client at startup. Apps render in a sandboxed frame whose host, size limits, and rate limits are set by the top-level mcpAppSandbox object.

mcpSettings:
  apps: true

catalogRecovery

catalogRecovery prevents passive catalog requests from repeatedly rediscovering disconnected OAuth servers and bounds the authorization-generation checks used across replicas. Most deployments should retain the defaults.

KeyTypeDescriptionExample
discoveryBackoffMsArray of NumbersProgressive delays after failed passive discovery, in milliseconds (1-8 entries).[300000, 600000, 1200000, 1800000]
discoveryTimeoutMsNumberTimeout for one passive discovery attempt.3000
discoverySettleGraceMsNumberAdditional time a timed-out discovery may retain its coalesced slot while it settles.10000
reauthRetryMsNumberDelay before retrying a server that requires interactive OAuth authorization.1800000
maxStateEntriesNumberMaximum process-local server recovery states retained in memory.10000
maxDetachedDiscoveriesNumberMaximum timed-out discoveries still settling before recovery stops starting new discoveries.3
generationReadTimeoutMsNumberDeadline for reading the cross-replica credential generation.500
authorizationFenceRetryMsArray of NumbersRetry delays for publishing an authorization-generation fence (1-8 entries).[0, 50, 200]
authorizationFenceTimeoutMsNumberTimeout for each authorization-fence write attempt.1000
authorizationFenceRetryIntervalMsNumberInterval for replaying durable failed fence writes.30000
authorizationFenceRetryBatchSizeNumberMaximum durable fence records replayed per interval.100

Concurrent passive discovery is coalesced per user and server. OAuth challenges settle into a stable reauthentication-required state, while transient token or cache outages remain retryable. Credential changes publish a generation fence so stale discovery results are discarded instead of being reused on another replica.

discoverySettleGraceMs may be 0 through 300000; the late discovery is never cancelled so a redeemed OAuth token can still persist. maxDetachedDiscoveries ranges from 1 to 1000 and bounds how many such released discoveries may continue before new recovery work waits for one to settle.

allowedDomains

Security Context (SSRF Protection)

LibreChat includes SSRF (Server-Side Request Forgery) protection with the following behavior:

When allowedDomains is NOT configured:

  • SSRF-prone targets are blocked by default
  • All other external domains are allowed

When allowedDomains IS configured:

  • Only domains on the list are allowed
  • Internal/SSRF targets can be allowed by explicitly adding them to the list

Blocked SSRF targets include:

  • Localhost addresses (localhost, 127.0.0.1, ::1)
  • Private IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
  • Link-local addresses (169.254.0.0/16, includes cloud metadata IPs)
  • Internal TLDs (.internal, .local, .localhost)
  • Common internal service names (redis, mongodb, postgres, api, rag_api, etc.)

If your MCP servers need to connect to internal services or Docker containers, either add them to the strict allowedDomains whitelist, or leave allowedDomains unset and add the exact private service to allowedAddresses.

Pattern Formats

The allowedDomains array supports several pattern formats:

  1. Exact Domain Match

    allowedDomains:
      - "example.com"

    Only allows connections to exactly example.com (any protocol/port)

  2. Wildcard Subdomain Match

    allowedDomains:
      - "*.example.com"

    Allows connections to all subdomains of example.com (e.g., api.example.com, mcp.example.com)

  3. Specific IP Address

    allowedDomains:
      - "192.168.1.100"
      - "172.24.1.165"

    Allows connections to specific IP addresses

  4. Local Docker Domains

    allowedDomains:
      - "mcp-server"
      - "host.docker.internal"

    Allows connections to Docker container names or special Docker domains

  5. With Protocol and Port

    allowedDomains:
      - "https://api.example.com:8443"
      - "http://internal-mcp:3000"

    Restricts connections to specific protocol and port combinations

Error Messages

If you see errors like:

  error: [MCPServersRegistry] Failed to inspect server "my-mcp": Domain "http://172.24.1.165:8000" is not allowed
  error: [MCP][my-mcp] Failed to initialize: Domain "http://172.24.1.165:8000" is not allowed

This likely indicates that the MCP server's private host and port need to be added to allowedAddresses, unless you intentionally use allowedDomains as a strict whitelist:

mcpSettings:
  allowedAddresses:
    - "172.24.1.165:8000"    # Add the private host/IP and MCP port

allowedAddresses

allowedAddresses is an exemption list for the SSRF private-IP block, not a domain whitelist. It is the right tool when you want to permit one or two specific private/internal services without restricting what your MCP servers can reach in the public internet.

When to use it instead of allowedDomains

allowedDomains is a strict whitelist: when it is set, only listed entries are reachable. Adding a private IP there to permit, say, a self-hosted MCP server also blocks every public destination (api.example.com, *.googleapis.com, etc.) that you didn't also list.

allowedAddresses is used only when allowedDomains is not configured. It permits specific private host:port targets while leaving the rest of the public internet reachable through the default SSRF policy. Common configuration:

mcpSettings:
  allowedAddresses:
    - "host.docker.internal:8080"
    - "10.0.0.5:8000"
  # allowedDomains is intentionally not set: public destinations
  # remain reachable, only listed private host:port services are exempted.

If allowedDomains is configured, it is authoritative: private services must be listed there instead of relying on allowedAddresses.

Acceptable entries

  • Hostnames with port: host.docker.internal:8080, mcp-server:3000, localhost:3001
  • Private IPv4 literals with port: 10.0.0.5:8000, 127.0.0.1:3001, 192.168.1.10:443, 169.254.169.254:80
  • Bracketed private IPv6 literals with port: [::1]:3001, [fc00::1]:8080, [fe80::1]:8080

Rejected entries (validated at config load)

  • URLs / paths / CIDR ranges: http://10.0.0.5, 10.0.0.0/24, /path
  • Bare hostnames or IPs: localhost, 10.0.0.5, ::1, [::1]: every entry must include a port
  • Invalid ports: localhost:0, localhost:65536, localhost:http
  • Public IP literals: 8.8.8.8:53, 1.1.1.1:53, [2001:4860::8888]:443: the field is scoped to private IP space; public IPs are not SSRF targets and a public-IP exemption has no defensive purpose

Hostname trust

A hostname entry trusts whatever IP that hostname resolves to at runtime on the listed port. If the DNS for a listed hostname is rotated or hijacked to point at a different private IP, the exemption follows. Only list hostnames whose DNS you control. Prefer literal IPs when you can.

References

How is this guide?