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:
Garfield
2026-06-12 15:09:19 -04:00
parent f084be6bc6
commit 2014e03190
2 changed files with 4 additions and 1 deletions

View File

@@ -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

View File

@@ -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}`);
});