Skip to content

🛂 fix: Gate MCP Queries Behind USE Permission to Prevent 403 Spam#12345

Merged
danny-avila merged 3 commits into
devfrom
fix/mcp-query-permission-guard
Mar 20, 2026
Merged

🛂 fix: Gate MCP Queries Behind USE Permission to Prevent 403 Spam#12345
danny-avila merged 3 commits into
devfrom
fix/mcp-query-permission-guard

Conversation

@danny-avila

@danny-avila danny-avila commented Mar 20, 2026

Copy link
Copy Markdown
Owner

Closes #12342

Summary

Fixed unconditional MCP data-fetching that flooded backend logs with 403 Forbidden errors whenever interface.mcpServers.use: false was set in librechat.yaml. Closes #12342.

  • Added a useHasAccess({ permissionType: PermissionTypes.MCP_SERVERS, permission: Permissions.USE }) check in useAppStartup and passed the resulting canUseMcp boolean as enabled to both useMCPServersQuery and useMCPToolsQuery, preventing either query from firing on startup, window focus, or stale intervals when the user lacks the permission.
  • Applied the same enabled: canUseMcp guard to useMCPServersQuery and useGetAllEffectivePermissionsQuery in useMCPServerManager, matching the guard pattern already used by MCP UI rendering components (MCPTools, ToolsDropdown, MCPSelect).
  • Added useAppStartup.spec.tsx with 6 test cases covering: correct permission type/permission passed to useHasAccess, both queries suppressed when canUseMcp is false, both queries enabled when permission is granted with servers loaded and user present, and tools query suppressed independently when the user prop is undefined, the servers object is empty, or servers are still loading.
  • Corrected local import order in useAppStartup.ts to comply with longest-to-shortest project convention.
  • Sorted the multi-line librechat-data-provider named import block in useMCPServerManager.ts shortest to longest.
  • Restored an intent comment on the useGetStartupConfig call in useMCPServerManager to document that it is retained specifically for interface.mcpServers.placeholder.

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

Verified the guard using the new unit test suite in client/src/hooks/Config/__tests__/useAppStartup.spec.tsx. To reproduce manually:

Test Configuration:

  1. Set interface.mcpServers.use: false in librechat.yaml and restart the backend.
  2. Log in and confirm that no requests to GET /api/mcp/servers appear in the browser network tab or backend logs on startup, window focus, or after 30 seconds.
  3. Remove the override (or set use: true) and restart — confirm MCP servers load normally and the tools dropdown and agent panel MCP tools render and function correctly.

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

Closes #12342

When `interface.mcpServers.use` is set to `false` in `librechat.yaml`,
the frontend was still unconditionally fetching `/api/mcp/servers` on
every app startup, window focus, and stale interval — producing
continuous 403 "Insufficient permissions" log entries.

Add `useHasAccess` permission checks to both `useMCPServersQuery` call
sites (`useAppStartup` and `useMCPServerManager`) so the query is
disabled when the user lacks `MCP_SERVERS.USE`, matching the guard
pattern already used by MCP UI components.
Copilot AI review requested due to automatic review settings March 20, 2026 20:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR prevents repeated unauthorized MCP network requests when MCP is disabled for a user (e.g., via interface.mcpServers.use: false), reducing backend 403/log spam by conditionally enabling MCP React Query hooks only when the user has MCP_SERVERS.USE.

Changes:

  • Add a useHasAccess (MCP_SERVERS.USE) gate to useAppStartup, disabling useMCPServersQuery and useMCPToolsQuery when access is not granted.
  • Add the same access gate to useMCPServerManager, disabling useMCPServersQuery when access is not granted.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
client/src/hooks/Config/useAppStartup.ts Gates MCP servers/tools startup queries behind MCP_SERVERS.USE permission.
client/src/hooks/MCP/useMCPServerManager.ts Gates MCP servers query behind MCP_SERVERS.USE permission inside the shared MCP manager hook.
Comments suppressed due to low confidence (1)

client/src/hooks/MCP/useMCPServerManager.ts:48

  • useMCPServersQuery is now gated by canUseMcp, but useGetAllEffectivePermissionsQuery(ResourceType.MCPSERVER) still runs unconditionally. If MCP is disabled for the user, this will continue to hit /api/permissions/MCPSERVER/effective/all on mount/stale refetch and can still generate 403/log spam. Consider passing a react-query enabled: canUseMcp (or canUseMcp && !!loadedServers) config to this permissions query as well.
  // Fetch effective permissions for all MCP servers
  const { data: permissionsMap } = useGetAllEffectivePermissionsQuery(ResourceType.MCPSERVER);


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Gate `useGetAllEffectivePermissionsQuery` behind `canUseMcp` in
  `useMCPServerManager` for consistency (wasted request when MCP
  disabled, even though this endpoint doesn't 403)
- Sort multi-line `librechat-data-provider` import shortest to longest
- Restore intent comment on `useGetStartupConfig` call
- Add `useAppStartup` test suite covering MCP permission gating:
  query suppression when USE denied, compound `enabled` conditions
  for tools query (servers loading, empty, no user)
@danny-avila danny-avila changed the title 🐛 fix: Gate MCP queries behind USE permission to prevent 403 spam 🛂 fix: Gate MCP Queries Behind USE Permission to Prevent 403 Spam Mar 20, 2026
@danny-avila danny-avila merged commit 01f19b5 into dev Mar 20, 2026
7 checks passed
@danny-avila danny-avila deleted the fix/mcp-query-permission-guard branch March 20, 2026 21:10
jcbartle pushed a commit to jcbartle/LibreChat that referenced this pull request May 11, 2026
…nny-avila#12345)

* 🐛 fix: Gate MCP queries behind USE permission to prevent 403 spam

Closes danny-avila#12342

When `interface.mcpServers.use` is set to `false` in `librechat.yaml`,
the frontend was still unconditionally fetching `/api/mcp/servers` on
every app startup, window focus, and stale interval — producing
continuous 403 "Insufficient permissions" log entries.

Add `useHasAccess` permission checks to both `useMCPServersQuery` call
sites (`useAppStartup` and `useMCPServerManager`) so the query is
disabled when the user lacks `MCP_SERVERS.USE`, matching the guard
pattern already used by MCP UI components.

* fix: Lint and import order corrections

* fix: Address review findings — gate permissions query, add tests

- Gate `useGetAllEffectivePermissionsQuery` behind `canUseMcp` in
  `useMCPServerManager` for consistency (wasted request when MCP
  disabled, even though this endpoint doesn't 403)
- Sort multi-line `librechat-data-provider` import shortest to longest
- Restore intent comment on `useGetStartupConfig` call
- Add `useAppStartup` test suite covering MCP permission gating:
  query suppression when USE denied, compound `enabled` conditions
  for tools query (servers loading, empty, no user)
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.

2 participants