# Agents Endpoint Object Structure (https://www.librechat.ai/docs/configuration/librechat_yaml/object_structure/agents)

This page applies to the [`agents`](/docs/features/agents) endpoint.

## Example

```yaml filename="Agents Endpoint"
endpoints:
  agents:
    recursionLimit: 50
    maxRecursionLimit: 100
    maxSubagents: 20
    maxToolCallArgBytes: 65536
    maxDeltaEventsPerTurn: 100000
    maxToolCallArgBytesByTool:
      create_file: 131072
    disableBuilder: false
    # (optional) Agent Capabilities available to all users. Omit the ones you wish to exclude. Defaults to list below.
    # Opt-in capabilities: "programmatic_tools", "stateful_code_sessions", "run_in_background", and "tool_intents".
    # capabilities: ["deferred_tools", "execute_code", "file_search", "web_search", "artifacts", "subagents", "actions", "context", "skills", "memory", "ask_user_question", "tools", "chain", "ocr"]
    # (optional) File citation configuration for file_search capability
    maxCitations: 30 # Maximum total citations in responses (1-50)
    maxCitationsPerFile: 7 # Maximum citations from each file (1-10)
    minRelevanceScore: 0.45 # Minimum relevance score threshold (0.0-1.0)
    titleTiming: immediate
    activityLabel: true
    activityModel: gpt-4.1-nano
    activityPhaseLabel: true
    activityPhaseMaxPerRun: 5
    skills:
      maxCatalogSkills: 20
    statefulCodeSessions:
      allowedEnvironments: ['user', 'agent-user', 'conversation']
      environments:
        - id: managed-default
          name: Managed Code API
          type: managed
          baseURL: https://code.example.com/v1
          default: true
        - id: engineering-vm
          name: Engineering VM
          type: attached
          baseURL: https://code-bridge.example.com/v1
          pairing:
            workerId: engineering-vm
            tokenEnv: CODE_BRIDGE_ADMIN_TOKEN
        - id: personal-workers
          name: Personal Code Workers
          type: attached
          baseURL: https://code-bridge.example.com/v1
          pairing:
            allowPrincipalWorkers: true
            tokenEnv: CODE_BRIDGE_ADMIN_TOKEN
    # eventDriven:
    #   selfUrl: https://librechat.internal
    backgroundTasks:
      completionWakeups: true
    toolApproval:
      enabled: true
      mode: default
      deny: ['mcp:*:delete_*']
      ask: ['mcp:*:*']
    checkpointer:
      type: mongo
      ttl: 86400
    remoteApi:
      auth:
        oidc:
          enabled: false
```

> This configuration enables the builder interface for agents.

## recursionLimit

<OptionTable
  options={[
    [
      'recursionLimit',
      'Number',
      'Sets the default number of steps an agent can take in a run.',
      'Controls recursion depth to prevent infinite loops. When the limit is reached, LibreChat preserves the partial turn and offers Keep going or Answer now. This value can be configured from the UI up to maxRecursionLimit.',
    ],
  ]}
/>

**Default:** `25`

**Example:**

```yaml filename="endpoints / agents / recursionLimit"
recursionLimit: 50
```

For more information about agent steps, see [Max Agent Steps](/docs/features/agents#max-agent-steps).

## maxRecursionLimit

<OptionTable
  options={[
    [
      'maxRecursionLimit',
      'Number',
      'Sets the absolute maximum number of steps an agent can take in a run.',
      'Defines the upper limit for the recursionLimit that can be set from the UI. This prevents users from setting excessively high values.',
    ],
  ]}
/>

**Default:** If omitted, defaults to the value of recursionLimit or 50 if recursionLimit is also omitted.

**Example:**

```yaml filename="endpoints / agents / maxRecursionLimit"
maxRecursionLimit: 100
```

For more information about agent steps, see [Max Agent Steps](/docs/features/agents#max-agent-steps).

## Stream circuit breakers

These settings stop an Agent run when a provider stream appears to be producing runaway tool arguments or an unbounded sequence of delta events.

<OptionTable
  options={[
    [
      'maxToolCallArgBytes',
      'Number',
      'Maximum cumulative bytes for one streamed tool call\'s arguments. Set to 0 to disable the global guard.',
      '65536',
    ],
    [
      'maxDeltaEventsPerTurn',
      'Number',
      'Maximum streamed events for one model generation turn. Set to 0 or omit it to disable this guard.',
      '0 (disabled)',
    ],
    [
      'maxToolCallArgBytesByTool',
      'Object',
      'Per-tool argument-byte overrides keyed by the model-facing tool name. A value of 0 disables the guard for that tool.',
      'create_file: 131072',
    ],
  ]}
/>

LibreChat uses a 64 KiB global argument limit and ships a 128 KiB override for `create_file`, whose legitimate payloads are often larger. Entries in `maxToolCallArgBytesByTool` merge over that built-in override. If either guard trips, LibreChat aborts the in-flight provider stream and reports which limit was exceeded.

```yaml filename="endpoints / agents / stream circuit breakers"
maxToolCallArgBytes: 65536
maxDeltaEventsPerTurn: 100000
maxToolCallArgBytesByTool:
  create_file: 262144
  large_import: 524288
```

To disable every argument-size guard, set both the global limit and the shipped `create_file` override to `0`:

```yaml
maxToolCallArgBytes: 0
maxToolCallArgBytesByTool:
  create_file: 0
```

## titleTiming

<OptionTable
  options={[
    [
      'titleTiming',
      'String',
      'Controls when conversation titles are generated for the agents endpoint. Valid values: "immediate" or "final".',
      'Defaults to "immediate".',
    ],
  ]}
/>

**Default:** `"immediate"`

**Available Values:**

- **`"immediate"`**: Generates the title as soon as the request starts, in parallel with the model response, using the user's first message.
- **`"final"`**: Defers title generation until the full response completes. This preserves the legacy behavior.

**Example:**

```yaml filename="endpoints / agents / titleTiming"
titleTiming: immediate
```

## activityLabel

Set `activityLabel: true` to group each block of Agent reasoning and tool calls under a generated one-line header. Use `activityModel`, `activityEndpoint`, `activityPrompt`, `activityMaxPerRun`, and `activityCharLimit` to control the additional model call and its cost. See [Agent Activity Groups](/docs/configuration/librechat_yaml/object_structure/shared_endpoint_settings#agent-activity-groups) for the full field reference and precedence rules.

```yaml filename="endpoints / agents / activity groups"
activityLabel: true
activityEndpoint: openAI
activityModel: gpt-4.1-nano
activityMaxPerRun: 20
activityCharLimit: 600
activityPhaseLabel: true
activityPhaseMaxPerRun: 5
```

`activityPhaseLabel` can independently add one collapsed parent summary around each run phase that contains at least two logical activities. Use `activityPhaseModel`, `activityPhaseEndpoint`, `activityPhasePrompt`, and `activityPhaseMaxPerRun` to tune those calls; `activityCharLimit` is shared with child activity labels.

## disableBuilder

<OptionTable
  options={[
    [
      'disableBuilder',
      'Boolean',
      'Controls the visibility and use of the builder interface for agents.',
      'When set to `true`, disables the builder interface for the agent, limiting direct manual interaction.',
    ],
  ]}
/>

**Default:** `false`

**Example:**

```yaml filename="endpoints / agents / disableBuilder"
disableBuilder: false
```

## allowedProviders

<OptionTable
  options={[
    [
      'allowedProviders',
      'Array/List of Strings',
      'Specifies a list of endpoint providers (e.g., "openAI", "anthropic", "google") that are permitted for use with the Agents feature.',
      'If defined, only agents configured with these providers can be initialized. If omitted or empty, all configured providers are allowed.',
    ],
  ]}
/>

**Default:** `[]` (empty list, all providers allowed)

**Note:** Must be one of the following, or a custom endpoint name as defined in your [configuration](/docs/configuration/librechat_yaml/object_structure/custom_endpoint#name): - `openAI, azureOpenAI, google, anthropic, assistants, azureAssistants, bedrock`

**Example:**

```yaml filename="endpoints / agents / allowedProviders"
allowedProviders:
  - openAI
  - google
```

## capabilities

<OptionTable
  options={[
    [
      'capabilities',
      'Array/List of Strings',
      'Specifies the agent capabilities available to all users for the agents endpoint.',
      'Defines the agent capabilities that are available to all users for the agents endpoint. You can omit the capabilities you wish to exclude from the list.',
    ],
  ]}
/>

**Default:** `["deferred_tools", "execute_code", "file_search", "web_search", "artifacts", "subagents", "actions", "context", "skills", "memory", "ask_user_question", "tools", "chain", "ocr"]`

`programmatic_tools`, `stateful_code_sessions`, `run_in_background`, and `tool_intents` are opt-in and must be added explicitly. Programmatic tools and stateful sessions also require `execute_code` and a compatible Code Interpreter deployment. The Agent Builder disables Programmatic MCP selections without Code Interpreter, and the server strips stale programmatic caller options when code execution is unavailable. `run_in_background` makes Code Interpreter tools eligible by default and allows per-tool opt-in for eligible MCP, Plugin, and Action tools; background code execution also requires `execute_code` and Code Interpreter.

`stateful_code_sessions` is highly experimental. It requires a separate `stateful`-profile Code Interpreter route configured with [`LIBRECHAT_CODE_BASEURL_STATEFUL`](/docs/configuration/dotenv#stateful-code-interpreter-endpoint) or [`statefulCodeSessions.environments`](#statefulcodesessions). Stateful requests fail closed instead of falling back to the normal stateless service. In the Agent Builder, each enabled Agent chooses a user, agent-and-user, or conversation workspace scope and, when named backends are configured, an execution environment. New Agents start with the user's personal scope default and the deployment's default execution environment.

**Example:**

```yaml filename="endpoints / agents / capabilities"
capabilities:
  - 'deferred_tools'
  # Optional: enables Programmatic Tool Calling for MCP tools marked Programmatic in the Agent Builder.
  # Requires execute_code and a Code Interpreter deployment with the Tool Call Server component.
  # - 'programmatic_tools'
  - 'execute_code'
  - 'file_search'
  - 'web_search'
  - 'artifacts'
  - 'subagents'
  - 'actions'
  - 'context'
  - 'skills'
  - 'memory'
  - 'ask_user_question'
  - 'tools'
  - 'chain'
  - 'ocr'
  # Optional and highly experimental: reuse a user-, agent-and-user-, or
  # conversation-scoped workspace. Requires LIBRECHAT_CODE_BASEURL_STATEFUL
  # or a named statefulCodeSessions environment.
  # - 'stateful_code_sessions'
  # Optional: allow eligible Code Interpreter, MCP, Plugin, and Action tools to run as background tasks.
  # - 'run_in_background'
  # Optional: show live model-written intent labels for native and selected MCP tools.
  # - 'tool_intents'
```

**Note:** This field is optional. If omitted, the default behavior is to include all the capabilities listed in the default.

## statefulCodeSessions

Configures the sharing scopes and optional execution backends for highly experimental stateful Code Interpreter workspaces.

<Callout type="warning" title="Highly experimental">
  Stateful Code Sessions, named execution environments, attached workers, and pairing are in an
  early experimentation phase. Their behavior, configuration, persistence characteristics, and
  integration protocol may change substantially.
</Callout>

<OptionTable
  options={[
    [
      'allowedEnvironments',
      'Array/List of Strings',
      'Allowed stateful workspace scopes: `user`, `agent-user`, and/or `conversation`.',
      '["user", "agent-user", "conversation"]',
    ],
    [
      'environments',
      'Array of Objects',
      'Optional named managed or attached Code API environments shown in the Agent Builder.',
      'Unset; LIBRECHAT_CODE_BASEURL_STATEFUL remains the stateful endpoint',
    ],
  ]}
/>

```yaml filename="endpoints / agents / statefulCodeSessions"
statefulCodeSessions:
  allowedEnvironments:
    - 'user'
    - 'agent-user'
    - 'conversation'
  environments:
    - id: managed-default
      name: Managed Code API
      type: managed
      baseURL: https://code.example.com/v1
      default: true
    - id: engineering-vm
      name: Engineering VM
      type: attached
      baseURL: https://code-bridge.example.com/v1
      owner: deployment
      pairing:
        workerId: engineering-vm
        tokenEnv: CODE_BRIDGE_ADMIN_TOKEN
    - id: personal-workers
      name: Personal Code Workers
      type: attached
      baseURL: https://code-bridge.example.com/v1
      owner: deployment
      configSchema:
        permissions:
          fileWrite:
            allowed: [allow, ask, deny]
            default: ask
          commandExecution:
            allowed: [ask, deny]
            default: ask
      pairing:
        allowPrincipalWorkers: true
        tokenEnv: CODE_BRIDGE_ADMIN_TOKEN
```

`allowedEnvironments` is required whenever the block is present and must include at least one workspace scope. Omit the entire block to allow all three scopes and continue routing stateful work through [`LIBRECHAT_CODE_BASEURL_STATEFUL`](/docs/configuration/dotenv#stateful-code-interpreter-endpoint). The personal default and Agent Builder only permit allowed values. If an administrator tightens the policy, a saved personal default remains visible but disabled, and new Agents use the first allowed scope. Existing enabled Agents retain their saved scope, but a now-disallowed scope fails closed at runtime until the Agent is reconfigured.

When `environments` is non-empty, every entry requires a unique `id`, a display `name`, a `type` of `managed` or `attached`, and an HTTP(S) `baseURL` without a query string or fragment. If the list contains executable environments, exactly one of those entries must set `default: true`. The Agent Builder then adds an **Execution environment** selector; leaving it on **Deployment default** uses that default entry. A list containing only self-service pairing control planes needs no default. An Agent that names an environment that is later removed or no longer accessible fails closed instead of falling back to another backend.

- `managed` points directly to an operator-managed stateful Code API.
- `attached` points to a compatible Code API `remote-bridge` backend that leases work to an outbound `@librechat/code` worker. The worker does not require an inbound public port, but its local execution endpoint still needs appropriate isolation.
- `workerId` optionally routes an attached environment to one outbound worker. It is server-only and is not exposed through client startup configuration.
- `owner` defaults to `deployment`. Principal-owned environments are created through LibreChat's authenticated Code Environments API, protected by ACLs, and merged only for authorized requests; do not place client-supplied URLs in deployment YAML.
- `pairing` is optional and valid only for deployment-owned `attached` entries. `pairing.workerId` identifies an operator-managed worker to enroll, while `pairing.allowPrincipalWorkers: true` lets authorized users enroll owner-bound workers against that control plane. At least one of those fields is required when `pairing` is present.
- `pairing.tokenEnv` names the environment variable containing the bridge administrator token; it never contains the token itself. Pairing requires HTTPS except for loopback development.
- `configSchema.permissions` optionally lets authorized owners choose `fileWrite` and `commandExecution` policy for personal environments under **Settings > Code environments**. Each field requires a non-empty `allowed` list containing `allow`, `ask`, and/or `deny`; `default` is `ask` when omitted and must appear in `allowed`. LibreChat rejects stored values outside the administrator's list.
- Do not configure `settings` in deployment YAML. LibreChat supplies that request-scoped field from the authenticated owner's server-validated preferences.
- Only file-write and command-execution policy is user-configurable. Isolation, networking, mounts, privileged execution, ingress, egress, and secrets remain administrator-controlled.
- If both top-level `workerId` and `pairing.workerId` are present, they must match. An entry with `allowPrincipalWorkers: true` and neither worker ID is pairing-only: it is omitted from execution selectors and cannot set `default: true`.

Attached execution automatically enables a safe approval baseline: file writes and command or code execution ask for confirmation, while read-only and search operations continue under the regular tool policy. The baseline is scoped to the Agent using the attached environment. If no user setting is available, LibreChat uses `ask`; [`toolApproval.enabled: false`](#toolapproval) is the administrator emergency override that disables this attached-environment baseline. Callers without approval and resume support fail closed unless that explicit override is set.

Attached execution requires a matching experimental Code Interpreter remote-bridge build. Pairing authenticates the outbound worker connection; it does not replace sandbox or VM isolation. Users with Code Environment management permission pair, configure permitted tool policy, and revoke personal workers under **Settings > Code environments**. See [Stateful Code Sessions](/docs/features/code_interpreter#stateful-code-sessions).

## eventDriven

Configures the trusted internal origin used by Agent event delivery. Most deployments should omit this block and use the current process's bound listener.

<OptionTable
  options={[
    [
      'selfUrl',
      'URL',
      'Overrides the current process bound listener for trusted internal trigger admission. Use only when delivery must traverse another trusted HTTP origin.',
      '',
    ],
  ]}
/>

```yaml filename="endpoints / agents / eventDriven"
endpoints:
  agents:
    eventDriven:
      selfUrl: https://librechat.internal
```

Bound child continuations are automatic. Older `childTurns`, `completionWakeups`, `coalescing`, `actorMailbox`, `checkpointForks`, and `durableReceipts` fields under `eventDriven` are no longer configuration switches and should be removed. The runtime now applies those delivery guarantees directly. The separate [`backgroundTasks.completionWakeups`](#backgroundtasks) field controls conversational delivery for completed background tools and detached Subagents.

Leave `selfUrl` unset for the normal bound-listener path. Set it only when trusted internal trigger admission must traverse another HTTP(S) origin, such as a TLS front door. `AGENT_TRIGGERS_SELF_URL` remains a compatibility fallback when this field is omitted. See [Agents API events](/docs/features/agents_api#agent-events) and [Automatic Parent Continuation](/docs/features/subagents#automatic-parent-continuation).

Event Actor detached Action completion is selected automatically from the built-in generation store. In-memory execution is process-local; Redis generation streams add durable restart recovery and replica handoff. No `librechat.yaml` switch or environment feature flag is required. See [Agent Event Runtime](/docs/configuration/dotenv#agent-event-runtime).

## backgroundTasks

Controls whether supported completed background tools and detached Subagents automatically resume their saved parent Agent.

<OptionTable
  options={[
    [
      'completionWakeups',
      'Boolean',
      'Automatically deliver supported background-task completions as a continuation. Set to false for poll-only behavior.',
      'true',
    ],
  ]}
/>

```yaml filename="endpoints / agents / backgroundTasks"
backgroundTasks:
  completionWakeups: true
```

Automatic completion delivery is enabled even when this block is omitted. Set `completionWakeups: false` to require the Agent to collect every result through `check_background_task`.

Ordinary background tool execution remains process-local and does not survive the loss of its worker process. Once a content-only terminal result is persisted, its delivery is durable and may continue on another replica. Tasks with live artifacts still require polling on the owning run. Detached Subagents keep their separate durable transcript and terminal-result path. Manual polling remains available for status, controls, and recovery in either mode. See [Background Tool Calls](/docs/features/agents#background-tool-calls) and [Automatic Parent Continuation](/docs/features/subagents#automatic-parent-continuation).

## toolApproval

Controls human review for Agent tool calls. The deployment-wide policy is disabled when this block is omitted. An Agent using an attached Code environment is the exception: LibreChat enables its scoped ask-by-default safety policy unless the administrator explicitly sets `enabled: false`. When review applies, matching calls pause until the user submits an allowed decision, such as approving, rejecting, or editing the arguments.

<OptionTable
  options={[
    [
      'enabled',
      'Boolean',
      'Enables deployment-wide tool approval. Explicit false also disables the attached Code environment safety baseline.',
      'Omitted',
    ],
    [
      'mode',
      'String',
      'Sets unmatched-call behavior: `default` asks, `dontAsk` denies, and `bypass` approves unless denied.',
      'default',
    ],
    ['allow', 'Array of strings', 'Glob patterns for calls that can run without prompting.', ''],
    ['deny', 'Array of strings', 'Glob patterns for calls that are always denied. Deny rules win.', ''],
    ['ask', 'Array of strings', 'Glob patterns for calls that always require review.', ''],
    [
      'reason',
      'String',
      'Optional explanation shown in the approval prompt. Use `{tool}` to insert the tool name.',
      '',
    ],
    [
      'hooks',
      'Array of objects',
      'Trusted programmatic policy modules for context-aware decisions. Hooks can only tighten the static policy.',
      '',
    ],
  ]}
/>

Patterns use glob matching. MCP tools can be scoped with `mcp:<server>:<tool>`; for example, `mcp:github:*` matches every tool from the `github` server. LibreChat applies static rules and hook matchers to MCP runtime names and model-facing aliases, including tools reachable through nested Subagents. Static rules are evaluated in `deny`, `ask`, then `allow` order before the selected mode supplies the fallback. A deny rule therefore always wins, including in `bypass` mode.

```yaml filename="endpoints / agents / toolApproval"
toolApproval:
  enabled: true
  mode: default
  allow:
    - 'mcp:analytics:read_*'
  deny:
    - 'mcp:*:delete_*'
  ask:
    - 'mcp:*:*'
  reason: 'Review {tool} before it runs.'
```

Hooks are loaded once at server startup and execute in the LibreChat process. Each entry accepts a `module`, an optional tool-name `matcher` regex, and an optional `options` object passed to the module's builder. Only load code you trust. Per-role or tenant overrides do not reload hook modules; implement contextual behavior inside the hook.

```yaml filename="endpoints / agents / toolApproval / hooks"
toolApproval:
  enabled: true
  hooks:
    - module: '@acme/librechat-approval-hook'
      matcher: '^mcp:production:'
      options:
        requireTicket: true
```

## checkpointer

Configures storage for Agent runs paused by tool approval or Ask User. When either feature needs a checkpointer and this block is omitted, LibreChat uses the primary MongoDB with a 24-hour decision window.

<OptionTable
  options={[
    [
      'type',
      'String',
      '`mongo` persists paused runs across restarts and replicas; `memory` is process-local and intended for development.',
      'mongo',
    ],
    ['ttl', 'Number', 'How long a paused run waits for a decision, in seconds.', '86400'],
    [
      'checkpointCollectionName',
      'String',
      'Optional MongoDB checkpoint collection name override.',
      'agent_checkpoints',
    ],
    [
      'checkpointWritesCollectionName',
      'String',
      'Optional MongoDB checkpoint-write collection name override.',
      'agent_checkpoint_writes',
    ],
  ]}
/>

```yaml filename="endpoints / agents / checkpointer"
checkpointer:
  type: mongo
  ttl: 86400
```

Use `type: memory` only for a single-process development deployment. A paused run stored in memory cannot resume after a restart or on another replica.

MongoDB checkpoints log a warning when serialized state exceeds 8 MiB and reject a durable pause above 15 MiB, leaving headroom below MongoDB's 16 MiB document limit. Large inlined media or tool outputs are common causes; start a new conversation or reduce its context if a run reports `CHECKPOINT_TOO_LARGE`.

## skills

Controls endpoint-level Skills settings for agents.

<OptionTable
  options={[
    [
      'skills.maxCatalogSkills',
      'Number',
      'Caps the number of active accessible Skills exposed in the model-visible catalog. Must be between 1 and 100.',
      'maxCatalogSkills: 20',
    ],
  ]}
/>

**Default:** No configured cap beyond the runtime catalog limit.

**Example:**

```yaml filename="endpoints / agents / skills"
skills:
  maxCatalogSkills: 20
```

This does not disable Skills. Use the `skills` capability and per-agent/model-spec skill scoping to control whether Skills are available.

## maxSubagents

<OptionTable
  options={[
    [
      'maxSubagents',
      'Number',
      'Maximum number of explicit subagents a single agent may reference.',
      'Applies to the `agent_ids` allowlist on agents and on model specs, and to configured subagent `graphs`, which agents support but model specs do not. Must be a whole number between 1 and 50.',
    ],
  ]}
/>

**Default:** `10`

**Range:** `1-50`

**Example:**

```yaml filename="endpoints / agents / maxSubagents"
endpoints:
  agents:
    maxSubagents: 20
```

Raise this when a deployment runs orchestration-heavy agents that need to delegate to more than ten children. The value is read at startup and enforced in three places:

- Agent create, update, and duplicate requests, for `subagents.agent_ids` and `subagents.graphs`
- Model spec `subagents.agent_ids` allowlists, validated in the same configuration pass
- The Agent Builder panel, which stops accepting new subagent entries at the configured value

Model specs accept only `enabled`, `allowSelf`, and `agent_ids` under `subagents`. Subagent `graphs` are an agent-level feature: a `graphs` key on a model spec is dropped when the config is parsed, without an error.

<Callout type="warning">
  `maxSubagents` must be a whole number between 1 and 50. A value outside that range fails
  `librechat.yaml` validation, and LibreChat logs the error and exits at startup instead of falling
  back to the default. Starting with `CONFIG_BYPASS_VALIDATION=true` skips the exit, but the entire
  custom config is discarded in that case, so the cap returns to `10`. To go back to the default
  deliberately, remove the key: an omitted `maxSubagents` resolves to `10` with no error.
</Callout>

<Callout type="note">
  The cap is process-wide and comes from `librechat.yaml`. A per-user or per-group database override
  of `endpoints.agents.maxSubagents` is reflected in the served configuration but is not applied by
  request validation.
</Callout>

Raising this only changes how many subagents one agent may reference. The depth, graph node, and run
configuration limits are unaffected. See [Subagents](/docs/features/subagents#limits).

## maxCitations

<OptionTable
  options={[
    [
      'maxCitations',
      'Number',
      'Controls the maximum total number of citations that can be included in a single agent response.',
      'When using file_search capability, limits the total number of source citations returned to prevent overwhelming responses while ensuring comprehensive coverage.',
    ],
  ]}
/>

**Default:** `30`

**Range:** `1-50`

**Example:**

```yaml filename="endpoints / agents / maxCitations"
maxCitations: 30
```

## maxCitationsPerFile

<OptionTable
  options={[
    [
      'maxCitationsPerFile',
      'Number',
      'Limits the maximum number of citations that can be extracted from any single file.',
      'Ensures citation diversity by preventing any single file from dominating the citations, encouraging representation from multiple sources.',
    ],
  ]}
/>

**Default:** `7`

**Range:** `1-10`

**Example:**

```yaml filename="endpoints / agents / maxCitationsPerFile"
maxCitationsPerFile: 7
```

## minRelevanceScore

<OptionTable
  options={[
    [
      'minRelevanceScore',
      'Number',
      'Sets the minimum relevance score threshold for sources to be included in responses.',
      'Filters out low-quality matches based on vector similarity scores. Higher values (e.g., 0.7) ensure only highly relevant sources are cited, while lower values (e.g., 0.0) include all sources regardless of quality.',
    ],
  ]}
/>

**Default:** `0.45` (45% relevance threshold)

**Range:** `0.0-1.0`

**Example:**

```yaml filename="endpoints / agents / minRelevanceScore"
minRelevanceScore: 0.45
```

### File Citation Configuration Examples

**Default Configuration (Balanced)**

```yaml
endpoints:
  agents:
    maxCitations: 30
    maxCitationsPerFile: 7
    minRelevanceScore: 0.45
```

Provides comprehensive citations while preventing overwhelming responses and filtering out low-quality matches.

**Strict Configuration (High Quality)**

```yaml
endpoints:
  agents:
    maxCitations: 10
    maxCitationsPerFile: 3
    minRelevanceScore: 0.7
```

Only includes highly relevant citations with strict limits for focused responses.

**Comprehensive Configuration (Research)**

```yaml
endpoints:
  agents:
    maxCitations: 50
    maxCitationsPerFile: 10
    minRelevanceScore: 0.0
```

Maximum information extraction for exhaustive research tasks, including all sources regardless of relevance.

## Agent Capabilities

The `capabilities` field allows you to enable or disable specific functionalities for agents. The available capabilities are:

- **deferred_tools**: Allows agents to discover deferred MCP tools at runtime instead of loading every tool into context upfront.
- **programmatic_tools**: Enables Programmatic Tool Calling for MCP tools marked Programmatic in the Agent Builder. Requires `execute_code` and a Code Interpreter deployment with the Tool Call Server component. This capability is opt-in and is not enabled by default.
- **execute_code**: Allows the agent to execute code.
- **stateful_code_sessions**: Lets opted-in agents reuse one Code Interpreter workspace at a user, agent-and-user, or conversation scope. Requires `execute_code`, a compatible Code Interpreter deployment, and the per-agent Advanced setting. New Agents use the signed-in user's preferred scope. This capability is highly experimental, is not enabled by default, and may change substantially during experimentation; do not treat its current behavior or configuration as a stable production contract.
- **file_search**: Enables the agent to search and interact with files. When enabled, citation behavior is controlled by `maxCitations`, `maxCitationsPerFile`, and `minRelevanceScore` settings.
- **web_search**: Enables web search functionality for agents, allowing them to search and retrieve information from the internet.
- **artifacts**: Enables the agent to generate interactive artifacts (React components, HTML, Mermaid diagrams).
- **subagents**: Enables isolated-context child agent runs. See [Subagents](/docs/features/subagents).
- **actions**: Permits the agent to perform predefined actions.
- **context**: Enables "Upload as Text" functionality in chat, and "File Context" for agents, allowing users to upload files and have their content extracted and included directly in the conversation.
- **skills**: Enables Skills in the side panel, manual `$` invocation, model-invoked skills, and agent skill allowlists. See [Skills](/docs/features/skills).
- **memory**: Lets agents use `set_memory` and `delete_memory` when memory is configured and the user has access. Enabled by default; removed at runtime when memory is disabled.
- **ask_user_question**: Lets agents pause to ask one to four related questions in a single form and resume with the answers. Enabled by default.
- **tools**: Grants the agent access to various tools.
- **chain**: Enables Beta feature for agent chaining, also known as Mixture-of-Agents (MoA) workflows.
- **ocr**: Optionally enhances "Upload as Text" in chat, and "File Context" for agents, allowing files to be uploaded and processed with OCR. **Requires an OCR service to be configured.**
- **run_in_background**: Makes Code Interpreter execution and shell tools background-eligible by default and enables per-tool background opt-in for eligible MCP, Plugin, and Action tools. An Action-level switch opts in every eligible operation; OAuth Actions and operations that already define a `run_in_background` parameter are excluded. An agent can explicitly opt Code Interpreter out. The setting permits background execution; the model decides per call whether to use it. Requires `execute_code` and a configured Code Interpreter deployment for code. This capability is not enabled by default.
- **tool_intents**: Adds live model-written intent labels to eligible tool calls. Native tools, including Code Interpreter tools, opt in automatically; MCP tools can be enabled individually or in bulk in the Agent Builder. Model specs use `describeIntent`. This capability is not enabled by default.

By specifying the capabilities, you can control the features available to users when interacting with agents.

## Example Configuration

Here is an example of configuring the `agents` endpoint with custom capabilities and file citation settings:

```yaml filename="Agents Endpoint"
endpoints:
  agents:
    disableBuilder: false
    # File citation configuration
    maxCitations: 20
    maxCitationsPerFile: 5
    minRelevanceScore: 0.6
    # Custom capabilities
    capabilities:
      # Optional: enables Programmatic Tool Calling for MCP tools marked Programmatic in the Agent Builder.
      # - 'programmatic_tools'
      - 'execute_code'
      # Optional: makes Code Interpreter background-eligible and enables selected MCP, Plugin, and Action tools.
      # - 'run_in_background'
      # Optional: enables live intent labels for native and selected MCP tools.
      # - 'tool_intents'
      - 'file_search'
      - 'skills'
      - 'subagents'
      - 'actions'
      - 'artifacts'
      - 'context'
      - 'ocr'
      - 'web_search'
```

In this example:

- The builder interface is enabled
- File citations are limited to 20 total, with maximum 5 per file
- Only sources with 60%+ relevance are included
- LibreChat Agents have access to code execution, file search (with citations), Skills, Subagents, actions, artifacts, file context, ocr services if configured, and web search capabilities
- Programmatic Tool Calling remains disabled unless you add the `programmatic_tools` capability alongside `execute_code`
- Background tool calls remain disabled unless you add `run_in_background`; Code Interpreter tools then become eligible by default, while eligible MCP, Plugin, and Action tools still require selection
- Tool intent labels remain disabled unless you add `tool_intents`; native tools then opt in automatically, while MCP tools still require per-tool selection

## remoteApi

Configuration for Remote Agent API authentication. Controls how external services authenticate when calling the Agents API endpoints.

### remoteApi.auth

<OptionTable
  options={[
    [
      'auth',
      'Object',
      'Authentication configuration for the Remote Agent API.',
      'Supports API key and/or OIDC Bearer token authentication. If omitted, only API key auth is active.',
    ],
  ]}
/>

#### remoteApi.auth.apiKey

<OptionTable
  options={[
    [
      'enabled',
      'Boolean',
      'Enable API key authentication for the Remote Agent API.',
      'When true, requests with a valid LibreChat API key are accepted. Can be used alongside or instead of OIDC.',
    ],
  ]}
/>

**Default:** `true`

#### remoteApi.auth.oidc

<OptionTable
  options={[
    [
      'enabled',
      'Boolean',
      'Enable OIDC Bearer token authentication.',
      'When true, the middleware validates Bearer tokens against the configured OIDC issuer via JWKS.',
    ],
    [
      'issuer',
      'String',
      'OIDC issuer URL.',
      'The base URL of your OIDC provider, such as a Keycloak realm URL. Used for token issuer validation and JWKS discovery if jwksUri is not set.',
    ],
    [
      'jwksUri',
      'String',
      'JWKS endpoint URL. Optional.',
      'If omitted, resolved automatically via {issuer}/.well-known/openid-configuration. You can also set OPENID_JWKS_URL as an alternative.',
    ],
    [
      'audience',
      'String',
      'Expected token audience. Required when OIDC auth is enabled.',
      'Tokens must contain this value in their aud claim.',
    ],
    [
      'scope',
      'String',
      'Required scope value. Optional.',
      'If set, the token must contain this value in its scp or scope claim. Use this to distinguish token intent across different APIs.',
    ],
  ]}
/>

**Default:** `enabled: false`

**Example - OIDC only:**

```yaml filename="endpoints / agents / remoteApi"
endpoints:
  agents:
    remoteApi:
      auth:
        apiKey:
          enabled: false
        oidc:
          enabled: true
          issuer: https://auth.example.com/realms/myrealm
          audience: my-client-id
```

**Example - OIDC with API key fallback:**

```yaml filename="endpoints / agents / remoteApi"
endpoints:
  agents:
    remoteApi:
      auth:
        apiKey:
          enabled: true
        oidc:
          enabled: true
          issuer: https://auth.example.com/realms/myrealm
          # jwksUri is optional and auto-discovered if omitted
          jwksUri: https://auth.example.com/realms/myrealm/protocol/openid-connect/certs
          audience: my-client-id
```

<Callout type="info">
  JWKS URI resolution priority is explicit `jwksUri`, then `OPENID_JWKS_URL`, then
  auto-discovery via `{issuer}/.well-known/openid-configuration`.
</Callout>

<Callout type="info">
  OIDC user matching uses the `sub` claim as primary lookup, with fallback to `email`,
  `preferred_username`, or `upn` claims. The matched user must already exist in LibreChat.
</Callout>

## Subagents

The `subagents` field controls which isolated child agents a parent agent can spawn when the `subagents` capability is available.

<OptionTable
  options={[
    [
      'enabled',
      'Boolean',
      'Adds the subagent spawn tool to this agent when true. Default: disabled.',
      'enabled: true',
    ],
    [
      'allowSelf',
      'Boolean',
      'Allows the agent to spawn itself in a fresh isolated context. Default: true.',
      'allowSelf: true',
    ],
    [
      'agent_ids',
      'Array/List of Strings',
      'Specific agents this agent may spawn. Capped by `maxSubagents`, which defaults to 10.',
      'agent_ids: ["agent_researcher"]',
    ],
    [
      'graphs',
      'Array of Objects',
      'Saved Agent teams that can run as one isolated child graph. The list is capped by `maxSubagents` (default: 10); each team can contain up to 32 members.',
      '',
    ],
  ]}
/>

```yaml filename="Agent subagents"
subagents:
  enabled: true
  allowSelf: true
  agent_ids:
    - 'agent_researcher'
    - 'agent_reviewer'
```

Each `graphs` entry requires a unique `type`, `name`, `description`, `agent_ids`, direct `edges`, `entry_agent_id`, and `result_agent_id`. Team definitions must form a connected directed acyclic graph, every member must be visible to the user, and the total configuration is bounded to 50 unique Agent targets and 100 expanded run configurations. See the [saved-team example and runtime behavior](/docs/features/subagents#configure-an-agent).

For user-facing behavior and limits, see [Subagents](/docs/features/subagents).

## Notes

- It's not recommended to disable the builder interface unless you are using [modelSpecs](/docs/configuration/librechat_yaml/object_structure/model_specs) to define a list of agents to choose from.
- File citation configuration (`maxCitations`, `maxCitationsPerFile`, `minRelevanceScore`) only applies when the `file_search` capability is enabled.
- The relevance score is calculated using vector similarity, where 1.0 represents a perfect match and 0.0 represents no similarity.
- Citation limits help balance comprehensive information retrieval with response quality and performance.
- The `context` capability works without OCR configuration using text parsing methods. OCR enhances extraction quality when configured.
- The `ocr` capability requires an OCR service to be configured (see [OCR Configuration](/docs/configuration/librechat_yaml/object_structure/ocr)).
- `maxSubagents` bounds how many subagents a single agent may reference. It does not change the depth or graph limits documented under [Subagents](/docs/features/subagents#limits).
