File size: 4,626 Bytes
46b3ce7
90a51c6
 
46b3ce7
90a51c6
46b3ce7
 
 
 
 
90a51c6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758eab6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
---
title: Hydraulic Solver MCP Server
emoji: 💧
colorFrom: blue
colorTo: green
sdk: docker
pinned: false
license: mit
---

# Hydraulic Solver MCP + REST Server

This repository exposes the Hydraulic Solver Teaching Mode backend as two agent-facing surfaces over the same `hydraulic_core.py`.

| Surface | File | Serves |
|---|---|---|
| MCP server | `server.py` | Claude, Cursor, LM Studio, n8n, HuggingChat, Codex, LangChain/LangGraph, AutoGen |
| REST / OpenAPI | `rest_api.py` | ChatGPT Custom GPT Actions, Gemini, Zapier/Make/curl, HTTP clients |

The tool set is intentionally deterministic. The Gradio Space remains the human-facing teaching app; this server is the agent-facing calculation layer.

## Included tools

- `load_network`
- `upload_network`
- `close_session`
- `network_summary`
- `solve_single_pipe`
- `solve_hardy_cross_loop`
- `solve_two_loop_hardy_cross`
- `solve_three_reservoir`
- `solve_pdd_demand`
- `simulate_tank_eps`
- `evaluate_valve_behavior`
- `solve_pump_operating_point`
- `pressure_zone_analysis`
- `leakage_nrw_analysis`
- `water_age_analysis`
- `chlorine_decay_analysis`
- `generate_epanet_validation_inp`

## Unit systems

| Quantity | MKS | FPS |
|---|---:|---:|
| Flow/demand | L/s | gpm |
| Length/head | m | ft |
| Diameter | mm | in |
| Pressure | m of head | psi |

Internal calculations are SI-normalized.

## Local stdio MCP

```bash
pip install -r requirements.txt
python server.py
```

Claude Desktop local config:

```json
{
  "mcpServers": {
    "hydraulic-solver": {
      "command": "python",
      "args": ["/absolute/path/to/server.py"]
    }
  }
}
```

## Remote MCP on HF Spaces

The included `Dockerfile` runs MCP HTTP by default on port 7860.

Set Space secret:

```text
CLIENT_API_KEY=your-secret
```

Run command used by Docker:

```bash
TRANSPORT=http PORT=7860 python server.py
```

Expected MCP URL:

```text
https://your-space.hf.space/mcp
```

Some clients use SSE:

```bash
TRANSPORT=sse PORT=7860 python server.py
```

Expected SSE URL:

```text
https://your-space.hf.space/sse
```

## REST / OpenAPI surface

Run locally:

```bash
CLIENT_API_KEY=your-secret uvicorn rest_api:app --host 0.0.0.0 --port 8000
```

OpenAPI schema:

```text
http://localhost:8000/openapi.json
```

Interactive docs:

```text
http://localhost:8000/docs
```

For a REST HF Space, change the Dockerfile command to:

```dockerfile
CMD ["uvicorn", "rest_api:app", "--host", "0.0.0.0", "--port", "7860"]
```

Then use:

```text
https://your-rest-space.hf.space/openapi.json
```

## Platform guide

| Platform | Surface | Transport |
|---|---|---|
| Claude Desktop | MCP | stdio local or SSE remote via mcp-remote |
| Claude.ai web | MCP | Streamable HTTP |
| Cursor | MCP | stdio or HTTP |
| LM Studio | MCP | stdio or HTTP |
| n8n | MCP | HTTP Streamable |
| HuggingChat | MCP | Streamable HTTP |
| Codex | MCP | Streamable HTTP |
| LangChain / LangGraph | MCP | `langchain-mcp-adapters` |
| AutoGen | MCP | MCP extension |
| ChatGPT Custom GPT | REST | OpenAPI Action |
| Gemini | REST | OpenAPI function tool |
| Zapier / Make / curl | REST | HTTP |

## ChatGPT Custom GPT Action

Use the REST surface, not MCP.

In GPT Builder:

1. Create Action
2. Import schema from URL:
   ```text
   https://your-rest-space.hf.space/openapi.json
   ```
3. Authentication:
   - API Key
   - Bearer
   - paste your secret

## Example REST call

```bash
curl -X POST "https://your-rest-space.hf.space/tools/solve_three_reservoir" \
  -H "Authorization: Bearer your-secret" \
  -H "Content-Type: application/json" \
  -d '{
    "unit_system": "MKS / L/s",
    "reservoir_heads": [140, 120, 105],
    "demand": 20,
    "initial_head": 100,
    "lengths": [500, 700, 600],
    "diameters": [300, 250, 250],
    "c_values": [120, 120, 120]
  }'
```

## Important note

This package exposes the current teaching solvers and component-learning calculations. It is prepared for later WNTR/EPANET engine wiring, but it does not yet run a full WNTR hydraulic simulation unless you add a WNTR layer.


## HF App tab shows "Not Found" — fixed in v2

A pure MCP server does not behave like a Gradio app. The actual MCP endpoint is `/mcp`, so opening the Space root URL in a browser may show `Not Found` if no landing route is defined.

This v2 package adds:

- `/` human-readable status page
- `/health` JSON health check
- `/mcp` Streamable HTTP MCP endpoint
- bearer-token middleware for MCP routes when `CLIENT_API_KEY` is set

Expected browser checks:

```text
https://your-space.hf.space/
https://your-space.hf.space/health
```

Expected MCP client URL:

```text
https://your-space.hf.space/mcp
```