Summary
MCP OAuth against https://mcp.higgsfield.ai/mcp can no longer be completed by any RFC 9207-compliant client. The browser flow looks like it succeeds — Higgsfield renders "Authentication successful", so the user believes they are connected — but the client discards the authorization code and never stores a token, because the iss on the callback contradicts the issuer Higgsfield advertises in its own discovery documents.
The cause is that /oauth2/authorize does not act as an authorization server at all. It issues a bare 302 to clerk.higgsfield.ai/oauth/authorize with the client's loopback redirect_uri passed through unchanged. Clerk therefore owns the browser leg and correctly stamps its own identity, iss=https://clerk.higgsfield.ai — while /.well-known/oauth-authorization-server claims issuer: https://mcp.higgsfield.ai. Per MCP's authorization spec (SEP-2468) the client MUST abort on that mismatch.
This is not a client bug and there is no client-side workaround: the documented escape hatch in the SDK (skipIssuerMetadataValidation) explicitly does not suppress the runtime iss check, and Claude Code exposes no flag for it either way.
Environment
Error
From ~/Library/Caches/claude-cli-nodejs/<cwd>/mcp-logs-higgsfield/*.jsonl:
{"debug":"Returning cached discovery state (authServer: https://mcp.higgsfield.ai)"}
{"debug":"No access token in storage"}
{"debug":"Redirecting to authorization URL"}
{"debug":"Initial auth result: REDIRECT"}
{"debug":"Completing auth flow with authorization code"}
{"debug":"Error during auth completion: Issuer mismatch in authorization response (RFC 9207):
expected \"https://mcp.higgsfield.ai\", received \"https://clerk.higgsfield.ai\""}
The server then stays parked in needs-auth for every subsequent session ("Skipping connection (cached needs-auth)"), so the only tools it exposes are authenticate and complete_authentication. All ~80 generation tools are unreachable.
Reproduction — no account or credentials needed
The delegation is unconditional, so two curl calls demonstrate the contradiction. Note the deliberately invalid client_id: the 302 happens before any client validation, which is itself worth a look.
1. The advertised issuer is mcp.higgsfield.ai:
curl -s https://mcp.higgsfield.ai/.well-known/oauth-authorization-server | jq '{issuer, authorization_endpoint, token_endpoint}'
{
"issuer": "https://mcp.higgsfield.ai",
"authorization_endpoint": "https://mcp.higgsfield.ai/oauth2/authorize",
"token_endpoint": "https://mcp.higgsfield.ai/oauth2/token"
}
2. But /oauth2/authorize hands the whole flow — including the client's redirect_uri — to a different issuer:
curl -s -o /dev/null -D - \
"https://mcp.higgsfield.ai/oauth2/authorize?response_type=code&client_id=NOT_A_REAL_CLIENT&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A8899%2Fcallback&state=teststate&scope=openid+email+offline_access&resource=https%3A%2F%2Fmcp.higgsfield.ai%2Fmcp"
HTTP/2 302
location: https://clerk.higgsfield.ai/oauth/authorize?response_type=code&client_id=NOT_A_REAL_CLIENT&...&redirect_uri=http%3A%2F%2Flocalhost%3A8899%2Fcallback&...
Because redirect_uri still points at the client's loopback listener, Clerk — not Higgsfield — terminates the flow, and stamps iss=https://clerk.higgsfield.ai. https://clerk.higgsfield.ai/.well-known/oauth-authorization-server self-reports "issuer":"https://clerk.higgsfield.ai", so the two documents are simply inconsistent about who the authorization server is.
Your own /.well-known/oauth-protected-resource already names the split explicitly:
"authorization_servers": ["https://mcp.higgsfield.ai", "https://fnf-device-auth.higgsfield.ai"],
"higgsfield_auth_hints": {
"options": [{
"flow": "authorization_code_pkce",
"authorization_server": "https://mcp.higgsfield.ai",
"upstream_authorization_server": "https://clerk.higgsfield.ai",
"potential_clients": ["anthropic","claude","claude-ai","claude-code"]
}]
}
So the flow you designate for Claude Code is exactly the one that cannot complete.
Why this started without any change on your side
MCP made the check mandatory and default-on. modelcontextprotocol/typescript-sdk#2344 (SEP-2468, merged 2026-06-24) implements:
On receiving the authorization response, MCP clients MUST apply the validation in RFC9207 Section 2.4 before transmitting the authorization code to any token endpoint.
If issuer validation fails, the client MUST treat the response as invalid and abort the authorization flow.
Comparison is exact — the spec forbids host case folding, trailing-slash and percent-encoding normalization — so clerk.higgsfield.ai can never satisfy an expectation of mcp.higgsfield.ai.
Other hosted MCP servers with the same front-a-different-auth-host topology broke on the same rollout, which may be useful prior art:
Suggested fixes
Preferred — terminate the callback yourself. Register a redirect URI at Clerk that points back to Higgsfield (e.g. https://mcp.higgsfield.ai/oauth2/callback) instead of forwarding the client's loopback URI upstream. Handle Clerk's callback server-side, then redirect to the client's redirect_uri with your own code plus iss=https://mcp.higgsfield.ai. This makes the advertised issuer truthful, and it is also the only option under which your own /oauth2/token endpoint is meaningful rather than a pass-through.
Alternative — stop advertising yourself as the authorization server. Publish https://clerk.higgsfield.ai in authorization_servers in /.well-known/oauth-protected-resource instead of https://mcp.higgsfield.ai. Clerk's metadata already echoes its own issuer correctly, so the discovered issuer would then match the iss it stamps. Worth checking that resource/audience binding for https://mcp.higgsfield.ai/mcp still holds if clients register directly with Clerk.
Either way, please also confirm /oauth2/authorize rejects an unregistered client_id before redirecting rather than after.
Impact
Every RFC 9207-compliant MCP client is affected, not just Claude Code, and it fails in the most confusing possible way: the browser says authentication succeeded, so users conclude their client is broken and file against the client instead of here. Existing users are hit as soon as their stored token expires and a silent re-auth is attempted. Verified reachable via the CLI in the meantime, so the outage is confined to the MCP surface.
Summary
MCP OAuth against
https://mcp.higgsfield.ai/mcpcan no longer be completed by any RFC 9207-compliant client. The browser flow looks like it succeeds — Higgsfield renders "Authentication successful", so the user believes they are connected — but the client discards the authorization code and never stores a token, because theisson the callback contradicts the issuer Higgsfield advertises in its own discovery documents.The cause is that
/oauth2/authorizedoes not act as an authorization server at all. It issues a bare 302 toclerk.higgsfield.ai/oauth/authorizewith the client's loopbackredirect_uripassed through unchanged. Clerk therefore owns the browser leg and correctly stamps its own identity,iss=https://clerk.higgsfield.ai— while/.well-known/oauth-authorization-serverclaimsissuer: https://mcp.higgsfield.ai. Per MCP's authorization spec (SEP-2468) the client MUST abort on that mismatch.This is not a client bug and there is no client-side workaround: the documented escape hatch in the SDK (
skipIssuerMetadataValidation) explicitly does not suppress the runtimeisscheck, and Claude Code exposes no flag for it either way.Environment
https://mcp.higgsfield.ai/mcp(streamable HTTP transport)/ja/quiz?redirect=loop and crashes, blockinghiggsfield auth login(CLI) and MCP OAuth entirely #64)@higgsfield/cli) is unaffected and still authenticates fine — this is MCP-only.Error
From
~/Library/Caches/claude-cli-nodejs/<cwd>/mcp-logs-higgsfield/*.jsonl:The server then stays parked in
needs-authfor every subsequent session ("Skipping connection (cached needs-auth)"), so the only tools it exposes areauthenticateandcomplete_authentication. All ~80 generation tools are unreachable.Reproduction — no account or credentials needed
The delegation is unconditional, so two
curlcalls demonstrate the contradiction. Note the deliberately invalidclient_id: the 302 happens before any client validation, which is itself worth a look.1. The advertised issuer is
mcp.higgsfield.ai:{ "issuer": "https://mcp.higgsfield.ai", "authorization_endpoint": "https://mcp.higgsfield.ai/oauth2/authorize", "token_endpoint": "https://mcp.higgsfield.ai/oauth2/token" }2. But
/oauth2/authorizehands the whole flow — including the client'sredirect_uri— to a different issuer:curl -s -o /dev/null -D - \ "https://mcp.higgsfield.ai/oauth2/authorize?response_type=code&client_id=NOT_A_REAL_CLIENT&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256&redirect_uri=http%3A%2F%2Flocalhost%3A8899%2Fcallback&state=teststate&scope=openid+email+offline_access&resource=https%3A%2F%2Fmcp.higgsfield.ai%2Fmcp"Because
redirect_uristill points at the client's loopback listener, Clerk — not Higgsfield — terminates the flow, and stampsiss=https://clerk.higgsfield.ai.https://clerk.higgsfield.ai/.well-known/oauth-authorization-serverself-reports"issuer":"https://clerk.higgsfield.ai", so the two documents are simply inconsistent about who the authorization server is.Your own
/.well-known/oauth-protected-resourcealready names the split explicitly:So the flow you designate for Claude Code is exactly the one that cannot complete.
Why this started without any change on your side
MCP made the check mandatory and default-on.
modelcontextprotocol/typescript-sdk#2344(SEP-2468, merged 2026-06-24) implements:Comparison is exact — the spec forbids host case folding, trailing-slash and percent-encoding normalization — so
clerk.higgsfield.aican never satisfy an expectation ofmcp.higgsfield.ai.Other hosted MCP servers with the same front-a-different-auth-host topology broke on the same rollout, which may be useful prior art:
mondaycom/mcp#453— identical error text,auth.monday.comvsauth.monday.com/mcptwentyhq/twenty#24153— same classSuggested fixes
Preferred — terminate the callback yourself. Register a redirect URI at Clerk that points back to Higgsfield (e.g.
https://mcp.higgsfield.ai/oauth2/callback) instead of forwarding the client's loopback URI upstream. Handle Clerk's callback server-side, then redirect to the client'sredirect_uriwith your owncodeplusiss=https://mcp.higgsfield.ai. This makes the advertisedissuertruthful, and it is also the only option under which your own/oauth2/tokenendpoint is meaningful rather than a pass-through.Alternative — stop advertising yourself as the authorization server. Publish
https://clerk.higgsfield.aiinauthorization_serversin/.well-known/oauth-protected-resourceinstead ofhttps://mcp.higgsfield.ai. Clerk's metadata already echoes its own issuer correctly, so the discovered issuer would then match theissit stamps. Worth checking thatresource/audience binding forhttps://mcp.higgsfield.ai/mcpstill holds if clients register directly with Clerk.Either way, please also confirm
/oauth2/authorizerejects an unregisteredclient_idbefore redirecting rather than after.Impact
Every RFC 9207-compliant MCP client is affected, not just Claude Code, and it fails in the most confusing possible way: the browser says authentication succeeded, so users conclude their client is broken and file against the client instead of here. Existing users are hit as soon as their stored token expires and a silent re-auth is attempted. Verified reachable via the CLI in the meantime, so the outage is confined to the MCP surface.