npm package: @missionsquad/mcp-ercot
Description: MCP server for ERCOT Public API (DAM and RTM data)
Author: Mission Squad AI
Latest version: 1.0.2

# ERCOT MCP Server (mcp-ercot)

A Model Context Protocol (MCP) server for accessing ERCOT (Electric Reliability Council of Texas) public API data, focusing on Day-Ahead Market (DAM) and Real-Time Market (RTM) information. Built with Node.js, TypeScript, and `@missionsquad/fastmcp`.

## Overview

This server exposes ERCOT API endpoints as tools for Language Learning Models (LLMs). It handles ERCOT's specific authentication mechanism (ID Token + Subscription Key) and provides structured data from various market reports.

**Key Features & Design Principles:**

- **ERCOT API Integration:** Connects to the official ERCOT Public API.
- **Targeted Data:** Focuses on Day-Ahead Market (DAM) and Real-Time Market (RTM) endpoints as specified in the project plan.
  - RTD Indicative LMPs (`/np6-970-cd/rtd_lmp_node_zone_hub`)
  - Real-Time SPPs (`/np6-905-cd/spp_node_zone_hub`)
  - DAM Settlement Point Prices (`/np4-190-cd/dam_stlmnt_pnt_prices`)
  - DAM Clearing Prices for Capacity (`/np4-188-cd/dam_clear_price_for_cap`)
- **Authentication Management:** Implements ERCOT's two-factor authentication (hourly access token and subscription key) via `ErcotAuthenticationService`.
- **Typed API Client:** Uses a TypeScript client generated by `openapi-typescript` from ERCOT's OpenAPI specification (`ercot-openapi-spec-dam-rtm.json`) and `openapi-fetch` for type-safe API interactions.
- **Timestamp Handling:** Correctly processes ERCOT's specific timestamp formats (e.g., `deliveryDate`, `deliveryHour`, `deliveryInterval`) and converts them to standard ISO 8601 UTC timestamps within the `ErcotApiService`, considering the "America/Chicago" timezone.
- **TypeScript & FastMCP:** Utilizes modern TypeScript (v5.3+) for type safety and `@missionsquad/fastmcp` for streamlined MCP server implementation.
- **Configurable:** Uses environment variables for ERCOT credentials, logging, and API behavior (see `.env.example`).
- **Robust Error Handling:** Includes error handling for authentication and API calls, propagating user-friendly errors via `UserError`.

## Who is this server for?

This server is for developers and applications that need to:

- Integrate LLMs with ERCOT market data.
- Access specific DAM and RTM information programmatically.
- Abstract away the complexities of ERCOT API authentication and data parsing.

## Getting Started

### Prerequisites

- Node.js v20 or later
- npm or yarn
- ERCOT Public API Credentials:
  - Username (for token generation)
  - Password (for token generation)
  - Subscription Key (Ocp-Apim-Subscription-Key)

### Setup

1.  **Clone or Copy:**
    ```bash
    git clone <repository-url> mcp-ercot
    cd mcp-ercot
    ```
2.  **Install Dependencies:**
    ```bash
    npm install
    # or
    yarn install
    ```
3.  **Configure Environment:**
    - Copy `.env.example` to `.env`.
    - Edit `.env` and set your ERCOT API credentials:
      - `ERCOT_USERNAME`
      - `ERCOT_PASSWORD`
      - `ERCOT_SUBSCRIPTION_KEY`
    - Adjust `LOG_LEVEL`, `ERCOT_API_RATE_LIMIT_DELAY_MS`, etc., as needed.
4.  **Generate ERCOT API Client Types:**
    This server uses types generated from a filtered ERCOT OpenAPI specification (`ercot-openapi-spec-dam-rtm.json`) focusing on DAM and RTM endpoints. Run the following command to generate the type definitions:
    ```bash
    npm run generate-ercot-client
    # or
    yarn generate-ercot-client
    ```
    This will create/update `src/generated/ercot-api-types.ts`. The server uses these types for interacting with the ERCOT API.
5.  **Build the Project:**
    ```bash
    npm run build
    # or
    yarn build
    ```
6.  **Start the Server:**
    ```bash
    npm start
    # or
    yarn start
    ```
    The server will now listen for MCP requests on stdio.

## Core Concepts

### ERCOT Authentication

The server implements ERCOT's required authentication flow:

1.  **ID Token (Access Token):**
    - An access token is fetched from ERCOT's B2C login endpoint using your `ERCOT_USERNAME` and `ERCOT_PASSWORD`.
    - This token is valid for one hour and is automatically refreshed by the `ErcotAuthenticationService` when needed.
2.  **Subscription Key:**
    - Your `ERCOT_SUBSCRIPTION_KEY` is passed as the `Ocp-Apim-Subscription-Key` header in API requests.
    - This key is static and configured via environment variables.

The `ErcotAuthenticationService` (`src/services/ercot-auth.service.ts`) manages this entire process. Credentials are provided via environment variables and are **not** passed per MCP tool request.

### ERCOT API Service

The `ErcotApiService` (`src/services/ercot-api.service.ts`) wraps the `openapi-fetch` ERCOT API client. It:

- Uses the `ErcotAuthenticationService` to get necessary credentials (access token and subscription key).
- Constructs and sends API requests using the typed client.
- Handles API response parsing and data transformation (including timestamp conversion to ISO 8601 UTC).
- Implements rate limiting based on `ERCOT_API_RATE_LIMIT_DELAY_MS`.

### Available Tools

The server exposes key ERCOT DAM and RTM data points as MCP tools. Refer to the `list_tools` MCP command output for a complete list of available tools, their descriptions, and Zod-defined parameters. The primary tools implemented are:

- `get_rtd_indicative_lmps`: Real-Time Dispatch Indicative LMPs (Report NP6-970-CD).
- `get_spp_node_zone_hub`: Real-Time Settlement Point Prices (Report NP6-905-CD).
- `get_dam_settlement_point_prices`: Day-Ahead Market Settlement Point Prices (Report NP4-190-CD).
- `get_dam_clearing_prices_for_capacity`: Day-Ahead Market Clearing Prices for Ancillary Services (Report NP4-188-CD).
- `get_dam_price_corrections_eblmp`: Day-Ahead Market Price Corrections for EBLMP (Report NP4-196-M).
- `get_dam_shadow_prices`: Day-Ahead Market Shadow Prices for Binding Constraints (Report NP4-191-CD).
- `get_rtm_price_corrections_shadow_prices`: Real-Time Market Price Corrections for Shadow Prices (Report NP4-197-M).
- `get_60_day_dam_energy_only_offers`: 60-Day Disclosed Day-Ahead Market Energy Only Offers (Report NP3-966-ER).
- `get_dam_cleared_ancillary_service_ecrsm`: Day-Ahead Market Cleared ERCOT Contingency Reserve Service - Market (ECRSM) (Report NP3-911-ER).
- `get_60_day_dam_ptp_obligation_bids`: 60-Day Disclosed Day-Ahead Market Point-to-Point (PTP) Obligation Bids (Report NP3-966-ER).
- `get_dam_price_corrections_spp`: Day-Ahead Market Price Corrections for Settlement Point Prices (SPP) (Report NP4-196-M).
- `get_dam_cleared_ancillary_service_rrspfr`: Day-Ahead Market Cleared Responsive Reserve Service from PFR Resources (RRSPFR) (Report NP3-911-ER).
- `get_60_day_dam_ptp_obligation_option_awards`: 60-Day Disclosed Day-Ahead Market PTP Obligation Option Awards (Report NP3-966-ER).
- `get_rtm_price_corrections_settlement_point_lmp`: Real-Time Market Price Corrections for Settlement Point LMPs (Report NP4-197-M).
- `get_dam_system_lambda`: Day-Ahead Market System Lambda (Report NP4-523-CD).
- `get_rtm_price_corrections_eblmp`: Real-Time Market Price Corrections for EBLMP (Report NP4-197-M).
- `get_60_day_dam_energy_only_offer_awards`: 60-Day Disclosed Day-Ahead Market Energy Only Offer Awards (Report NP3-966-ER).
- `get_rtm_price_corrections_sog_price`: Real-Time Market Price Corrections for SOG Prices (Report NP4-197-M).
- `get_60_day_dam_generation_resource_as_offers`: 60-Day Disclosed Day-Ahead Market Generation Resource AS Offers (Report NP3-966-ER).
- `get_dam_cleared_ancillary_service_regdn`: Day-Ahead Market Cleared Regulation Down Service (REGDN) (Report NP3-911-ER).
- `get_rtm_price_corrections_spp`: Real-Time Market Price Corrections for Settlement Point Prices (SPP) (Report NP4-197-M).
- `get_dam_cleared_ancillary_service_nspin`: Day-Ahead Market Cleared Non-Spinning Reserve Service (NSPIN) (Report NP3-911-ER).
- `get_dam_cleared_ancillary_service_rrsufr`: Day-Ahead Market Cleared Responsive Reserve Service from UFR Resources (RRSUFR) (Report NP3-911-ER).
- `get_60_day_dam_load_resource_data`: 60-Day Disclosed Day-Ahead Market Load Resource Data (Report NP3-966-ER).
- `get_rtm_price_corrections_sog_lmp`: Real-Time Market Price Corrections for SOG LMPs (Report NP4-197-M).
- `get_60_day_dam_generation_resource_data`: 60-Day Disclosed Day-Ahead Market Generation Resource Data (Report NP3-966-ER).
- `get_dam_cleared_ancillary_service_regup`: Day-Ahead Market Cleared Regulation Up Service (REGUP) (Report NP3-911-ER).
- `get_dam_ancillary_service_plan`: Day-Ahead Market Ancillary Service (AS) Plan (Report NP4-33-CD).
- `get_60_day_dam_ptp_obligation_option_offers`: Fetches 60-Day disclosed Day-Ahead Market (DAM) Point-to-Point (PTP) Obligation Option offers. This report provides data on submitted PTP Obligation Option offers, including quantities and prices (premiums). Corresponds to ERCOT report NP3-966-ER.
- `get_60_day_dam_ptp_obligation_bid_awards`: Fetches 60-Day disclosed Day-Ahead Market (DAM) awarded Point-to-Point (PTP) Obligation bids. This report details which PTP Obligation bids were cleared (awarded) in the DAM, including awarded MW and clearing prices. Corresponds to ERCOT report NP3-966-ER.
- `get_60_day_dam_energy_bids`: Fetches 60-Day disclosed Day-Ahead Market (DAM) energy bids. This report provides detailed data on energy bids submitted to the DAM, including price/quantity pairs forming bid curves. Corresponds to ERCOT report NP3-966-ER.
- `get_dam_cleared_ancillary_service_ecrss`: Fetches Day-Ahead Market (DAM) cleared ERCOT Contingency Reserve Service - Static (ECRSS). This report details awarded ECRSS quantities and prices. Corresponds to ERCOT report NP3-911-ER.
- `get_60_day_dam_qse_self_arranged_as_quantities`: Fetches 60-Day disclosed Day-Ahead Market (DAM) data on QSE self-arranged Ancillary Service quantities. Corresponds to ERCOT report NP3-966-ER.
- `get_dam_hourly_lmps`: Day-Ahead Market (DAM) Hourly Locational Marginal Prices (LMPs) (Report NP4-183-CD).

Each tool's parameters correspond to the query parameters defined in the ERCOT OpenAPI specification for that endpoint, validated by Zod schemas.

### Timestamp Handling

ERCOT API responses often contain date and time components in separate fields (e.g., `deliveryDate`, `deliveryHour`, `deliveryInterval`) or specific timestamp strings (e.g., `RTDTimestamp`). The server includes logic within `src/utils/timestamp.utils.ts` (used by `ErcotApiService`) to convert these into standard ISO 8601 UTC timestamps, correctly applying the "America/Chicago" timezone where necessary. Transformed timestamps are typically added as a new field (e.g., `parsedDeliveryTimestampUTC`) in the API response data.

## Configuration

Configure the server using environment variables defined in `.env`. See `.env.example` for available options:

| Variable                        | Description                                                             | Default           |
| :------------------------------ | :---------------------------------------------------------------------- | :---------------- |
| `ERCOT_USERNAME`                | Your ERCOT API username for token generation.                           | `null` (Required) |
| `ERCOT_PASSWORD`                | Your ERCOT API password for token generation.                           | `null` (Required) |
| `ERCOT_SUBSCRIPTION_KEY`        | Your ERCOT API subscription key (`Ocp-Apim-Subscription-Key`).          | `null` (Required) |
| `LOG_LEVEL`                     | Logging level (`error`, `warn`, `info`, `debug`).                       | `info`            |
| `RESOURCE_CLEANUP_INTERVAL`     | Interval (ms) to clean up inactive managed resources.                   | `1800000` (30m)   |
| `MAX_RETRIES`                   | Max retries for ERCOT token fetching operations.                        | `3`               |
| `RETRY_BASE_DELAY`              | Base delay (ms) for ERCOT token fetching retries (exponential backoff). | `1000`            |
| `ERCOT_API_RATE_LIMIT_DELAY_MS` | Delay (ms) between ERCOT API calls to respect rate limits.              | `1000`            |

## Project Structure

```
.
├── .env.example              # Example environment variables
├── .gitignore                # Git ignore rules
├── README.md                 # This file
├── dist/                     # (Generated) Compiled JavaScript output
├── ercot-openapi-spec-dam-rtm.json # Filtered OpenAPI spec for client generation
├── glama.json                # MCP server metadata
├── node_modules/             # Project dependencies
├── package.json              # Project manifest and dependencies
├── src/                      # Source code
│   ├── config.ts             # Configuration loading and schema
│   ├── index.ts              # Main server entry point, tool definitions
│   ├── logger.ts             # Console logger
│   ├── resource-manager.ts   # Generic resource management (from template)
│   ├── shared.ts             # Shared constants/utilities (from template)
│   ├── types.ts              # Core MCP TypeScript type definitions (from template)
│   ├── services/             # ERCOT specific services
│   │   ├── ercot-auth.service.ts # Handles ERCOT authentication
│   │   ├── ercot-api.service.ts  # Wraps ERCOT API client and calls
│   │   └── ercot-client.ts     # Initializes openapi-fetch client for ERCOT
│   ├── generated/            # Generated ERCOT API client types
│   │   └── ercot-api-types.ts  # (Generated by 'npm run generate-ercot-client')
│   ├── tools/                # Individual tool definitions (Zod schemas, API paths, types)
│   │   ├── getRtdIndicativeLmps.tool.ts
│   │   ├── getSppNodeZoneHub.tool.ts
│   │   └── ... (other tool files)
│   └── utils/                # Utility functions
│       └── timestamp.utils.ts  # ERCOT timestamp conversion logic
│   └── types/                # Aggregated type definitions for ERCOT API
│       ├── ercot-api-paths.ts  # Aggregated 'paths' interface for all tools
│       └── ercot-api-types.ts  # Common ERCOT API component schemas (Report, Exception, etc.)
└── tsconfig.json             # TypeScript compiler options
```

## Nexus Documentation

This project may include Nexus System documentation in a `.nexus` directory if initialized or copied from a template. For this ERCOT MCP server, key planning and decision details related to ERCOT API integration, authentication, and tool implementation would be documented there. A basic plan document (`.nexus/plans/mcp_ercot_initial_setup.md`) has been added.

## Contributing

Contributions are welcome! Please follow standard Git workflow (fork, branch, pull request). Ensure changes align with the project's focus on ERCOT DAM and RTM data and maintain code quality.

#https://raw.githubusercontent.com/ercot/api-specs/main/pubapi/pubapi-apim-api.json