fix(oauth): include state in /oauth/connect-claude-ai flow
Claude.ai's MCP auth callback requires a state parameter. Generate a random state in /oauth/connect-claude-ai and preserve it through the consent form and login redirect so it is echoed back to claude.ai.
This commit is contained in:
@@ -22,7 +22,7 @@ spec:
|
||||
fsGroup: 1000
|
||||
containers:
|
||||
- name: hermes-mcp
|
||||
image: localhost:32000/hermes-mcp@sha256:ab1d74247354c49cd5be651433a95b683da8a7204ddfb0367569ee6b48a62561
|
||||
image: localhost:32000/hermes-mcp@sha256:c12b7fcfa46eac5cbb5a2ccbb8e9ea8062f52494ddf2700cb5d0bcdd51744e4b
|
||||
imagePullPolicy: Always
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
@@ -726,17 +726,20 @@ app.get('/oauth/connect-mcp', (req, res) => {
|
||||
|
||||
// Dedicated entry point for the Claude.ai web MCP client. It uses the official
|
||||
// Anthropic redirect_uri so Claude.ai receives the authorization code directly.
|
||||
// A state parameter is included because Claude.ai's callback requires it.
|
||||
app.get('/oauth/connect-claude-ai', (req, res) => {
|
||||
const clientId = process.env.OAUTH_CLIENT_ID;
|
||||
if (!clientId) {
|
||||
res.status(503).send('MCP OAuth app not configured (OAUTH_CLIENT_ID missing)');
|
||||
return;
|
||||
}
|
||||
const state = crypto.randomBytes(16).toString('hex');
|
||||
const params = new URLSearchParams({
|
||||
client_id: clientId,
|
||||
redirect_uri: 'https://claude.ai/api/mcp/auth_callback',
|
||||
response_type: 'code',
|
||||
scope: 'mcp',
|
||||
state,
|
||||
});
|
||||
res.redirect(`/oauth/authorize?${params}`);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user