Build a scenario's mesh and package
build_scenarioBuild a scenario's package (mesh + inputs) after showing what it will cost, and poll until built.
Order of operations, so the number is shown before anything is spent:
GET the scenario detail. A record with no
boundary/computed_statuskeys is a non-member's read of a public project → refused: a build needs the EDITOR role.Re-call checks on
latest_run(a re-POST is NOT deduplicated afterbuilt/complete— it would dispatch a duplicate build): no run → proceed; runcreated/building→ resume polling, no POST; runbuilt/queued/computing/processing/completewithlatest_run_is_validnot false → return that state, no POST unless rebuild=true; runerror/cancelled, orlatest_run_is_validfalse (the scenario was edited since the build) → proceed.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.POST /projects//scenarios//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; coarsenresolutionor shrink the boundary; no run was created), 409 COMPUTE_TARGET_UNAVAILABLE, 400/403/404. A 409 WITHOUT an error_code is the dedup body ({status, run_id, detail}: a build is already in flight) — the tool resumes polling that run.On 202 poll the detail's
computed_status(created → building → built | error), bounded by timeout_seconds.
Returns a COMPACT state, never the whole detail: outcome (built, error,
cancelled, complete/queued/computing/processing for a run past the build,
timed_out, or refused), computed_status, mesh_triangle_count_estimate,
posted, the POST's build body + http_status when one was made, and
the latest run's run_id, run_status, error_message, user_message,
mesh_triangle_count. timed_out is normal (make_package re-downloads
the terrain from S3 every build; minutes): call again with the same
arguments — step 2 resumes polling the same run, it never POSTs twice —
or cancel_run(run_id) if the run is stuck in created with no worker.
error is terminal: error_message says why (fix the inputs, then call
again — an errored latest run is rebuilt).
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.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | Required (true) when the estimate is above 100,000 triangles — the tool refuses first and tells you the number. Default false. | |
| rebuild | No | 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). | |
| project_id | Yes | The project ID | |
| scenario_id | Yes | The scenario ID from create_scenario | |
| timeout_seconds | No | 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. | |
| poll_interval_seconds | No | Seconds between polls (default 5) |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||