[Resolved] Cannot Resolve MCP OAuth Client During ChatGPT Connector Setup
Update (September 21, 2025): The bug was in my reverse-proxy. ChatGPT asks for
/.well-known/oauth-authorization-server/mcp
, but my NGINX rule rewrote that path
to /mcp/.well-known/oauth-authorization-server
before proxying to the MCP service.
That mismatch meant ChatGPT received an empty discovery document and defaulted to
oauth_client_params: null
. Fixing the proxy_pass
target so it relays the request
verbatim restored the OAuth client metadata and the connector now links reliably.
Summary
What looked like ChatGPT “forgetting” my client id was really an NGINX routing error
on my end. Claude continued to work because it only ever called the top-level discovery
endpoint, while ChatGPT asked for the MCP-specific variant (/.well-known/.../mcp
) that I
was accidentally rewriting. Once I stopped mangling that path, ChatGPT immediately started
resolving the metadata and the connector succeeds end-to-end.
Impact
ChatGPT users could not start OAuth because the discovery doc I served them did not
include the MCP section. The moment I corrected the proxy rule, new ChatGPT sessions
negotiated oauth_client_params
normally and existing users could reconnect without code
changes.
Expected vs. Actual
Expected: ChatGPT should fetch my discovery document, see the mcp.client_id
, and
proceed with PKCE just like Claude.
Pre-fix Actual: ChatGPT hit https://dexter.cash/.well-known/oauth-authorization- server/mcp
, received an empty payload (because I proxied to the wrong upstream path), and
bailed out with Failed to resolve OAuth client
.
Post-fix Actual: With the corrected proxy target, ChatGPT receives the full metadata,
populates oauth_client_params
, and completes the OAuth handshake without issue.
Evidence
1. NGINX rule (fixed)
# Broken: appended "/mcp" before the well-known path and dropped the content ChatGPT needs
# location = /.well-known/oauth-authorization-server/mcp {
# proxy_pass http://127.0.0.1:3930/mcp/.well-known/oauth-authorization-server;
# }
# Working: relay the request verbatim to the MCP service
location = /.well-known/oauth-authorization-server/mcp {
proxy_pass http://127.0.0.1:3930/.well-known/oauth-authorization-server/mcp;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
add_header Cache-Control "no-store" always;
}
2. Discovery document ChatGPT now receives
$ curl https://dexter.cash/.well-known/oauth-authorization-server/mcp | jq '{issuer,
authorization_endpoint, token_endpoint, mcp}'
{
"issuer": "https://dexter.cash/mcp",
"authorization_endpoint": "https://dexter.cash/mcp/authorize",
"token_endpoint": "https://dexter.cash/mcp/token",
"mcp": {
"client_id": "cid_a859560609a6448aa2f3a1c29f6ab496",
"redirect_uri": "https://dexter.cash/mcp/callback"
}
}
ChatGPT stopped returning oauth_client_params: null as soon as this document was
available.
3. Connector flow after the fix
[dexter-api] [connector/oauth/authorize] issued request { clientId:
'cid_a859560609a6448aa2f3a1c29f6ab496', ... }
[dexter-api] [connector/oauth/exchange] issued code { codePreview: 'code_b65a11d', ... }
[dexter-mcp] [oauth] token accepted { user: '…', claims: { sub: '…', email: '…' } }
This is the same healthy log sequence I see in Claude, now mirrored in ChatGPT.
Investigation Timeline
- Verified Claude could still complete OAuth, proving the upstream MCP+OAuth stack was
fine.
- Captured ChatGPT’s POST payload and noticed oauth_client_params: null every time.
- Focused on the discovery endpoint and finally tested the precise URL ChatGPT calls
(/.well-known/oauth-authorization-server/mcp). That request hit my special-case NGINX
location that rewrote the path before proxying.
- Compared the route with my MCP server implementation and realized I had added the
extra /mcp/ segment while experimenting.
- Removed the path mangling, reloaded NGINX, re-ran the connector setup, and watched
ChatGPT complete OAuth on the very next attempt.
Notes
- Leaving this up for posterity: if your connector suddenly claims Failed to resolve OAuth client, double-check every /.well-known/… rule in front of the MCP service. ChatGPT is stricter than Claude about the MCP-specific discovery path.
- Claude kept working throughout because it never called the MCP-scoped discovery route, so it masked my mistake.
Resolution
No bug, just a misconfiguration – one that I suspect a lot of people will run into.
The fix was to update nginx so that /.well-known/oauth-authorization-server/mcp proxies straight through to the MCP service without mutating the path. After reloading, ChatGPT picked up the client id automatically and the connector is back to normal.