Swmm Builder

Dev Tools

Assemble a runnable SWMM INP deterministically from subcatchment geometry/attributes, merged parameter JSON, network JSON, and climate references. Use when creating auditable INP + manifest artifacts for downstream swmm-runner/calibration.

Install

openclaw skills install swmm-builder

SWMM Builder (INP assembly layer)

Part of Agentic SWMM — install the project first for the executable toolchain (aiswmm CLI, SWMM solver, MCP servers).

Contract

Build a runnable SWMM .inp using explicit file inputs:

  • subcatchments.csv (shape/area/outlet/routing basics)
  • merged params JSON from swmm-params
  • network JSON from swmm-network
  • rainfall/time-series references from swmm-climate
  • optional options config JSON

The builder writes:

  • final SWMM INP text (--out-inp)
  • manifest JSON (--out-manifest) with source paths + SHA256 + key metadata
  • strict validation diagnostics for critical sections ([OPTIONS], [RAINGAGES], [TIMESERIES], [SUBCATCHMENTS], [SUBAREAS], [INFILTRATION], and current network sections)

Inputs

Subcatchments CSV schema (required)

Required columns:

  • subcatchment_id
  • outlet
  • area_ha
  • width_m
  • slope_pct

Optional columns:

  • rain_gage (falls back to default gage from climate/config)
  • curb_length_m (default 0)
  • snow_pack (default blank)

Params JSON (required)

Expected to match skills/swmm-params/scripts/merge_swmm_params.py output:

  • sections.subcatchments (id, pct_imperv)
  • sections.subareas (id, runoff/subarea fields)
  • sections.infiltration (id, Green-Ampt fields)
  • Required fields are now validated strictly with type/range checks (for example %Imperv and routing percentages must be 0..100).

Network JSON (required)

Expected to match skills/swmm-network schema (junctions, outfalls, conduits, etc.). Builder now validates required network fields used to emit [JUNCTIONS], [OUTFALLS], [CONDUITS], [XSECTIONS], [COORDINATES], and [VERTICES].

Climate references (required in MVP)

Provide either:

  • --timeseries-text directly, or
  • --rainfall-json produced by swmm-climate/format_rainfall.py (must include outputs.timeseries_text)

For [RAINGAGES], provide either:

  • --raingage-json from swmm-climate/build_raingage_section.py, or
  • rely on default deterministic gage generation from rainfall series_name.

--raingage-json supports both the original single-gage form and a multi-gage form:

{
  "gages": [
    {
      "id": "RG1",
      "rain_format": "VOLUME",
      "interval_min": 5,
      "scf": 1.0,
      "source": {"kind": "TIMESERIES", "series_name": "TS_RG1"}
    },
    {
      "id": "RG2",
      "rain_format": "VOLUME",
      "interval_min": 5,
      "scf": 1.0,
      "source": {"kind": "TIMESERIES", "series_name": "TS_RG2"}
    }
  ]
}

The timeseries text must include rows for every referenced series_name, and each subcatchment rain_gage must reference one of the emitted gage IDs.

Validation behavior:

  • Missing critical fields fail fast with explicit section-scoped errors.
  • [TIMESERIES] rows are validated for series-name consistency and basic token/time/value correctness.
  • Manifest includes validation plus validation_diagnostics metadata.

Scripts

  • scripts/build_swmm_inp.py
    • single entrypoint that reads all inputs and writes INP + manifest.

MCP

MCP wrapper location:

  • mcp/swmm-builder/server.js (was previously skills/swmm-builder/scripts/mcp/; moved during the mcp/ root restructure)

Exposed tools:

  • build_inp — assemble a runnable SWMM INP + manifest from subcatchments CSV, area-weighted params JSON, network JSON, rainfall JSON + timeseries text, and an options-config JSON. Required args: subcatchmentsCsvPath, paramsJsonPath, networkJsonPath, outInpPath, outManifestPath. Optional: rainfallJsonPath, raingageJsonPath, timeseriesTextPath, configJsonPath, defaultGageId, waterQualityJsonPath (path to a WQ config JSON — enables [POLLUTANTS]/[LANDUSES]/[BUILDUP]/[WASHOFF]/[COVERAGES]/ [LOADINGS] sections for pollutant buildup/washoff simulation). The subcatchments CSV must carry outlet values that point to real upstream junctions (use swmm-network-mcp.assign_subcatchment_outlets first if it currently points to the literal outfall).

Smoke example

The builder requires upstream outputs from swmm-params and swmm-climate. Generate them first, then call build_swmm_inp.py:

# 1. Generate merged params from the bundled examples
mkdir -p /tmp/builder-smoke
python3 skills/swmm-params/scripts/landuse_to_swmm_params.py \
  --input skills/swmm-params/examples/landuse_input.csv \
  --output /tmp/builder-smoke/landuse.json
python3 skills/swmm-params/scripts/soil_to_greenampt.py \
  --input skills/swmm-params/examples/soil_input.csv \
  --output /tmp/builder-smoke/soil.json
python3 skills/swmm-params/scripts/merge_swmm_params.py \
  --landuse-json /tmp/builder-smoke/landuse.json \
  --soil-json /tmp/builder-smoke/soil.json \
  --output /tmp/builder-smoke/merged_params.json

# 2. Format rainfall from the bundled climate example
python3 skills/swmm-climate/scripts/format_rainfall.py \
  --input skills/swmm-climate/examples/rainfall_event.csv \
  --out-json /tmp/builder-smoke/rainfall.json \
  --out-timeseries /tmp/builder-smoke/rainfall_timeseries.txt

# 3. Build the INP
python3 skills/swmm-builder/scripts/build_swmm_inp.py \
  --subcatchments-csv skills/swmm-builder/examples/subcatchments_input.csv \
  --params-json /tmp/builder-smoke/merged_params.json \
  --network-json skills/swmm-network/examples/basic-network.json \
  --rainfall-json /tmp/builder-smoke/rainfall.json \
  --config-json skills/swmm-builder/examples/options_config.json \
  --out-inp /tmp/builder-smoke/example_model.inp \
  --out-manifest /tmp/builder-smoke/example_manifest.json

Water quality sections

Pass --water-quality-json <path> to enable pollutant buildup/washoff simulation. The JSON must satisfy the schema in skills/swmm-water-quality/SKILL.md. Omit the flag for pure hydrology runs (Water Quality: NO in the INP).

# Build an INP with water quality (TSS, 1 landuse, executed example):
python3 skills/swmm-builder/scripts/build_swmm_inp.py \
  --subcatchments-csv skills/swmm-builder/examples/subcatchments_input.csv \
  --params-json /tmp/builder-smoke/merged_params.json \
  --network-json skills/swmm-network/examples/basic-network.json \
  --water-quality-json /tmp/wq_example.json \
  --out-inp /tmp/wq_model.inp \
  --out-manifest /tmp/wq_manifest.json

The builder validates all cross-references (pollutant/landuse/subcatchment consistency) before writing the INP.

MVP limitations

  • No automatic polygon export, LID controls, snowpack, or RTC rules.
  • Assumes one raingage source for all subcatchments unless rain_gage is explicitly set per row.