fix(mcp): eager-auth flag on the Grok connector links so Grok starts OAuth (#2167)

* fix(mcp): eager-auth flag on the Grok connector links so Grok starts OAuth

Live test after #2158: pasting the Grok URL into grok.com's custom
connector dialog listed all 150+ tools and never opened the sign-in. Grok
probes the URL without credentials, like claude.ai, and reads the lazy
200 on initialize as an authless server; only the 401 challenge starts
OAuth (#2159 fixed the same thing for the claude.ai link).

- lib/onboarding/checklist.ts: mcpServerUrl() builds the server URL with
  an optional eagerAuth flag; sideDoorServerUrl() gives the Grok side door
  auth=required and keeps ChatGPT lazy; claudeConnectorLink() reuses it.
  SIDE_DOORS / SideDoor move here from the component. Tests for all three.
- NewUserChecklist copies the door-specific URL (now with a client marker).
- ApiKeysPanel's Grok row copies the flagged URL, mirroring the Claude one.
- auth-mode.ts comment records the second consumer; registry entry's Grok
  step carries the flag; DECISIONS.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhTJcwgzmN3TsLR8tVHwdi
Signed-off-by: Emil <emilmattsson14@gmail.com>

* docs(mcp): registry Claude.ai step carries auth=required too

Review pass on #2167: the registry entry flagged the Grok install URL
but left the Claude.ai step on the bare URL, which pre-fills "None" in
claude.ai's dialog (#2159). Same file, same flag, now consistent.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhTJcwgzmN3TsLR8tVHwdi
Signed-off-by: Emil <emilmattsson14@gmail.com>

---------

Signed-off-by: Emil <emilmattsson14@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Mattsson
2026-09-02 16:55:23 +02:00
committed by GitHub
co-authored by Claude Fable 5.1
parent f1230282a9
commit a80ce54b78
7 changed files with 96 additions and 23 deletions
+6 -9
View File
@@ -17,6 +17,9 @@ import {
checklistNumbers,
claudeConnectorLink,
completionPatchBody,
SIDE_DOORS,
sideDoorServerUrl,
type SideDoor,
type VatDeadlineLine,
} from '@/lib/onboarding/checklist'
import { ENABLED_EXTENSION_IDS } from '@/lib/extensions/_generated/enabled-extensions'
@@ -47,12 +50,6 @@ interface NewUserChecklistProps {
sieSweep?: { auto_linked: number; suggested: number; unmatched: number; errors: number } | null
}
/** Clients that get a collapsed "Using X?" side door under the Claude step.
* Each value keys the i18n strings step_claude_<door>_link / _steps and the
* telemetry step name. Order is display order. */
const SIDE_DOORS = ['chatgpt', 'grok'] as const
type SideDoor = (typeof SIDE_DOORS)[number]
/**
* Activation funnel events, mirroring the one existing product-event site
* (lib/support/submit-feedback.ts): guarded, try/caught, no PII in
@@ -276,8 +273,8 @@ export default function NewUserChecklist({
return open === door ? null : door
})
}
const copyServerUrl = async () => {
const serverUrl = `${window.location.origin}/api/extensions/ext/mcp-server/mcp?tool_namespace=accounted`
const copyServerUrl = async (door: SideDoor) => {
const serverUrl = sideDoorServerUrl({ origin: window.location.origin, door })
try {
await navigator.clipboard.writeText(serverUrl)
setServerUrlCopied(true)
@@ -495,7 +492,7 @@ export default function NewUserChecklist({
<p className="max-w-prose text-xs leading-5 text-muted-foreground">
{t(`step_claude_${sideDoor}_steps`, { appName })}
</p>
<Button size="sm" variant="outline" onClick={() => void copyServerUrl()}>
<Button size="sm" variant="outline" onClick={() => void copyServerUrl(sideDoor)}>
{serverUrlCopied
? t('step_claude_chatgpt_copied')
: t('step_claude_chatgpt_copy')}
+4 -1
View File
@@ -320,6 +320,9 @@ export function ApiKeysPanel() {
// (extensions/general/mcp-server/auth-mode.ts). Claude Code, Cursor and the
// stdio bridge keep the lazy URL.
const claudeConnectorUrl = `${mcpUrl('claude-connector')}&auth=required`
// Grok's custom-connector dialog does the same probe: on the lazy URL it
// lists every tool and never opens the sign-in (observed 2026-09-02).
const grokConnectorUrl = `${mcpUrl('grok')}&auth=required`
// claude.ai install link: opens Add-custom-connector with name and URL
// prefilled. It only prefills the dialog, so the user still reviews and
@@ -436,7 +439,7 @@ export function ApiKeysPanel() {
path: (chunks) => <strong>{chunks}</strong>,
})}
</p>
<CopyBlock text={mcpUrl('grok')} copyAriaLabel={t('copy_aria')} />
<CopyBlock text={grokConnectorUrl} copyAriaLabel={t('copy_aria')} />
</div>
<div>