MCPcopy Index your code
hub / github.com/codeaashu/claude-code / revokeToken

Function revokeToken

src/services/mcp/auth.ts:381–459  ·  view source on GitHub ↗

* Revokes a single token on the OAuth server. * * Per RFC 7009, public clients (like Claude Code) should authenticate by including * client_id in the request body, NOT via an Authorization header. The Bearer token * in an Authorization header is meant for resource owner authentication, not clien

({
  serverName,
  endpoint,
  token,
  tokenTypeHint,
  clientId,
  clientSecret,
  accessToken,
  authMethod = 'client_secret_basic',
}: {
  serverName: string
  endpoint: string
  token: string
  tokenTypeHint: 'access_token' | 'refresh_token'
  clientId?: string
  clientSecret?: string
  accessToken?: string
  authMethod?: 'client_secret_basic' | 'client_secret_post'
})

Source from the content-addressed store, hash-verified

379 * approach or ignore unexpected headers.
380 */
381async function revokeToken({
382 serverName,
383 endpoint,
384 token,
385 tokenTypeHint,
386 clientId,
387 clientSecret,
388 accessToken,
389 authMethod = 'client_secret_basic',
390}: {
391 serverName: string
392 endpoint: string
393 token: string
394 tokenTypeHint: 'access_token' | 'refresh_token'
395 clientId?: string
396 clientSecret?: string
397 accessToken?: string
398 authMethod?: 'client_secret_basic' | 'client_secret_post'
399}): Promise<void> {
400 const params = new URLSearchParams()
401 params.set('token', token)
402 params.set('token_type_hint', tokenTypeHint)
403
404 const headers: Record<string, string> = {
405 'Content-Type': 'application/x-www-form-urlencoded',
406 }
407
408 // RFC 7009 §2.1 requires client auth per RFC 6749 §2.3. XAA always uses a
409 // confidential client at the AS — strict ASes (Okta/Stytch) reject public-
410 // client revocation of confidential-client tokens.
411 if (clientId && clientSecret) {
412 if (authMethod === 'client_secret_post') {
413 params.set('client_id', clientId)
414 params.set('client_secret', clientSecret)
415 } else {
416 const basic = Buffer.from(
417 `${encodeURIComponent(clientId)}:${encodeURIComponent(clientSecret)}`,
418 ).toString('base64')
419 headers.Authorization = `Basic ${basic}`
420 }
421 } else if (clientId) {
422 params.set('client_id', clientId)
423 } else {
424 logMCPDebug(
425 serverName,
426 `No client_id available for ${tokenTypeHint} revocation - server may reject`,
427 )
428 }
429
430 try {
431 await axios.post(endpoint, params, { headers })
432 logMCPDebug(serverName, `Successfully revoked ${tokenTypeHint}`)
433 } catch (error: unknown) {
434 // Fallback for non-RFC-7009-compliant servers that require Bearer auth
435 if (
436 axios.isAxiosError(error) &&
437 error.response?.status === 401 &&
438 accessToken

Callers 1

revokeServerTokensFunction · 0.85

Calls 5

logMCPDebugFunction · 0.85
postMethod · 0.80
toStringMethod · 0.65
deleteMethod · 0.65
setMethod · 0.45

Tested by

no test coverage detected