Skip to main content
Glama
README.md
# Federal Reserve Economic Data MCP Server

> [!NOTE]
> This open-source project is not affiliated with, sponsored by, or endorsed by the *Federal Reserve* or the *Federal Reserve Bank of St. Louis*. "FRED" is a registered trademark of the *Federal Reserve Bank of St. Louis*, used here for descriptive purposes only.

A production-grade [Model Context Protocol](https://modelcontextprotocol.io/) server for [FRED®](https://fred.stlouisfed.org/) economic data. Covers all **31 endpoints** exposed by [fred-py-api](https://github.com/zachspar/fred-py-api).

## Features

- Full FRED API v1 coverage: series, categories, releases, sources, and tags
- FastMCP 3.x with structured tool output and proper `ToolError` handling
- Dual-mode credentials: environment variable (stdio) or per-client HTTP header (remote BYOK)
- Transports: `stdio`, `streamable-http`, and `sse`
- Docker image published to GHCR

## Installation

```bash
pip install fred-mcp
```

Requires Python 3.10+.

Get a free FRED API key at [fredaccount.stlouisfed.org/apikey](https://fredaccount.stlouisfed.org/apikey).

## Setup

### Remote hosted server (recommended)

Use the public hosted server with **bring your own key** (BYOK): no install and no shared server-side API key. Each client sends its own FRED API key in the `X-FRED-API-Key` header.

Transport: **streamable HTTP**. Endpoint: `https://fred-mcp-prod.fly.dev/mcp`.

Add this to your MCP client's configuration file and restart the client:

```json
{
  "mcpServers": {
    "fred-mcp": {
      "url": "https://fred-mcp-prod.fly.dev/mcp",
      "headers": {
        "X-FRED-API-Key": "<your fred api key>"
      }
    }
  }
}
```

Programmatic example with the FastMCP client:

```python
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport

transport = StreamableHttpTransport(
    "https://fred-mcp-prod.fly.dev/mcp",
    headers={"X-FRED-API-Key": "your_fred_api_key"},
)
async with Client(transport=transport) as client:
    await client.ping()
```

### Local (stdio)

For clients that spawn a local process, install [fred-mcp](#installation) and use:

```json
{
  "mcpServers": {
    "fred-mcp": {
      "command": "fred-mcp",
      "env": {
        "FRED_API_KEY": "<your fred api key>"
      }
    }
  }
}
```

Or run directly from the terminal:

```bash
export FRED_API_KEY=your_api_key
fred-mcp
```

### Self-hosted HTTP

Deploy your own instance and use the same `url` + `headers` configuration, substituting your host for the endpoint above. **No shared server-side key is required** when clients send `X-FRED-API-Key`.

For public internet deployment, terminate TLS at a reverse proxy (nginx, Caddy, Cloudflare). Do not expose plain HTTP with API keys.

#### Docker

Run the server:

```bash
docker run -d -p 8000:8000 \
  --name fred-mcp-server \
  ghcr.io/zachspar/fred-mcp/fred-mcp-server:latest
```

Connect with your FRED API key in the `X-FRED-API-Key` header (same JSON shape as the remote hosted example, with `url` set to your deployment).

For stdio via Docker:

```json
{
  "mcpServers": {
    "fred-mcp": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_SERVER_TRANSPORT=stdio",
        "-e", "FRED_API_KEY=<your fred api key>",
        "ghcr.io/zachspar/fred-mcp/fred-mcp-server:latest"
      ]
    }
  }
}
```

#### Optional server-side fallback key

Set `FRED_API_KEY` on the server for clients that cannot send custom headers. Header takes precedence when both are present.

| Variable | Default | Description |
|----------|---------|-------------|
| `FRED_API_KEY` | — | FRED API key (required for stdio; optional HTTP fallback) |
| `FRED_API_KEY_HEADER` | `X-FRED-API-Key` | HTTP header name for BYOK |
| `MCP_SERVER_TRANSPORT` | `stdio` | `stdio`, `streamable-http`, or `sse` |
| `MCP_SERVER_HOST` | `localhost` | Bind host for HTTP transports |
| `MCP_SERVER_PORT` | `8000` | Bind port for HTTP transports |

## Tools (31)

### Series

| Tool | Description |
|------|-------------|
| `get_series` | Series metadata |
| `get_series_categories` | Categories for a series |
| `get_series_observations` | Data values / observations |
| `get_series_release` | Release that publishes a series |
| `search_series` | Search series by text or ID |
| `search_series_tags` | Tags for a series search |
| `search_series_related_tags` | Related tags for a series search |
| `get_series_tags` | Tags on a series |
| `get_series_updates` | Recently updated series |
| `get_series_vintage_dates` | Vintage / revision dates |

### Categories

| Tool | Description |
|------|-------------|
| `get_category` | Category metadata |
| `get_category_children` | Child categories |
| `get_category_related` | Related categories |
| `get_category_series` | Series in a category |
| `get_category_tags` | Tags in a category |
| `get_category_related_tags` | Related tags in a category |

### Releases

| Tool | Description |
|------|-------------|
| `list_releases` | All releases |
| `list_release_dates` | Release dates across releases |
| `get_release` | Release metadata |
| `get_release_dates` | Dates for one release |
| `get_release_series` | Series in a release |
| `get_release_sources` | Sources for a release |
| `get_release_tags` | Tags for a release |
| `get_release_related_tags` | Related tags for a release |
| `get_release_tables` | Release tables |

### Sources

| Tool | Description |
|------|-------------|
| `list_sources` | All data sources |
| `get_source` | Source metadata |
| `get_source_releases` | Releases from a source |

### Tags

| Tool | Description |
|------|-------------|
| `list_tags` | Search / list tags |
| `get_related_tags` | Related tags |
| `get_tags_series` | Series matching tags |

## Migration from 0.x

Version 1.0.0 renames tools to snake_case and upgrades to FastMCP 3.x.

| Old name (0.x) | New name (1.0) |
|----------------|----------------|
| `FREDSeries` | `get_series` |
| `FREDSeriesCategories` | `get_series_categories` |
| `FREDSeriesObservations` | `get_series_observations` |
| `FREDSeriesRelease` | `get_series_release` |
| `FREDSeriesSearch` | `search_series` |
| `FREDSeriesSearchTags` | `search_series_tags` |
| `FREDSeriesSearchRelatedTags` | `search_series_related_tags` |
| `FREDSeriesTags` | `get_series_tags` |
| `FREDSeriesUpdates` | `get_series_updates` |
| `FREDSeriesVintageDates` | `get_series_vintage_dates` |

21 additional tools were added for categories, releases, sources, and tags.

Error responses now use MCP `ToolError` (`isError: true`) instead of `{"error": ...}` payloads.

## Development

```bash
python3.13 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check src tests
```

## License

MIT

TDQS

B3.3/5.0

Scored across 31 tools

Disambiguation4/5

Most tools have clearly distinct purposes based on resource and action, but reverse relationships like get_source_releases vs get_release_sources and the many tag-related variants (e.g., get_related_tags, get_category_related_tags) could cause confusion if descriptions are not carefully read. Overall, the names and descriptions do an adequate job of disambiguating.

Naming Consistency4/5

The server generally follows a get_<resource>_<detail> pattern with list_ and search_ prefixes for broader operations. However, there are minor inconsistencies such as get_series_updates (a listing operation) and the confusing name get_tags_series (which returns series, not tags) that deviate from the otherwise predictable scheme.

Tool Count2/5

With 31 tools, the server exceeds the typical range and feels heavy. While the FRED API is broad, the tool set could be consolidated, especially the many tag-related and reverse-relationship tools, without losing functionality.

Completeness5/5

The tool set provides comprehensive coverage of FRED's data model, including series metadata, observations, categories, releases, sources, and tags, as well as search and vintage date functionality. No obvious gaps are apparent for the server's stated purpose.

Maintenance

ActivityInactive
ResponsivenessNo issues