Skip to content

🧭 docs: Reconcile Contradictory Custom Endpoint and MCP Guidance - #757

Merged
berry-13 merged 4 commits into
mainfrom
berry-13/auto-librechat-ai-address-feedbacks-run-5-20260905T1800
Sep 6, 2026
Merged

berry-13 merged 4 commits into
mainfrom
berry-13/auto-librechat-ai-address-feedbacks-run-5-20260905T1800

Conversation

@berry-13

@berry-13 berry-13 commented Sep 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

Two docs pages told readers something the code does not do. Both came in through Discord feedback and both were verified against origin/dev of the app before editing.

/docs/quick_start/custom_endpoints listed apiKey: '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 chose user_provided was 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 .env entry.

Verified in packages/api/src/endpoints/custom/initialize.ts: when apiKey is user_provided, LibreChat reads the key from the per-user Key record via getUserKeyValues and never consults process.env. Two smaller corrections came out of the same reading: the .env sample omitted ANTHROPIC_API_KEY even though the example config above it references that variable, and an unresolved ${VAR} does not drop the endpoint (it stays in the selector and throws Missing API Key for <endpoint> only when a message is sent).

/docs/features/mcp opened 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 by createMCPServerController and MCPServersRegistry.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.mdx page the reporters were reading is bot output from translate_docs.yml, which retranslates the changed blocks on merge to main.

Change Type

  • Documentation update

Feedback addressed

  • 1545680589888421981 and /docs/quick_start/custom_endpoints

    • Page presented user_provided as an option, then required an .env variable for the API key, which is the opposite of what that option does.
    • Scoped Step 3 to ${VAR} endpoints, stated per option whether .env is involved, completed the .env sample, and documented the real missing-variable failure mode.
    • Classification: FIXED
  • 1545681058937307189 and /de/docs/features/mcp

    • "Providing a growing ecosystem of dynamic, ready-to-use integrations" is marketing rather than documentation.
    • Replaced with a concrete, source-verified capability, and scoped the contradictory restart sentence it sat above.
    • Classification: FIXED
  • 1545680954620780568 and /de/docs/features/mcp

    • Same reporter, sent 25 seconds earlier, containing only the quoted sentence with no complaint attached.
    • Resolved by the same change.
    • Classification: DUPLICATE of 1545681058937307189

Validation

  • pnpm lint passed, exit 0
  • pnpm typecheck passed
  • pnpm test passed, 392 tests across 33 files
  • pnpm prettier --check on both changed files passed
  • pnpm build passed with NODE_OPTIONS=--max-old-space-size=8192
  • Verified in the built HTML that both pages render the new text, that id="step-4-restart-and-verify" and id="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 tag

At Node's default heap size pnpm build exits 134 with a V8 out-of-memory error on this machine. That reproduces identically on the base commit c2458735 with these changes absent, so it is a local memory limit rather than a regression from this PR.

Not changed

  • 1545723846936629279 and 1545793533032796341, both positive ratings on /docs with no report attached. Investigated and classified NON-ACTIONABLE, no repository change.
  • No translated *.de.mdx files were hand-edited. translate_docs.yml treats them as generated output and explicitly excludes them from its own triggers.
  • The wider claim in the first report that the page is "AI-generated nonsense" did not hold up. The instructions were individually correct; the defect was that Step 3 was presented unconditionally, which is what this fixes.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RtKgYeptrzc2kctgcyR8Mf

berry-13 and others added 2 commits September 5, 2026 20:11
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
@vercel

vercel Bot commented Sep 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
librechat-ai Ready Ready Preview Sep 6, 2026 7:08pm UTC

Request Review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-06T19:04:52.364010Z ca79c7f Manual request
🔒 Security Review ✅ Completed 2026-09-05T18:21:39.538501Z 5c7a6d6 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread content/docs/features/mcp.mdx Outdated
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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

📦 Next.js Bundle Analysis for librechat.ai

This 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
@berry-13

berry-13 commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review
Please review the current PR head (9c848cd). Confirm that this exact commit is the reviewed commit and ignore findings that apply only to earlier heads.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

📦 Next.js Bundle Analysis for librechat.ai

This 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
@berry-13

berry-13 commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review
Please review the current PR head (ca79c7f). Confirm that this exact commit is the reviewed commit and ignore findings that apply only to earlier heads.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: ca79c7f0e5

ℹ️ 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".

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

📦 Next.js Bundle Analysis for librechat.ai

This analysis was generated by the Next.js Bundle Analysis action. 🤖

This PR introduced no changes to the JavaScript bundle! 🙌

@berry-13
berry-13 merged commit fe66545 into main Sep 6, 2026
6 checks passed
@berry-13
berry-13 deleted the berry-13/auto-librechat-ai-address-feedbacks-run-5-20260905T1800 branch September 6, 2026 19:22

This branch was successfully deployed

1 active deployment
Preview — ca79c7f0 Deployed Sep 6, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant