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
Metadata
Release files for pypsamcp 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pypsamcp-0.2.0.tar.gz | 43.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pypsamcp-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 73.0 kB
Release files / pypsamcp-0.2.0.tar.gz
| Download URL | pypsamcp-0.2.0.tar.gz |
|---|---|
| Size | 43.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e117f7bc7a1eb1fa0bb7105e06339912a7076f89d0a02fbb275674e3a6934342
|
|
BLAKE2b-256 checksum How to use checksums |
000bd66b1e5b3b08b1cf4984ba40214d262a5d27eb1afa10ad8cc707e44aa7f4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|
Release files / pypsamcp-0.2.0-py3-none-any.whl
| Download URL | pypsamcp-0.2.0-py3-none-any.whl |
|---|---|
| Size | 29.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1ba4964d27590d92b3e8e772d09ceeaf6e304f9a4cb09ddd41e0629abe08ece4
|
|
BLAKE2b-256 checksum How to use checksums |
267a7725c7c0c0fb40cc54f263bd32efcbbb5e1c4e7e89243a4fd03f34642d2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.7.8
|