Conversation
The custom endpoints quick start offered `user_provided` as one of three
apiKey styles and then sent every reader into "Step 3. Set Environment
Variables", which reads as mandatory. A reader who picked `user_provided`
was told to do the one thing that option exists to avoid.
Scope Step 3 to the `${VARIABLE_NAME}` form and say so in the callout, so
each option states whether it needs an .env entry at all. Verified against
initializeCustom in packages/api/src/endpoints/custom/initialize.ts: a
`user_provided` endpoint reads the key from the per-user encrypted Key
record and never touches process.env.
Also list ANTHROPIC_API_KEY in the .env sample, which the example config
above references but the sample omitted, and note that an unresolved
`${VAR}` keeps the endpoint in the selector and only fails at send time
rather than dropping it.
Feedback: 1545680589888421981
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RtKgYeptrzc2kctgcyR8Mf
"Providing a growing ecosystem of dynamic, ready-to-use integrations" told the reader nothing and was not accurate: LibreChat ships no built-in MCP registry, marketplace or curated catalog, and users always supply their own server config through librechat.yaml or the MCP Settings panel. Smithery is an external site, not a bundled catalog. Replace it with runtime server management, which the page already documents at length under "Adding MCP Servers in the UI" and which is backed by createMCPServerController and MCPServersRegistry.addServer in the app. That bullet contradicted the blanket "any time you add or edit an MCP server, you will need to restart LibreChat" two paragraphs below, so scope that sentence to librechat.yaml servers. YAML servers load at boot with no file watcher; servers saved through the panel are inspected and stored in the DB tier during the request and need no restart. Feedback: 1545680954620780568, 1545681058937307189 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RtKgYeptrzc2kctgcyR8Mf
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5c7a6d694f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| LibreChat provides two ways to use MCP servers, either in the chat area or with agents. | ||
|
|
||
| You can configure MCP servers manually in your `librechat.yaml` file or by using [smithery.ai](https://smithery.ai) to find and install MCP servers into `librechat.yaml` ([see example below](#basic-configuration)). Any time you add or edit an MCP server, you will need to restart LibreChat to initialize the connections. | ||
| You can configure MCP servers manually in your `librechat.yaml` file or by using [smithery.ai](https://smithery.ai) to find and install MCP servers into `librechat.yaml` ([see example below](#basic-configuration)). Any time you add or edit a server in `librechat.yaml`, you will need to restart LibreChat to initialize the connections. Servers added through the [MCP Settings panel](#adding-mcp-servers-in-the-ui) are initialized as soon as they are saved and need no restart. |
There was a problem hiding this comment.
Do not call OAuth servers initialized when saved
For a UI-created server that requires OAuth, saving only registers the server; the same page later says it remains disconnected and requires an explicit Authenticate/Initialize action before it can be used. Saying every panel-created server is initialized as soon as it is saved contradicts that workflow and may cause users to skip the required authentication step; describe the configuration as taking effect without a restart instead.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 9c848cd. Confirmed against Step 3 of this same page: a panel-created OAuth server is registered on save but shows as disconnected until the user runs the authenticate flow, so "initialized as soon as they are saved" was an overclaim that could lead readers to skip authentication. The sentence now says panel-created servers take effect without a restart, and adds that an OAuth one starts out disconnected with a link to the authenticate step.
| ``` | ||
|
|
||
| Each `${VARIABLE_NAME}` in librechat.yaml must have a matching entry in `.env`. | ||
| Every `${VARIABLE_NAME}` in `librechat.yaml` needs a matching entry. A missing one does not drop the endpoint: it still appears in the selector, and the problem only surfaces as `Missing API Key for <endpoint>` once someone sends a message through it. |
There was a problem hiding this comment.
Scope the missing-variable error to API key references
The ${VARIABLE_NAME} syntax is also supported by fields such as baseURL and headers, so a missing variable does not universally surface as Missing API Key for <endpoint>. This troubleshooting claim is accurate only when the unresolved reference is the endpoint's apiKey; as written, users with another unresolved field are told to expect the wrong failure mode.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 9c848cd. Verified in initializeCustom (packages/api/src/endpoints/custom/initialize.ts): apiKey and baseURL are resolved separately and each unresolved reference throws its own error, 'Missing API Key for ' and 'Missing Base URL for '. The text now names both instead of presenting the apiKey failure as the universal outcome. I did not extend the claim to headers: for custom endpoints, extractEnvVariable is applied to apiKey and baseURL specifically, and endpointConfig.headers is passed through at that site, so I left headers out rather than assert a failure mode I had not confirmed.
📦 Next.js Bundle Analysis for librechat.aiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
Two accuracy corrections from PR review on the previous two commits. The MCP intro said servers added in the MCP Settings panel "are initialized as soon as they are saved". That contradicts Step 3 of the same page: a panel-created server that uses OAuth is registered on save but shows as disconnected until the user runs the authenticate flow. Saying it is initialized on save invites readers to skip that step, so the sentence now claims only that the configuration takes effect without a restart and points at the authentication step. The custom endpoints page said a missing .env entry surfaces as "Missing API Key for <endpoint>". That holds only when the unresolved reference is the endpoint's apiKey. initializeCustom resolves apiKey and baseURL separately and throws a distinct error for each, so name both instead of presenting the apiKey failure as universal. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BwbrBkBq4fq9G8g3oRnh1j
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9c848cd011
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ## Step 3. Set Environment Variables | ||
|
|
||
| Add the API keys referenced in your `librechat.yaml` to the `.env` file: | ||
| This step applies only to endpoints written with the `${VARIABLE_NAME}` form. If every endpoint you added uses `user_provided`, skip to [Step 4](#step-4-restart-and-verify). |
There was a problem hiding this comment.
Base Step 3 on all environment references
At the confirmed head 9c848cd0, this skip condition is still incorrect when every endpoint's apiKey uses user_provided but another field—such as headers.X-Tenant: '${TENANT_ID}'—references an environment variable. Custom endpoint headers explicitly support ${ENV_VAR} values (content/docs/configuration/librechat_yaml/object_structure/custom_endpoint.mdx, lines 757–782), so following this instruction can leave required headers unresolved; tell readers to skip Step 3 only when their endpoint configuration contains no ${...} references.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in ca79c7f. Confirmed in the app source, not just the reference page: resolveHeaders runs every header value through processSingleValue, which calls extractEnvVariable (packages/api/src/utils/env.ts:326), so a header like X-Tenant: '${TENANT_ID}' does need a .env entry even when no endpoint reads its key from the environment. The skip condition is now based on whether the configuration contains any ${...} reference at all, and the two callout claims are scoped to the API key rather than to Step 3 as a whole. I also documented the header failure mode while I was there: RESOLVABLE_PLACEHOLDER_PATTERN only strips {{...}} forms, so an unresolved ${VAR} in a header is forwarded to the provider as literal text rather than raising a LibreChat error. That makes it quieter than the apiKey and baseURL cases, which is worth telling readers.
📦 Next.js Bundle Analysis for librechat.aiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
The skip condition told readers to jump past Step 3 whenever every
endpoint used `user_provided`, but `apiKey` is not the only field that
takes `${VARIABLE_NAME}`. resolveHeaders runs each header value through
processSingleValue, which calls extractEnvVariable, so a header such as
`X-Tenant: '${TENANT_ID}'` needs a .env entry even when no endpoint
reads a key from the environment.
Base the skip on whether the configuration contains any `${...}`
reference at all, and scope the two callout claims to the API key rather
than to Step 3 as a whole.
Also name the header failure mode, which is quieter than the other two:
RESOLVABLE_PLACEHOLDER_PATTERN only strips `{{...}}` forms, so an
unresolved `${VAR}` in a header reaches the provider as literal text
instead of raising a LibreChat error.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwbrBkBq4fq9G8g3oRnh1j
|
Codex Review: Didn't find any major issues. 🚀 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
📦 Next.js Bundle Analysis for librechat.aiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
Summary
Two docs pages told readers something the code does not do. Both came in through Discord feedback and both were verified against
origin/devof the app before editing./docs/quick_start/custom_endpointslistedapiKey: 'user_provided'as one of three options and then walked every reader into "Step 3. Set Environment Variables" as an unconditional step. A reader who choseuser_providedwas being told to do the exact thing that option exists to avoid. Step 3 is now scoped to the${VARIABLE_NAME}form, and each option in the callout says whether it needs an.enventry.Verified in
packages/api/src/endpoints/custom/initialize.ts: whenapiKeyisuser_provided, LibreChat reads the key from the per-userKeyrecord viagetUserKeyValuesand never consultsprocess.env. Two smaller corrections came out of the same reading: the.envsample omittedANTHROPIC_API_KEYeven though the example config above it references that variable, and an unresolved${VAR}does not drop the endpoint (it stays in the selector and throwsMissing API Key for <endpoint>only when a message is sent)./docs/features/mcpopened with "Providing a growing ecosystem of dynamic, ready-to-use integrations". It is contentless, and it is not accurate: LibreChat ships no MCP registry, marketplace or curated catalog. Users always bring their own server config, and Smithery is an external site rather than a bundled catalog. It is replaced with runtime server management, which the page already documents at length and which is backed bycreateMCPServerControllerandMCPServersRegistry.addServer.That replacement exposed a contradiction already on the page: the intro said a restart is needed "any time you add or edit an MCP server", while the UI section below says servers can be added "without editing any configuration files or restarting the server". Both are half right, so the intro sentence is now scoped to
librechat.yaml. YAML servers load at boot and have no file watcher; servers saved through the MCP Settings panel are inspected and stored in the DB tier during the request.Only English sources are touched. The
.de.mdxpage the reporters were reading is bot output fromtranslate_docs.yml, which retranslates the changed blocks on merge tomain.Change Type
Feedback addressed
1545680589888421981and/docs/quick_start/custom_endpointsuser_providedas an option, then required an.envvariable for the API key, which is the opposite of what that option does.${VAR}endpoints, stated per option whether.envis involved, completed the.envsample, and documented the real missing-variable failure mode.1545681058937307189and/de/docs/features/mcp1545680954620780568and/de/docs/features/mcp1545681058937307189Validation
pnpm lintpassed, exit 0pnpm typecheckpassedpnpm testpassed, 392 tests across 33 filespnpm prettier --checkon both changed files passedpnpm buildpassed withNODE_OPTIONS=--max-old-space-size=8192id="step-4-restart-and-verify"andid="adding-mcp-servers-in-the-ui"exist as real heading targets for the two new links, and that<endpoint>escapes as text rather than being parsed as a tagAt Node's default heap size
pnpm buildexits 134 with a V8 out-of-memory error on this machine. That reproduces identically on the base commitc2458735with these changes absent, so it is a local memory limit rather than a regression from this PR.Not changed
1545723846936629279and1545793533032796341, both positive ratings on/docswith no report attached. Investigated and classified NON-ACTIONABLE, no repository change.*.de.mdxfiles were hand-edited.translate_docs.ymltreats them as generated output and explicitly excludes them from its own triggers.🤖 Generated with Claude Code
https://claude.ai/code/session_01RtKgYeptrzc2kctgcyR8Mf