Spaces:
Sleeping
Sleeping
File size: 9,360 Bytes
03e5849 85ece5b 03e5849 85ece5b c8f17d6 9e14867 c8f17d6 98c386f 0090fb6 9e14867 0090fb6 c8f17d6 98c386f 0090fb6 98c386f c8f17d6 9e14867 c8f17d6 9e14867 | 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 | ---
title: SWMM Analysis MCP Server
emoji: π§οΈ
colorFrom: blue
colorTo: red
sdk: docker
app_port: 7860
pinned: false
short_description: Dual-surface MCP + REST EPA-SWMM analysis server.
tags:
- mcp-server
- stormwater
- swmm
- hydrology
- agent
---
# π§οΈ SWMM Analysis MCP Server
A dual-surface **MCP + REST** server for deterministic EPA-SWMM stormwater analysis,
with a **built-in multi-provider agent**. Wraps the SWMM6 GIS Tool engine (Rev 23.2):
crash-isolated OpenSWMM simulation, result summaries, Calgary-style criteria
screening, deterministic QA/QC findings, engine-report (`.rpt`) reconciliation,
controlled scenario comparison, and Calgary SWMR draft report generation.
**All outputs are preliminary engineering screening β not professional
determinations.** Screening thresholds require confirmation by the responsible
engineer.
## Surfaces
| Surface | Endpoint | For |
|---|---|---|
| **MCP (Streamable HTTP)** | `https://<space-url>/mcp` | Claude Desktop / claude.ai, ChatGPT connectors, Gemini, Codex CLI, LangChain, n8n MCP node, Flowise, Langflow, local MCP clients |
| **REST / OpenAPI** | `POST /api/tool/{name}` Β· catalog `/api/tools` Β· schema `/openapi.json` | Custom GPT Actions, n8n HTTP nodes, webhooks, anything speaking OpenAPI |
| **Built-in agent** | `POST /api/agent` and MCP tool `agent_analyze` | One natural-language call; the server's own LLM loop plans and runs the tools |
| **Files** | `GET /files/{session_id}/{filename}` | Generated SWMR docx / audit-zip downloads |
## Tools (19)
`upload_model` β `run_simulation` β then: `get_node_results`, `get_link_results`,
`get_subcatchment_results`, `get_timeseries` (bounded series with authoritative
`time_of_peak`), `query_results` (validated JSON plans against a 34-table SQLite
store incl. the complete tokenized INP), `get_table_catalog`,
`calgary_screening`, `set_report_details` (site description, design objectives,
methodology, project metadata β see the swmr-site-details skill),
`set_report_configuration` (project-specific major routes, criteria,
classifications, drawing inventory, applicable reports and checklist overrides),
`preliminary_design_review` (deterministic findings register incl.
RPT-### reconciliation findings), `get_reconciliation`, `run_scenario` (base never
mutated; deterministic comparison), `attach_figure` (embed client-generated
PNG/JPEG figures into the audited report), `generate_report` (SWMR docx + audit
zip; APPENDIX D reproduces the model .inp and .rpt as fixed-width listings
per the Calgary checklist, with untruncated copies archived under `model/`), `list_sessions`, `close_session`, `agent_analyze`.
### Client-figure workflow (recommended)
When your LLM client plots a hydrograph or map from `get_timeseries` data,
do **not** let it rebuild the report document itself β that bypasses the
audited tables and provenance package. Instead:
1. Client generates the figure (its own sandbox / code interpreter).
2. `attach_figure(session_id, image_base64, caption, section="results")`.
3. `generate_report(...)` β the figure is embedded at the end of the matching
Heading-1 section with a caption labelling it *client-attached,
illustrative*, and it is archived in the audit zip under `figures/` with a
manifest. The report itself remains the server's verified artifact.
Typical CoC flow: **upload_model β set_report_details β
set_report_configuration β run_simulation β deterministic QA/QC and Calgary
screening β generate_report**, reusing the returned `session_id`. Sessions
expire after 6 h of inactivity.
Generated Calgary-style SWMR drafts include a deterministic depth-velocity
criteria figure immediately below Table 9. It plots the tabulated 2011
Alberta/Calgary envelope, the modeled overland-route depth/velocity pairs, and
peak flow by marker colour. The figure PNG and its criterion CSV are retained
in the audit ZIP. The report discloses straight-line interpolation and the need
to verify current and project-specific requirements.
The report also generates Figure 3-1, an automated SWMM model schematic, from
the tokenized INP. It uses `[COORDINATES]` and `[VERTICES]` when available,
falls back to a stable topology layout when coordinates are incomplete, shows
subcatchment runoff routing and hydraulic-link direction, and archives both the
PNG and a generation manifest. It is a topology aid and remains subject to
drawing-to-model reconciliation.
### Legacy zero-value solver options
For dynamic-wave models, explicit zero values for `MAX_TRIALS`,
`HEAD_TOLERANCE`, and `MIN_SURFAREA` are treated as legacy/default sentinels.
The uploaded INP remains immutable. The server creates and runs a derivative
execution copy with unit-aware EPA SWMM defaults, and records every
substitution plus the SHA-256 hashes of both files. Negative or non-numeric
values remain blocking configuration errors. The report audit ZIP retains both
the original and derivative INP files whenever normalization occurs.
## Connecting from each platform
Replace `SPACE` with this Space's direct URL, e.g.
`https://username-swmm-mcp.hf.space` (use the *direct* subdomain, not the
huggingface.co page URL).
### Claude (claude.ai web / desktop, remote connector)
Settings β Connectors β Add custom connector β URL: `SPACE/mcp`.
### Claude Desktop (mcp-remote bridge, or any stdio-only client)
```json
{
"mcpServers": {
"swmm-analysis": {
"command": "npx",
"args": ["-y", "mcp-remote", "SPACE/mcp"]
}
}
}
```
### ChatGPT
Settings β Connectors β Create β MCP server URL: `SPACE/mcp` (Developer mode).
Alternatively build a **Custom GPT** with Actions: import the schema from
`SPACE/openapi.json` β the REST surface is designed for this.
### Gemini CLI
```json
// ~/.gemini/settings.json
{ "mcpServers": { "swmm-analysis": { "httpUrl": "SPACE/mcp" } } }
```
### Codex CLI
```toml
# ~/.codex/config.toml
[mcp_servers.swmm-analysis]
url = "SPACE/mcp"
```
### n8n
- **MCP Client Tool node**: endpoint `SPACE/mcp`, transport *HTTP Streamable*.
- Or plain **HTTP Request** nodes against `POST SPACE/api/tool/{name}`.
- Or one-shot: `POST SPACE/api/agent` with `{"question": "...", "provider": "gemini"}`.
### Flowise / Langflow
Add the **Custom MCP** (Flowise) / **MCP Tools** (Langflow) component with a
Streamable-HTTP config pointing at `SPACE/mcp`; the tool list auto-populates.
### LangChain / LangGraph
```python
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"swmm": {"url": "SPACE/mcp", "transport": "streamable_http"}
})
tools = await client.get_tools() # bind to any model
```
### Local LLMs (Ollama, LM Studio, vLLM)
Two options:
1. Point any local MCP-capable client (e.g. LM Studio, mcp-use) at `SPACE/mcp`.
2. Reverse: let the **server's agent** use your local model β
`POST /api/agent` with `{"provider": "local", "base_url": "http://host:11434/v1", "model": "llama3.1", "question": "..."}`.
## Built-in agent
`POST /api/agent` body:
```json
{
"question": "Upload this model, run it, and screen velocities against Calgary criteria.",
"provider": "anthropic",
"inp_content": "<.inp text or base64>",
"session_id": "optional-existing-session",
"allow_report": false
}
```
Providers: `anthropic`, `openai`, `gemini`, `groq`, `mistral`, `local`
(OpenAI-compatible `base_url`). Keys come from **Space secrets**
(`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GEMINI_API_KEY`, `GROQ_API_KEY`,
`MISTRAL_API_KEY`) or a per-request `api_key`. Every response includes the
complete `tool_trace` audit trail (tool, arguments, elapsed time, result
preview) β the agent may only report numbers that came from tools.
> If your platform is already an MCP client, prefer driving the tools directly:
> your model is the agent, and it sees full (not previewed) tool results.
## Architecture notes
- **Crash isolation**: the native OpenSWMM engine runs only in a one-shot
subprocess in its own venv (`/opt/swmm-venv`); a segfaulting model cannot
take down the server.
- **Single source of truth**: MCP, REST, and the agent all dispatch to the
same typed registry (`tools.py`), so behaviour is identical per platform.
- **Result integrity**: every simulation is cross-checked against the
engine's own `.rpt` (velocity/flow/depth/continuity); disagreements surface
as `RPT-###` findings and the verdict is embedded in report manifests.
- **HF Spaces specifics baked in**: DNS-rebinding protection disabled for the
Spaces proxy, MCP session-manager lifespan wired into FastAPI, stateless
HTTP + JSON responses for maximum connector compatibility.
- **Sessions**: process-local with TTL sweep; Space restarts clear state
(persistent storage is not required for the workflow).
## Security
No authentication is enabled by default β anyone with the URL can run models
and (if Space secrets are set) spend your LLM keys via `/api/agent`. For
non-demo use, set the Space to private, or front it with an auth proxy, and
prefer per-request `api_key` over Space secrets.
## Local development
```bash
pip install -r requirements.txt
python -m venv /opt/swmm-venv && /opt/swmm-venv/bin/pip install -r worker-requirements.txt
SWMM_WORKER_PYTHON=/opt/swmm-venv/bin/python uvicorn server:app --port 7860
```
Free and non-commercial, for the water-engineering community. |