danny-avila/LibreChat · error · Error

[MCP][${serverName}][${toolName}] upstream authentication fa

Error message

[MCP][${serverName}][${toolName}] upstream authentication failed; MCP OAuth is not configured for this server.

What it means

In the MCP tool _call catch block (MCP.js:1144), when the upstream error looks like an auth failure (401/OAuth/authentication substring) AND the captured server config does not require OAuth machinery, the tool refuses with this message. It tells the operator the MCP server returned 401 but LibreChat has no OAuth flow configured for that server, so the credential path is misconfigured rather than merely pending.

Source

Thrown at api/server/services/MCP.js:1144

      );

      /** OAuth error, provide a helpful message */
      const isOAuthError =
        error.message?.includes('401') ||
        error.message?.includes('OAuth') ||
        error.message?.includes('authentication') ||
        error.message?.includes('Non-200 status code (401)');
      const isOAuthFlowSignal =
        error.message === 'OAuth flow initiated - return early' ||
        error.message === 'Pending OAuth flow reused - return early';

      if (isOAuthError) {
        if (
          capturedServerConfig &&
          !requiresOAuthMachinery(capturedServerConfig) &&
          !isOAuthFlowSignal
        ) {
          throw new Error(
            `[MCP][${serverName}][${toolName}] upstream authentication failed; MCP OAuth is not configured for this server.`,
          );
        }
        throw new Error(
          `[MCP][${serverName}][${toolName}] OAuth authentication required. Please check the server logs for the authentication URL.`,
        );
      }

      throw new Error(
        `[MCP][${serverName}][${toolName}] tool call failed${error?.message ? `: ${error?.message}` : '.'}`,
      );
    }
  };

  const toolInstance = tool(_call, {
    schema,
    name: normalizedToolKey,
    description: description || '',

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Add an OAuth configuration block for the MCP server in librechat.yaml so requiresOAuthMachinery returns true.
  2. If the server uses static credentials, fix the headers/token config so the 401 stops — the error is a symptom of the upstream rejecting your (absent) credentials.
  3. Confirm the MCP server definition key matches what the tool registry expects; a mismatch can drop the oauth block.

Example fix

# before
mcpServers:
  github:
    url: https://mcp.github.example/sse
# after
mcpServers:
  github:
    type: sse
    url: https://mcp.github.example/sse
    oauth:
      scope: github
      client_id: ${MCP_GH_CLIENT_ID}
Defensive patterns

Strategy: try-catch

Validate before calling

function assertMcpAuthConfigured(serverName, serverConfig) {
  const needsOauth = upstreamRequiresAuth(serverConfig);
  if (needsOauth && !requiresOAuthMachinery(serverConfig)) {
    throw new Error(`Add an oauth block for ${serverName} in librechat.yaml`);
  }
}

Type guard

const hasOauthBlock = (cfg) => !!(cfg?.oauth || cfg?.oauthConfig);

Try / catch

try {
  await callMcpTool(...);
} catch (e) {
  if (/OAuth is not configured/.test(e.message)) { await fixServerConfig(serverName); return; }
  throw e;
}

Prevention

When it happens

Trigger: An MCP server returns HTTP 401 (or a message containing 'authentication'/'OAuth') during callTool, but the server entry in librechat.yaml has no oauth config block and requiresOAuthMachinery(capturedServerConfig) is false. The user has no usable static token and no OAuth path to fall back to.

Common situations: MCP server added with only a url but the upstream now requires OAuth. Token fields renamed/moved in config. The server's auth header/token injection code path is broken so the upstream sees an anonymous request.

Understand the failure class

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/3c775b5dd8fcd84a. Report an issue: GitHub.