Hello team, we are observing strange behavior during the reconnection flow of the application.
Scenario #1
- We create a new Connector. ChatGPT parses our well-known endpoints to retrieve information about available endpoints and scopes.
- ChatGPT calls the
/registerendpoint to create a new client (Client Dynamic Registration), and we return theclient_idalong with additional client information. - ChatGPT calls the
/authorizeendpoint withclient_id,redirect_uri,scope, etc. - Example request:
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- The user reaches the consent page, approves the requested scopes, and we redirect back to the
redirect_uriwith a code. - ChatGPT calls the
/tokenendpoint to exchange the authorization code using thecode_verifier, and we return anaccess_tokenand arefresh_token. - Everything works correctly and the user can start using our MCP server.
Scenario #2
- The user goes to the Apps & Connector page and clicks Disconnect for our application.
- They click Connect again, and a popup appears to reconnect our Connector.
- After clicking Continue, ChatGPT calls
/authorizebut without thescopeparameter. - Example request:
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:
- New Connector created, ChatGPT fetches well-known endpoints and scopes.
- ChatGPT calls
/register. - ChatGPT calls
/authorizewith scopes.
However: - We do not allow consent, close the tab, and open a new ChatGPT tab.
- The Connector entry exists but is not connected, so we click Connect again.
- The same popup appears (as in Scenario #2), but this time ChatGPT does include scopes in the
/authorizerequest.
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.