Forex Factory Calendar MCP
by atirek-pro
README.md
# π Forex Factory Calendar MCP
> A Python-based Forex Factory economic calendar collector and **MCP server** that transforms Forex Factory's weekly calendar data into structured, enriched event data for AI agents.
[](https://www.python.org/)
[](https://gofastmcp.com/)
[](https://fastapi.tiangolo.com/)
[](https://modelcontextprotocol.io/)
---
## π Overview
**Forex Factory Calendar MCP** collects economic calendar data from Forex Factory, enriches events with detailed information, stores the resulting dataset as JSON, and exposes the data through the **Model Context Protocol (MCP)**.
The project combines:
- π₯ Forex Factory weekly JSON data
- π Forex Factory calendar HTML
- π Event ID extraction
- π§© Event matching and enrichment
- π° Event detail information
- πΎ Structured JSON output
- π MCP tools
- π MCP resources
- β‘ FastAPI HTTP transport
The goal is to make Forex Factory economic-calendar data easily consumable by **AI agents and MCP-compatible applications**.
---
# ποΈ Architecture
```text
ββββββββββββββββββββββββ
β Forex Factory β
ββββββββββββ¬ββββββββββββ
β
ββββββββββββββββββ΄βββββββββββββββββ
β β
βΌ βΌ
Weekly Calendar JSON Calendar HTML
β β
βΌ βΌ
Basic Events Event IDs / Metadata
β β
ββββββββββββββββββ¬βββββββββββββββββ
βΌ
Event Matching
β
βΌ
Event Detail Endpoint
β
βΌ
Enriched Event Dataset
β
βΌ
ββββββββββββββββββββββ
β JSON Store β
β /data β
βββββββββββ¬βββββββββββ
β
ββββββββββββββββ΄βββββββββββββββ
β β
βΌ βΌ
FastMCP Tools MCP Resource
β β
β β
βΌ βΌ
get_forex_calendar() events://all
get_calendar_stats()
β β
ββββββββββββββββ¬βββββββββββββββ
βΌ
MCP Client
β
βΌ
AI Agent
```
---
# β¨ Features
| Feature | Description |
| ------------------ | --------------------------------------------------- |
| π
Weekly Calendar | Fetches Forex Factory's current-week calendar |
| π HTML Parsing | Extracts event IDs and additional metadata |
| π Event Matching | Matches JSON events with HTML calendar rows |
| π° Event Details | Fetches detailed information for identified events |
| πΎ JSON Storage | Saves the enriched calendar locally |
| π§ Configurable | Supports detail-impact filtering and request delays |
| π MCP Tools | Exposes calendar operations as MCP tools |
| π MCP Resource | Exposes calendar data through `events://all` |
| β‘ FastAPI | Makes the MCP server available over HTTP |
| π§ͺ Inspectable | Supports FastMCP inspection and CLI testing |
---
# π Data Collection Pipeline
The collector currently follows this pipeline:
```text
1. Fetch Weekly JSON
β
βΌ
2. Normalize Calendar Events
β
βΌ
3. Fetch Calendar HTML
β
βΌ
4. Parse Calendar Rows
β
βΌ
5. Extract Event IDs
β
βΌ
6. Match HTML β JSON Events
β
βΌ
7. Fetch Event Details
β
βΌ
8. Enrich Events
β
βΌ
9. Save JSON Dataset
```
---
# π‘ Data Sources
## 1. Forex Factory Weekly JSON
The initial calendar data is fetched from:
```text
https://nfs.faireconomy.media/ff_calendar_thisweek.json
```
The feed provides fields such as:
- Date / time
- Currency
- Impact
- Event title
- Actual
- Forecast
- Previous
---
## 2. Forex Factory Calendar HTML
The collector also requests:
```text
https://www.forexfactory.com/calendar
```
The HTML is required because the weekly JSON feed does not currently provide the Forex Factory `event_id`.
The parser looks for calendar rows containing:
```html
<tr class="calendar__row" data-event-id="..."></tr>
```
The extracted event ID is then associated with the normalized calendar event.
---
## 3. Event Details
Once an event ID has been identified, the collector requests:
```text
https://www.forexfactory.com/calendar/details/1-{event_id}
```
The response can contain information such as:
- Event specifications
- Description
- Source
- Speaker
- Usual Effect
- FF Notes
- Why Traders Care
- Historical information
- Linked discussion threads
The current implementation stores the raw detail response under the event's `news` field.
---
# π¦ Output
Generated calendar files are stored inside:
```text
data/
```
The current tool generates files using:
```text
forex_calendar_YYYY-MM-DD.json
```
Example:
```text
data/
βββ forex_calendar_2026-09-04.json
```
A typical top-level response looks like:
```json
{
"source": "Forex Factory",
"fetched_at": "...",
"total_events": 0,
"events_with_event_id": 0,
"events_with_news": 0,
"events": []
}
```
### Event Structure
```json
{
"event_id": "146911",
"datetime": "2026-09-04T12:30:00-04:00",
"timestamp": "2026-09-04T16:30:00+00:00",
"currency": "USD",
"impact": "High",
"event": "Non-Farm Employment Change",
"actual": null,
"forecast": "75K",
"previous": "73K",
"event_url": null,
"graph_url": null,
"news": {}
}
```
---
# π MCP Integration
The project now exposes the collector through **FastMCP**.
The MCP layer currently provides:
### π οΈ Tools
#### `get_forex_calendar`
Fetches the complete current-week Forex Factory calendar.
Parameters:
```text
save_to_file: bool = True
output_filename: str | None = None
```
Example:
```text
get_forex_calendar(save_to_file=true)
```
---
#### `get_calendar_stats`
Returns summary statistics for the current calendar.
Example response:
```json
{
"total_events": 113,
"high_impact": 25,
"medium_impact": 41,
"low_impact": 47,
"events_with_news": 45,
"fetched_at": "..."
}
```
---
# π MCP Resources
The server currently exposes one MCP resource:
```text
events://all
```
This resource provides the calendar dataset as JSON.
Conceptually:
```text
MCP Client
β
β resources/list
βΌ
events://all
β
β resources/read
βΌ
Calendar JSON
```
The resource is declared using:
```python
@mcp.resource(
"events://all",
name="Forex Factory Events",
description="Forex Factory economic calendar events for the current week",
mime_type="application/json",
)
def get_events() -> str:
...
```
> **Note:** The current test implementation reads `data/test_output.json`, while `get_forex_calendar()` currently generates `forex_calendar_YYYY-MM-DD.json`. These should be unified so `events://all` always exposes the latest generated dataset.
---
# β‘ FastAPI Integration
FastMCP is exposed through FastAPI using Streamable HTTP.
The architecture is:
```text
FastAPI
β
ββββββββββββββ΄βββββββββββββ
β β
βΌ βΌ
/health /mcp
β
βΌ
FastMCP
βββββββ΄ββββββ
β β
βΌ βΌ
Tools Resources
```
The MCP HTTP application is mounted under:
```text
/mcp
```
Resulting endpoint:
```text
http://127.0.0.1:8000/mcp
```
---
# π§° Installation
Clone the project and create a virtual environment:
```bash
python -m venv .venv
```
Activate it on Windows:
```bash
.venv\Scripts\activate
```
Install dependencies:
```bash
pip install requests beautifulsoup4 tqdm fastmcp fastapi uvicorn
```
---
# βΆοΈ Running the Server
## Run FastAPI + MCP
Start the HTTP server with:
```bash
uvicorn server:app --reload
```
The API will be available at:
```text
http://127.0.0.1:8000
```
Health check:
```text
http://127.0.0.1:8000/health
```
MCP endpoint:
```text
http://127.0.0.1:8000/mcp
```
> `/mcp` is an MCP protocol endpoint and should be accessed by an MCP client rather than treated as a normal browser page.
---
# π§ͺ Testing
## Inspect the local MCP server
```bash
fastmcp inspect server.py
```
For the complete FastMCP representation:
```bash
fastmcp inspect server.py --format fastmcp
```
---
## List MCP tools
```bash
fastmcp list http://127.0.0.1:8000/mcp
```
Expected:
```text
Tools (2)
get_forex_calendar(...)
get_calendar_stats()
```
---
## List tools + resources
Use:
```bash
fastmcp list http://127.0.0.1:8000/mcp --resources
```
Expected resources include:
```text
events://all
```
For machine-readable output:
```bash
fastmcp list http://127.0.0.1:8000/mcp --resources --json
```
---
# π Project Structure
```text
Forex-Factory-MCP/
β
βββ server.py
β βββ FastMCP server
β βββ MCP tools
β βββ MCP resources
β βββ FastAPI application
β
βββ scrapper.py
β βββ Calendar JSON collection
β βββ Calendar HTML parsing
β βββ Event matching
β βββ Event detail enrichment
β
βββ config.py
β βββ URLs
β βββ Request delay
β βββ Detail impact configuration
β βββ HTTP headers
β βββ Output directory
β
βββ data/
β βββ Generated calendar JSON files
β
βββ README.md
β
βββ .venv/
```
---
# βοΈ Configuration
Configuration is centralized in `config.py`.
### Request Delay
```python
REQUEST_DELAY = 1.5
```
This introduces a delay between requests to avoid making requests too aggressively.
### Detail Impact Filter
```python
DETAIL_IMPACTS = None
```
Current behavior:
```text
None
β
Fetch details for every event with an event_id
```
You can restrict detail fetching:
```python
DETAIL_IMPACTS = {"High"}
```
or:
```python
DETAIL_IMPACTS = {"High", "Medium"}
```
---
# β οΈ Current Limitations
## Event ID Matching
The biggest current limitation is matching the weekly JSON events against the HTML calendar.
The pipeline currently relies on:
```text
Weekly JSON
β
Calendar HTML
```
A typical run can produce:
```text
Fetched 113 events from JSON feed
Found 121 calendar HTML rows
Extracted 45 events with event IDs
Matched: 45
Unmatched: 68
```
Events without an `event_id` cannot currently receive detailed event information.
Improving event-ID resolution is therefore a major priority.
---
## Fixed Weekly Source
The current JSON source is:
```text
ff_calendar_thisweek.json
```
Therefore, the collector currently relies on Forex Factory's definition of **"this week"** rather than accepting arbitrary date ranges.
---
## Calendar URL
The HTML collector currently uses:
```text
https://www.forexfactory.com/calendar
```
A future implementation should use an explicit date-range URL.
---
## Timezone Handling
Timezone handling is not yet exposed as an input to the MCP tools.
Future versions are expected to support IANA timezone names such as:
```text
Asia/Kolkata
America/New_York
Europe/London
Asia/Tokyo
UTC
```
---
## Resource/Data Synchronization
The current MCP resource reads:
```text
data/test_output.json
```
while the calendar tool generates:
```text
data/forex_calendar_YYYY-MM-DD.json
```
This is temporary and should be changed so the resource always points to the latest generated weekly dataset.
---
# πΊοΈ Roadmap
## π΄ High Priority
- [ ] Improve JSON β HTML event matching
- [ ] Make event IDs the primary downstream identifier
- [ ] Use explicit Forex Factory date-range URLs
- [ ] Unify MCP resource with the latest generated JSON
- [ ] Improve timezone-aware date handling
- [ ] Improve HTTP error handling
- [ ] Add retry/backoff behavior
- [ ] Handle malformed Forex Factory responses gracefully
## π‘ MCP Layer
- [x] Implement FastMCP
- [x] Add `get_forex_calendar`
- [x] Add `get_calendar_stats`
- [x] Add `events://all` resource
- [x] Expose MCP through FastAPI
- [ ] Improve resource/data synchronization
- [ ] Add timezone-aware inputs
- [ ] Add date-range support
- [ ] Improve LLM-friendly response structures
## π’ Data Layer
- [x] Weekly JSON collection
- [x] Calendar HTML collection
- [x] Event ID extraction
- [x] Event matching
- [x] Event detail collection
- [x] JSON persistence
- [ ] Cleaner normalized event-detail schema
---
# π§ Design Principles
The long-term architecture separates the system into three layers:
```text
βββββββββββββββββββββββββββββββββββββββββββ
β MCP Layer β
β β
β Tools β
β Resources β
β Input validation β
β Agent-facing responses β
ββββββββββββββββββββββ¬βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Domain / Collector Layer β
β β
β Date handling β
β Timezone handling β
β Calendar collection β
β Event matching β
β Event enrichment β
ββββββββββββββββββββββ¬βββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Forex Factory β
β β
β Weekly JSON β
β Calendar HTML β
β Event detail endpoint β
βββββββββββββββββββββββββββββββββββββββββββ
```
This keeps the scraping and data-collection logic independent from the MCP protocol.
The collector should remain reusable even when the data is consumed outside an AI-agent environment.
---
# π Responsible Usage
This project relies on publicly accessible Forex Factory pages/endpoints and scraping behavior rather than an official Forex Factory developer API.
The collector should therefore:
- Respect Forex Factory's terms and policies.
- Use reasonable request rates.
- Avoid unnecessary repeated requests.
- Handle changes to the site's HTML structure gracefully.
- Avoid excessive requests to the service.
HTML selectors and endpoint behavior may change over time.
---
# π― Project Goal
The long-term goal is to build a reliable, timezone-aware Forex Factory economic-calendar service that provides high-quality structured data to AI agents through MCP.
The project is evolving toward:
```text
Forex Factory
β
βΌ
Data Collection
β
βΌ
Event Enrichment
β
βΌ
Structured Dataset
β
βΌ
FastMCP
β
βββββββββββββββββ
βΌ βΌ
Tools Resources
β β
βββββββββ¬ββββββββ
βΌ
AI Agents
```
The current focus is improving **data quality, event-ID resolution, MCP resource consistency, and timezone-aware calendar handling**.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues