feat(mcp): allowlist Grok's connector callback and document the Grok path (#2158)
* feat(mcp): allowlist Grok's connector callback and document the Grok path Grok custom connectors self-register through /api/mcp-oauth/register with redirect_uri https://grok.com/connectors-oauth-exchange-code/, which the built-in allowlist rejected with invalid_redirect_uri before consent. Add the callback as an exact-path BUILT_IN_PATTERNS entry (trailing slash optional, no prefix) with provider 'grok', named "Grok (xAI)" on the consent page. Tests: accept, foreign-host and other-path rejection, provider mapping, and a register route test for the Grok DCR shape. Surface Grok next to ChatGPT: a "Using Grok?" side door on the onboarding Claude step (one side door open at a time, telemetry step grok), a Grok row under "Other clients" in the API & MCP settings tab using ?client=grok, and sv/en strings for both. Docs: mcp-server rule, ARCHITECTURE, README, registry entry (install section), DECISIONS. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EGbspj3hiNqvqTWZqdwysa Signed-off-by: Emil <emilmattsson14@gmail.com> * fix(mcp): cite X Corp's published Grok callback, test the consent label Review pass on #2158: the allowlist comment and DECISIONS entry claimed xAI publishes no callback and the value came from a live observation; X Corp lists https://grok.com/connectors-oauth-exchange-code/ as the "Grok (web)" redirect URL at docs.x.com/x-ads-api/mcp, and grok.com serves the path itself (slash form 308s to no-slash on the same origin). Reworded both to cite that. Adds the consent-page test for "Grok (xAI)" next to the ChatGPT one and a JSDoc on the onboarding side-door toggle. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EGbspj3hiNqvqTWZqdwysa 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:
co-authored by
Claude Fable 5.1
parent
61a76b1669
commit
6a85efb00a
@@ -51,6 +51,25 @@ describe('POST /api/mcp-oauth/register', () => {
|
||||
expect(response.status).toBe(201)
|
||||
})
|
||||
|
||||
it('accepts registration with the grok.com connector callback', async () => {
|
||||
const response = await POST(createRequest({
|
||||
client_name: 'Grok',
|
||||
redirect_uris: ['https://grok.com/connectors-oauth-exchange-code/'],
|
||||
token_endpoint_auth_method: 'none',
|
||||
}))
|
||||
expect(response.status).toBe(201)
|
||||
const body = await response.json()
|
||||
expect(body.redirect_uris).toEqual(['https://grok.com/connectors-oauth-exchange-code/'])
|
||||
expect(body.token_endpoint_auth_method).toBe('none')
|
||||
})
|
||||
|
||||
it('rejects other grok.com paths', async () => {
|
||||
const response = await POST(createRequest({
|
||||
redirect_uris: ['https://grok.com/oauth/callback'],
|
||||
}))
|
||||
expect(response.status).toBe(400)
|
||||
})
|
||||
|
||||
it('rejects registration with disallowed redirect_uris', async () => {
|
||||
const response = await POST(createRequest({
|
||||
redirect_uris: ['https://evil.com/callback'],
|
||||
|
||||
Reference in New Issue
Block a user