MCPcopy
hub / github.com/codeaashu/claude-code / revokeServerTokens

Function revokeServerTokens

src/services/mcp/auth.ts:467–618  ·  view source on GitHub ↗
(
  serverName: string,
  serverConfig: McpSSEServerConfig | McpHTTPServerConfig,
  { preserveStepUpState = false }: { preserveStepUpState?: boolean } = {},
)

Source from the content-addressed store, hash-verified

465 * access tokens and many servers implicitly invalidate associated access tokens.
466 */
467export async function revokeServerTokens(
468 serverName: string,
469 serverConfig: McpSSEServerConfig | McpHTTPServerConfig,
470 { preserveStepUpState = false }: { preserveStepUpState?: boolean } = {},
471): Promise<void> {
472 const storage = getSecureStorage()
473 const existingData = storage.read()
474 if (!existingData?.mcpOAuth) return
475
476 const serverKey = getServerKey(serverName, serverConfig)
477 const tokenData = existingData.mcpOAuth[serverKey]
478
479 // Attempt server-side revocation if there are tokens to revoke (best-effort)
480 if (tokenData?.accessToken || tokenData?.refreshToken) {
481 try {
482 // For XAA (and any PRM-discovered auth), the AS is at a different host
483 // than the MCP URL — use the persisted discoveryState if we have it.
484 const asUrl =
485 tokenData.discoveryState?.authorizationServerUrl ?? serverConfig.url
486 const metadata = await fetchAuthServerMetadata(
487 serverName,
488 asUrl,
489 serverConfig.oauth?.authServerMetadataUrl,
490 )
491
492 if (!metadata) {
493 logMCPDebug(serverName, 'No OAuth metadata found')
494 } else {
495 const revocationEndpoint =
496 'revocation_endpoint' in metadata
497 ? metadata.revocation_endpoint
498 : null
499 if (!revocationEndpoint) {
500 logMCPDebug(serverName, 'Server does not support token revocation')
501 } else {
502 const revocationEndpointStr = String(revocationEndpoint)
503 // RFC 7009 defines revocation_endpoint_auth_methods_supported
504 // separately from the token endpoint's list; prefer it if present.
505 const authMethods =
506 ('revocation_endpoint_auth_methods_supported' in metadata
507 ? metadata.revocation_endpoint_auth_methods_supported
508 : undefined) ??
509 ('token_endpoint_auth_methods_supported' in metadata
510 ? metadata.token_endpoint_auth_methods_supported
511 : undefined)
512 const authMethod: 'client_secret_basic' | 'client_secret_post' =
513 authMethods &&
514 !authMethods.includes('client_secret_basic') &&
515 authMethods.includes('client_secret_post')
516 ? 'client_secret_post'
517 : 'client_secret_basic'
518 logMCPDebug(
519 serverName,
520 `Revoking tokens via ${revocationEndpointStr} (${authMethod})`,
521 )
522
523 // Revoke refresh token first (more important - prevents future access token generation)
524 if (tokenData.refreshToken) {

Callers 3

MCPRemoteServerMenuFunction · 0.85
handleClearAuthFunction · 0.85
runHeadlessStreamingFunction · 0.85

Calls 9

getSecureStorageFunction · 0.85
getServerKeyFunction · 0.85
fetchAuthServerMetadataFunction · 0.85
logMCPDebugFunction · 0.85
revokeTokenFunction · 0.85
readMethod · 0.65
updateMethod · 0.65
errorMessageFunction · 0.50

Tested by

no test coverage detected