Skip to main content
Glama
Jaldekoa
by Jaldekoa

get_fred_series_observations

Retrieve economic time series observations from the Federal Reserve Bank of St. Louis (FRED) database to analyze historical data trends and economic indicators.

Instructions

Get series observations from the Fred API.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
series_idYesThe id for a series.
realtime_startNoThe start of the real-time period. Format: YYYY-MM-DD. Defaults to today's date.
realtime_endNoThe end of the real-time period. Format: YYYY-MM-DD. Defaults to today's date.
limitNoMaximum number of observations to return. Defaults to 10.
offsetNoNumber of observations to offset from first. Defaults to 0.
sort_orderNoSort order of observations. Options: 'asc' or 'desc'. Defaults to 'asc'.asc
observation_startNoStart date of observations. Format: YYYY-MM-DD.
observation_endNoEnd date of observations. Format: YYYY-MM-DD.
unitsNoData value transformation. Options: 'lin', 'chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log'. Defaults to 'lin'.lin
frequencyNoFrequency of observations. Options: 'd', 'w', 'bw', 'm', 'q', 'sa', 'a', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem'. Defaults to no value for no frequency aggregation.
aggregation_methodNoAggregation method for frequency. Options: 'avg', 'sum', 'eop'. Defaults to 'avg'.avg
output_typeNoOutput type of observations. Options: 1, 2, 3, 4. Defaults to 1.
vintage_datesNoComma-separated list of vintage dates.

Implementation Reference

  • server.py:30-93 (handler)
    The @mcp.tool decorated async function implementing the get_fred_series_observations tool. Handles input parameters, constructs API params, calls the make_request helper to fetch data from FRED API endpoint /series/observations, and returns the observations list.
    @mcp.tool(name="get_fred_series_observations", description="""Get series observations from the Fred API.""")
    async def get_fred_series_observations(
        series_id: Annotated[str, Field(description="The id for a series.")],
        realtime_start: Annotated[Optional[str], Field(description="The start of the real-time period. Format: YYYY-MM-DD. Defaults to today's date.")] = None,
        realtime_end: Annotated[Optional[str], Field(description="The end of the real-time period. Format: YYYY-MM-DD. Defaults to today's date.")] = None,
        limit: Annotated[Optional[int | str], Field(description="Maximum number of observations to return. Defaults to 10.")] = 10,
        offset: Annotated[Optional[int | str], Field(description="Number of observations to offset from first. Defaults to 0.")] = 0,
        sort_order: Annotated[Literal['asc', 'desc'], Field(description="Sort order of observations. Options: 'asc' or 'desc'. Defaults to 'asc'.")] = 'asc',
        observation_start: Annotated[Optional[str], Field(description="Start date of observations. Format: YYYY-MM-DD.")] = None,
        observation_end: Annotated[Optional[str], Field(description="End date of observations. Format: YYYY-MM-DD.")] = None,
        units: Annotated[Literal['lin', 'chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log'], Field(description="Data value transformation. Options: 'lin', 'chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log'. Defaults to 'lin'.")] = 'lin',
        frequency: Annotated[Literal['d', 'w', 'bw', 'm', 'q', 'sa', 'a', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem'], Field(description="Frequency of observations. Options: 'd', 'w', 'bw', 'm', 'q', 'sa', 'a', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem'. Defaults to no value for no frequency aggregation.")] = None,
        aggregation_method: Annotated[Literal['avg', 'sum', 'eop'], Field(description="Aggregation method for frequency. Options: 'avg', 'sum', 'eop'. Defaults to 'avg'.")] = 'avg',
        output_type: Annotated[Literal[1, 2, 3, 4], Field(description="Output type of observations. Options: 1, 2, 3, 4. Defaults to 1.")] = 1,
        vintage_dates: Annotated[Optional[str], Field(description="Comma-separated list of vintage dates.")] = None,
    ):
        """Get series observations from the Fred API.
        
        Args:
            series_id (str): The id for a series.
            realtime_start (str): The start of the real-time period. YYYY-MM-DD formatted string, optional, default: today's date.
            realtime_end (str): The end of the real-time period. YYYY-MM-DD formatted string, optional, default: today's date.
            limit (int or str): The maximum number of observations to return. Optional, default: 1000.
            offset (int or str): The number of observations to offset from the first observation. Optional, default: 0.
            sort_order (str): The sort order of the observations. Possible values: "asc" or "desc". Optional, default: "asc".
            observation_start (str): The start date of the observations to get. YYYY-MM-DD formatted string. Optional, default: 1776-07-04 (earliest available).
            observation_end (str): The end date of the observations to get. YYYY-MM-DD formatted string. Optional, default: 9999-12-31 (latest available).
            units (str): A key that indicates a data value transformation. Posible values: 'lin', 'chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log'. Optional, default: 'lin' (No transformation).
            frequency (str): The frequency of the observations. Posible values: 'd', 'w', 'bw', 'm', 'q', 'sa', 'a', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem'. Optional, default: no value for no frequency aggregation.
            aggregation_method (str): A key that indicates the aggregation method used for frequency aggregation. This parameter has no affect if the frequency parameter is not set. Posible values: 'avg', 'sum', 'eop'. Optional, default: "avg".
            output_type (int): The output type of the observations. Optional, default: 1.
            vintage_dates (str): A comma-separated list of vintage dates to return. Optional, default: no vintage dates are set by default.
    
        Returns:
            dict[str, str]: A dictionary containing the observations or data values for an economic data series.
        """
        params = {
            "series_id": series_id, # ✅
            "realtime_start": realtime_start, # ❌
            "realtime_end": realtime_end, # ❌
            "limit": limit, # ✅
            "offset": offset, # ✅
            "sort_order": sort_order, # ✅
            "observation_start": observation_start, # ❌
            "observation_end": observation_end, # ❌
            "units": units, # ✅
            "frequency": frequency, # ✅
            "aggregation_method": aggregation_method, # ✅
            "output_type": output_type, # ✅
            "vintage_dates": vintage_dates, # ❌
            "file_type": "json"
        }
        
        data = await make_request(f"{FRED_API_URL}/series/observations", params)
    
        if not data:
            raise ConnectionError("Failed to fetch data from the FRED API")
        
        observations = data["observations"]
    
        if not observations:
            raise ValueError("No observations found for the given series")
        
        return observations
  • Input schema defined in the function parameters using Annotated with Pydantic Field for validation, descriptions, and types (e.g., series_id: str, limit: Optional[int|str], etc.).
    async def get_fred_series_observations(
        series_id: Annotated[str, Field(description="The id for a series.")],
        realtime_start: Annotated[Optional[str], Field(description="The start of the real-time period. Format: YYYY-MM-DD. Defaults to today's date.")] = None,
        realtime_end: Annotated[Optional[str], Field(description="The end of the real-time period. Format: YYYY-MM-DD. Defaults to today's date.")] = None,
        limit: Annotated[Optional[int | str], Field(description="Maximum number of observations to return. Defaults to 10.")] = 10,
        offset: Annotated[Optional[int | str], Field(description="Number of observations to offset from first. Defaults to 0.")] = 0,
        sort_order: Annotated[Literal['asc', 'desc'], Field(description="Sort order of observations. Options: 'asc' or 'desc'. Defaults to 'asc'.")] = 'asc',
        observation_start: Annotated[Optional[str], Field(description="Start date of observations. Format: YYYY-MM-DD.")] = None,
        observation_end: Annotated[Optional[str], Field(description="End date of observations. Format: YYYY-MM-DD.")] = None,
        units: Annotated[Literal['lin', 'chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log'], Field(description="Data value transformation. Options: 'lin', 'chg', 'ch1', 'pch', 'pc1', 'pca', 'cch', 'cca', 'log'. Defaults to 'lin'.")] = 'lin',
        frequency: Annotated[Literal['d', 'w', 'bw', 'm', 'q', 'sa', 'a', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem'], Field(description="Frequency of observations. Options: 'd', 'w', 'bw', 'm', 'q', 'sa', 'a', 'wef', 'weth', 'wew', 'wetu', 'wem', 'wesu', 'wesa', 'bwew', 'bwem'. Defaults to no value for no frequency aggregation.")] = None,
        aggregation_method: Annotated[Literal['avg', 'sum', 'eop'], Field(description="Aggregation method for frequency. Options: 'avg', 'sum', 'eop'. Defaults to 'avg'.")] = 'avg',
        output_type: Annotated[Literal[1, 2, 3, 4], Field(description="Output type of observations. Options: 1, 2, 3, 4. Defaults to 1.")] = 1,
        vintage_dates: Annotated[Optional[str], Field(description="Comma-separated list of vintage dates.")] = None,
    ):
  • server.py:30-30 (registration)
    Tool registration decorator @mcp.tool(name="get_fred_series_observations", description=...).
    @mcp.tool(name="get_fred_series_observations", description="""Get series observations from the Fred API.""")
  • make_request helper function that performs authenticated async HTTP GET requests to FRED API using httpx, adding API key from env.
    async def make_request(url: str, params: dict):
        """Make a request to the Federal Reserve Economic Data API."""
        
        if FRED_API_KEY := os.getenv("FRED_API_KEY"):
            params["api_key"] = FRED_API_KEY
    
        async with httpx.AsyncClient() as client:
            try:
                response = await client.get(url, params=params)
                response.raise_for_status()
                return response.json()
    
            except httpx.HTTPStatusError as e:
                raise ConnectionError(f"Failed to fetch data from the FRED API: {e}")
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It states 'Get series observations' which implies a read-only operation, but doesn't mention any behavioral traits like rate limits, authentication requirements, error handling, or what the return format looks like (e.g., JSON structure, pagination). This leaves significant gaps for an API tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence with zero waste—it directly states the tool's function without unnecessary words. It's appropriately sized for a tool with a clear name and detailed schema, though it could benefit from more context.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity (13 parameters, no output schema, no annotations), the description is incomplete. It doesn't explain the output format, error conditions, or typical usage patterns. For a data retrieval tool with many filtering options, more guidance on what 'observations' entail and how results are structured is needed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, meaning all parameters are well-documented in the schema itself. The description adds no additional meaning beyond the schema—it doesn't explain parameter interactions, provide examples, or clarify complex concepts like 'realtime period' vs. 'observation period'. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Get series observations from the Fred API' states the basic action (get) and resource (series observations), but it's vague about what 'observations' means in this context (e.g., economic data points over time). With no sibling tools, it doesn't need differentiation, but the purpose lacks specificity about the nature of the data being retrieved.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, prerequisites, or typical use cases. With no sibling tools, it doesn't need sibling differentiation, but it offers no context about appropriate scenarios (e.g., retrieving historical economic indicators).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/Jaldekoa/mcp-fredapi'

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