UNPKG

tesouro-direto-mcp

Version:

Model Context Protocol (MCP) server for Tesouro Direto API integration

101 lines (100 loc) 3.17 kB
import { logger } from '../utils/logger.js'; import { fetchTesouroDiretoAPI } from '../api/tesouroDireto.js'; // Cache duration in milliseconds (10 minutes) const CACHE_DURATION_MS = 10 * 60 * 1000; // Cache configuration const cacheConfig = { isEnabled: process.env.USE_MCP_CACHE !== 'false', durationMs: CACHE_DURATION_MS }; let cachedData = null; /** * Helper function to check if cache is enabled and log if disabled */ function withCache(operation, fn) { if (!cacheConfig.isEnabled) { logger.debug(`Cache is disabled via USE_MCP_CACHE environment variable, skipping ${operation}`); return null; } return fn(); } /** * Checks if the cached data is valid based on the BizSts timestamp */ export function isCacheValid() { return withCache('cache validation', () => { if (!cachedData) return false; const now = new Date(); const bizTime = new Date(cachedData.bizTimestamp); const bizAge = now.getTime() - bizTime.getTime(); logger.debug("Cache BizSts age is " + (bizAge / 1000) + " seconds"); // Check if BizSts timestamp is less than 10 minutes old return bizAge < cacheConfig.durationMs; }) ?? false; } /** * Gets data from cache if valid, otherwise returns null */ export function getFromCache() { return withCache('cache retrieval', () => { if (isCacheValid()) { logger.info('Returning data from cache, BizSts age: ' + ((new Date().getTime() - new Date(cachedData.bizTimestamp).getTime()) / 1000) + ' seconds'); return cachedData.data; } logger.info('Cache invalid or expired'); return null; }); } /** * Stores API response in cache */ export function storeInCache(data) { withCache('cache storage', () => { cachedData = { data, timestamp: new Date().toISOString(), bizTimestamp: data.BizSts.dtTm }; logger.info(`Data cached with BizSts timestamp: ${data.BizSts.dtTm}`); }); } /** * Checks if the new data has a different BizSts timestamp than the cached data * Used to determine if we should update the cache */ export function hasNewData(newData) { if (!cacheConfig.isEnabled) return true; if (!cachedData) return true; return cachedData.bizTimestamp !== newData.BizSts.dtTm; } /** * Clears the cache */ export function clearCache() { withCache('cache clearing', () => { cachedData = null; logger.info('Cache cleared'); }); } /** * Gets API data with caching logic * Attempts to get data from cache first, falls back to API if needed */ export async function getApiDataWithCache(context = 'API request') { // Try to get data from cache first let responseData = getFromCache(); // If nothing in cache, fetch from API if (!responseData) { logger.info(`Fetching fresh data for ${context}`); responseData = await fetchTesouroDiretoAPI(); // Store in cache if it's new data if (hasNewData(responseData)) { storeInCache(responseData); } } return responseData; }