Skip to main content
Glama
auth.tsโ€ข3.45 kB
import { logger } from './logger.js'; // Types interface TokenData { access_token: string; expires_in: number; } // Global variables for OAuth2 token management let accessToken: string | null = null; let tokenExpiry: number | null = null; const TOKEN_REFRESH_MARGIN = 30 * 60 * 1000; // 30 minutes in milliseconds // OAuth2 authentication export async function authenticateWithCisco(): Promise<string> { const { CISCO_CLIENT_ID, CISCO_CLIENT_SECRET } = process.env; if (!CISCO_CLIENT_ID || !CISCO_CLIENT_SECRET) { throw new Error('Missing Cisco API credentials in environment variables'); } const tokenUrl = 'https://id.cisco.com/oauth2/default/v1/token'; const credentials = Buffer.from(`${CISCO_CLIENT_ID}:${CISCO_CLIENT_SECRET}`).toString('base64'); try { logger.info('Requesting OAuth2 token from Cisco'); const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout for auth const response = await fetch(tokenUrl, { method: 'POST', headers: { 'Authorization': `Basic ${credentials}`, 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' }, body: 'grant_type=client_credentials', signal: controller.signal }); clearTimeout(timeoutId); if (!response.ok) { const errorText = await response.text(); throw new Error(`OAuth2 authentication failed: ${response.status} ${response.statusText} - ${errorText}`); } const tokenData = await response.json() as TokenData; if (!tokenData.access_token) { throw new Error('No access token received from Cisco OAuth2 API'); } // Calculate token expiry (default 12 hours if not provided) const expiresIn = tokenData.expires_in || 43200; // 12 hours default tokenExpiry = Date.now() + (expiresIn * 1000); accessToken = tokenData.access_token; logger.info('Successfully obtained OAuth2 token', { expiresIn: expiresIn, expiryTime: new Date(tokenExpiry).toISOString() }); return accessToken; } catch (error) { // Handle specific timeout errors if (error instanceof Error) { if (error.name === 'AbortError' || error.message.includes('timeout')) { logger.error('OAuth2 authentication timed out', { timeout: '30s' }); throw new Error(`OAuth2 authentication timed out after 30 seconds. Cisco's authentication service may be experiencing issues.`); } else if (error.message.includes('Headers Timeout') || error.message.includes('UND_ERR_HEADERS_TIMEOUT')) { logger.error('OAuth2 headers timeout'); throw new Error(`OAuth2 authentication connection timed out. Cisco's authentication service may be temporarily unavailable.`); } } logger.error('OAuth2 authentication failed', error); throw error; } } // Get valid access token, refreshing if necessary export async function getValidToken(): Promise<string> { const now = Date.now(); // Check if token exists and is not expired (with margin) if (accessToken && tokenExpiry && (tokenExpiry - now) > TOKEN_REFRESH_MARGIN) { return accessToken; } logger.info('Token expired or missing, refreshing...'); return await authenticateWithCisco(); } // Reset token (for testing or manual refresh) export function resetToken(): void { accessToken = null; tokenExpiry = null; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sieteunoseis/mcp-cisco-support'

If you have feedback or need assistance with the MCP directory API, please join our Discord server