{"record":{"id":"9242aa35baca26a5","repo":"siyuan-note/siyuan","slug":"oauth-authorization-server-does-not-support-dynami","errorCode":null,"errorMessage":"OAuth authorization server does not support dynamic client registration","messagePattern":"OAuth authorization server does not support dynamic client registration","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/mcp/client/oauth.go","lineNumber":287,"sourceCode":"\tif err != nil {\n\t\treturn err\n\t}\n\tcallbackURL := fmt.Sprintf(\"http://127.0.0.1:%s/api/ai/mcp/oauth/callback/%s\", util.ServerPort, flowID)\n\tscopes := append([]string(nil), prm.ScopesSupported...)\n\tif len(scopes) == 0 {\n\t\tscopes = append(scopes, asm.ScopesSupported...)\n\t}\n\tfor _, scope := range strings.Fields(bearerChallengeParam(challenges, \"scope\")) {\n\t\tif !slices.Contains(scopes, scope) {\n\t\t\tscopes = append(scopes, scope)\n\t\t}\n\t}\n\tregistrationCredential := credential\n\tcanReuseRegistration := hasCredential && credential.Issuer == asm.Issuer && credential.RedirectURL == callbackURL &&\n\t\tcredential.ClientID != \"\" && !oauthClientRegistrationExpired(credential) && oauthScopesContain(credential.Scopes, scopes)\n\tif !canReuseRegistration {\n\t\tif asm.RegistrationEndpoint == \"\" {\n\t\t\treturn fmt.Errorf(\"OAuth authorization server does not support dynamic client registration\")\n\t\t}\n\t\ttokenAuthMethod := preferredTokenAuthMethod(asm.TokenEndpointAuthMethodsSupported)\n\t\tif len(asm.TokenEndpointAuthMethodsSupported) > 0 && tokenAuthMethod == \"\" {\n\t\t\treturn fmt.Errorf(\"OAuth authorization server does not support a compatible token endpoint authentication method\")\n\t\t}\n\t\tgrantTypes := []string{\"authorization_code\"}\n\t\tif len(asm.GrantTypesSupported) == 0 || slices.Contains(asm.GrantTypesSupported, \"refresh_token\") {\n\t\t\tgrantTypes = append(grantTypes, \"refresh_token\")\n\t\t}\n\t\tregistration, registerErr := oauthex.RegisterClient(ctx, asm.RegistrationEndpoint, &oauthex.ClientRegistrationMetadata{\n\t\t\tRedirectURIs:            []string{callbackURL},\n\t\t\tTokenEndpointAuthMethod: tokenAuthMethod,\n\t\t\tGrantTypes:              grantTypes,\n\t\t\tResponseTypes:           []string{\"code\"},\n\t\t\tClientName:              \"SiYuan\",\n\t\t\tScope:                   strings.Join(scopes, \" \"),\n\t\t\tApplicationType:         \"native\",\n\t\t}, h.client)","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/mcp/client/oauth.go#L269-L305","documentation":"No reusable client registration exists (no stored credential for this issuer/redirect/scopes combination, or it expired), and the authorization server's metadata has no RegistrationEndpoint, so RFC 7591 dynamic client registration is impossible. SiYuan's MCP client relies on DCR to obtain a ClientID, so without it the flow cannot proceed.","triggerScenarios":"Interactive Authorize where canReuseRegistration is false (first connect, changed redirect URL because the server port changed, expired registration, or changed scopes) and asm.RegistrationEndpoint == \"\".","commonSituations":"IdP without RFC 7591 support (e.g. most enterprise IdPs) — clients must be registered manually; SiYuan restarted on a different port changing the loopback callback URL and invalidating the stored registration; registration record expired.","solutions":["Use an authorization server that supports RFC 7591 dynamic client registration","If the IdP requires manual registration, pre-register the client and provide the ClientID through the server's configuration mechanism","Re-run authorization on the same SiYuan server port so the stored registration's RedirectURL matches the callback URL","Re-authorize to refresh an expired client registration before scopes change"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if asm.RegistrationEndpoint == \"\" {\n    return errors.New(\"IdP lacks RFC 7591 dynamic client registration; register the client manually\")\n}","typeGuard":null,"tryCatchPattern":"if err := h.Authorize(ctx, req, resp); err != nil && strings.Contains(err.Error(), \"dynamic client registration\") {\n    guideManualClientRegistration(err)\n}","preventionTips":["Prefer IdPs with RFC 7591 DCR for MCP integrations","Keep the SiYuan server port stable so the stored registration's loopback redirect URL stays valid","Re-authorize before client registrations or scopes expire/change"],"tags":["oauth","mcp","dcr","compatibility"],"backgroundTag":"operation-not-supported","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}