mastra-ai/mastra · error · Error
Cannot authenticate MCP server ${serverName}: the provider's
Error message
Cannot authenticate MCP server ${serverName}: the provider's redirect URL must be a loopback address, got ${redirectUrl.origin}. What it means
Error thrown during runAuthorizationFlow when the provider's redirect URL is not an http:// loopback address. The local OAuth callback server only binds loopback hostnames (localhost/127.0.0.1/etc.) over plain HTTP, so non-loopback or https redirect URLs are rejected before binding.
Source
Thrown at packages/mcp/src/client/configuration.ts:899
let provider: MCPOAuthClientProvider | undefined;
let sessionStarted = false;
let callbackServer: OAuthCallbackServer | undefined;
// Installed before the first fallible step so the abort-controller entry,
// provider session, and callback server never leak on an early throw.
try {
const config = this.getServerConfig(serverName);
const candidateProvider = config.authProvider;
if (!(candidateProvider instanceof MCPOAuthClientProvider)) {
throw new Error(
`Cannot authenticate MCP server ${serverName}: it is not configured with an MCPOAuthClientProvider.`,
);
}
provider = candidateProvider;
const redirectUrl = new URL(provider.redirectUrl.toString());
if (redirectUrl.protocol !== 'http:' || !isLoopbackHostname(redirectUrl.hostname)) {
throw new Error(
`Cannot authenticate MCP server ${serverName}: the provider's redirect URL must be a loopback address, got ${redirectUrl.origin}.`,
);
}
const state = await provider.beginAuthorizationSession();
sessionStarted = true;
// A cancel that arrived during beginAuthorizationSession() has no callback
// server to close yet, so bail here before binding a port and parking.
throwIfAborted();
callbackServer = await createOAuthCallbackServer({ redirectUrl, state });
// A cancel during port binding: bail before we ever wait for a code that
// will never arrive. The outer finally closes the freshly-bound server.
throwIfAborted();
this.authCallbackServersByServer.set(serverName, callbackServer);
// Point the authorization request at the callback URL that actually
// bound, and register every fallback candidate during dynamic clientView on GitHub (pinned to 75dd419e61)
Solutions
- Change the provider redirectUrl to a loopback http URL, e.g. http://localhost:<port>/callback.
- Pick a port (or port range) that is free on the local machine.
- Register the loopback redirect URL with the OAuth authorization server if it validates exact redirects.
- For remote/web deployments, do not use the local callback flow; use a flow appropriate for server-to-server auth.
Example fix
// before
new MCPOAuthClientProvider({ redirectUrl: 'https://myapp.example.com/callback' })
// after
new MCPOAuthClientProvider({ redirectUrl: 'http://localhost:3456/callback' }) Defensive patterns
Strategy: validation
Validate before calling
const redirectUrl = new URL(provider.redirectUrl.toString());
const isLoopback = ['localhost', '127.0.0.1', '[::1]'].includes(redirectUrl.hostname) || /^127\./.test(redirectUrl.hostname);
if (redirectUrl.protocol !== 'http:' || !isLoopback) {
throw new Error(`redirectUrl must be http loopback, got ${redirectUrl.origin}`);
} Type guard
function isLoopbackHttpRedirect(url: URL): boolean {
return url.protocol === 'http:' && (url.hostname === 'localhost' || /^127\./.test(url.hostname) || url.hostname === '::1');
} Prevention
- Use http://localhost:<port>/callback for local OAuth flows.
- Register the exact loopback redirect with the OAuth provider's app settings.
- Never reuse production https redirect URLs for local flows.
- Validate provider config at construction time in tests.
When it happens
Trigger: Configuring MCPOAuthClientProvider with redirectUrl such as https://myapp.example.com/callback or http://10.0.0.5:3000/callback, then invoking the authorization flow.
Common situations: Copying a production web-app redirect URL into a local CLI/desktop flow; using https for the local callback; using a LAN hostname or container name instead of localhost.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Cannot authenticate MCP server ${serverName}: it is not conf
- Redirect URI is required for SSO login
- Google client ID is required. Provide it in the options or s
- Redirect URI is required for Google SSO. Set GOOGLE_REDIRECT
- No Slack installation found for agent "${agentId}"
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/a1913f0c25e5ebc1.
Report an issue: GitHub.