Skip to main content
Glama
openrouter.ts7.43 kB
import { Router } from 'express'; import { OpenRouter } from '@openrouter/sdk'; import axios from 'axios'; import { logger } from '../logging/logger.js'; import { providerManager } from '../config/provider-manager.js'; /** * Get OpenRouter client instance */ async function getOpenRouterClient(): Promise<OpenRouter> { const apiKey = await providerManager.getApiKey('openrouter'); if (!apiKey) { throw new Error('OpenRouter API key not configured'); } return new OpenRouter({ apiKey }); } /** * Get OpenRouter API key for direct axios calls */ async function getOpenRouterApiKey(): Promise<string> { const apiKey = await providerManager.getApiKey('openrouter'); if (!apiKey) { throw new Error('OpenRouter API key not configured'); } return apiKey; } /** * Create and configure OpenRouter routes */ export function createOpenRouterRoutes(): Router { const router = Router(); /** * GET /v1/openrouter/models * Fetch available models from OpenRouter */ router.get('/models', async (req, res) => { try { let modelsData; try { // Try OpenRouter SDK first const client = await getOpenRouterClient(); const response = await client.models.list(); modelsData = response.data || response; } catch (sdkError) { // Fallback to direct API call if SDK fails logger.warn('OpenRouter SDK failed, using fallback API', { error: sdkError }); const apiKey = await getOpenRouterApiKey(); const response = await axios.get('https://openrouter.ai/api/v1/models', { headers: { 'Authorization': `Bearer ${apiKey}`, 'HTTP-Referer': req.get('origin') || 'https://github.com/babasida246/ai-mcp-gateway', 'X-Title': 'ai-mcp-gateway' } }); modelsData = response.data.data || response.data; } // Ensure proper data structure for models const processedModels = Array.isArray(modelsData) ? modelsData.map(model => ({ ...model, context_length: typeof model.context_length === 'number' ? model.context_length : 0, pricing: model.pricing || { prompt: 0, completion: 0 } })) : []; res.json({ success: true, models: processedModels }); } catch (error: any) { logger.error('Failed to fetch OpenRouter models', { error: error.message }); res.status(error.status || 500).json({ success: false, error: error.message || 'Failed to fetch models' }); } }); /** * GET /v1/openrouter/limits * Get rate limits and usage */ router.get('/limits', async (req, res) => { try { const apiKey = await getOpenRouterApiKey(); const response = await axios.get('https://openrouter.ai/api/v1/auth/key', { headers: { 'Authorization': `Bearer ${apiKey}`, 'HTTP-Referer': req.get('origin') || 'https://github.com/babasida246/ai-mcp-gateway', 'X-Title': 'ai-mcp-gateway' } }); // Extract rate limit info from auth/key response const keyData = response.data.data || response.data; const limitsData = { usage: typeof keyData.usage === 'number' ? keyData.usage : 0, limit: typeof keyData.limit === 'number' ? keyData.limit : 100000, is_free_tier: keyData.is_free_tier || false, rate_limit: keyData.rate_limit || null, label: keyData.label || null }; res.json({ success: true, limits: limitsData }); } catch (error: any) { logger.error('Failed to fetch OpenRouter limits', { error: error.message }); res.status(error.response?.status || 500).json({ success: false, error: error.response?.data || error.message }); } }); /** * GET /v1/openrouter/credits * Get remaining credits */ router.get('/credits', async (req, res) => { try { const apiKey = await getOpenRouterApiKey(); const response = await axios.get('https://openrouter.ai/api/v1/auth/key', { headers: { 'Authorization': `Bearer ${apiKey}`, 'HTTP-Referer': req.get('origin') || 'https://github.com/babasida246/ai-mcp-gateway', 'X-Title': 'ai-mcp-gateway' } }); // Extract credit info from auth/key response const keyData = response.data.data || response.data; const creditsData = { balance: typeof keyData.credit === 'number' ? keyData.credit : 0, usage: typeof keyData.usage === 'number' ? keyData.usage : 0, limit: typeof keyData.credit_limit === 'number' ? keyData.credit_limit : 10 }; res.json({ success: true, credits: creditsData }); } catch (error: any) { logger.error('Failed to fetch OpenRouter credits', { error: error.message }); res.status(error.response?.status || 500).json({ success: false, error: error.response?.data || error.message }); } }); /** * GET /v1/openrouter/activity * Get user activity grouped by endpoint */ router.get('/activity', async (req, res) => { try { const apiKey = await getOpenRouterApiKey(); const response = await axios.get('https://openrouter.ai/api/v1/activity', { headers: { 'Authorization': `Bearer ${apiKey}`, 'HTTP-Referer': req.get('origin') || 'https://github.com/babasida246/ai-mcp-gateway', 'X-Title': 'ai-mcp-gateway' } }); // Ensure proper data structure for activity items const activityData = response.data.data || response.data || []; const processedActivity = Array.isArray(activityData) ? activityData.map(item => ({ ...item, total_cost: typeof item.total_cost === 'number' ? item.total_cost : 0, generations: typeof item.generations === 'number' ? item.generations : 0, created_at: item.created_at || new Date().toISOString() })) : []; res.json({ success: true, activity: processedActivity }); } catch (error: any) { logger.error('Failed to fetch OpenRouter activity', { error: error.message }); res.status(error.response?.status || 500).json({ success: false, error: error.response?.data || error.message }); } }); return router; } export default createOpenRouterRoutes();

Latest Blog Posts

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/babasida246/ai-mcp-gateway'

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