mcpField
E
eia-energy-mcp-server

eia-energy-mcp-server

远程服务
github.com/cyanheads法律与政务25 天前更新
代码仓库

关于 eia-energy-mcp-server

eia-energy-mcp-server 为探索能源数据集和时间序列的用户提供访问美国能源信息署 API v2 的 MCP 服务,支持路线发现、筛选查询,以及对暂存结果运行可选 SQL。

主要功能

  1. 01浏览并描述 EIA 数据路线
  2. 02搜索路线、序列名称和筛选值
  3. 03按筛选条件与日期范围查询时间序列
  4. 04使用 DataCanvas 暂存结果以运行 SQL
  5. 05查看或删除暂存数据框

适用场景

  1. 01查找能源指标对应的 EIA 路线
  2. 02按筛选条件和日期范围获取数据
  3. 03对暂存的查询结果运行 SQL 分析

MCP 相关

提供 4 个核心工具用于路线发现和数据查询,并提供 DataCanvas 工具以检查、查询及按需删除暂存数据框。支持 STDIO 和 Streamable HTTP 传输。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://eia-energy.caseyjhand.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@cyanheads/eia-energy-mcp-server0.4.6

工具

6
参数类型必填说明
pathstring否要浏览的路由路径(例如 "electricity"、"petroleum/pri")。根路径可省略。开头、结尾及重复的斜杠都会被移除,因此像 "/electricity/retail-sales/" 这样的 EIA 文档写法会解析为同一路由。

详细介绍

@cyanheads/eia-energy-mcp-server

通过 MCP 浏览和查询美国能源信息署 API v2——电力、石油、天然气、煤炭、预测等数据。支持 STDIO 或 Streamable HTTP。

4 个核心工具 + 3 个 DataCanvas 工具

Version License Docker MCP SDK npm TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework


概述

美国能源信息署(EIA)的美国能源数据:电力、石油、天然气、煤炭和预测。通过自然语言查找数据集,使用分面筛选条件查询时间序列,并对大型结果运行 SQL。

工具
工具描述
eia_browse_routes列出 EIA 数据集分类体系中某个路径下的子路径;省略 path 可查看 14 个顶层类别。
eia_describe_route返回叶子路径的分面、有效值、数据列、频率和日期范围。
eia_search_routes在路径名称、描述、STEO 和 SEDS 序列名称以及分面值中进行模糊文本搜索,包括 Henry Hub、WTI 和 Cushing 等基准序列。将旧版 APIv1 序列 ID(PET.RWTC.W)解析为对应路径及筛选条件。
eia_query_route使用分面筛选条件、日期范围和列选择,从叶子路径获取数据;也可选择将结果暂存以供 SQL 使用。
eia_dataframe_describe列出由 eia_query_route 暂存的活动 DataCanvas 数据帧,并提供架构和来源信息。
eia_dataframe_query对暂存的 DataCanvas 数据帧运行只读 SQL SELECT 查询。
eia_dataframe_drop删除 DataCanvas 数据帧,释放其占用的内存。

这三个 eia_dataframe_* 工具需要 DataCanvas;默认情况下已启用;eia_dataframe_drop 还需要 EIA_DATAFRAME_DROP_ENABLED=true。在 Claude Desktop 捆绑包设置的 CANVAS_PROVIDER_TYPE=none 情况下,这些工具既无法调用,也不会由 MCP 列出。已禁用的定义仍会保留在服务清单中,并附带启用提示。默认部署会列出前六个工具。

功能参考

浏览工具接受 route 作为 path 的别名;描述和查询工具接受 path 作为 route 的别名。若同时提供两种写法,将被拒绝。空白字符和斜杠会被规范化,随后只移除一个完整的前导 v2 段:/v2/electricity/retail-sales/ 会解析为 electricity/retail-sales,而 /v2/ 会浏览根目录。完整 URL、/data 后缀、路径中间的 v2 和大小写均保持不变。

所有四个路径工具都会区分可重试的上游故障:HTTP 429 或 OVER_RATE_LIMIT 对应 rate_limited;传输故障对应 upstream_unreachable;HTTP 服务中断对应 upstream_unavailable;响应正文不可用或缺少信封对应 upstream_invalid_response;EIA 未能及时响应对应 upstream_timeout。每次尝试的时限为 45 s;一次调用中的各次尝试、退避和链式请求共用 56 s 的时限,低于 MCP 客户端采用的 60 s 超时。恢复提示会显示在两种响应界面中。HTTP 501 仍视为确定性错误,504 仍视为超时,调用方取消操作仍视为取消。

eia_browse_routes 工具
  • 省略 path 可查看 14 个顶层类别;传入路径可浏览其子项。
  • 每个子项都带有 isLeaf:叶子路径使用 describe 和 query;类别则继续浏览。
  • 缺失路径会返回 route_not_found;EIA 限流、无法访问或未能及时响应时,会返回可重试的 rate_limited、upstream_unreachable 或 upstream_timeout。

eia_describe_route 工具
  • 传入叶子 route,可获取分面、数据列、频率和日期范围。每个分面窗口的上限为 EIA_FACET_VALUE_CAP(默认值为 50);可使用 facet 和 values_offset 分页。
  • 若要在大型分面中按名称查找值(电厂、实体和矿井 ID 数以千计),请传入 values_query:每个分面会保留 id、name 或 alias 中包含该字符串的值,且不区分大小写;使用 values_offset 对匹配项分页。在 electricity/facility-fuel 的 plantCode 上传入 values_query: "palo verde",一次调用即可返回 6008 和 57773。
  • date_range 是默认频率的元数据;其他频率的日期范围可能超出该范围。两种响应界面都会在未更改的起止值旁注明这一点。
  • value_count、values_truncated 以及在使用 values_query 时的 values_matched,用于描述各个窗口。若 EIA 未返回某个分面的值,该分面会列在 unavailable_facets 中;下一次调用会重试该分面。
  • 错误:route_not_found、route_not_queryable、facet_not_found,以及可重试的 facet_unavailable、rate_limited、upstream_unreachable、upstream_timeout。

eia_search_routes 工具
  • 搜索路由名称、描述、STEO 的 1,469 个和 SEDS 的 968 个序列名称,以及分面值。在描述任何路由之前,分面值涵盖燃料、行业、技术和煤炭等级词汇、RTO 平衡机构(Electric Reliability Council of Texas → respondent: ERCO),以及每日和每周石油与天然气路由的序列和产品名称(Henry Hub → natural-gas/pri/fut、series: RNGWHHD);描述路由时还会添加该路由自身的分面值。limit 默认为 10;大于 30 的正整数会被限制为 30,并披露请求值和实际采用值,即使结果较少或为空也一样。存在更多匹配项时,truncated 为 true。搜索的 query 仅取前 256 个字符,截断时会显示提示。
  • 匹配项包含 score(0 表示精确匹配,1 表示无匹配;大于 0.72 表示匹配较弱),也可能包含供 eia_query_route 使用的 filter_hint。在信任较短的结果集之前,请先检查 indexComplete 和 indexGaps。
  • EIA 网站和 Excel 加载项使用的旧版 APIv1 序列 ID,会先通过 EIA 的 /v2/seriesid 查询进行解析,再进行任何文本搜索,无论大小写:ELEC.PRICE.TX-RES.M 会返回一个结果,即 electricity/retail-sales,并附带 filter_hint {sectorid: "RES", stateid: "TX"}、frequency: "monthly" 和 columns: ["price"],可直接用于 eia_query_route。命中不需要索引,因此即使服务刚启动,也能在不到一秒内返回。如果 EIA 自身的查询报告该映射没有行(部分 AEO ID 属于这种情况),提示会说明查询将返回空结果。EIA 无法识别的 ID(PET.ZZZZZZ.W 或看起来像 ID 的 U.S.A)会返回文本搜索结果,并附带说明;查询超时、受到速率限制或遇到服务中断时也会如此,并附带重试提示,而不会报错。
  • 首次搜索会构建索引,通常需要 20–40 秒(最长 45 秒);之后的搜索会从已构建的索引中返回结果。如果 EIA 限制请求速率、无法访问或未能及时响应,调用会失败,并返回可重试的 rate_limited、upstream_unreachable 或 upstream_timeout。
eia_query_route 工具
  • 传入叶级 route,以及可选的 facet ID filters、columns、frequency、start/end 和 sort。使用 offset 和 length 分页(默认值为 100;超过 5000 的正整数会限制为 5000,并附带提示)。
  • 响应大小不超过 64,000 字节:页面可能会在最后一整行处提前结束,以确保不超出限制;next_offset 会给出继续读取的位置。若单行过大而无法容纳,则会跳过该行,提示中会给出用于跳过它的偏移量。
  • describe 缓存完整的 facet 词汇表后,查询提示会指出未匹配的筛选值,并在可能时建议区分大小写的 ID。筛选条件及其回显保持不变;诊断不会获取元数据或 facet 值。
  • 对于有效频率为月度的 YYYY-MM 数据,仅指定年份的边界表示 1 月:end: "2021" 会在 2021-01 截止;若要覆盖全年,请使用 2021-12。对于任一边界,查询提示都会说明这一点,但不会展开该边界。
  • EIA 会将每个边界视为其首日所属的有效频率周期,因此在月度频率下,start: "2023-01", end: "2023" 会返回 1 月。仅当 EIA 未返回任何行,且 start 选定的周期晚于 end 时,才会将范围报告为倒置(no_data);消息会指出两个周期。对于 local-hourly,每个边界都必须包含小时和 UTC 偏移量(2024-02-01T02-06);缺少其中任一项时,会在发出任何请求前报错为 invalid_period。如果边界指定的日期或小时在其频率精确读取的形状中不存在,也会报错,例如 daily 或 weekly 频率下的 2024-02-30,以及 hourly 频率下的 2024-02-01T24;对于这些情况,EIA 返回的是 HTTP 500,而不是数据行。
  • total 报告完整的匹配数;值仍以字符串表示,单位以 {col}-units 的形式出现。错误涵盖无效的 route、facet、列、频率、排序或周期,倒置范围(no_data),筛选列表过长、超出 EIA 约 8 KB 请求 URI 限制(uri_too_long;请将值拆分到多次调用中),以及可重试的 rate_limited、upstream_unreachable 和 upstream_timeout。
  • stage: true 会将最多 EIA_CANVAS_MAX_ROWS(默认 25000)行暂存为用于 SQL 的 dataset 句柄,供 eia_dataframe_describe 和 eia_dataframe_query 使用(列名中的连字符会替换为下划线)。如果暂存失败,则不会返回 dataset,并会在提示中说明。若暂存过程会超出调用截止时间,则会在请求下一页之前停止,暂存已获取的行,并在提示中说明时间已耗尽,同时给出可继续读取的偏移量。

eia_dataframe_describe 工具
  • 省略 name 可列出当前有效的暂存 dataframe;传入句柄可查看单个 dataframe。未找到时会返回 found: false 及 active_names。
  • 条目包含 source_tool、query_params、created_at、expires_at、row_count、truncated/max_rows 和 column_schema。列出条目不会延长过期时间。

eia_dataframe_query 工具
  • 对暂存句柄运行一条只读 SQL SELECT。row_limit 默认值为 1000;preview 用于缩小内联结果的范围,并接受 0。任一输入中的整数超过 10000 时,都会限制为 10000,并披露请求值和实际采用的值;每个输出面的 64,000 字节限制可能会导致行数更早截断。register_as 仍会暂存完整结果。
  • truncated: true 表示 totalRows 是上限,而非完整计数。register_as 会使用未占用的名称暂存完整结果,并提供精确计数;提示中会给出用于分页读取剩余结果的 ORDER BY … LIMIT/OFFSET 查询。
  • 对 EIA VARCHAR 值进行算术运算前,请先转换其类型。写入、读取文件和访问系统目录均会被拒绝;声明的失败包括 missing_table、invalid_sql、non_select_statement、denied_function、multi_statement、sql_read_only、system_catalog_access 和 register_as_clash。

eia_dataframe_drop 工具
  • 传入 name 可移除暂存的 dataframe;需要 EIA_DATAFRAME_DROP_ENABLED=true。
  • 未匹配到任何内容时会返回 dropped: false;删除失败时会返回可重试的 canvas_drop_failed,且 dataframe 会继续保持暂存状态。清理为可选操作:未使用的 dataframe 会在 24 h 后过期。

功能

基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔的身份验证(none / jwt / oauth)、可替换的存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志。

EIA 专属功能:

  • 覆盖 EIA API v2 的全部 14 个顶级数据集类别,并在进程内缓存路由树
  • 对路由名称和描述、全部 1,469 个 STEO 和 968 个 SEDS 系列名称以及分面值进行模糊搜索(Fuse.js)——其中包含 1,753 个基准石油和天然气系列名称及 RTO 平衡机构,并在预热时建立索引
  • eia_describe_route 会按路由获取并缓存分面值;如果 EIA 未返回某个列表,则会将其报告在 unavailable_facets 中,并在下次调用时重试
  • 无法获取元数据的路由会通过 eia_search_routes 报告,而不会被丢弃
  • 默认启用 DataCanvas(DuckDB),每次调用均可选择是否暂存;关闭 DataCanvas 后,三个数据框工具将无法调用

便于 Agent 使用的输出:

  • 来源信息——eia_query_route 会回显规范路由,暂存的数据框会记录其 source_tool 和 query_params
  • 窗口上限说明——响应被截断时会报告数量上限及达到的数量,并提供指明下一次调用的 notice
  • 类型化失败——错误 reason 值(例如 route_not_queryable、invalid_facet、missing_table)会附带 recovery 提示

开始使用

公共托管实例

公共实例可通过 https://eia-energy.caseyjhand.com/mcp 访问——无需安装。通过 Streamable HTTP 将任意 MCP 客户端连接到该实例:

{
  "mcpServers": {
    "eia-energy-mcp-server": {
      "type": "streamable-http",
      "url": "https://eia-energy.caseyjhand.com/mcp"
    }
  }
}
自托管 / 本地运行

在 api.eia.gov 免费获取 API 密钥,然后将以下内容添加到 MCP 客户端配置文件中。

{
  "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"
      }
    }
  }
}

也可以使用 npx(无需 Bun):

{
  "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"
      }
    }
  }
}

也可以使用 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"
      ]
    }
  }
}

对于 Streamable HTTP,设置传输方式并启动服务:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 EIA_API_KEY=your-key bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
  • Bun v1.4.0 或更高版本(或 Node.js v24+)。
  • 从 api.eia.gov 免费获取 EIA API 密钥。DEMO_KEY 很快就会触及速率限制;持续使用需要真实密钥。
安装
  1. 克隆代码仓库:
git clone https://github.com/cyanheads/eia-energy-mcp-server.git
  1. 进入目录:
cd eia-energy-mcp-server
  1. 安装依赖:
bun install
  1. 配置环境:
cp .env.example .env
# edit .env and set required vars (at minimum, EIA_API_KEY)

配置

所有配置都会在启动时通过 src/config/server-config.ts 中的 Zod 架构进行验证。主要环境变量:

变量说明默认值
EIA_API_KEY必填。 从 api.eia.gov 获取的免费 API 密钥,每次请求都会将其作为 api_key 附加。—
EIA_BASE_URLEIA API 基础 URL。https://api.eia.gov/v2
EIA_DATASET_TTL_SECONDS数据帧的存活时间(秒);每次引用数据帧的 eia_dataframe_query 都会延长其存活时间。86400(24 小时)
EIA_DATAFRAME_DROP_ENABLED设为 true 可启用 eia_dataframe_drop(当 CANVAS_PROVIDER_TYPE=none 时无效)。默认关闭,以避免意外清理 Canvas。false
EIA_CANVAS_MAX_ROWSeia_query_route 暂存操作的行数上限。达到上限需要额外 5 次请求:窄路由(如 electricity/retail-sales)约需 8.5 秒,宽路由(如 electricity/facility-fuel)约需 30–46 秒。若暂存操作会超出调用期限,则会提前停止并指出可继续执行的偏移量。25000
EIA_FACET_VALUE_CAPeia_describe_route 每个分面返回的值数量上限,超过后会截断;可使用 facet 和 values_offset 分页,或使用 values_query 缩小范围。50
CANVAS_PROVIDER_TYPEDataCanvas 提供方。duckdb 会启用 eia_dataframe_describe、eia_dataframe_query 和 stage: true;启用 drop 还需要设置 EIA_DATAFRAME_DROP_ENABLED=true。none 会禁用 DataCanvas。Claude Desktop bundle 会设置为 none。duckdb
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_HTTP_ENDPOINT_PATHHTTP 端点路径。/mcp
MCP_SESSION_MODEHTTP 会话模式:stateless、stateful 或 auto。stateless
MCP_PUBLIC_URL用于 TLS 终止型反向代理部署的公共源站覆盖值。—
MCP_AUTH_MODE身份验证模式:none、jwt 或 oauth。none
MCP_LOG_LEVEL日志级别(RFC 5424)。info
LOGS_DIR日志文件目录(仅 Node.js)。<project-root>/logs
STORAGE_PROVIDER_TYPE存储后端:in-memory、filesystem、supabase、cloudflare-kv/r2/d1。in-memory
OTEL_ENABLED启用 OpenTelemetry 插桩。false

完整的可选覆盖项列表请参见 .env.example。

运行服务

本地开发
  • 构建并运行:

    # One-time build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
    
  • 运行检查和测试:

    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    
Docker
docker build -t eia-energy-mcp-server .
docker run --rm -e EIA_API_KEY=your-key -p 3010:3010 eia-energy-mcp-server

Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/eia-energy-mcp-server。默认会安装 OpenTelemetry 对等依赖;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖。

项目结构

目录用途
src/index.tscreateApp() 入口点——注册工具并初始化服务。
src/config使用 Zod 解析并验证服务专用环境变量。
src/mcp-server/tools工具定义(*.tool.ts)——浏览、描述、搜索、查询,以及三个 DataCanvas 数据帧工具。
src/services/eiaEIA API v2 服务——路由树缓存、Fuse.js 索引、分面扇出请求、HTTP 客户端。
src/services/canvas-bridgeDataCanvas 桥接层——将 EIA 查询结果注册为 DuckDB 数据帧,并路由 SQL 查询。
tests/与 src/ 结构对应的单元测试和集成测试。
docs/设计文档(design.md、idea.md)。

开发指南

开发指南和架构规则请参见 CLAUDE.md。简要概述:

  • 处理器抛出异常,框架负责捕获——工具逻辑中不要使用 try/catch
  • 使用 ctx.log 记录请求范围的日志,使用 ctx.state 保存租户范围的存储
  • 始终先调用 eia_describe_route,再调用 eia_query_route——分面值需要单独进行 API 扇出请求,不包含在路由元数据中
  • 封装 EIA 响应:先验证原始数据,再规范化为领域类型,最后返回输出架构;数据值均为字符串,切勿静默强制转换

贡献

欢迎提交问题。提交前请运行检查和测试:

bun run devcheck
bun run test

许可证

Apache-2.0 — 详情请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。