epanet-mcp-server 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026- EURECAT.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,196 @@
1
+ Metadata-Version: 2.4
2
+ Name: epanet-mcp-server
3
+ Version: 0.1.0
4
+ Summary: MCP server for EPANET water distribution network simulation via ePyT
5
+ License: MIT
6
+ Keywords: epanet,epyt,mcp,water-distribution,hydraulic-simulation
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: mcp>=1.0.0
11
+ Requires-Dist: epyt>=2.0.0
12
+ Requires-Dist: numpy>=1.24.0
13
+ Requires-Dist: pandas>=2.0.0
14
+ Provides-Extra: dev
15
+ Requires-Dist: pytest>=7.0; extra == "dev"
16
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
17
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
18
+ Dynamic: license-file
19
+
20
+ # EPANET MCP Server
21
+
22
+ [![Linter](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/linter.yml/badge.svg?branch=main)](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/linter.yml)
23
+ [![Pytest](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/test.yml)
24
+
25
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that
26
+ exposes EPANET water-distribution network modelling capabilities through
27
+ [ePyT](https://github.com/KIOS-Research/EPyT) - the EPANET Python Toolkit.
28
+
29
+ Any MCP-compatible LLM can load water network models, run
30
+ simulations, modify parameters, and generate complex what-if scenarios through
31
+ natural language.
32
+
33
+ ---
34
+
35
+ ## Features
36
+
37
+ | Category | Tools |
38
+ |---|---|
39
+ | **Load & Inspect** | `load_network`, `unload_network`, `list_networks`, `list_bundled_networks`, `get_network_summary`, `get_nodes`, `get_links`, `get_patterns`, `get_controls`, `get_curves`, `get_options` |
40
+ | **Simulate** | `run_hydraulic_simulation`, `run_quality_simulation`, `run_full_simulation`, `get_pressure_at_time`, `get_flow_at_time` |
41
+ | **Modify** | `set_node_base_demand`, `set_pattern`, `add_pattern`, `set_pipe_diameter`, `set_pipe_roughness`, `set_pipe_status`, `set_pipe_length`, `set_pump_status`, `set_pump_speed`, `set_pump_head_curve`, `set_valve_setting`, `set_valve_status`, `set_tank_parameters`, `set_reservoir_head`, `set_simulation_duration`, `set_hydraulic_timestep`, `set_quality_timestep`, `set_quality_type`, `add_control`, `delete_control`, `save_network` |
42
+ | **Scenarios** | `create_demand_perturbation`, `create_leakage_event`, `create_contamination_event`, `create_pressure_change_scenario`, `create_pump_control_scenario`, `create_valve_control_scenario`, `create_multi_failure_scenario` |
43
+
44
+ ---
45
+
46
+ ## Requirements
47
+
48
+ - Python ≥ 3.10
49
+ - [ePyT](https://pypi.org/project/epyt/) ≥ 2.0
50
+ - [mcp](https://pypi.org/project/mcp/) ≥ 1.0
51
+
52
+ ```bash
53
+ pip install epyt mcp
54
+ ```
55
+
56
+ ---
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ git clone https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server.git
62
+ cd epanet-mcp-server
63
+ pip install -e .
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Running the server
69
+
70
+ ### stdio (for Claude Desktop / Claude Code)
71
+
72
+ ```bash
73
+ epanet-mcp-server
74
+ # or
75
+ python -m epanet_mcp.server
76
+ ```
77
+
78
+ ### SSE / HTTP
79
+
80
+ ```bash
81
+ epanet-mcp-server --transport sse --port 8000
82
+ ```
83
+
84
+ ---
85
+
86
+ ## Claude Desktop configuration
87
+
88
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`
89
+ (macOS) or the equivalent on your platform:
90
+
91
+ ```json
92
+ {
93
+ "mcpServers": {
94
+ "epanet": {
95
+ "command": "epanet-mcp-server",
96
+ "args": []
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ If not on `PATH`:
103
+
104
+ ```json
105
+ {
106
+ "mcpServers": {
107
+ "epanet": {
108
+ "command": "python",
109
+ "args": ["-m", "epanet_mcp.server"],
110
+ "cwd": "/path/to/epanet-mcp-server/src"
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Claude Code (`.mcp.json`)
119
+
120
+ Place this in the root of your project or `~/.claude/`:
121
+
122
+ ```json
123
+ {
124
+ "mcpServers": {
125
+ "epanet": {
126
+ "command": "epanet-mcp-server",
127
+ "args": []
128
+ }
129
+ }
130
+ }
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Example interactions
136
+
137
+ Once the server is connected, you can ask things like:
138
+
139
+ > **"Load Net1.inp and show me a summary of the network."**
140
+
141
+ > **"Run a hydraulic simulation and tell me which node has the lowest pressure at hour 12."**
142
+
143
+ > **"Double the base demand at junction 11 and re-run the simulation. How does pressure change?"**
144
+
145
+ > **"Simulate a burst on pipe 10 with a 20% leakage fraction."**
146
+
147
+ > **"Inject 10 mg/L of chlorine at node 11 between hours 1 and 3 and show me the contamination spread."**
148
+
149
+ > **"What happens to pressures if the reservoir head drops from 150 m to 120 m?"**
150
+
151
+ > **"Schedule Pump 9 to start at 06:00 and stop at 22:00."**
152
+
153
+ > **"Close pipes 10 and 11 and the pump simultaneously. Where are service disruptions?"**
154
+
155
+ ---
156
+
157
+ ## Architecture
158
+
159
+ ```
160
+ src/epanet_mcp/
161
+ ├── server.py # FastMCP server – tool registration + entry point
162
+ ├── session.py # Thread-safe registry of open ePyT sessions
163
+ ├── utils.py # numpy → Python serialisation helpers
164
+ └── tools/
165
+ ├── inspection.py # load / inspect network models
166
+ ├── simulation.py # run hydraulic & quality simulations
167
+ ├── modification.py# in-memory parameter changes
168
+ └── scenarios.py # what-if scenario generators (clone + modify + run)
169
+ ```
170
+
171
+ **Session model**: Each loaded network lives in a named session. Scenario
172
+ tools automatically clone the source session into a new independent session so
173
+ the baseline network is never mutated.
174
+
175
+ ---
176
+
177
+ ## Running the tests
178
+
179
+ ```bash
180
+ pip install pytest
181
+ pytest tests/ -v
182
+ ```
183
+
184
+ ---
185
+
186
+ ## Bundled networks
187
+
188
+ ePyT ships with many standard benchmark networks including Net1, Net2, L-TOWN,
189
+ Hanoi, Anytown, Balerma and others. Use `list_bundled_networks` to discover
190
+ them all.
191
+
192
+ ---
193
+
194
+ ## License
195
+
196
+ MIT
@@ -0,0 +1,177 @@
1
+ # EPANET MCP Server
2
+
3
+ [![Linter](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/linter.yml/badge.svg?branch=main)](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/linter.yml)
4
+ [![Pytest](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server/actions/workflows/test.yml)
5
+
6
+ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that
7
+ exposes EPANET water-distribution network modelling capabilities through
8
+ [ePyT](https://github.com/KIOS-Research/EPyT) - the EPANET Python Toolkit.
9
+
10
+ Any MCP-compatible LLM can load water network models, run
11
+ simulations, modify parameters, and generate complex what-if scenarios through
12
+ natural language.
13
+
14
+ ---
15
+
16
+ ## Features
17
+
18
+ | Category | Tools |
19
+ |---|---|
20
+ | **Load & Inspect** | `load_network`, `unload_network`, `list_networks`, `list_bundled_networks`, `get_network_summary`, `get_nodes`, `get_links`, `get_patterns`, `get_controls`, `get_curves`, `get_options` |
21
+ | **Simulate** | `run_hydraulic_simulation`, `run_quality_simulation`, `run_full_simulation`, `get_pressure_at_time`, `get_flow_at_time` |
22
+ | **Modify** | `set_node_base_demand`, `set_pattern`, `add_pattern`, `set_pipe_diameter`, `set_pipe_roughness`, `set_pipe_status`, `set_pipe_length`, `set_pump_status`, `set_pump_speed`, `set_pump_head_curve`, `set_valve_setting`, `set_valve_status`, `set_tank_parameters`, `set_reservoir_head`, `set_simulation_duration`, `set_hydraulic_timestep`, `set_quality_timestep`, `set_quality_type`, `add_control`, `delete_control`, `save_network` |
23
+ | **Scenarios** | `create_demand_perturbation`, `create_leakage_event`, `create_contamination_event`, `create_pressure_change_scenario`, `create_pump_control_scenario`, `create_valve_control_scenario`, `create_multi_failure_scenario` |
24
+
25
+ ---
26
+
27
+ ## Requirements
28
+
29
+ - Python ≥ 3.10
30
+ - [ePyT](https://pypi.org/project/epyt/) ≥ 2.0
31
+ - [mcp](https://pypi.org/project/mcp/) ≥ 1.0
32
+
33
+ ```bash
34
+ pip install epyt mcp
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ git clone https://github.com/Applied-Artificial-Intelligence-Eurecat/epanet-mcp-server.git
43
+ cd epanet-mcp-server
44
+ pip install -e .
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Running the server
50
+
51
+ ### stdio (for Claude Desktop / Claude Code)
52
+
53
+ ```bash
54
+ epanet-mcp-server
55
+ # or
56
+ python -m epanet_mcp.server
57
+ ```
58
+
59
+ ### SSE / HTTP
60
+
61
+ ```bash
62
+ epanet-mcp-server --transport sse --port 8000
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Claude Desktop configuration
68
+
69
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`
70
+ (macOS) or the equivalent on your platform:
71
+
72
+ ```json
73
+ {
74
+ "mcpServers": {
75
+ "epanet": {
76
+ "command": "epanet-mcp-server",
77
+ "args": []
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ If not on `PATH`:
84
+
85
+ ```json
86
+ {
87
+ "mcpServers": {
88
+ "epanet": {
89
+ "command": "python",
90
+ "args": ["-m", "epanet_mcp.server"],
91
+ "cwd": "/path/to/epanet-mcp-server/src"
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Claude Code (`.mcp.json`)
100
+
101
+ Place this in the root of your project or `~/.claude/`:
102
+
103
+ ```json
104
+ {
105
+ "mcpServers": {
106
+ "epanet": {
107
+ "command": "epanet-mcp-server",
108
+ "args": []
109
+ }
110
+ }
111
+ }
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Example interactions
117
+
118
+ Once the server is connected, you can ask things like:
119
+
120
+ > **"Load Net1.inp and show me a summary of the network."**
121
+
122
+ > **"Run a hydraulic simulation and tell me which node has the lowest pressure at hour 12."**
123
+
124
+ > **"Double the base demand at junction 11 and re-run the simulation. How does pressure change?"**
125
+
126
+ > **"Simulate a burst on pipe 10 with a 20% leakage fraction."**
127
+
128
+ > **"Inject 10 mg/L of chlorine at node 11 between hours 1 and 3 and show me the contamination spread."**
129
+
130
+ > **"What happens to pressures if the reservoir head drops from 150 m to 120 m?"**
131
+
132
+ > **"Schedule Pump 9 to start at 06:00 and stop at 22:00."**
133
+
134
+ > **"Close pipes 10 and 11 and the pump simultaneously. Where are service disruptions?"**
135
+
136
+ ---
137
+
138
+ ## Architecture
139
+
140
+ ```
141
+ src/epanet_mcp/
142
+ ├── server.py # FastMCP server – tool registration + entry point
143
+ ├── session.py # Thread-safe registry of open ePyT sessions
144
+ ├── utils.py # numpy → Python serialisation helpers
145
+ └── tools/
146
+ ├── inspection.py # load / inspect network models
147
+ ├── simulation.py # run hydraulic & quality simulations
148
+ ├── modification.py# in-memory parameter changes
149
+ └── scenarios.py # what-if scenario generators (clone + modify + run)
150
+ ```
151
+
152
+ **Session model**: Each loaded network lives in a named session. Scenario
153
+ tools automatically clone the source session into a new independent session so
154
+ the baseline network is never mutated.
155
+
156
+ ---
157
+
158
+ ## Running the tests
159
+
160
+ ```bash
161
+ pip install pytest
162
+ pytest tests/ -v
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Bundled networks
168
+
169
+ ePyT ships with many standard benchmark networks including Net1, Net2, L-TOWN,
170
+ Hanoi, Anytown, Balerma and others. Use `list_bundled_networks` to discover
171
+ them all.
172
+
173
+ ---
174
+
175
+ ## License
176
+
177
+ MIT
@@ -0,0 +1,35 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "epanet-mcp-server"
7
+ version = "0.1.0"
8
+ description = "MCP server for EPANET water distribution network simulation via ePyT"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ keywords = ["epanet", "epyt", "mcp", "water-distribution", "hydraulic-simulation"]
13
+ dependencies = [
14
+ "mcp>=1.0.0",
15
+ "epyt>=2.0.0",
16
+ "numpy>=1.24.0",
17
+ "pandas>=2.0.0",
18
+ ]
19
+
20
+ [project.optional-dependencies]
21
+ dev = [
22
+ "pytest>=7.0",
23
+ "pytest-asyncio>=0.21",
24
+ "ruff>=0.1.0",
25
+ ]
26
+
27
+ [project.scripts]
28
+ epanet-mcp-server = "epanet_mcp.server:main"
29
+
30
+ [tool.setuptools.packages.find]
31
+ where = ["src"]
32
+
33
+ [tool.pytest.ini_options]
34
+ testpaths = ["tests"]
35
+ asyncio_mode = "auto"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """EPANET MCP Server – ePyT-powered water network simulation tools."""
2
+
3
+ __version__ = "0.1.0"