PyPSA MCP: PyPSA Energy Modeling for LLMs
Project description
PyPSA MCP
A Model Context Protocol (MCP) server that lets LLMs like Claude build, configure, and optimize energy system models using PyPSA through natural language.
Demo
https://github.com/user-attachments/assets/5633a431-7c3b-4a2f-9a9e-395dcbbb2e29
What's New in 0.2.0
Bug fixes
- Rolling horizon — fixed
setting an array element with a sequencecrash caused by PyPSA's_set_dynamic_datamishandling single-column pnl DataFrames when slicing snapshot windows. Fixed via adup2-level_patch_set_dynamic_datacontext manager. - MGA single-column crash — same root cause in
optimize_mgapost-processing. Fixed by patching bothpypsa.optimization.commonandpypsa.optimization.optimizebefore each MGA call. - Stale results after infeasible solve —
run_simulationwas returning cached dispatch from a prior successful solve when a subsequent solve was infeasible. Now returns a cleannullresponse with an explicitinfeasibility_note. compute_infeasibilitieswith HiGHS — instead of silently returning wrong results, the server now correctly reports that this flag requires Gurobi in PyPSA 1.x and suggests the load-shedding VoLL workaround.- HiGHS stdout pollution — HiGHS writes solver logs via C-level stdio, bypassing Python's
sys.stdout. Fixed by redirectingfd 1 → fd 2withos.dup2around every solver call, keeping the MCP stdio stream clean. - Silent fallbacks in statistics — replaced silent zero-fill fallbacks with fail-fast errors that include actionable messages.
Simulation modes validated end-to-end
All 8 modes now confirmed working: pf, lpf, optimize, mga, security_constrained, rolling_horizon, transmission_expansion_iterative, optimize_and_pf.
Features
22 MCP tools across 10 modules:
| Module | Tools |
|---|---|
| Management | create_energy_model, list_models, delete_model, export_model_summary |
| Discovery | list_component_types, describe_component |
| Components | add_component, update_component, remove_component, query_components |
| Time config | configure_time (snapshots, investment periods, scenarios, CVaR risk preference) |
| Simulation | run_simulation (8 modes) |
| Statistics | get_statistics (19 metrics) |
| Clustering | cluster_network (spatial: kmeans/hac/greedy; temporal: resample/downsample/segment) |
| I/O | network_io (export/import NetCDF & CSV, copy, merge, consistency check) |
| Deprecated | add_bus, add_generator, add_load, add_line, set_snapshots, run_powerflow, run_optimization |
13 component types: Bus, Generator, Load, Line, Link, StorageUnit, Store, Transformer, ShuntImpedance, Carrier, GlobalConstraint, LineType, TransformerType.
Simulation modes:
optimize— linear OPF, capacity expansion, CO2 constraints, multi-investment periods, unit commitmentrolling_horizon— limited-foresight dispatch with configurable horizon and overlapmga— Modeling to Generate Alternatives (near-optimal solution space exploration)security_constrained— N-1 contingency-constrained OPFtransmission_expansion_iterative— iterative TEP with PTDF-based congestionpf/lpf— non-linear and linearized power flowoptimize_and_pf— optimization followed by non-linear power flow
Advanced modelling: sector coupling (Links with multiple outputs), CVaR risk preference, scenario-based optimization, temporal/spatial network clustering, load shedding via VoLL dummy generators.
Installation
Requirements
- Python 3.10+
- uv (recommended)
From PyPI
pip install pypsamcp
# or
uv pip install pypsamcp
Running the server
pypsamcp
Claude Desktop configuration
Locate ~/.config/Claude/config.json and add:
"mcpServers": {
"PyPSA MCP": {
"command": "uv",
"args": ["run", "--with", "pypsamcp", "pypsamcp"]
}
}
Restart Claude Desktop after saving.
Development installation
git clone https://github.com/cdgaete/pypsa-mcp.git
cd pypsa-mcp
uv pip install -e ".[dev]"
python -m pypsamcp.server
For development with Claude Desktop, point directly to the virtualenv Python so source changes are picked up immediately:
"mcpServers": {
"PyPSA-MCP-Dev": {
"command": "/home/carlos/projects/pypsa-mcp/.venv/bin/python",
"args": ["-m", "pypsamcp.server"]
}
}
Usage examples
Minimal dispatch model
Build a single-bus model with coal (300 MW, €20/MWh), gas (200 MW, €80/MWh),
and solar (150 MW, free) over 24 hourly snapshots. Add a diurnal load profile
peaking at 310 MW. Run OPF and explain the dispatch and marginal prices.
Sector coupling — power + hydrogen + heat
Build a model with an AC bus, H2 bus, and heat bus. Add 400 MW wind,
a 200 MW gas backup, an extendable PEM electrolyzer (70% efficiency,
€120k/MW), a heat pump (COP=3, €60k/MW), a district heating load,
and a flat 20 MW H2 industrial demand. Run OPF and compare the heat pump
against a gas boiler alternative.
Transmission expansion planning
Build a 3-bus ring (North: coal + wind, South: gas + heavy load, East: solar + load).
Set all lines to 50 MW with capital cost. Run OPF to show congestion and LMP divergence,
then run transmission_expansion_iterative to find the optimal line investments.
Rolling horizon with battery
Add a 100 MW / 4h battery to the dispatch model and run rolling_horizon
with horizon=6 and overlap=2. Compare the battery's intraday arbitrage
against perfect-foresight OPF.
Multi-investment periods
Build a model with two planning years (2025, 2030). Solar capital cost drops
from €50k/MW in 2025 to €30k/MW in 2030. Coal is fixed. Show when the
optimizer invests in solar and the resulting scarcity prices.
Known limitations
compute_infeasibilities=Truerequires Gurobi. With HiGHS, diagnose infeasibility using load-shedding generators (setmarginal_costto a high VoLL such as €10,000/MWh on each bus).- Temporal clustering with
method="segment"requirestsam(pip install tsam). - CVaR scenario-differentiated time series (different p_max_pu or marginal costs per scenario) must be set manually via
update_componentwith per-snapshot values after scenario configuration. - Model state is in-memory only; models are lost on server restart. Use
network_iowithoperation="export_netcdf"to persist, andoperation="import_netcdf"to reload.
Changelog
0.2.0 (2026-03-20)
Bug fixes
- Fixed rolling horizon crash (
setting an array element with a sequence) via_patch_set_dynamic_datacontext manager - Fixed MGA post-processing crash for single-component models via
_patch_single_column_pnl - Fixed stale results returned after infeasible solve — now returns clean null response
- Fixed
compute_infeasibilitiessilently returning wrong results with HiGHS — now returns actionable guidance - Fixed HiGHS C-level stdout pollution via
os.dup2fd redirection instdout_to_stderrcontext manager - Fixed silent fallbacks in
get_statistics— replaced with fail-fast errors
Confirmed working: all 8 simulation modes, all 19 statistics metrics, all 13 component types
0.1.4
- Initial public release with 22 tools across 10 modules
- Simulation: pf, lpf, optimize, mga, security_constrained, rolling_horizon, transmission_expansion_iterative, optimize_and_pf
- Components: full CRUD for all 13 PyPSA component types
- Statistics: 19 metrics including capacity factors, energy balance, market values, transmission
- Clustering: spatial (kmeans, hac, greedy_modularity) and temporal (resample, downsample, segment)
- I/O: NetCDF/CSV export-import, copy, merge, consistency check
License
MIT — see LICENSE.
Acknowledgments
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pypsamcp-0.2.0.tar.gz.
File metadata
- Download URL: pypsamcp-0.2.0.tar.gz
- Upload date:
- Size: 43.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e117f7bc7a1eb1fa0bb7105e06339912a7076f89d0a02fbb275674e3a6934342
|
|
| MD5 |
9803267a3aacf28e7cf9dfd5413d0630
|
|
| BLAKE2b-256 |
000bd66b1e5b3b08b1cf4984ba40214d262a5d27eb1afa10ad8cc707e44aa7f4
|
File details
Details for the file pypsamcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pypsamcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 29.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ba4964d27590d92b3e8e772d09ceeaf6e304f9a4cb09ddd41e0629abe08ece4
|
|
| MD5 |
9f919ed322832486364b98094cffcbb9
|
|
| BLAKE2b-256 |
267a7725c7c0c0fb40cc54f263bd32efcbbb5e1c4e7e89243a4fd03f34642d2a
|