razaali10's picture
Update README.md
9e14867 verified
|
Raw
History Blame Contribute Delete
9.36 kB
---
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.