RMI Utility Transition Hub — MCP Server
One-line summary: This MCP server loads RMI's public Utility Transition Hub data into a local DuckDB database so any MCP client can explore U.S. utility emissions, generation, and climate alignment using natural language.
Discover the data —
list_tablesshows every table with column names, types, and row counts;preview_tableshows sample rows so you can see the actual shape of a dataset.Find utilities —
list_utilitiessearches by two-letter state code or a case-insensitive name substring, returning utility/parent names, EIA and FERC1 IDs, RMI utility type, and in-state owned capacity (MW).Track emissions —
get_emissions_trendreturns yearly CO2 (MMT), stated-target and IRP-projection emissions, the 1.5°C benchmark, plus generation (TWh) and emissions intensity, on adelivered,owned, orallaccounting basis.Break down generation —
get_generation_mixshows capacity (GW), net generation (TWh), capacity factor, and CO2 by technology (Coal, Gas, Wind, Solar, Nuclear, Hydro, Storage, …); optionally include purchased power, exchanges, EE/DR, and transmission losses as separate rows.Assess climate alignment —
get_climate_alignmentcompares actual CO2 to RMI's 1.5°C pathway year by year, adding a gap column and status label;rank_climate_alignmentranks utilities or parents by distance from the pathway and flags which entities were excluded.Run custom SQL —
query_dataexecutes read-only DuckDB SQL (one SELECT or WITH…SELECT per call) across emissions, generation, reliability, customers/sales, revenue, assets, debt/equity, and net plant tables, with documented join keys and double-counting traps.Read the documentation — resources
rmi://data-dictionary,rmi://data-dictionary-full(the full PDF), andrmi://methodologygive field definitions, sources, assumptions, and calculations.Use guided prompts —
decarbonization_assessment,state_landscape, andinvestment_risk_profilestructure common analyses.Get consistent output — every tool returns the same envelope (
rows,units,metawithgrain/non_additive,notes,error) so you can tell whether rows double-count or columns must not be summed.Answer typical questions — e.g. which utilities are furthest off the 1.5°C pathway, which Wisconsin utilities emit most, or how two utilities' generation mixes compare.
Caveat — it is an unaudited demo; results can be wrong and should be checked against the Utility Transition Hub and RMI methodology before use.
Loads RMI's public Utility Transition Hub data (utility emissions, generation mix, capacity, reliability, financials) into a DuckDB database, exposing tools to list/preview tables and run read-only DuckDB SQL queries against the data.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@RMI Utility Transition Hub — MCP Server Which Colorado utilities have the highest CO2 emissions?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Server for RMI's Utility Transition Hub
This MCP server loads RMI's public Utility Transition Hub data into DuckDB. Any MCP client can then query U.S. utility emissions, generation mix, and climate alignment with natural language.
This is a demo. Use it at your own risk.
This software is not audited, validated, or ready for production. The tools can return errors. The tools can also aggregate the data incorrectly, and a language model can interpret the results incorrectly.
Check every result against the Utility Transition Hub and the RMI methodology before you cite it, publish it, or make a decision with it. RMI does not endorse this tool. This tool has no affiliation with RMI.
Setup
1. Install the Dependencies
pip install fastmcp duckdb pandas pymupdfOr use uv:
uv init rmi-mcp-uth
cd rmi-mcp-uth
uv add fastmcp duckdb pandas pymupdf2. Download the RMI Data
Download the data from the Utility Transition Hub. Extract the data into a data/ directory:
mkdir data
cd data
curl -LO https://utilitytransitionhub.rmi.org/static/data_download/data_download_all_pt_1.zip
curl -LO https://utilitytransitionhub.rmi.org/static/data_download/data_download_all_pt_2.zip
unzip -q -o -j data_download_all_pt_1.zip
unzip -q -o -j data_download_all_pt_2.zip
rm data_download_all_pt_1.zip data_download_all_pt_2.zip3. Test With the MCP Inspector
npx @modelcontextprotocol/inspector python server.pyThis command opens a browser interface. In the interface, you can call each tool, examine the resources, and monitor the protocol traffic.
4. Connect a Client
The server uses the stdio transport, and any MCP client can connect to it. See your provider's documentation or ask your agent (e.g., Claude Code) to set it up.
Related MCP server: US ISO Grid MCP
What the Server Exposes
Tools
Tool | What it does |
| Show all tables, columns, and row counts |
| Show sample rows from a table |
| Find utilities by state or name. The best matches come first. |
| Show CO2 emissions over time for a utility. |
| Show the generation breakdown by |
| Compare the actual CO2 to the 1.5°C pathway. |
| Rank utilities or parents by distance from the 1.5°C pathway. Excludes the utilities whose benchmark makes the comparison meaningless, and says which. |
| Run read-only SQL in DuckDB syntax |
Response Format
Every tool returns the same envelope:
{
"rows": [{"utility_name": "Wisconsin Power & Light Co.", "year": 2024,
"owned_delivered": "delivered", "emissions_co2": 4.87}],
"units": {"emissions_co2": "MMT CO2"},
"meta": {"grain": ["utility_name", "year", "owned_delivered"],
"matched_utilities": ["Wisconsin Power & Light Co."]},
"notes": [{"kind": "projection", "message": "Rows at or after projected_from are ..."}],
"error": null
}Key | What it holds |
| The data. Every row has the same keys. Warnings and errors never appear here. |
| The unit of each column that has one. Columns absent from it are unitless. |
|
|
| Warnings that apply to the whole response. Each has a |
|
|
grain guards against counting the same row twice. Whether a column can be
added up at all is a separate question, answered by meta.non_additive — the
list of returned columns that must never be summed across rows. It is present
only when such a column is in the result.
Most entries are rates, and have to be recomputed from the two totals
underneath them rather than added: co2_intensity_kg_mwh, capacity_factor,
pct_over, saidi, bill, burden. But do not infer non-additivity from the
unit — capacity_owned_in_state is plain MW and still must not be summed,
because RMI's figure runs several times above the utility's ownership share and
adding it across a state's utilities exceeds that state's real capacity. Read
non_additive, not the unit string.
Resources
URI | Description |
| A summary of the datasets, columns, and units |
| The full data dictionary PDF. It gives the definitions, sources, and methodology for each field. |
| The RMI methodology document. It gives the data sources, assumptions, and calculations. |
Prompts
Prompt | Description |
| Analyze the climate progress of a utility |
| Show an overview of the utilities in a state |
| Show the financial exposure of a utility to fossil fuel assets |
Example Conversations
"Which US utilities are furthest off the 1.5°C pathway?"
"Which Wisconsin utilities have the highest CO2 emissions?"
"Compare Alliant Energy and Xcel Energy's generation mix"
"Show me Wisconsin Power & Light's emissions trend since 2015"
"Is Alliant Energy on track for 1.5°C, or is WEC Energy Group closer?"
"What share of Wisconsin generation comes from renewables?"
Rebuilding the Database
Delete utility_hub.duckdb and restart the server. The server builds the database again from the CSV files.
Data License
RMI licenses the Utility Transition Hub data under CC BY 4.0.
Available Tools
7 toolsget_climate_alignmentA
Compare a utility's emissions to RMI's 1.5°C pathway, year by year.
Adds a gap column (CO2 minus the 1.5°C benchmark: positive = above the pathway) and a status label. Historical years use reported CO2; future years fall back to the utility's stated target, then its IRP projection.
basis is "delivered" (default), "owned", or "all" — see get_emissions_trend.
The search is case-insensitive and supports partial names.
Inputs: utility_name (required), basis. Returns: result
get_emissions_trendA
Get yearly CO2 emissions and 1.5°C pathway comparison for a utility.
Returns historical CO2 (MMT), emissions implied by the utility's stated targets, its IRP projection, and RMI's 1.5°C benchmark — plus generation (TWh) and emissions intensity (metric tons/MWh).
basis selects the accounting boundary and MUST be one of:
"delivered" (default) — emissions behind the power the utility sells
"owned" — emissions from generation the utility owns
"all" — both, distinguished by the owned_delivered column
The two bases are separate row sets; never sum across them.
The search is case-insensitive and supports partial names.
Inputs: utility_name (required), basis. Returns: result
get_generation_mixA
Get electricity generation breakdown by technology for a utility.
Shows capacity (GW), net generation (TWh), capacity factor, and CO2 emissions (MMT) by RMI technology group (Coal, Gas, Wind, Solar, Nuclear, Hydro, Storage, ...).
By default this covers only generation the utility OWNS. The underlying table also carries non-owned energy_source rows — wholesale power purchases, net exchanges, wheeled power, energy efficiency, demand response, and negative transmission losses. Those are supply, not generation, and summing them together with owned output overstates the fleet and mixes in negative rows. Set include_purchases=True to get them as separate rows, split by the energy_source and owned_energy_source columns.
The search is case-insensitive and supports partial names. Optionally filter to a single year; defaults to all years (2005-2024).
Inputs: utility_name (required), year, include_purchases. Returns: result
list_tablesA
List all tables with their column names and types.
Call this first to understand what data is available before querying.
Inputs: no named parameters. Returns: result
list_utilitiesA
List utilities, optionally filtered by two-letter state code (e.g. 'CO', 'TX').
Returns utility and parent names, EIA/FERC1 IDs, RMI utility type, and — when
a state is given — the capacity that utility owns in that state (MW), largest
first. name_contains additionally filters on utility or parent name
(case-insensitive substring).
Use this to find the right utility name before pulling emissions or generation data.
Inputs: limit, state_abbr, name_contains. Returns: result
preview_tableA
Show the first few rows of a table to understand its structure.
Use this after list_tables to see what the actual data looks like.
Inputs: table_name (required), rows. Returns: result
query_dataA
Run a read-only SQL query against the database. DuckDB SQL syntax.
Call list_tables() first to see available tables and columns. One SELECT statement per call (a leading WITH ... CTE is fine).
There is no single join key across all tables: utility_id_eia — utility_information, utility_state_map, operations_emissions_by_tech / _by_fuel, reliability utility_id_ferc1 — utility_information, customers_sales, revenue_by_tech, assets_earnings_investments, debt_equity_returns, net_plant_balance respondent_id — expenditure_bills_burden, housing_units_income only emissions_targets has NO id column; join it on utility_name_irp / parent_name. utility_name and parent_name appear in most tables directly.
Two traps worth knowing:
emissions_targets holds separate 'owned' and 'delivered' row sets —
filter owned_delivered or you double-count.
operations_emissions_by_tech mixes owned generation with purchased
power, exchanges, EE/DR, and negative transmission losses —
filter owned_energy_source for generation only.
Example: SELECT utility_name_irp, year, emissions_co2_historical, emissions_co2_1point5c FROM emissions_targets WHERE year >= 2015 AND owned_delivered = 'delivered' ORDER BY emissions_co2_historical DESC LIMIT 20
Inputs: sql (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 7 tools
list_tables, preview_table, list_utilities, and get_generation_mix are clearly distinct, but get_emissions_trend and get_climate_alignment both promise yearly CO2 emissions versus a 1.5°C pathway. The detailed descriptions help, but an agent could easily pick the wrong one.
Most tools follow a get_/list_ + noun pattern, which is predictable. preview_table and query_data deviate slightly, but they still read naturally and fit the overall exploration-oriented convention.
Seven tools is well-scoped for a domain-specific utility data hub. Each tool has a clear role, and the count is neither bloated nor too thin.
The surface covers data discovery, table preview, utility lookup, standard analytical queries, and raw SQL for arbitrary exploration. There are no obvious dead ends for a read-only analysis server.
Related MCP Connectors
US power plant, generation, price, curtailment and water data, with sources on every result.
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Live US power market prices, load, generation, weather and permits for AI agents.
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Related MCP Servers
- FlicenseAqualityDmaintenanceAn MCP server that provides access to Northwood Capital Partners' portfolio carbon data, enabling MCP-compatible agents to query emissions, analyze decarbonization gaps, and simulate reduction initiatives through natural language.5-
- AlicenseNot gradedqualityCmaintenanceEnables real-time access to US electricity generation, fuel mix, and demand data through natural language queries.277 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables natural-language Q&A, human-approved actions, and dashboard generation over a data ontology via MCP.-

Atlas MCPofficial
AlicenseNot gradedqualityAmaintenanceEnables natural language querying of SQL databases and REST APIs through the MCP protocol, grounded in a semantic layer.195 npm1AGPL 3.0