fred-mcp-server
Version:
Federal Reserve Economic Data (FRED) MCP Server - Access all 800,000+ economic time series with search, browse, and data retrieval capabilities
88 lines (87 loc) • 3.63 kB
JavaScript
/**
* FRED Series Data API Client
*
* Provides functionality for fetching series data and metadata
*/
import { makeRequest } from "../common/request.js";
import { getSeriesInfo } from "./search.js";
/**
* Fetches data for any FRED series with enhanced options
*/
export async function getSeriesData(options) {
try {
const { series_id, ...queryOptions } = options;
if (!series_id) {
throw new Error("series_id is required");
}
// Prepare query parameters
const queryParams = {
series_id
};
// Add optional parameters
if (queryOptions.observation_start)
queryParams.observation_start = queryOptions.observation_start;
if (queryOptions.observation_end)
queryParams.observation_end = queryOptions.observation_end;
if (queryOptions.limit !== undefined)
queryParams.limit = queryOptions.limit;
if (queryOptions.offset !== undefined)
queryParams.offset = queryOptions.offset;
if (queryOptions.sort_order)
queryParams.sort_order = queryOptions.sort_order;
if (queryOptions.units)
queryParams.units = queryOptions.units;
if (queryOptions.frequency)
queryParams.frequency = queryOptions.frequency;
if (queryOptions.aggregation_method)
queryParams.aggregation_method = queryOptions.aggregation_method;
if (queryOptions.output_type !== undefined)
queryParams.output_type = queryOptions.output_type;
if (queryOptions.vintage_dates)
queryParams.vintage_dates = queryOptions.vintage_dates;
// Fetch the series data
const dataResponse = await makeRequest("series/observations", queryParams);
// Try to get series metadata (but don't fail if it's not available)
let seriesInfo = null;
try {
const infoResponse = await getSeriesInfo(series_id);
if (infoResponse.content && infoResponse.content[0]) {
seriesInfo = JSON.parse(infoResponse.content[0].text);
}
}
catch (error) {
console.error(`Could not fetch series info for ${series_id}:`, error);
}
// Transform the data for easier consumption
const formattedData = dataResponse.observations.map(obs => ({
date: obs.date,
value: obs.value === "." ? null : parseFloat(obs.value)
}));
const responseData = {
series_id,
title: seriesInfo?.title || `FRED Series: ${series_id}`,
units: seriesInfo?.units || (queryOptions.units ? `Transformed (${queryOptions.units})` : "Value"),
frequency: seriesInfo?.frequency || "Unknown",
seasonal_adjustment: seriesInfo?.seasonal_adjustment || "Unknown",
observation_range: seriesInfo?.observation_range || `${dataResponse.observation_start} to ${dataResponse.observation_end}`,
total_observations: dataResponse.count,
data_offset: dataResponse.offset,
data_limit: dataResponse.limit,
source: "Federal Reserve Economic Data (FRED)",
notes: seriesInfo?.notes,
data: formattedData
};
return {
content: [{
type: "text",
text: JSON.stringify(responseData, null, 2)
}]
};
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to retrieve series data: ${error.message}`);
}
throw error;
}
}