Skip to main content
Glama

Bucket Feature Flags MCP Server

Official
by reflagcom
fetch-http-client.ts2.92 kB
import { API_TIMEOUT_MS } from "./config"; import { HttpClient } from "./types"; import { ok } from "./utils"; /** * The default HTTP client implementation. * * @remarks * This implementation uses the `fetch` API to send HTTP requests. **/ const fetchClient: HttpClient = { post: async <TBody, TResponse>( url: string, headers: Record<string, string>, body: TBody, timeoutMs: number = API_TIMEOUT_MS, ) => { ok(typeof url === "string" && url.length > 0, "URL must be a string"); ok(typeof headers === "object", "Headers must be an object"); const response = await fetch(url, { method: "post", headers, body: JSON.stringify(body), signal: AbortSignal.timeout(timeoutMs), }); const json = await response.json(); return { ok: response.ok, status: response.status, body: json as TResponse, }; }, get: async <TResponse>( url: string, headers: Record<string, string>, timeoutMs: number = API_TIMEOUT_MS, ) => { ok(typeof url === "string" && url.length > 0, "URL must be a string"); ok(typeof headers === "object", "Headers must be an object"); const response = await fetch(url, { method: "get", headers, signal: AbortSignal.timeout(timeoutMs), // We must use no-cache to avoid services such as Next.js from caching the response indefinitely. // We also can't use no-store because of Next.js error withRetry https://github.com/vercel/next.js/discussions/54036. // We also have local caching in the SDKs, so we don't need to cache the response. cache: "no-cache", }); const json = await response.json(); return { ok: response.ok, status: response.status, body: json as TResponse, }; }, }; /** * Implements exponential backoff retry logic for async functions. * * @param fn - The async function to retry. * @param maxRetries - Maximum number of retry attempts. * @param baseDelay - Base delay in milliseconds before retrying. * @param maxDelay - Maximum delay in milliseconds. * @returns The result of the function call or throws an error if all retries fail. */ export async function withRetry<T>( fn: () => Promise<T>, onFailedTry: (error: unknown) => void, maxRetries: number, baseDelay: number, maxDelay: number, ): Promise<T> { let lastError: unknown; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (error) { lastError = error; if (attempt === maxRetries) { break; } onFailedTry(error); // Calculate exponential backoff with jitter const delay = Math.min( maxDelay, baseDelay * Math.pow(2, attempt) * (0.8 + Math.random() * 0.4), ); await new Promise((resolve) => setTimeout(resolve, delay)); } } throw lastError; } export default fetchClient;

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/reflagcom/bucket-javascript-sdk'

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