| --- |
| 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 |
| ``` |
|
|