Hydrata - ANUGA Flood Simulation
REMOTE · HYDRATA.COM
Run ANUGA flood simulations, track progress, and retrieve results on Hydrata Cloud.
Available components
Last scanned (14 hours ago)
Scores higher than 26% of remote servers
Reachable. Last reached 5 Nov 2026.
Category Health and Science
How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →
Endpoint Security92
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- The endpoint enforces authorisation, advertised via RFC 9728 protected-resource metadata. View diagnostics → Pass
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- HSTS check failed: the Strict-Transport-Security header is absent. See how to fix → View diagnostics → Fail
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
- The authorisation server supports Client ID Metadata Documents, the current MCP client-registration mechanism. View diagnostics → Pass
Transport & Reachability0
- Transport blocked by authentication: the endpoint requires auth we don't have to verify streamable-http. See how to fix → View diagnostics → Unverified
Schema Quality & AI Usability0
- Schema blocked by authentication: the endpoint requires auth we don't have to read it. See how to fix → Unverified
Stability & Change Management0
- Stability not yet verified: not enough scan history yet (needs a 30-day window).Unverified
Tool Coverage0
- Tool coverage blocked by authentication: the endpoint requires auth we don't have to read its tools.Unverified
Tool Safety0
- Tool safety blocked by authentication: the endpoint requires auth we don't have to read its tools.Unverified
Capabilities0
- Capabilities blocked by authentication: the endpoint requires auth we don't have to read them. See how to fix → Unverified
Unverified: 6 categories
Categories scored 0 because we could not verify them: authentication we do not have, an unreachable endpoint, or not enough scan history. We only credit what we can confirm. Claim this server and supply a read-only token to verify it and lift the score.
Checks we ran (5)
- TLS certificate
- Authorization
- HTTPS
- HSTS header
- DNSSEC
Checks we could not complete (6)
These are gaps on our side, not findings about this hosted endpoint. We only credit what we can confirm, so a category made up entirely of them scores 0.
- Transport in Transport & Reachability (scores 0 for this)Transport blocked by authentication: the endpoint requires auth we don't have to verify streamable-http.
- Schema quality in Schema Quality & AI Usability (scores 0 for this)Schema blocked by authentication: the endpoint requires auth we don't have to read it.
- Stability in Stability & Change Management (scores 0 for this)Stability not yet verified: not enough scan history yet (needs a 30-day window).
- Tool coverage in Tool Coverage (scores 0 for this)Tool coverage blocked by authentication: the endpoint requires auth we don't have to read its tools.
- Tool safety in Tool Safety (scores 0 for this)Tool safety blocked by authentication: the endpoint requires auth we don't have to read its tools.
- Capabilities in Capabilities (scores 0 for this)Capabilities blocked by authentication: the endpoint requires auth we don't have to read them.
Does not apply to this hosted endpoint (2)
- Supply Chain SecurityScored on package channels only. This is a hosted endpoint, so there is nothing to install or inspect.
- Provenance & TransparencyScored on package channels only. This is a hosted endpoint, so there is nothing to install or inspect.
The score does not measure everything. What the score does not measure →
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 23 Oct 26 −53
- Endpoint reachability: reachable → behind authorisation ▼ security
- Stability: pass → unverified ▼ security
- Tool safety: pass → unverified ▼ security
- Transport: pass → unverified ▼ security
- Authorization: The endpoint enforces authorisation, advertised via RFC 9728 protected-resource metadata. security
- Capabilities: pass → unverified ▼ functional
- Tool coverage: 100 → unverified ▼ functional
- First check of Schema quality: unverified functional
- 22 Oct 26 +3
- Authorization: fail → pass ▲ security
- First check of Authorization: pass security
- The server rewrote its instructions, which are the text every model session reads security
- Tool “attach_input_layer” rewrote its description, which is the text the model reads security
- Tool “build_scenario” rewrote its description, which is the text the model reads security
- Tool “cancel_run” rewrote its description, which is the text the model reads security
- Tool “create_project” rewrote its description, which is the text the model reads security
- Tool “create_time_series” rewrote its description, which is the text the model reads security
- Tool “finalize_terrain_upload” rewrote its description, which is the text the model reads security
- Tool “get_scenario” rewrote its description, which is the text the model reads security
- Tool “list_inputs” rewrote its description, which is the text the model reads security
- Tool “presign_terrain_upload” rewrote its description, which is the text the model reads security
- Tool “retry_run” rewrote its description, which is the text the model reads security
- Tool “start_simulation” rewrote its description, which is the text the model reads security
- Schema quality: 329 → 385 ▼ functional
- “create_time_series” added an optional parameter “hold_last_value” cosmetic
- “start_simulation” added an optional parameter “consent_timeout_seconds” cosmetic
- “start_simulation” added an optional parameter “poll_interval_seconds” cosmetic
- “create_time_series” reworded the description of “units” cosmetic
- 20 Oct 26 0
- The server rewrote its instructions, which are the text every model session reads security
- New tool “delete_observation”, which the server declares destructive security
- Schema quality: 6701 → 9225 ▼ functional
- Destructive annotations: pass → 100 functional
- New tool “add_observation_photo_link” functional
- New tool “add_observations” functional
- New tool “create_observation_layer” functional
- New tool “get_observation_comparison” functional
- New tool “list_observations” functional
- New tool “set_comparison_tolerance” functional
- New tool “set_observation_exclusion” functional
- New tool “update_observation” functional
- 16 Oct 26 0
- Tool “attach_input_layer” rewrote its description, which is the text the model reads security
- 15 Oct 26 0
- The server rewrote its instructions, which are the text every model session reads security
- Tool “attach_input_layer” rewrote its description, which is the text the model reads security
- Tool “get_scenario” rewrote its description, which is the text the model reads security
- Tool “list_inputs” rewrote its description, which is the text the model reads security
- “create_scenario” added an optional parameter “culvert” cosmetic
- “attach_input_layer” reworded the description of “kind” cosmetic
- 10 Oct 26 0
- Schema quality: 5178 → 6256 ▼ functional
- 28 Sept 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
- 25 Sept 26 0
- We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 5 Nov 2026 · Probed https://hydrata.com/mcp/
TLS valid
Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .
| Subject | Issuer | Valid from | Valid until | Key | Signature | Serial |
|---|---|---|---|---|---|---|
| CN=hydrata.com | CN=YR2,O=Let's Encrypt,C=US | 26 Sept 2026 | 25 Dec 2026 | RSA 2048 | SHA256-RSA | 63fa367fad628796f28c31cf71bde0b980c |
| SANs: backlog.hydrata.com, hydrata.com | ||||||
| CN=YR2,O=Let's Encrypt,C=US (CA) | CN=Root YR,O=ISRG,C=US | 3 Sept 2025 | 2 Sept 2028 | RSA 2048 | SHA256-RSA | 4ebd24947e24d394802d84a52fd5b319 |
| CN=Root YR,O=ISRG,C=US (CA) | CN=ISRG Root X1,O=Internet Security Research Group,C=US | 13 May 2026 | 2 Sept 2032 | RSA 4096 | SHA256-RSA | f24b6d17f9d9ad7cb1c9fea78782699f |
Background: What to check on a remote MCP endpoint →
DNSSEC insecure
Validation of hydrata.com. — Not signed
| Zone | DS | Keys | Algorithms | Outcome |
|---|---|---|---|---|
| . | Trust anchor | 20326, 38696 | 8, 8 | Verified |
| com. | DS published | 19718 | 13 | Verified |
| hydrata.com. | No DS | Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation |
Authentication Enforced and verified
The endpoint asked for a token and published valid RFC 9728 metadata describing how to get one.
| Result | Enforced and verified |
|---|---|
| Enforced | On connection |
| HTTP status | 401 |
WWW-Authenticate challenge Bearer realm="hydrata.com", resource_metadata="https://hydrata.com/.well-known/oauth-protected-resource/mcp/"
Bearer realm="hydrata.com", resource_metadata="https://hydrata.com/.well-known/oauth-protected-resource/mcp/" | Header | Value |
|---|---|
| permissions-policy | camera=(), microphone=(), geolocation=(self), payment=() |
| www-authenticate | Bearer realm="hydrata.com", resource_metadata="https://hydrata.com/.well-known/oauth-protected-resource/mcp/" |
Protected resource metadata
| Document | https://hydrata.com/.well-known/oauth-protected-resource/mcp/ |
|---|---|
| Retrieved | Yes |
| Resource | https://hydrata.com/mcp/ |
| Authorisation server | https://cozy-steam-24.authkit.app |
Background: How OAuth 2.1 works in the 2026 MCP spec →
Transports 2 probes
| Transport | URL | Outcome | Status | Location |
|---|---|---|---|---|
| streamable-http | https://hydrata.com/mcp/ | Auth required | 401 | |
| http (plaintext) | http://hydrata.com/mcp/ | HTTPS enforced | 301 | https://hydrata.com/mcp/ |
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
add_observation_photo_link Attach a photo link to a flood observation ~211
Attach a photo to a flood observation as a reference LINK (never a file). MCP never uploads photo bytes. A local path, file:// URL or data: URI is refused: to upload a photo file, open the observation in the map and use the photo strip on its form (JPEG, PNG or HEIC, 25 MB, 10 per observation). The link counts toward the 10.
| Name | Type | Req | Description |
|---|---|---|---|
| caption | string | – | What the photo shows (optional, up to 500 characters) |
| credit | string | – | Who took it / the rights holder (optional) |
| fid | integer | yes | The observation's fid |
| layer_id | integer | yes | The flood observation layer id |
| project_id | integer | yes | The project ID |
| public_consent | boolean | – | Show this photo to visitors of a public project (default false: members only) |
| reference_url | string | yes | An http(s) link to the photo (stored, never fetched) |
Structured output declared, but exposes no named fields.
No examples provided.
add_observations Add flood observations to a layer ~503
Add flood observations (Flood mark, Timed level, Gauge record, Dry point) to a layer. POSTs each observation to /projects/<id>/flood-observations/<layer>/observations/ in order. The API validates every field: a row it refuses (400) is listed in `rejected` with its `problems` and the rest still land; a refusal that is not about the row (403 not an Editor, 404, 409) stops the batch and is reported in `stopped`, with `not_sent_count`. Stages are on the LAYER's vertical datum. Photos are not part of an observation: attach a link with add_observation_photo_link.
| Name | Type | Req | Description |
|---|---|---|---|
| entry_timezone | – | – | IANA zone for naive observed_start/observed_end on rows that do not carry their own entry_timezone; omit to use the project's zone (derived from where the project is, reported back as entry_timezone)… |
| layer_id | integer | yes | The flood observation layer id (create_observation_layer / list_observations) |
| observations | array | yes | Observations, each the API write body: subtype (flood_mark | timed_level | gauge_record | dry_point), name (required: a short label, e.g. the survey mark id), geometry {type: Point, coordinates: [lon… |
| project_id | integer | yes | The project ID |
| srid | – | – | EPSG code for every geometry that does not carry its own `srid` (the projected CRS its eastings/northings are in, e.g. a UTM zone); omit for [lon, lat] (EPSG:4326) |
Structured output declared, but exposes no named fields.
No examples provided.
attach_input_layer Attach an uploaded layer as a project input ~1,142
Attach a GeoJSON you uploaded to GeoNode as the project's boundary, friction, inflow, rainfall, building, mesh_region or culvert layer. The agent moves the bytes: first upload the GeoJSON yourself, with the same agent key, to GeoNode's upload endpoint at the site origin: curl -sS -H 'Authorization: Bearer hk_...' -F "base_file=@/path/rainfall.geojson" https://<site>/api/v2/uploads/upload/ → JSON with `execution_id`. Then call this tool with it. The tool polls GET /api/v2/resource-service/execution-status/<execution_id> (bounded by timeout_seconds; statuses ready → running → finished | failed), reads the new dataset's pk, and PATCHes it onto the project's DEFAULT row of that kind ('Boundary 01' … 'MeshRegion 01' — the six rows the terrain import seeds ~30 s after get_terrain reports ready; if the list is still empty the tool says so: run finalize_terrain_upload / wait for get_terrain first). kind `culvert` (Hydraulic Structures; one two-point line per culvert, Inlet first, then Outlet): no culvert row is seeded, so the tool creates 'Culvert 01' when the project has none and waits for its layer. It reads your culverts back and maps your attribute names onto the culvert fields — name, shape (box|circular), width_m, height_m, diameter_m, upstream_invert_m, downstream_invert_m, barrels (1-20), wall_thickness_m, entrance_type, material (concrete|corrugated_metal), manning_n, blockage_pct (Reduced-area blockage, percent), length_override_m, description — accepting common alternatives (width, diameter, label, us_invert, ds_invert, num_barrels, manning, blockage, length, shape 'pipe' = circular, …) and filling the defaults (barrels 1, wall 0.20 m, square_edge_headwall, concrete, manning_n from the material, blockage 0). Other attributes are kept. If anything changed it re-uploads the mapped culverts and attaches THAT layer (`mapped`: renamed, filled, source_dataset_pk). `culvert_problems` lists what the build will still refuse (typically missing inverts) — the user…
| Name | Type | Req | Description |
|---|---|---|---|
| execution_id | string | yes | `execution_id` returned by your multipart POST to <origin>/api/v2/uploads/upload/ |
| kind | string | yes | Which input the uploaded layer is: boundary, friction, inflow, rainfall, building, mesh_region or culvert ('structure' is a deprecated alias of building). breakline is refused (see below). |
| poll_interval_seconds | number | – | Seconds between polls (default 5) |
| project_id | integer | yes | The project ID |
| timeout_seconds | integer | – | How long this call keeps polling the upload before it returns `timed_out` (default 240, ceiling 280 — the prod /mcp/ proxy cuts a call at 300 s). 0 = one status read, no waiting. |
Structured output declared, but exposes no named fields.
No examples provided.
build_scenario Build a scenario's mesh and package ~1,146
Build a scenario's package (mesh + inputs) after showing what it will cost, and poll until built. Needs a launch-level agent key (a build can start AWS Batch); a read or draft key gets 403 AGENT_LEVEL_INSUFFICIENT — the user creates a launch key on the site's Agent keys page (/agents/). Order of operations, so the number is shown before anything is spent: 1. GET the scenario detail. A record with no `boundary`/`computed_status` keys is a non-member's read of a public project → refused: a build needs the EDITOR role. 2. Re-call checks on `latest_run` (a re-POST is NOT deduplicated after `built`/`complete` — it would dispatch a duplicate build): no run → proceed; run `created`/`building` → resume polling, no POST; run `built`/`queued`/`computing`/`processing`/`complete` with `latest_run_is_valid` not false → return that state, no POST unless rebuild=true; run `error`/`cancelled`, or `latest_run_is_valid` false (the scenario was edited since the build) → proceed. 3. Spend gates, each a refusal with `outcome: "refused"` and no POST: the scenario has no boundary or its boundary row has no features (the server would admit the build and fail it in make_package); the estimate is None (resolution is 0/unset); the estimate is above 100,000 triangles and confirm is not true — the refusal states the number; re-call with confirm=true to proceed. An estimate of 0 over a boundary WITH features is buildable and is reported, not refused. 4. POST /projects/<id>/scenarios/<pk>/build/. Every 4xx comes back verbatim as a normal result with `http_status`: 422 MESH_TOO_LARGE (`error_code`, `estimate`, `ceiling`, `detail` — the server's hard ceiling; coarsen `resolution` or shrink the boundary; no run was created), 409 COMPUTE_TARGET_UNAVAILABLE, 400/403/404. 409 UNREVIEWED_INPUTS (inputs you wrote that the user has not reviewed) answers `outcome` `unreviewed_inputs` with the `unreviewed_inputs` list and a `ui_url` to the s…
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | Required (true) when the estimate is above 100,000 triangles — the tool refuses first and tells you the number. Default false. |
| poll_interval_seconds | number | – | Seconds between polls (default 5) |
| project_id | integer | yes | The project ID |
| rebuild | boolean | – | true to dispatch a NEW build of a scenario whose latest run is already built/complete and still valid (default false: the tool returns that state instead of duplicating the build). |
| scenario_id | integer | yes | The scenario ID from create_scenario |
| timeout_seconds | integer | – | How long this call keeps polling before it returns `timed_out` (default 240, ceiling 280 — the prod /mcp/ proxy cuts a call at 300 s). 0 = one status read, no waiting. |
Structured output declared, but exposes no named fields.
No examples provided.
cancel_run Cancel a run ~106
Cancel an in-flight simulation run. Needs a launch-level agent key; a read or draft key gets 403 AGENT_LEVEL_INSUFFICIENT. Works on runs in built, queued, or computing status. Cleans up compute resources (terminates EC2 instance, Celery task, or Batch job). Returns 409 if the run is already in a terminal state (complete, cancelled, or error).
| Name | Type | Req | Description |
|---|---|---|---|
| run_id | integer | yes | The run ID to cancel |
Structured output declared, but exposes no named fields.
No examples provided.
create_observation_layer Create a flood observation layer ~320
Create a flood observation layer in a project and wait for its map layer. A flood observation layer holds real flood evidence (Flood marks, Timed levels, Gauge records, Dry points) that every historic run is compared with (Compare with observations). It is project-level: it is never a scenario input. POSTs /projects/<id>/flood-observations/, then polls the layer until its GeoServer layer exists (`ready`), usually a few seconds; until then add_observations refuses. On `timed_out`, call list_observations later.
| Name | Type | Req | Description |
|---|---|---|---|
| datum_offset_m | – | – | Metres ADDED to every stage on the layer to bring it onto the terrain datum. Required for vertical_datum=local; null means 0 otherwise |
| poll_interval_seconds | number | – | Seconds between layer polls |
| project_id | integer | yes | The project ID |
| timeout_seconds | integer | – | How long to wait for the map layer (clamped to 280) |
| title | string | yes | Layer title, e.g. 'August 1998 survey' |
| vertical_datum | string | – | The datum the layer's stages are on: terrain (default, 'Same as terrain'), local ('Local datum (constant offset)', needs datum_offset_m), or the vertical datum the levels were surveyed on: an EPSG ve… |
Structured output declared, but exposes no named fields.
No examples provided.
create_project Create a project ~202
Create a new ANUGA project. Returns the project record including its id, base_map and ui_url. The caller's own account becomes the owner. `projection` is the projected CRS every scenario in the project is meshed and run in — pick the UTM zone covering the site. The project's map is created alongside it; `ui_url` opens it — give it to the user. A project you create is unpublished (`is_published: false`): only its owner and members can see it until the user presses Publish in its Sharing panel in the browser — you cannot publish it. Next step for a new project: presign_terrain_upload.
| Name | Type | Req | Description |
|---|---|---|---|
| name | string | yes | Project name |
| projection | string | yes | Working CRS as an EPSG string, normally the UTM zone of the site, e.g. 'EPSG:32756' (WGS 84 / UTM 56S) |
Structured output declared, but exposes no named fields.
No examples provided.
create_scenario Create a draft scenario ~773
Create a DRAFT scenario (no build, no run) and report its mesh-triangle estimate. POSTs /projects/<id>/scenarios/ with the write fields, then GETs the scenario detail — the create response carries NO estimate; the detail's `mesh_triangle_count_estimate` (+ `_breakdown`) does. Returns a compact record (the same fields get_scenario answers with): id, name, the FK ids as stored, resolution, duration, `computed_status` (`created` = no run yet), the estimate and its breakdown, the price (`compute_cost_estimate` in USD, `vcpu_hours_estimate`), `inflow_anchor_mismatch`, and http_status. Next step: build_scenario (which asks for confirm=true above 100,000 triangles). Nothing is meshed or queued here. Units: `resolution` — on the SCENARIO and on every MeshRegion FEATURE — is a LENGTH in metres; ANUGA maximum_triangle_area = resolution²/2 (FloatField default 100, not nullable; 0 makes the estimate None), and the estimate prices both the same way (TASK-3186). The smallest value becomes the raster cell size. A MeshRegion feature must carry `resolution_units = m` (features drawn in the map are marked automatically); an unmarked one makes the build answer 422 MESH_REGION_UNITS_UNMARKED, naming the conversion an operator runs. The server does NOT validate that the FK ids belong to `project_id` — pass the row ids attach_input_layer / get_terrain returned for THIS project. Every FK is nullable at create time, and the build fails later on a scenario with no terrain, or with neither an inflow nor a rainfall. A `boundary` whose row has no features (the default 'Boundary 01' before attach_input_layer) is accepted here and refused by build_scenario. The estimate is None when resolution is 0; an estimate of 0 with a real boundary is a very coarse mesh, not an error.
| Name | Type | Req | Description |
|---|---|---|---|
| boundary | – | – | Boundary row id (attach_input_layer kind=boundary → row_id) |
| building | – | – | Building row id (optional) |
| culvert | – | – | Culvert row id (optional; attach_input_layer kind=culvert → row_id). The build refuses a culvert missing its shape, size or invert levels. |
| description | string | – | Free-text description (optional) |
| duration | integer | yes | Simulation duration in seconds (e.g. 43200 = 12 h) |
| friction | – | – | Friction row id (optional) |
| inflow | – | – | Inflow row id (optional; the build needs an inflow OR a rainfall) |
| mesh_region | – | – | MeshRegion row id (optional): finer meshing inside its polygons, each feature's `resolution` a LENGTH in metres (see the units note). |
| name | string | yes | Scenario name |
| project_id | integer | yes | The project ID |
| rainfall | – | – | Rainfall row id (optional; the build needs an inflow OR a rainfall) |
| resolution | number | yes | Mesh resolution as a LENGTH in metres (ANUGA maximum_triangle_area = resolution²/2). Coarser (larger) = fewer triangles: on a ~13 km² boundary 36-40 m gives ~16-20k triangles, 10 m ~255k, 1 m ~25M (r… |
| structure | – | – | Deprecated alias of `building` (TASK-3586); ignored when `building` is given. |
| terrain | – | – | Terrain id (get_terrain → terrain.id); the build fails without one |
Structured output declared, but exposes no named fields.
No examples provided.
create_time_series Create a time series ~672
Create a time series (rain gauge, hydrograph, tide/stage) in a project. POSTs /projects/<id>/time-series/ with `series_type` and `units` as top-level fields. `series_type` is checked against the four choices and `data` against the {"rowData": [{timestamp, value}, ...]} shape before any request is made — the API answers 500 (not 400) to a malformed row. Returns a compact record — id, name, series_type, units, timezone, row_count, http_status — not the echoed rows; fetch the full row with the REST API (GET /projects/<id>/time-series/<id>/) if you need to round-trip it. A rainfall polygon references its gauge by the series NAME, so create the gauges with the exact names the rainfall GeoJSON's features carry. The units must match the series_type (see `units`), and a hydrograph or hyetograph must END at 0 unless `hold_last_value` is true. The result carries Hydrata's own `summary` of the series (peak, volume or depth, first and last stamp, trailing value): repeat those numbers to the user (`say_to_user` does) rather than computing your own.
| Name | Type | Req | Description |
|---|---|---|---|
| data | object | yes | The rows: {"rowData": [{"timestamp": "1998-08-17T00:00:00", "value": 1.5}, ...]}. Timestamps ISO 8601 (a trailing Z is tolerated), values numeric. Validated here before anything is sent. |
| description | string | – | Free-text description (optional) |
| hold_last_value | boolean | – | Set true ONLY when the last value is meant to be held after the series ends. A hydrograph or hyetograph whose last value is not 0 is refused (TRAILING_VALUE_HELD) unless this is true: end the series… |
| location_name | string | – | Human-readable location of the gauge (optional) |
| name | string | yes | Series name, kept VERBATIM — a rainfall polygon binds to its gauge by this exact name (its `data` property), so use the name the GeoJSON features carry |
| project_id | integer | yes | The project ID |
| series_type | string | – | One of hyetograph (rainfall depth/intensity — the default), hydrograph (flow, read by the Hydrographs panel and inflow boundaries), stage (water level, e.g. a tide) or generic. Sent as a top-level fi… |
| source | string | – | Where the data came from, e.g. a gauge id or agency (optional) |
| timezone | string | – | IANA timezone of the timestamps (default 'UTC'), e.g. 'Australia/Sydney' |
| units | string | – | Units of the values. REQUIRED for hyetograph ('mm/hr' or 'mm/h'), hydrograph ('m3/s', 'm^3/s' or 'cumec') and stage ('m'): the engine reads those units whatever the label says, so a mismatch is refus… |
Structured output declared, but exposes no named fields.
No examples provided.
delete_observation Delete one flood observation ~92
Delete one flood observation and its photos (cannot be undone). DELETEs /projects/<id>/flood-observations/<layer>/observations/<fid>/; a missing fid is an error (404), not a silent success.
| Name | Type | Req | Description |
|---|---|---|---|
| fid | integer | yes | The observation's fid |
| layer_id | integer | yes | The flood observation layer id |
| project_id | integer | yes | The project ID |
Structured output declared, but exposes no named fields.
No examples provided.
finalize_terrain_upload Register an uploaded terrain ~292
Step 2 of a terrain import: register the PUT GeoTIFF as a Terrain and start the import. Needs a launch-level agent key (the import can start AWS Batch); a read or draft key gets 403 AGENT_LEVEL_INSUFFICIENT — the user creates a launch key on the site's Agent keys page (/agents/). Call this only after the presigned PUT returned 200. Creates the Terrain row (status `creating`) and queues the import chain — reproject to UTM, publish the layer + hillshade, style — which also seeds the project's six default boundary, friction, inflow, rainfall, building and mesh-region rows. Returns 202 with the terrain record; keep its `id` for get_terrain. A 400 UPLOAD_NOT_FOUND means no object is at `staging_key`: the PUT did not land (check its status code and Content-Type) — do not retry finalize until it has.
| Name | Type | Req | Description |
|---|---|---|---|
| process_id | string | – | `process_id` returned by presign_terrain_upload (pass it so the upload's progress record is reused; the API tolerates its absence) |
| project_id | integer | yes | The project ID |
| staging_key | string | yes | `staging_key` returned by presign_terrain_upload |
| title | string | – | Terrain title (default: the filename without .tif) |
Structured output declared, but exposes no named fields.
No examples provided.
get_observation_comparison Compare a run with flood observations ~535
Compare a run with the project's flood observations: how well does it match them? Returns `headline` (the figures to tell the user, e.g. "47 observations · 31 within ±0.30 m (66%) · bias -0.12 m · RMSE 0.35 m · 1 excluded"), `headline_numbers` (the same as numbers), `tolerance_m` (used) and `default_tolerance_m` (the project's saved one), `statistics` (the API's summary: n, within, within_pct, bias_m, rmse_m, weighted_rmse_m, mae_m, max_abs_m, excluded, not_scored by reason, gauges), `gauges` (Gauge records: peak error, timing error, NSE), `datum_checks` (warn the user only when `warning` is true: both datums known and different; `not_recorded` = the terrain has no recorded datum, stated in `note`, not a warning) and one row per observation: observed_m / modelled_m / residual_m (modelled - observed, + = model high), within, scored / not_scored_reason, match (`outside_run_window` = not this flood), excluded + exclusion {reason, by, at}. `sampling` counts how the modelled values were read: `centroid` (the peak of the mesh triangle the observation sits in), `nearest_node_fallback` (an older run without that peak: the nearest mesh node's value, tell the user) and `nearest_node` (just outside the mesh); each row's `sample.method` says which. There is no pass or fail: report the figures. A run that is not historic has none (`has_comparison` false) — do not retry it.
| Name | Type | Req | Description |
|---|---|---|---|
| fid | – | – | With layer_id: the observation's fid (list_observations) |
| include_series | boolean | – | Keep each Gauge record's modelled stage series (every saved frame); default false |
| layer_id | – | – | With fid: narrow the rows to ONE flood observation and add its history |
| run_id | integer | yes | The run ID (a historic run; others are not compared with observations) |
| tolerance | – | – | Metres within which a residual counts as within (default: the project's saved tolerance, 0.3 unless an Editor changed it; presets 0.15, 0.3, 0.4; above 0 and at most 5). Not stored: it only changes t… |
Structured output declared, but exposes no named fields.
No examples provided.
get_project Get a project and its map link ~145
Get one ANUGA project: id, name, projection, visibility, your role, its base map — and the link to it. Returns the project record (`id`, `name`, `projection` (EPSG code), `simple_view_config`, `visibility`, `owner_username`, `my_role`, `base_map`) plus `ui_url`: the link that opens the project's map, for the user (`<site>/catalogue/#/map/<base_map>`; null while a new project's map is still being created). Scenarios are NOT listed here — use get_scenario with a scenario id.
| Name | Type | Req | Description |
|---|---|---|---|
| project_id | integer | yes | The project ID |
Structured output declared, but exposes no named fields.
No examples provided.
get_run Get a run's full record ~143
Get full details of a simulation run including timing and results. Returns the complete run record: status, progress, timing (start/end timestamps, duration), compute details (backend, instance type, cost), mesh info, error messages, and result log. Use get_run_status for lightweight polling; use this for final results. The presigned `s3_*_url` download links are ELIDED — each is a 6-hour capability and no tool relays one. The results stay viewable through the `gn_layer_*` entries (published WMS layers on the project's map).
| Name | Type | Req | Description |
|---|---|---|---|
| run_id | integer | yes | The run ID |
Structured output declared, but exposes no named fields.
No examples provided.
get_run_status Poll a run's status ~143
Lightweight status check for a simulation run (fast, <50ms). Use this for polling instead of get_run. Returns only: id, status, `phase`, progress_pct (0-100), eta_seconds, error_message, and compute_backend. `phase` is never empty: it is `status`, except `preparing_inputs` while a `computing` run has no progress yet (it is downloading its input package and building the domain — minutes on a big model; this is NOT a stall). Poll every 5-10 seconds. Terminal states: complete, error, cancelled.
| Name | Type | Req | Description |
|---|---|---|---|
| run_id | integer | yes | The run ID |
Structured output declared, but exposes no named fields.
No examples provided.
get_scenario Get a scenario's state, inputs and price ~649
Get a scenario's COMPACT state: its `computed_status`, inputs, estimate and price. Returns a compact record, never the raw ~50 KB detail: `scenario_id`, `computed_status`, `mesh_triangle_count_estimate` and its `_breakdown`, `latest_run_is_valid`, the latest run's `run_id`, `run_status`, `error_message`, `user_message`, `status_detail` and `mesh_triangle_count` — plus what the scenario IS and what it will cost: `name`, `description`, `project`, `resolution`, `duration`, the input row ids (`terrain`, `boundary`, `friction`, `inflow`, `rainfall`, `building`, `mesh_region`, `culvert`), `compute_cost_estimate` (USD), `vcpu_hours_estimate`, and `inflow_anchor_mismatch` (null unless an inflow series starts after the model does, whose first value is then held backwards), and `hydrology_check` (when Hydrata sends it: for each inflow and rainfall feature, the series that drives it, its peak and volume, and structured warnings — repeat those numbers to the user, never your own), and `unbound_series` with a `say_to_user` warning when the project holds a rainfall or flow series that no inflow or rainfall feature uses (the model ignores it: tell the user and ask which input it belongs to). The `computed_status` field (there is NO `status` key on a scenario) is derived from the latest run and will be one of: created, building, built, queued, computing, processing, complete, error, or cancelled — `created` also means no run exists yet. A scenario must be `built` before it can be run. `latest_run_is_valid` is false after any edit since the last build. `unreviewed_inputs` lists the inputs written by an agent key that the user has not reviewed at their current content (kind, layer_id, title, feature_count, the grant that wrote it, `reopened` when an edit undid an earlier input review): while it is not empty, build and run are refused UNREVIEWED_INPUTS. Only the user reviews, in the browser — poll this tool every 30-60 s after giving them the review link. A non-member reading a pub…
| Name | Type | Req | Description |
|---|---|---|---|
| project_id | integer | yes | The project ID |
| scenario_id | integer | yes | The scenario ID |
Structured output declared, but exposes no named fields.
No examples provided.
get_terrain Wait for a terrain import ~452
Poll a terrain's import until it is `ready` (or `error`), bounded by timeout_seconds. Returns `outcome` — exactly one of `ready`, `error`, `timed_out`, `not_found` (the project has no terrain yet; an unknown terrain_id is an API 404 error instead) — plus the last `status` seen (creating → styling → ready | error) and `phase` (that status, or `not_found`; never empty), `polls`, `elapsed_seconds` and the full `terrain` record (its `gn_layer` is the published elevation dataset pk once ready). An import takes minutes to tens of minutes (the SAME 32 MB 1 m DEM measured 4.5 min once and 26 min once — the worker's S3 download speed dominates), so `timed_out` is normal and NOT a failure: keep calling with the same arguments while `status` is still `creating`/`styling`; several calls in a row is expected. `error` is terminal — the import failed and no default input rows were seeded; upload a corrected GeoTIFF as a new terrain. `ready` is written by the import task; the project's default input rows (Boundary 01, Friction 01, Inflow 01, Rainfall 01, Building 01, MeshRegion 01, one GeoNode layer each) are seeded by the NEXT task in the chain and appear over the following ~30 s. Poll the input-layer list until it is non-empty before attaching your own layer to a default row.
| Name | Type | Req | Description |
|---|---|---|---|
| poll_interval_seconds | number | – | Seconds between polls (default 5) |
| project_id | integer | yes | The project ID |
| terrain_id | – | – | The terrain ID from finalize_terrain_upload. Omit to follow the project's newest terrain. |
| timeout_seconds | integer | – | How long this call keeps polling before it returns `timed_out` (default 240, ceiling 280 — the prod /mcp/ proxy cuts a call at 300 s). 0 = one status read, no waiting. |
Structured output declared, but exposes no named fields.
No examples provided.
list_inputs List a project's input layers ~175
List every input layer row of a project, per kind, with whether it has features. For each of boundary, friction, inflow, rainfall, building, mesh_region and culvert: the rows (`row_id`, `title`, `gn_layer` — the dataset pk — and `dataset_alternate`, the `workspace:name` WFS typename) and `has_features`. `has_features` is the API's own answer for every kind. It is null only when a row's record does not carry it: treat null as unknown, not as empty. A row with no `gn_layer` has no layer yet (`has_features` false). Use the row ids with create_scenario; this is the listing primitive — no need to probe files.
| Name | Type | Req | Description |
|---|---|---|---|
| project_id | integer | yes | The project ID |
Structured output declared, but exposes no named fields.
No examples provided.
list_observations List flood observation layers or observations ~170
List a project's flood observation layers, or one layer's observations. Without layer_id: every layer (layer_id, title, dataset_alternate, vertical_datum, datum_offset_m, has_features). With layer_id: {layer, count, results} where each observation carries its `fid` (the key for update_observation / delete_observation), subtype + subtype_label, stage/depth, sigma, bound, the observed window in UTC, `datum` status (an `unknown` datum is not scored), `photo_count` and `problems` (fields drawn in the map that fail validation, reported, never fixed).
| Name | Type | Req | Description |
|---|---|---|---|
| layer_id | – | – | A flood observation layer id; omit to list the project's layers instead |
| project_id | integer | yes | The project ID |
Structured output declared, but exposes no named fields.
No examples provided.
list_projects List projects ~70
List ANUGA simulation projects accessible to the authenticated user. Returns a paginated list of projects with their names, projections, and base map references.
| Name | Type | Req | Description |
|---|---|---|---|
| page | integer | – | Page number (default 1) |
| page_size | integer | – | Results per page, max 100 (default 100) |
Structured output declared, but exposes no named fields.
No examples provided.
list_runs List a project's runs ~140
List all simulation runs across all scenarios in a project. Returns a paginated list of runs. Optionally filter by status to find active, completed, or failed runs. Each row's presigned `s3_*_url` download links are elided (6-hour capabilities).
| Name | Type | Req | Description |
|---|---|---|---|
| page | integer | – | Page number (default 1) |
| page_size | integer | – | Results per page, max 100 (default 100) |
| project_id | integer | yes | The project ID |
| status_filter | – | – | Filter by status: created, building, built, queued, computing, processing, complete, error, cancelled. Omit for all. |
Structured output declared, but exposes no named fields.
No examples provided.
list_time_series List a project's time series ~127
List a project's time series (rain gauges, hydrographs, tides) — never their rows. Each series: `id`, `name` (a rainfall polygon binds to its gauge by this exact name), `series_type`, `units`, `timezone`, `row_count`, `first_timestamp` and `last_timestamp`. The data rows themselves are dropped (a project's list is megabytes); fetch one series with the REST API (GET /projects/<id>/time-series/<id>/) if you need its values.
| Name | Type | Req | Description |
|---|---|---|---|
| project_id | integer | yes | The project ID |
Structured output declared, but exposes no named fields.
No examples provided.
presign_terrain_upload Get a terrain upload URL ~487
Step 1 of a terrain import: get a presigned S3 PUT URL for a GeoTIFF DEM. The import needs a launch-level agent key: a draft key can presign, but finalize_terrain_upload (and the multipart fallback below) answer a read or draft key 403 AGENT_LEVEL_INSUFFICIENT — check the key before moving bytes. The agent moves the bytes itself — no tool accepts file contents. After this call, PUT the file straight to `upload_url`, sending the SAME Content-Type you passed here (it is part of the signature; a mismatch is a 403 SignatureDoesNotMatch before it is anything else): curl -sS -X PUT -H "Content-Type: image/tiff" --upload-file /path/dem.tif "$UPLOAD_URL" then call finalize_terrain_upload with the returned staging_key and process_id. Nothing exists in Hydrata until finalize; the URL expires after `expires_in` seconds (3600). Platform guidance: keep the terrain extent within 5° across and 40,000 km² (200 × 200 km). The API enforces that cap on its bbox-fetch path; an uploaded GeoTIFF is only rejected above 5 GiB, but a larger DEM will not mesh or run well. The GeoTIFF must carry a CRS; the import reprojects it to the site's UTM zone and builds a hillshade. Fallback when a presigned PUT is impossible: multipart-POST the file with the same agent key to /api/v2/anuga/projects/<id>/terrain/upload/ (form field `file`, optional `title`), which creates the terrain in one step — then get_terrain.
| Name | Type | Req | Description |
|---|---|---|---|
| content_type | string | – | MIME type the PUT will send (default 'image/tiff'). It is SIGNED into the URL, so the PUT must send exactly this Content-Type header. |
| filename | string | yes | Base name of the GeoTIFF, e.g. 'dem.tif' (a name only — never contents) |
| project_id | integer | yes | The project ID |
| size | – | – | File size in bytes (`stat -c %s <file>`). The API rejects > 5 GiB up front. Omit if unknown. |
Structured output declared, but exposes no named fields.
No examples provided.
retry_run Retry a failed run ~140
Retry a failed simulation run. Needs a launch-level agent key (a retry rebuilds the package and can start AWS Batch); a read or draft key gets 403 AGENT_LEVEL_INSUFFICIENT. Starts a fresh package build of the run's scenario as a NEW run, which becomes the scenario's latest run. The errored run keeps its status and error as history, and the response describes that old run; the new run's ID is get_scenario's `run_id`. Only valid when status is 'error'. Returns 409 for any other state.
| Name | Type | Req | Description |
|---|---|---|---|
| run_id | integer | yes | The run ID to retry |
Structured output declared, but exposes no named fields.
No examples provided.
set_comparison_tolerance Save a project's default comparison tolerance ~141
Save a project's default tolerance for comparing runs with flood observations. Needs Editor (or above). Every later get_observation_comparison (and the map's Compare with observations tab) uses it unless a tolerance is passed. Only save it when the user asks to change the project's default; to show the figures at another tolerance, pass `tolerance` to get_observation_comparison.
| Name | Type | Req | Description |
|---|---|---|---|
| project_id | integer | yes | The project ID |
| tolerance_m | number | yes | The project's default tolerance in metres (above 0 and at most 5; presets 0.15, 0.3, 0.4) |
Structured output declared, but exposes no named fields.
No examples provided.
set_observation_exclusion Exclude or include a flood observation in a run's comparison ~211
Exclude a flood observation from ONE run's comparison with observations, or include it again. Needs Editor (or above) on the project. The exclusion is logged with the user and reason (nothing is overwritten) and keyed on (run, layer, fid), so it survives a recompute. The figures change at once: `headline_after` is the run's headline with the change applied. To exclude, the user must give the reason: if they have not, ASK them; do not make one up.
| Name | Type | Req | Description |
|---|---|---|---|
| excluded | boolean | – | true to exclude (default), false to include it again |
| fid | integer | yes | The observation's fid |
| layer_id | integer | yes | The flood observation layer id |
| reason | string | – | WHY the engineer excludes it, in their words (required to exclude; never invent one — ask the user). Optional when including it again |
| run_id | integer | yes | The run ID (a historic run) |
Structured output declared, but exposes no named fields.
No examples provided.
start_simulation Start a simulation run (spends compute) ~577
Start a flood simulation run for a built scenario. Needs a launch-level agent key (a run spends compute); a read or draft key gets 403 AGENT_LEVEL_INSUFFICIENT — the user creates a launch key on the site's Agent keys page (/agents/). The scenario must be in 'built' status. Returns 202 with the new run. The run transitions through: built → queued → computing → processing → complete. After starting, poll get_run_status to track progress. Returns 409 if the scenario is not in the correct state. The returned run record has its presigned `s3_*_url` links elided (6-hour capabilities). INPUT REVIEW (Hydrata enforces it): while an input you wrote is not reviewed by the user, the run is not started - `outcome` `unreviewed_inputs`, `error_code` UNREVIEWED_INPUTS, a `ui_url` to the scenario's review screen. A run built from inputs other than the ones reviewed now answers `outcome` `run_invalidated` (RUN_INVALIDATED): build_scenario with rebuild=true, then start it again. SPEND CONSENT (Hydrata enforces it; you cannot): a run whose quote does not fit your agent key's monthly spend limit (default $0), or that Hydrata cannot price, is NOT started. The result is then a normal (non-error) answer with `outcome` `consent_required`, `error_code` CONSENT_REQUIRED, `quoted_cost_usd` and `consent_url`: give the user the link and the price (`say_to_user`). Only they can approve, in their browser. Then do NOT call start_simulation again for this run: poll get_run_status(run_id) — the run leaves `built` once they press the button. (With consent_timeout_seconds > 0 this call polls the run itself and answers `outcome` `consented`, with the run, if they approve within that time.)
| Name | Type | Req | Description |
|---|---|---|---|
| compute_backend | string | – | Compute backend: 'local' (Celery), 'ec2' (dedicated instance), or 'batch' (AWS Batch spot, cheapest). Default: 'local' |
| consent_timeout_seconds | integer | – | When the run needs the person's consent (CONSENT_REQUIRED), how long this call keeps polling the run for their click before it returns (ceiling 280). Default 0: return the consent link at once, so yo… |
| poll_interval_seconds | number | – | Seconds between consent polls (default 5) |
| scenario_id | integer | yes | The scenario ID to run |
Structured output declared, but exposes no named fields.
No examples provided.
update_observation Edit one flood observation ~177
Edit one flood observation (PATCH; only the fields given change). The API checks the stored observation merged with `changes` and refuses (400, every bad field named) rather than store a half-valid one. Photos are not fields: attach a link with add_observation_photo_link.
| Name | Type | Req | Description |
|---|---|---|---|
| changes | object | yes | Only the fields to change, in the add_observations write shape (e.g. {"stage_m": 2.5} or a new geometry); validated by the API against the stored observation (a flood_mark or dry_point must keep a da… |
| fid | integer | yes | The observation's fid (from list_observations / add_observations) |
| layer_id | integer | yes | The flood observation layer id |
| project_id | integer | yes | The project ID |
Structured output declared, but exposes no named fields.
No examples provided.
How do I install the Hydrata - ANUGA Flood Simulation MCP server?
Hydrata - ANUGA Flood Simulation is a hosted endpoint at https://hydrata.com/mcp/, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
remote · hydrata.com
claude mcp add --transport http com-hydrata-hydrata-mcp-server 'https://hydrata.com/mcp/'
What is the Hydrata - ANUGA Flood Simulation MCP server?
Hydrata - ANUGA Flood Simulation is an MCP server listed in the public MCP registry as com.hydrata/hydrata-mcp-server. Run ANUGA flood simulations, track progress, and retrieve results on Hydrata Cloud. This page covers its hosted endpoint (https://hydrata.com/mcp/).
Is the Hydrata - ANUGA Flood Simulation MCP server safe to use?
Hydrata - ANUGA Flood Simulation scores 37 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Hydrata - ANUGA Flood Simulation MCP server expose?
Hydrata - ANUGA Flood Simulation exposes 28 tools: list_projects, get_project, get_scenario, start_simulation, get_run_status, and 23 more. Their descriptions and schemas cost roughly 9,941 tokens of context every time the server is loaded.
Does the Hydrata - ANUGA Flood Simulation MCP server require authentication?
Yes. Hydrata - ANUGA Flood Simulation asked us for credentials when we connected, so you will need to authorise it in your MCP client before it can do anything.
Is the Hydrata - ANUGA Flood Simulation MCP server still maintained?
Hydrata - ANUGA Flood Simulation is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What did VerifyMCP test on the Hydrata - ANUGA Flood Simulation MCP server?
VerifyMCP ran 5 checks on Hydrata - ANUGA Flood Simulation, covering TLS certificate, Authorization, HTTPS, HSTS header and 1 more. 6 items could not be completed, a gap on our side rather than a finding about Hydrata - ANUGA Flood Simulation: Transport, Schema quality, Stability, Tool coverage and 2 more. 6 categories score 0 for that reason, because we only credit what we can confirm. Supply Chain Security and Provenance & Transparency do not apply to a hosted endpoint, so they were not tested. The score does not measure everything, and the scoring documentation lists what it leaves out.