Connects Claude to the U.S. Energy Information Administration's v2 API with seven tools covering the full query workflow. Browse the 14 top-level dataset categories (electricity, petroleum, natural gas, coal, forecasts), search 1,469 STEO series by fuzzy text, describe route schemas with facet vocabularies, then pull filtered data by state, sector, or date range. Query results spill to DuckDB tables when they exceed page limits, so you can run SQL over large datasets. Handles the EIA's string-formatted numerics and per-row unit fields. Useful when you need structured energy data for analysis, dashboards, or policy research without manually navigating the API docs.
Browse and query the U.S. Energy Information Administration API v2 — electricity, petroleum, natural gas, coal, forecasts, and more via MCP. STDIO or Streamable HTTP.
Public Hosted Server: https://eia-energy.caseyjhand.com/mcp
Seven tools covering the two-phase EIA workflow — find the right dataset route, pull the data, and query spilled results via SQL:
| Tool | Description |
|---|---|
eia_browse_routes | Lists child routes under a given path in the EIA dataset taxonomy. Start at root to see top-level categories, then drill into subcategories and leaf routes. |
eia_describe_route | Returns full metadata for a leaf route: available facets with valid values, data column names, frequency options, units, and date range. Call before eia_query_route to understand filter options. |
eia_search_routes | Fuzzy text search across route names, descriptions, and category labels. Resolves natural-language queries like "gasoline retail prices" or "solar capacity by state" to matching route paths. |
eia_query_route | Fetches data from a leaf route with optional facet filters, date range, frequency, and column selection. Spills large result sets to a DataCanvas table for SQL analysis. |
eia_dataframe_describe | Lists active DataCanvas dataframes created by prior eia_query_route calls. Shows table name, column names and types, row count, and canvas ID. |
eia_dataframe_query | Runs a read-only SQL SELECT against a DataCanvas dataframe by canvas ID or table name. |
eia_dataframe_drop | Drops a DataCanvas dataframe, freeing its memory. Only exposed when EIA_DATAFRAME_DROP_ENABLED=true. |
eia_browse_routesWalk the EIA dataset taxonomy from root to leaf.
eia_describe_routeSTEO (Short-Term Energy Outlook) is a flat leaf with 1,469 named series — no sub-routeseia_describe_routeFull schema for a leaf route. Required before constructing facet filters.
eia_search_routes and eia_browse_routes resolve the route path; this tool provides the filter vocabularyeia_search_routesFuzzy search across the in-memory route index.
eia_query_routePull data from a leaf route.
{ "stateid": "TX", "sectorid": ["RES", "COM"] })eia_describe_routeoffset/length (max 5,000 rows per page); total row count in response{col}-units fields per rowlength: returns canvas_id for SQL queries over the full datasetBuilt on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1EIA-specific:
Promise.all fan-out — valid filter values available without re-fetchingGet a free API key at api.eia.gov, then add the following to your MCP client configuration file.
{
"mcpServers": {
"eia-energy-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/eia-energy-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"EIA_API_KEY": "your-api-key"
}
}
}
}
Or with npx (no Bun required):
{
"mcpServers": {
"eia-energy-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/eia-energy-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"EIA_API_KEY": "your-api-key"
}
}
}
}
Or with Docker:
{
"mcpServers": {
"eia-energy-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "EIA_API_KEY=your-api-key",
"ghcr.io/cyanheads/eia-energy-mcp-server:latest"
]
}
}
}
For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 EIA_API_KEY=your-key bun run start:http
# Server listens at http://localhost:3010/mcp
DEMO_KEY hits rate limits quickly; a real key is required for sustained use.git clone https://github.com/cyanheads/eia-energy-mcp-server.git
cd eia-energy-mcp-server
bun install
cp .env.example .env
# edit .env and set required vars (at minimum, EIA_API_KEY)
All configuration is validated at startup via Zod schemas in src/config/server-config.ts. Key environment variables:
| Variable | Description | Default |
|---|---|---|
EIA_API_KEY | Required. Free API key from api.eia.gov — appended as api_key on every request. | — |
EIA_BASE_URL | EIA API base URL. | https://api.eia.gov/v2 |
EIA_DATASET_TTL_SECONDS | Per-table TTL for DataCanvas dataframes in seconds. | 86400 (24 h) |
EIA_DATAFRAME_DROP_ENABLED | Set to true to expose eia_dataframe_drop. Off by default to avoid accidental canvas cleanup. | false |
CANVAS_PROVIDER_TYPE | Set to duckdb to enable DataCanvas spillover for large result sets (Node only). | — |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | HTTP server port. | 3010 |
MCP_HTTP_ENDPOINT_PATH | HTTP endpoint path. | /mcp |
MCP_PUBLIC_URL | Public origin override for TLS-terminating reverse-proxy deployments. | — |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
LOGS_DIR | Directory for log files (Node.js only). | <project-root>/logs |
STORAGE_PROVIDER_TYPE | Storage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1. | in-memory |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
Build and run:
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http
Run checks and tests:
bun run devcheck # Lint, format, typecheck, security
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against spec
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and inits services. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/mcp-server/tools | Tool definitions (*.tool.ts) — browse, describe, search, query, and three DataCanvas dataframe tools. |
src/services/eia | EIA API v2 service — route tree cache, Fuse.js index, facet fan-out, HTTP client. |
src/services/canvas-bridge | DataCanvas bridge — registers EIA query results as DuckDB dataframes, routes SQL queries. |
tests/ | Unit and integration tests mirroring src/. |
docs/ | Design documents (design.md, idea.md). |
See CLAUDE.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storageeia_describe_route before eia_query_route — facet values require a separate API fan-out and are not embedded in route metadataIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run test
Apache-2.0 — see LICENSE for details.
EIA_API_KEY*Free API key from api.eia.gov. Required — all requests use this as the api_key query parameter.
EIA_DATASET_TTL_SECONDSdefault: 86400Per-table TTL for DataCanvas dataframes in seconds.
EIA_DATAFRAME_DROP_ENABLEDdefault: falseSet to 'true' to expose eia_dataframe_drop for manual canvas cleanup.
CANVAS_PROVIDER_TYPESet to 'duckdb' to enable DataCanvas spillover for large query result sets (Node.js only).
MCP_LOG_LEVELdefault: infoSets the minimum log level for output (e.g., 'debug', 'info', 'warn').
MCP_HTTP_HOSTdefault: 127.0.0.1The hostname for the HTTP server.
MCP_HTTP_PORTdefault: 3010The port to run the HTTP server on.
MCP_HTTP_ENDPOINT_PATHdefault: /mcpThe endpoint path for the MCP server.
MCP_PUBLIC_URLPublic origin override for deployments behind a TLS-terminating reverse proxy (e.g. https://mcp.example.com).
MCP_AUTH_MODEdefault: noneAuthentication mode to use: 'none', 'jwt', or 'oauth'.