Oauth missing scopes after Reconnect

Hello team, we are observing strange behavior during the reconnection flow of the application.
Scenario #1

  1. We create a new Connector. ChatGPT parses our well-known endpoints to retrieve information about available endpoints and scopes.
  2. ChatGPT calls the /register endpoint to create a new client (Client Dynamic Registration), and we return the client_id along with additional client information.
  3. ChatGPT calls the /authorize endpoint with client_id, redirect_uri, scope, etc.
  4. Example request:
  5. https://my-domain/oauth/authorize?response_type=code&client_id=811703c8-c50a-4a49-a119-0035430610cd&redirect_uri=https%3A%2F%2Fchatgpt.com%2Fconnector_platform_oauth_redirect&state=oauth_s_691b55f5b11481919ddp59nge4998443f&scope=worker%3Aread+time-off%3Aread+time-off%3Awrite+contracts%3Aread+people%3Aread&code_challenge=wQiZOt66Pv46ulV0WG8K9vqHiy1VcPaSmeEb5LqtD6Y&code_challenge_method=S256&resource=https%3A%2F%2Fmy-domain%2Fmcp
  6. The user reaches the consent page, approves the requested scopes, and we redirect back to the redirect_uri with a code.
  7. ChatGPT calls the /token endpoint to exchange the authorization code using the code_verifier, and we return an access_token and a refresh_token.
  8. Everything works correctly and the user can start using our MCP server.

Scenario #2

  1. The user goes to the Apps & Connector page and clicks Disconnect for our application.
  2. They click Connect again, and a popup appears to reconnect our Connector.
  3. After clicking Continue, ChatGPT calls /authorize but without the scope parameter.
  4. Example request:
  5. https://my-domain/oauth/authorize?response_type=code&client_id=811703c8-c50a-4a49-a119-0035430610cd&redirect_uri=https%3A%2F%2Fchatgpt.com%2Fconnector_platform_oauth_redirect&state=oauth_s_691b57560b648191a5a85lt8e30e0894&code_challenge=usJfT28XGmDtSalaQQgcvouUG95K5jDvwNiL21j8u5o&code_challenge_method=S256&resource=https%3A%2F%2Fmy-domain%2Fmcp

We return an error because scope must not be empty, per OAuth 2 specification.

Scenario #3
This scenario starts the same way as Scenario #1:

  1. New Connector created, ChatGPT fetches well-known endpoints and scopes.
  2. ChatGPT calls /register.
  3. ChatGPT calls /authorize with scopes.
    However:
  4. We do not allow consent, close the tab, and open a new ChatGPT tab.
  5. The Connector entry exists but is not connected, so we click Connect again.
  6. The same popup appears (as in Scenario #2), but this time ChatGPT does include scopes in the /authorize request.
    This is strange:
  • The UI flow is identical to Scenario #2.
  • In Scenario #2, scopes are missing.
  • In Scenario #3, scopes are present.

Debugging Notes

  • Our logs show no backend errors.
  • Initially, ChatGPT correctly calls the well-known endpoints to retrieve available scopes and endpoints.
  • During the reconnection attempt in Scenario #2, ChatGPT does not call any endpoints that would allow it to retrieve scopes again.
  • As per OAuth 2.0, only the well-known endpoint should store information about available scopes.
  • We suspect this may be related to Developer Mode, but this is only an assumption.

Problem
According to the OAuth 2.0 specification, the /authorize endpoint must always be called with a scope parameter that lists the permissions the application is requesting on behalf of the user.
However, ChatGPT sometimes sends the /authorize request without scopes during a reconnect attempt.

1 Like