Skip to main content
Glama
iceener

Linear Streamable MCP Server

by iceener
limits.ts2.25 kB
export type TokenBucket = { take: (n?: number) => boolean; refill: (tokens?: number) => void; }; export const makeTokenBucket = ( capacity: number, refillPerSec: number, ): TokenBucket => { let tokens = capacity; let last = Date.now(); const refillLoop = () => { const now = Date.now(); const delta = (now - last) / 1000; last = now; tokens = Math.min(capacity, tokens + delta * refillPerSec); }; return { take(n = 1) { refillLoop(); if (tokens >= n) { tokens -= n; return true; } return false; }, refill(n = capacity) { tokens = Math.min(capacity, tokens + n); }, }; }; export const makeConcurrencyGate = (max: number) => { let active = 0; const queue: (() => void)[] = []; return async <T>(fn: () => Promise<T>): Promise<T> => { if (active >= max) { await new Promise<void>((resolve) => queue.push(resolve)); } active++; try { return await fn(); } finally { active--; const next = queue.shift(); if (next) next(); } }; }; /** Delay helper */ export const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); /** Check if error is a rate limit error */ export const isRateLimitError = (error: unknown): boolean => { const message = (error as Error)?.message ?? ''; return ( message.includes('Too many subrequests') || message.includes('rate limit') || message.includes('Rate limit') || message.includes('429') ); }; /** Retry with exponential backoff for rate-limited requests */ export const withRetry = async <T>( fn: () => Promise<T>, options: { maxRetries?: number; baseDelayMs?: number; maxDelayMs?: number; } = {}, ): Promise<T> => { const { maxRetries = 3, baseDelayMs = 500, maxDelayMs = 5000 } = options; let lastError: unknown; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (error) { lastError = error; if (!isRateLimitError(error) || attempt === maxRetries) { throw error; } const delayMs = Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs); await delay(delayMs); } } throw lastError; };

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/iceener/linear-streamable-mcp-server'

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