🧩 refactor: Decouple MCP Config from Startup Config (#10689)

* Decouple mcp config from start up config

* Chore: Work on AI Review and Copilot Comments

- setRawConfig is not needed since the private raw config is not needed any more
- !!serversLoading bug fixed
- added unit tests for route /api/mcp/servers
- copilot comments addressed

* chore: remove comments

* chore: rename data-provider dir for MCP

* chore: reorganize mcp specific query hooks

* fix: consolidate imports for MCP server manager

* chore: add dev-staging branch to frontend review workflow triggers

* feat: add GitHub Actions workflow for building and pushing Docker images to GitHub Container Registry and Docker Hub

* fix: update label for tag input in BookmarkForm tests to improve clarity

---------

Co-authored-by: Atef Bellaaj <slalom.bellaaj@external.daimlertruck.com>
Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
Atef Bellaaj 2025-11-26 21:26:40 +01:00 committed by Danny Avila
parent 98b188f26c
commit ef1b7f0157
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
36 changed files with 548 additions and 301 deletions

View file

@ -12,10 +12,10 @@ function MCPSelectContent() {
mcpValues,
isInitializing,
placeholderText,
configuredServers,
batchToggleServers,
getConfigDialogProps,
getServerStatusIconProps,
availableMCPServers,
} = mcpServerManager;
const renderSelectedValues = useCallback(
@ -78,7 +78,7 @@ function MCPSelectContent() {
return (
<>
<MultiSelect
items={configuredServers}
items={availableMCPServers?.map((s) => s.serverName)}
selectedValues={mcpValues ?? []}
setSelectedValues={batchToggleServers}
renderSelectedValues={renderSelectedValues}
@ -99,9 +99,9 @@ function MCPSelectContent() {
function MCPSelect() {
const { mcpServerManager } = useBadgeRowContext();
const { configuredServers } = mcpServerManager;
const { availableMCPServers } = mcpServerManager;
if (!configuredServers || configuredServers.length === 0) {
if (!availableMCPServers || availableMCPServers.length === 0) {
return null;
}

View file

@ -20,7 +20,7 @@ const MCPSubMenu = React.forwardRef<HTMLDivElement, MCPSubMenuProps>(
setIsPinned,
isInitializing,
placeholderText,
configuredServers,
availableMCPServers,
getConfigDialogProps,
toggleServerSelection,
getServerStatusIconProps,
@ -33,7 +33,7 @@ const MCPSubMenu = React.forwardRef<HTMLDivElement, MCPSubMenuProps>(
});
// Don't render if no MCP servers are configured
if (!configuredServers || configuredServers.length === 0) {
if (!availableMCPServers || availableMCPServers.length === 0) {
return null;
}
@ -85,19 +85,19 @@ const MCPSubMenu = React.forwardRef<HTMLDivElement, MCPSubMenuProps>(
'border border-border-light bg-surface-secondary p-1 shadow-lg',
)}
>
{configuredServers.map((serverName) => {
const statusIconProps = getServerStatusIconProps(serverName);
const isSelected = mcpValues?.includes(serverName) ?? false;
const isServerInitializing = isInitializing(serverName);
{availableMCPServers.map((s) => {
const statusIconProps = getServerStatusIconProps(s.serverName);
const isSelected = mcpValues?.includes(s.serverName) ?? false;
const isServerInitializing = isInitializing(s.serverName);
const statusIcon = statusIconProps && <MCPServerStatusIcon {...statusIconProps} />;
return (
<Ariakit.MenuItem
key={serverName}
key={s.serverName}
onClick={(event) => {
event.preventDefault();
toggleServerSelection(serverName);
toggleServerSelection(s.serverName);
}}
disabled={isServerInitializing}
className={cn(
@ -112,7 +112,7 @@ const MCPSubMenu = React.forwardRef<HTMLDivElement, MCPSubMenuProps>(
>
<div className="flex flex-grow items-center gap-2">
<Ariakit.MenuItemCheck checked={isSelected} />
<span>{serverName}</span>
<span>{s.serverName}</span>
</div>
{statusIcon && <div className="ml-2 flex items-center">{statusIcon}</div>}
</Ariakit.MenuItem>