Skip to main content
Glama

DevDb MCP Server

http-client.ts4.45 kB
import { RequestOptions, IncomingMessage, IncomingHttpHeaders } from 'http'; import https from 'https'; interface RetryConfig { maxRetries: number; delayMs: number; exponentialBackoff?: boolean; retryStatusCodes?: number[]; } interface HttpResponse<T = any> { data: T; status: number; headers: IncomingHttpHeaders; } interface HttpError<T = any> { status: number; data: T; headers: IncomingHttpHeaders; } interface RequestConfig extends Omit<RequestOptions, 'body'> { body?: Record<string, any> | string; retry?: RetryConfig; } const DEFAULT_RETRY_CONFIG: RetryConfig = { maxRetries: 3, delayMs: 1000, exponentialBackoff: true, retryStatusCodes: [408, 429, 500, 502, 503, 504] }; async function sleep(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } async function makeRequestWithRetry<T = any>( url: string, options: RequestConfig = {}, currentAttempt = 1 ): Promise<HttpResponse<T>> { const retryConfig = { ...DEFAULT_RETRY_CONFIG, ...options.retry }; try { return await makeRequest<T>(url, options); } catch (error) { const shouldRetry = error instanceof Object && 'status' in error && retryConfig.retryStatusCodes?.includes(error.status as number) && currentAttempt < retryConfig.maxRetries; if (!shouldRetry) { throw error; } const delayMs = retryConfig.exponentialBackoff ? retryConfig.delayMs * Math.pow(2, currentAttempt - 1) : retryConfig.delayMs; await sleep(delayMs); return makeRequestWithRetry<T>(url, options, currentAttempt + 1); } } function makeRequest<T = any>(url: string, options: RequestConfig = {}): Promise<HttpResponse<T>> { return new Promise((resolve, reject) => { const req = https.request(url, options, (res: IncomingMessage) => { let data = ''; res.on('data', (chunk: Buffer) => { data += chunk; }); res.on('end', () => { try { const contentType = res.headers['content-type']; const response = contentType?.includes('application/json') ? JSON.parse(data) : data; if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { resolve({ data: response, status: res.statusCode, headers: res.headers }); } else { reject({ status: res.statusCode, data: response, headers: res.headers } as HttpError<T>); } } catch (error) { reject(error); } }); }); req.on('error', (error: Error) => { reject(error); }); if (options.body) { req.write(typeof options.body === 'string' ? options.body : JSON.stringify(options.body)); } req.end(); }); } class HttpClient { private defaultRetryConfig?: RetryConfig; constructor(defaultRetryConfig?: RetryConfig) { this.defaultRetryConfig = defaultRetryConfig; } async get<T = any>( url: string, headers: Record<string, string> = {}, retry?: RetryConfig ): Promise<HttpResponse<T>> { return makeRequestWithRetry<T>(url, { method: 'GET', headers, retry: retry || this.defaultRetryConfig }); } async post<T = any>( url: string, body: Record<string, any>, headers: Record<string, string> = {}, retry?: RetryConfig ): Promise<HttpResponse<T>> { return makeRequestWithRetry<T>(url, { method: 'POST', headers: { 'Content-Type': 'application/json', ...headers }, body, retry: retry || this.defaultRetryConfig }); } async put<T = any>( url: string, body: Record<string, any>, headers: Record<string, string> = {}, retry?: RetryConfig ): Promise<HttpResponse<T>> { return makeRequestWithRetry<T>(url, { method: 'PUT', headers: { 'Content-Type': 'application/json', ...headers }, body, retry: retry || this.defaultRetryConfig }); } async delete<T = any>( url: string, headers: Record<string, string> = {}, retry?: RetryConfig ): Promise<HttpResponse<T>> { return makeRequestWithRetry<T>(url, { method: 'DELETE', headers, retry: retry || this.defaultRetryConfig }); } } export const httpClient = new HttpClient(); export default httpClient;

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/damms005/devdb-vscode'

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