Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Troubleshooting MCP auth

Troubleshooting guide for common errors while adding auth for MCP Servers

Use this guide when you use Scalekit as the authentication server for your MCP servers and a client fails to connect, a request stalls, or the authentication handshake breaks. Start with the category that matches your symptom, then open the matching scenario.

Most issues fall into configuration and setup, CORS and network access, or client-specific behavior. Each scenario explains the cause and the fix.

/auth-requests/ returns a 404 or “invalid ID” error

You may be passing the MCP server’s resource ID instead of the connection ID in the URL path.

These are two different identifiers with different purposes:

IdentifierFormatPurpose
resource_idres_xxxIdentifies the MCP server; used in token audiences and client registration
connection_idconn_xxxIdentifies your BYOA auth connection; required in /auth-requests/ endpoints

The correct endpoint uses connection_id:

/api/v1/connections/<connection_id>/auth-requests/<login_request_id>/user

To find your connection_id, open Dashboard > MCP Servers > [your server] > Advanced Configurations > Connection ID.

Access token issued but no refresh token

Add the offline_access scope to your authorization request. Without it, Scalekit does not issue a refresh token alongside the access token.

Include it with your other scopes:

openid profile email offline_access

After you add it, subsequent logins return both an access token and a refresh token.

Client fails with an invalid_client_metadata_url error

This error means Scalekit rejected the OAuth client that tried to connect, because the client sent a client_id that Scalekit never issued or a client metadata URL it can’t resolve. The connection often succeeds for some users and fails for others on the same MCP server, which points to client-side configuration rather than a problem with your Scalekit setup.

Two causes account for most occurrences.

Cause 1: The connecting application has stale client credentials configured

Some applications (for example, Glean) let you paste a client_id and client_secret for the MCP server. When those fields hold credentials that Scalekit didn’t issue, the auth server rejects the connection.

To resolve it:

  1. Open the connecting application’s integration settings for your MCP server.
  2. Clear the client_id and client_secret fields.
  3. Reconnect. Applications that support Dynamic Client Registration (DCR) obtain valid credentials automatically once the fields are empty.
  4. If the application cannot use DCR, generate a static pre-registered client in Dashboard > MCP Servers > [your server] and share those credentials instead.

Cause 2: mcp-remote is sending a client_id it did not register

mcp-remote can reuse a client_id from a different MCP server session or send a non-Scalekit value. Scalekit issues DCR clients only in the m2m_xxx format, so it rejects any other value. This affects only the users who route the connection through mcp-remote.

mcp-remote was a temporary bridge for clients that couldn’t reach remote MCP servers directly. Claude Desktop, Claude Code, and Cursor now support remote HTTP MCP servers natively, so you no longer need it. Connect with the native HTTP transport instead:

  • Claude Desktop: open Settings > Connectors > Add custom connector and enter your MCP server URL.

  • Claude Code: run the following in your terminal.

    Terminal window
    claude mcp add --transport http <server-name> https://your-mcp-server.example.com/mcp
What is the difference between DCR and CIMD?

MCP clients identify themselves to Scalekit’s authorization server using one of two mechanisms:

  • Dynamic Client Registration (DCR): The client registers itself with Scalekit and receives a client_id in the m2m_xxx format. See RFC 7591.
  • Client ID Metadata Document (CIMD): The client presents a URL that hosts its client metadata document, and Scalekit fetches that URL to identify the client.

The invalid_client_metadata_url error belongs to the CIMD path: Scalekit couldn’t resolve or validate the metadata URL the client sent. A client that completes DCR correctly doesn’t trigger this error. Follow the resolution steps in the previous scenario.

View authentication logs to debug a failed connection

Open Dashboard > Authentication > Logs to inspect the authorization and token requests for your environment. Each entry shows the OAuth client, the requested scopes, and the outcome of each step in the flow.

When you debug a failed connection, change the log filter to show all events rather than successful events only. Failed authorization and token requests appear only when you include error events, so a success-only view can hide the request you need to diagnose.

MCP server does not connect to the MCP Inspector

A failed connection to the MCP Inspector usually points to a problem with the authentication handshake or metadata configuration. Work through these checks.

Verify the MCP server is responding correctly:

  1. Open your browser’s developer tools (Network tab)
  2. Navigate to your MCP server URL (for example, http://localhost:3002/)
  3. Confirm the response returns a 401 status code
  4. Check the response headers for www-authenticate containing resource_metadata="<metadata-url>"

Validate the metadata:

  1. Copy the metadata URL from the www-authenticate header
  2. Open it in your browser
  3. Confirm the JSON structure matches what you see in your Scalekit dashboard
redirect_uri mismatch during authorization

This error typically occurs when your MCP client has cached an old MCP server domain after you changed it. The client keeps sending requests to the old URL, which no longer matches your Scalekit configuration.

Clear cached authentication by client type.

mcp-remote:

  1. Delete the cached configuration folder: ~/.mcp-auth/mcp-remote-<version>
  2. Reconnect to your MCP server

VS Code:

  1. Open the Command Palette (Cmd/Ctrl + Shift + P)
  2. Search for Authentication: Remove Dynamic Authentication Provider
  3. Select and remove the cached entry
  4. Reconnect to your MCP server

Claude Desktop:

GitHub Copilot CLI: stale cached credentials after an environment switch

GitHub Copilot CLI caches OAuth client credentials locally. If you switch your Scalekit environment (for example, from US to EU), the cached client_id no longer matches the new environment and login fails with unable to retrieve client by id.

  1. Locate and delete the cached OAuth config files:
    Terminal window
    rm -rf ~/.copilot/mcp-oauth-config
  2. Reconnect your MCP server in GitHub Copilot CLI. It registers a fresh client against the correct environment.
CORS errors in the network logs when using MCP Inspector

CORS errors occur when your MCP client cannot make cross-origin requests to your Scalekit environment during the authentication handshake, which prevents the flow from completing.

  1. Navigate to Dashboard > Authentication > Redirect URLs > Allowed Callback URLs
  2. Add your MCP Inspector URL to the allowed list: http://localhost:6274/
  3. Retry the connection
MCP client requests never reach the server

If requests from your MCP client silently fail to reach your server, a proxy or firewall may be blocking them. This often happens in corporate environments or when you use CDN services.

  1. Check whether you’re using a proxy (for example, Cloudflare, AWS WAF, or a corporate proxy)
  2. Configure your proxy to allow or exempt requests from your MCP client to your server domain
  3. Review proxy logs to confirm whether requests are being blocked
  4. Test direct connectivity from your client machine to your MCP server, without the proxy if possible
Cloudflare bot protection is blocking MCP client requests

If your MCP server is behind Cloudflare and AI agents (such as Claude Desktop, Cursor, or other MCP clients) cannot reach it, Cloudflare’s Bot Fight Mode, Super Bot Fight Mode, or AI Crawl Control settings may classify agent traffic as bot traffic and block it at the edge.

Symptoms:

  • MCP client connections fail silently or return 403 Forbidden
  • The authentication handshake never completes
  • Browser access to the MCP server works, but programmatic access from AI agents does not
  • Cloudflare serves a JavaScript challenge or Turnstile page instead of your MCP response

Diagnose which rule is blocking:

  1. Open the Cloudflare dashboard for your domain
  2. Navigate to Security > Events
  3. Filter for your MCP server path and look for blocked or challenged requests
  4. Note the rule name. It tells you which Cloudflare feature caused the block (Bot Fight Mode, Super Bot Fight Mode, AI Crawl Control, or a managed rule)

Resolution for the Cloudflare Free plan (Bot Fight Mode):

On the Free plan, Bot Fight Mode runs before the WAF Ruleset Engine, so custom WAF skip rules have no effect on it. Your options are:

  1. Open Security Settings in the Cloudflare dashboard (direct link: https://dash.cloudflare.com/?to=/:account/:zone/security/settings)
  2. Under Bot traffic, turn Bot Fight Mode off
  3. If Block AI Scrapers and Crawlers is also enabled, disable it
  4. Retry the MCP client connection

Resolution for Pro, Business, or Enterprise plans (Super Bot Fight Mode):

On paid plans, you can create a WAF custom rule that skips bot protection only for MCP traffic while keeping the rest of your domain protected:

  1. Navigate to Security > WAF > Custom rules > Create rule
  2. Set the expression to match your MCP server path: starts_with(http.request.uri.path, "/mcp"). Adjust the path to match your MCP server’s base path
  3. Set the action to Skip, then select Super Bot Fight Mode
  4. Move this rule to the top of your custom rules list so it evaluates first
  5. Save and deploy, then retry the MCP client connection

Alternatively, navigate to AI Crawl Control in your bot settings and set Claude-related bots (ClaudeBot, Claude-User) to Allow.

Claude Desktop ignores custom ports when connecting to MCP servers

Claude Desktop currently supports only standard HTTPS traffic on port 443. If your MCP server runs on a custom port (for example, https://mymcp.internal:8443/), Claude Desktop still attempts to connect to port 443, so the connection fails.

  • Expose your MCP server on port 443 (requires a proxy or load balancer)
  • Use a reverse proxy that listens on 443 and forwards requests to your custom port
Multiple authentication tabs open when using both mcp-remote and Claude Desktop

Recent versions of Claude Desktop include Connectors, which removes the need to run mcp-remote separately. The Custom Connector feature lets you configure MCP servers directly without additional tools.

  • Use Claude Desktop’s built-in Custom Connector feature for MCP server management
  • Disable or stop mcp-remote if you’re only using Claude Desktop
  • If you have a specific use case that requires both, contact Claude’s official support
OAuth popup closes immediately or shows “window closed too soon”

MCP clients that use a popup-based OAuth flow (such as Amazon Q) may report that the popup closed too soon or that authentication failed, even though the OAuth flow completed successfully in the popup window.

Root cause: Your application’s login page returns a Cross-Origin-Opener-Policy: same-origin HTTP header. When a cross-origin MCP client (for example, quick.aws.com) opens a popup that navigates to a page with this header, the browser severs the opener’s reference to the popup. The MCP client sees the popup as closed immediately, before the OAuth callback can complete.

Diagnosis:

Check the response headers on your login or redirect endpoint:

Terminal window
curl -sI https://your-app.com/login | grep -i cross-origin-opener-policy

If the output includes cross-origin-opener-policy: same-origin, this is the cause.

Resolution:

Remove the Cross-Origin-Opener-Policy header from your login and OAuth callback endpoints, or change its value to unsafe-none:

Cross-Origin-Opener-Policy: unsafe-none

You can scope this change to only the endpoints involved in the OAuth flow rather than your entire application. After the change, retry the MCP client connection.

The browser does not open during authentication

Some MCP clients require permission to open your default browser during the authentication flow. If your browser doesn’t launch, the authentication handshake may time out.

macOS:

  1. Open System Preferences > Security & Privacy > App Management
  2. Confirm the MCP client has permission to open applications
  3. Restart your MCP client

Windows:

  1. Navigate to Settings > Privacy > App permissions
  2. Enable Allow apps to manage your default app settings
  3. Restart your MCP client

Linux:

  1. Confirm xdg-open or your default browser opener is installed: which xdg-open
  2. Verify the command is accessible from your terminal
  3. Restart your MCP client

Follow these best practices to avoid common issues and maintain a robust MCP authentication setup:

  1. Use separate Scalekit environments for development and production to prevent configuration conflicts
  2. Register MCP servers with environment-specific domains:
    • Development: https://mcp-dev.yourdomain.com/
    • Production: https://mcp.yourdomain.com/
  3. Update your MCP client configuration to point to the correct Scalekit environment for each deployment
  4. Test authentication independently in each environment before you deploy to production
  5. Monitor authentication logs in Dashboard > Authentication > Logs to identify and resolve issues quickly
  6. Keep callback URLs updated whenever you change domains or ports

If none of the scenarios resolve the issue, open Dashboard > Authentication > Logs and review the authorization and token requests for the failing attempt.

When you contact support, include:

  • The failing client_id and the MCP server resource_id
  • The MCP client and transport (for example, a Claude Desktop custom connector or mcp-remote)
  • The full error text and the approximate timestamp of the attempt
  • The steps that reproduce the failure