{"record":{"id":"149c2929381739b9","repo":"vercel/ai","slug":"incompatible-auth-server-does-not-support-dynamic","errorCode":null,"errorMessage":"Incompatible auth server: does not support dynamic client registration","messagePattern":"Incompatible auth server: does not support dynamic client registration","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/mcp/src/tool/oauth.ts","lineNumber":1115,"sourceCode":" * Performs OAuth 2.0 Dynamic Client Registration according to RFC 7591.\n */\nexport async function registerClient(\n  authorizationServerUrl: string | URL,\n  {\n    metadata,\n    clientMetadata,\n    fetchFn,\n  }: {\n    metadata?: AuthorizationServerMetadata;\n    clientMetadata: OAuthClientMetadata;\n    fetchFn?: FetchFunction;\n  },\n): Promise<OAuthClientInformationFull> {\n  let registrationUrl: URL;\n\n  if (metadata) {\n    if (!metadata.registration_endpoint) {\n      throw new Error(\n        'Incompatible auth server: does not support dynamic client registration',\n      );\n    }\n\n    registrationUrl = new URL(metadata.registration_endpoint);\n  } else {\n    registrationUrl = new URL('/register', authorizationServerUrl);\n  }\n  assertSafeOAuthEndpoint(registrationUrl);\n\n  const applicationType =\n    clientMetadata.application_type ??\n    inferOAuthApplicationType(clientMetadata.redirect_uris);\n  const response = await (fetchFn ?? fetch)(registrationUrl, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n    },","sourceCodeStart":1097,"sourceCodeEnd":1133,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/mcp/src/tool/oauth.ts#L1097-L1133","documentation":"registerClient performs OAuth dynamic client registration (RFC 7591). When authorization server metadata is available, it requires a registration_endpoint; if the metadata has none, the server does not support dynamic registration and the function throws. Callers must supply pre-registered client information instead.","triggerScenarios":"Calling registerClient (or auth() when provider.clientInformation() returns nothing) against an AS whose metadata omits registration_endpoint.","commonSituations":"Enterprise IdPs (e.g. Azure AD/Entra, many SAML-first providers) that require manual/static client registration, or OAuth servers where dynamic registration is disabled by policy.","solutions":["Manually register a client in the AS admin console and return it from provider.clientInformation() so dynamic registration is skipped.","Enable the dynamic client registration plugin/feature on the authorization server if you control it.","Verify the metadata is being fetched from the correct AS (a fallback to the MCP server itself as AS may lack a registration endpoint).","If the AS publishes a registration_endpoint via a different discovery document, fix the discovery URL configuration."],"exampleFix":"// before: relying on dynamic registration\nclass MyProvider { async clientInformation() { return undefined; } }\n// after: supply a statically registered client\nclass MyProvider {\n  async clientInformation() {\n    return { client_id: process.env.OAUTH_CLIENT_ID, client_secret: process.env.OAUTH_CLIENT_SECRET };\n  }\n}","handlingStrategy":"validation","validationCode":"const metadata = await discoverAuthorizationServerMetadata(asUrl);\nif (metadata && !metadata.registration_endpoint && !(await provider.clientInformation())) {\n  throw new Error('Register a client manually; this AS has no registration_endpoint');\n}","typeGuard":"function supportsDynamicRegistration(m: { registration_endpoint?: string } | undefined): boolean {\n  return typeof m?.registration_endpoint === 'string' && m.registration_endpoint.length > 0;\n}","tryCatchPattern":"try {\n  await auth(provider, { serverUrl });\n} catch (error) {\n  if (String(error.message).includes('does not support dynamic client registration')) {\n    console.error('Provide pre-registered client credentials via provider.clientInformation().');\n  }\n}","preventionTips":["For ASes without dynamic registration (Entra ID, many enterprise IdPs), always supply static client credentials.","Check for registration_endpoint in metadata before relying on the default auth() registration path.","Document per-environment whether clients are registered statically or dynamically."],"tags":["oauth","dynamic-client-registration","mcp"],"backgroundTag":"dynamic-client-registration-unsupported","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}