@juspay/neurolink
Version:
Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applicatio
401 lines (400 loc) • 14.8 kB
TypeScript
/**
* Anthropic OAuth 2.0 Authentication for Claude Pro/Max Subscriptions
*
* This module implements OAuth 2.0 flow with PKCE support for authenticating
* Claude Pro and Max subscription users through console.anthropic.com.
*
* OAuth Flow:
* 1. Generate PKCE code verifier and challenge
* 2. User is redirected to Anthropic authorization URL
* 3. User authenticates and grants permissions
* 4. Callback receives authorization code
* 5. Code is exchanged for access and refresh tokens
* 6. Tokens are used for API authentication
*
* @module auth/anthropicOAuth
*/
import type { Server } from "http";
import type { ClaudeCodeIdentity } from "../types/index.js";
/**
* Claude Code's official OAuth client ID
* Used to authenticate with Anthropic's OAuth system
*/
export declare const CLAUDE_CODE_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
/**
* Anthropic OAuth authorization URL for Claude Pro/Max
*/
export declare const ANTHROPIC_AUTH_URL = "https://claude.ai/oauth/authorize";
/**
* Anthropic OAuth token endpoint (primary — lighter Cloudflare)
*/
export declare const ANTHROPIC_TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
/**
* Anthropic OAuth token endpoint (fallback)
*/
export declare const ANTHROPIC_TOKEN_URL_FALLBACK = "https://console.anthropic.com/v1/oauth/token";
/**
* Anthropic OAuth redirect URI (official callback)
*/
export declare const ANTHROPIC_REDIRECT_URI = "https://console.anthropic.com/oauth/code/callback";
/**
* Default OAuth scopes for Claude subscription access
*/
export declare const DEFAULT_SCOPES: readonly string[];
/**
* User-Agent string to spoof Claude CLI
*/
export declare const CLAUDE_CODE_VERSION = "2.1.87.6d6";
export declare const CLAUDE_CODE_ENTRYPOINT = "sdk-cli";
export declare const CLAUDE_CLI_USER_AGENT = "claude-cli/2.1.87 (external, sdk-cli)";
export declare function parseClaudeCodeUserId(userId: unknown): ClaudeCodeIdentity | null;
export declare function getOrCreateClaudeCodeIdentity(seed: string, options?: {
existingUserId?: unknown;
preferredSessionId?: string;
}): ClaudeCodeIdentity;
export declare function purgeExpiredClaudeCodeIdentities(now?: number): number;
export declare function buildStableClaudeCodeBillingHeader(originalText?: string): string;
/**
* Required beta headers for OAuth API requests.
* The "oauth-2025-04-20" header is CRITICAL for OAuth authentication.
*/
export declare const OAUTH_BETA_HEADERS = "oauth-2025-04-20";
export declare const CLAUDE_CODE_OAUTH_BETAS: readonly ["oauth-2025-04-20", "claude-code-20250219", "context-management-2025-06-27", "prompt-caching-scope-2026-01-05", "advanced-tool-use-2025-11-20", "effort-2025-11-24"];
/**
* Tool name prefix required for OAuth API requests
*/
export declare const MCP_TOOL_PREFIX = "mcp_";
/**
* @deprecated Use ANTHROPIC_AUTH_URL instead
*/
export declare const ANTHROPIC_OAUTH_BASE_URL = "https://console.anthropic.com/oauth";
/**
* @deprecated Use ANTHROPIC_REDIRECT_URI instead
*/
export declare const DEFAULT_REDIRECT_URI = "https://console.anthropic.com/oauth/code/callback";
/**
* Default local callback server port (for local testing only)
*/
export declare const DEFAULT_CALLBACK_PORT = 8787;
import type { OAuthFlowTokens, ClaudeTokenValidationResult, AnthropicOAuthConfig, PKCEParams, CallbackResult } from "../types/index.js";
/**
* AnthropicOAuth - OAuth 2.0 authentication for Claude Pro/Max subscriptions
*
* Implements OAuth 2.0 authorization code flow with PKCE support for
* authenticating users with Claude Pro or Max subscriptions.
*
* @example
* ```typescript
* const oauth = new AnthropicOAuth({
* clientId: "your-client-id",
* redirectUri: "http://localhost:8787/callback",
* });
*
* // Generate PKCE parameters
* const codeVerifier = AnthropicOAuth.generateCodeVerifier();
* const codeChallenge = await AnthropicOAuth.generateCodeChallenge(codeVerifier);
*
* // Generate auth URL
* const authUrl = oauth.generateAuthUrl({
* codeChallenge,
* state: "random-state",
* });
*
* // After user authenticates, exchange code for tokens
* const tokens = await oauth.exchangeCodeForTokens(code, codeVerifier);
* ```
*/
export declare class AnthropicOAuth {
private readonly clientId;
private readonly clientSecret?;
private readonly redirectUri;
private readonly scopes;
private readonly authorizationUrl;
private readonly tokenUrl;
private readonly validationUrl;
private readonly revocationUrl;
constructor(config?: AnthropicOAuthConfig);
/**
* Generates a cryptographically secure code verifier for PKCE
*
* The code verifier is a high-entropy random string between 43-128 characters
* using URL-safe characters (A-Z, a-z, 0-9, "-", ".", "_", "~").
*
* @returns A random code verifier string (64 characters)
*
* @example
* ```typescript
* const codeVerifier = AnthropicOAuth.generateCodeVerifier();
* // Returns something like "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
* ```
*/
static generateCodeVerifier(): string;
/**
* Generates a PKCE code challenge from a code verifier
*
* Uses SHA-256 hashing as per RFC 7636. The challenge is the
* base64url-encoded SHA-256 hash of the code verifier.
*
* @param verifier - The code verifier to generate challenge from
* @returns Promise resolving to the code challenge string
*
* @example
* ```typescript
* const verifier = AnthropicOAuth.generateCodeVerifier();
* const challenge = await AnthropicOAuth.generateCodeChallenge(verifier);
* ```
*/
static generateCodeChallenge(verifier: string): Promise<string>;
/**
* Generates both code verifier and challenge for PKCE
*
* Convenience method that generates both PKCE parameters at once.
*
* @returns Promise resolving to PKCE parameters object
*
* @example
* ```typescript
* const pkce = await AnthropicOAuth.generatePKCE();
* console.log(pkce.codeVerifier);
* console.log(pkce.codeChallenge);
* ```
*/
static generatePKCE(): Promise<PKCEParams>;
/**
* Generates the OAuth authorization URL with PKCE support
*
* Builds the complete authorization URL including all required parameters
* for the OAuth 2.0 authorization code flow with PKCE.
*
* @param config - Authorization URL configuration
* @param state - Optional state parameter for CSRF protection
* @returns The complete authorization URL
*
* @example
* ```typescript
* const pkce = await AnthropicOAuth.generatePKCE();
* const authUrl = oauth.generateAuthUrl({
* codeChallenge: pkce.codeChallenge,
* state: crypto.randomUUID(),
* });
* // Redirect user to authUrl
* ```
*/
generateAuthUrl(config?: {
/** PKCE code challenge (required for public clients) */
codeChallenge?: string;
/** Additional URL parameters */
additionalParams?: Record<string, string>;
}, state?: string): string;
/**
* Exchanges an authorization code for access and refresh tokens
*
* Performs the token exchange step of the OAuth flow. For public clients
* using PKCE, the code verifier must be provided.
*
* @param code - The authorization code from the OAuth callback
* @param codeVerifier - The PKCE code verifier used to generate the challenge
* @param config - Optional additional configuration
* @returns Promise resolving to the parsed OAuth tokens
* @throws OAuthTokenExchangeError if the exchange fails
*
* @example
* ```typescript
* const tokens = await oauth.exchangeCodeForTokens(
* authorizationCode,
* pkce.codeVerifier
* );
* console.log("Access token:", tokens.accessToken);
* console.log("Expires at:", tokens.expiresAt);
* ```
*/
exchangeCodeForTokens(code: string, codeVerifier: string, config?: AnthropicOAuthConfig): Promise<OAuthFlowTokens>;
private _exchangeCodeForTokens;
/**
* Refreshes an expired access token using a refresh token
*
* @param refreshToken - The refresh token from a previous authentication
* @param config - Optional configuration overrides
* @returns Promise resolving to new OAuth tokens
* @throws OAuthTokenRefreshError if the refresh fails
*
* @example
* ```typescript
* if (AnthropicOAuth.isTokenExpired(tokens.expiresAt)) {
* const newTokens = await oauth.refreshAccessToken(tokens.refreshToken);
* console.log("New access token:", newTokens.accessToken);
* }
* ```
*/
refreshAccessToken(refreshToken: string, config?: AnthropicOAuthConfig): Promise<OAuthFlowTokens>;
private _refreshAccessToken;
/**
* Validates an access token and returns token information
*
* Checks if the token is still valid by calling the validation endpoint.
* Returns user information if available.
*
* @param accessToken - The access token to validate
* @returns Promise resolving to validation result
*
* @example
* ```typescript
* const result = await oauth.validateToken(accessToken);
* if (result.isValid) {
* console.log("Token is valid, expires in:", result.expiresIn, "seconds");
* console.log("User email:", result.user?.email);
* } else {
* console.log("Token is invalid:", result.error);
* }
* ```
*/
validateToken(accessToken: string): Promise<boolean>;
/**
* Validates token and returns detailed information
*
* @param accessToken - The access token to validate
* @returns Promise resolving to detailed validation result
*/
validateTokenWithDetails(accessToken: string): Promise<ClaudeTokenValidationResult>;
/**
* Revokes an access token or refresh token
*
* @param token - The token to revoke
* @param tokenType - Type of token ("access_token" or "refresh_token")
* @returns Promise that resolves when revocation is complete
* @throws OAuthTokenRevocationError if revocation fails
*/
revokeToken(token: string, tokenType?: "access_token" | "refresh_token"): Promise<void>;
private _revokeToken;
/**
* Build the list of token endpoint URLs to try, with optional fallback.
*
* When a custom tokenUrl was provided (via config param OR constructor), never
* fall back to the default Anthropic endpoint — leaking credentials to an
* unexpected endpoint is a security risk.
*/
private getTokenUrls;
/**
* Parses a token response into structured OAuthFlowTokens
*/
private parseTokenResponse;
/**
* Generates a random state parameter for CSRF protection
*/
private generateState;
/**
* Checks if a token is expired or about to expire
*
* @param expiresAt - Token expiration date
* @param bufferSeconds - Buffer time before actual expiration (default: 60 seconds)
* @returns True if token is expired or will expire within buffer time
*/
static isTokenExpired(expiresAt: Date, bufferSeconds?: number): boolean;
/**
* Gets the configured client ID
*/
getClientId(): string;
/**
* Gets the configured redirect URI
*/
getRedirectUri(): string;
/**
* Gets the configured scopes
*/
getScopes(): readonly string[];
}
/**
* Creates and starts a local HTTP server to receive OAuth callbacks
*
* This helper function starts a temporary HTTP server that listens for
* the OAuth callback and extracts the authorization code.
*
* @param port - Port to listen on (default: 8787)
* @param path - Path to listen on (default: "/callback")
* @param timeout - Timeout in milliseconds (default: 5 minutes)
* @returns Promise resolving to the callback result with authorization code
*
* @example
* ```typescript
* // Start callback server before redirecting user
* const callbackPromise = startCallbackServer();
*
* // Generate auth URL and redirect user
* const authUrl = oauth.generateAuthUrl({ codeChallenge });
* console.log("Please visit:", authUrl);
*
* // Wait for callback
* const result = await callbackPromise;
* console.log("Got authorization code:", result.code);
*
* // Exchange for tokens
* const tokens = await oauth.exchangeCodeForTokens(result.code, codeVerifier);
* ```
*/
export declare function startCallbackServer(port?: number, path?: string, timeout?: number): Promise<CallbackResult>;
/**
* Stops the callback server if running
* Note: The server automatically stops after receiving a callback or timing out
*/
export declare function stopCallbackServer(server: Server): Promise<void>;
/**
* Creates an AnthropicOAuth instance with default configuration from environment
*
* @param overrides - Optional configuration overrides
* @returns Configured AnthropicOAuth instance
*
* @example
* ```typescript
* const oauth = createAnthropicOAuth();
* const authUrl = oauth.generateAuthUrl({ codeChallenge });
* ```
*/
export declare function createAnthropicOAuth(overrides?: Partial<AnthropicOAuthConfig>): AnthropicOAuth;
/**
* Anthropic OAuth configuration creator for providerConfig pattern
*
* @returns Provider configuration options for Anthropic OAuth
*/
export declare function createAnthropicOAuthConfig(): {
providerName: string;
envVarName: string;
setupUrl: string;
description: string;
instructions: string[];
fallbackEnvVars: never[];
};
/**
* Checks if Anthropic OAuth credentials are configured
*
* @returns True if OAuth client ID is available
*/
export declare function hasAnthropicOAuthCredentials(): boolean;
/**
* Performs a complete OAuth flow including callback server
*
* This is a convenience function that handles the entire OAuth flow:
* 1. Generates PKCE parameters
* 2. Starts the callback server
* 3. Opens the browser (if possible)
* 4. Waits for the callback
* 5. Exchanges the code for tokens
*
* @param oauth - AnthropicOAuth instance
* @param options - Flow options
* @returns Promise resolving to OAuth tokens
*
* @example
* ```typescript
* const oauth = createAnthropicOAuth();
* const tokens = await performOAuthFlow(oauth);
* console.log("Authenticated! Token expires at:", tokens.expiresAt);
* ```
*/
export declare function performOAuthFlow(oauth: AnthropicOAuth, options?: {
/** Port for callback server (default: 8787) */
port?: number;
/** Timeout in milliseconds (default: 5 minutes) */
timeout?: number;
/** Whether to automatically open browser (default: true) */
openBrowser?: boolean;
}): Promise<OAuthFlowTokens>;