Spaces:
Sleeping
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:
- Client generates the figure (its own sandbox / code interpreter).
attach_figure(session_id, image_base64, caption, section="results").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 underfigures/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)
{
"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
// ~/.gemini/settings.json
{ "mcpServers": { "swmm-analysis": { "httpUrl": "SPACE/mcp" } } }
Codex CLI
# ~/.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/agentwith{"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
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:
- Point any local MCP-capable client (e.g. LM Studio, mcp-use) at
SPACE/mcp. - Reverse: let the server's agent use your local model β
POST /api/agentwith{"provider": "local", "base_url": "http://host:11434/v1", "model": "llama3.1", "question": "..."}.
Built-in agent
POST /api/agent body:
{
"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 asRPT-###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
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.