Skip to main content
Glama
discovery-runner.ts2.47 kB
import type { UniversalResourceType } from '@/handlers/tool-configs/universal/types.js'; import type { CachedMetadataResult, MetadataCacheKey, MetadataCacheService, MetadataMetricsService, MetadataResult, } from './types.js'; interface DiscoveryMetricsContext { resourceType: UniversalResourceType; objectSlug?: string; } interface DiscoveryTask { cacheKey: MetadataCacheKey; cacheTtl?: number; useCache?: boolean; loader: () => Promise<MetadataResult>; metrics: DiscoveryMetricsContext; onError: (error: unknown) => never; } export class DiscoveryRunner { constructor( private readonly cacheService: MetadataCacheService, private readonly metricsService: MetadataMetricsService ) {} async run(task: DiscoveryTask): Promise<MetadataResult> { const startTime = Date.now(); try { const result = await this.load(task); this.recordMetrics({ ...task.metrics, duration: Date.now() - startTime, cacheHit: result.fromCache, result: result.data, }); return result.data; } catch (error: unknown) { this.recordMetrics({ ...task.metrics, duration: Date.now() - startTime, cacheHit: false, result: { attributes: [] }, error, }); task.onError(error); } } private async load({ cacheKey, cacheTtl, useCache = true, loader, }: DiscoveryTask): Promise<CachedMetadataResult> { if (useCache) { return this.cacheService.getOrLoad(cacheKey, loader, cacheTtl); } const data = await loader(); return { data, fromCache: false, }; } private recordMetrics({ resourceType, objectSlug, duration, cacheHit, result, error, }: { resourceType: UniversalResourceType; objectSlug?: string; duration: number; cacheHit: boolean; result: MetadataResult | undefined; error?: unknown; }): void { const attributeCount = Array.isArray(result?.attributes) ? result.attributes.length : 0; this.metricsService.record({ resourceType, objectSlug, duration, cacheHit, attributeCount, error: error ? this.formatError(error) : undefined, }); } private formatError(error: unknown): string { if (error instanceof Error) { return error.message; } try { return JSON.stringify(error); } catch { return String(error); } } }

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/kesslerio/attio-mcp-server'

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