← WebMCP Directory

Tool tree

roadway-design-compiler.gandidhyaneswar.workers.dev

Developer ToolsTools verified
Website
Roadway Design Compiler
Explore capabilities
    read_designAnswer

    Read the whole current road design: project setup, horizontal elements, vertical PVIs, templates and template drops, plus whether it currently validates. Start here.

    View tool JSON
    {
      "name": "read_design",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the whole current road design: project setup, horizontal elements, vertical PVIs, templates and template drops, plus whether it currently validates. Start here.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    read_alignment_rangeAnswer

    Read the alignment's begin station, end station and total length in US survey feet. The vertical profile and the template drops are stationed BY this range, so any horizontal edit moves the end station and the profile must follow it.

    View tool JSON
    {
      "name": "read_alignment_range",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the alignment's begin station, end station and total length in US survey feet. The vertical profile and the template drops are stationed BY this range, so any horizontal edit moves the end station and the profile must follow it.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    read_curve_tableAnswer

    Read the computed horizontal curve table: for each circular curve the PC and PT stations, radius, delta, tangent, arc length and external distance. These are computed by the deterministic kernel, not by the agent.

    View tool JSON
    {
      "name": "read_curve_table",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the computed horizontal curve table: for each circular curve the PC and PT stations, radius, delta, tangent, arc length and external distance. These are computed by the deterministic kernel, not by the agent.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    read_profile_tableAnswer

    Read the computed vertical profile: each vertical curve with its PVI station and elevation, curve length, K value, PVC and PVT stations and the incoming/outgoing grades, plus the high and low points. K = L / |g2 - g1| and governs stopping sight distance.

    View tool JSON
    {
      "name": "read_profile_table",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the computed vertical profile: each vertical curve with its PVI station and elevation, curve length, K value, PVC and PVT stations and the incoming/outgoing grades, plus the high and low points. K = L / |g2 - g1| and governs stopping sight distance.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    read_cross_sectionAnswer

    Read the corridor cross-section at one station: every template point with its offset from centreline and its elevation. Use this to check what the road actually looks like at a location, rather than inferring it from the template definition.

    View tool JSON
    {
      "name": "read_cross_section",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the corridor cross-section at one station: every template point with its offset from centreline and its elevation. Use this to check what the road actually looks like at a location, rather than inferring it from the template definition.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "station": {
            "type": "number",
            "description": "Station in feet, e.g. 2500 means 25+00."
          }
        },
        "required": [
          "station"
        ]
      }
    }
    what_do_i_needAction

    Ask the design what is currently wrong with it. Returns a typed refusal carrying the exact numbers needed to fix it and the name of the tool that fixes it, or valid: true. Call this whenever a change is refused.

    View tool JSON
    {
      "name": "what_do_i_need",
      "kind": "act",
      "impl": "imperative",
      "description": "Ask the design what is currently wrong with it. Returns a typed refusal carrying the exact numbers needed to fix it and the name of the tool that fixes it, or valid: true. Call this whenever a change is refused.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    set_superelevationAction

    Turn on superelevation — banking the roadway through its horizontal curves — and set the policy. Once on, every circular curve gets a superelevation rate computed from its radius and the design speed, with a runoff and tangent runout sized from the maximum relative gradient. The 3D corridor and the cross sections rotate accordingly. A flatter curve that friction alone can carry stays at normal crown; a curve at or below the minimum radius is banked at emax. Pass enabled: false to remove banking and return the road to its template cross slopes. Coefficients are inputs with illustrative defaults, NOT an adopted agency standard.

    View tool JSON
    {
      "name": "set_superelevation",
      "kind": "act",
      "impl": "imperative",
      "description": "Turn on superelevation — banking the roadway through its horizontal curves — and set the policy. Once on, every circular curve gets a superelevation rate computed from its radius and the design speed, with a runoff and tangent runout sized from the maximum relative gradient. The 3D corridor and the cross sections rotate accordingly. A flatter curve that friction alone can carry stays at normal crown; a curve at or below the minimum radius is banked at emax. Pass enabled: false to remove banking and return the road to its template cross slopes. Coefficients are inputs with illustrative defaults, NOT an adopted agency standard.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "description": "false removes banking entirely. Default true."
          },
          "designSpeedMph": {
            "type": "number",
            "description": "Design speed in mph. Required when enabling."
          },
          "emax": {
            "type": "number",
            "description": "Maximum superelevation rate as a decimal, e.g. 0.06. Default 0.06."
          },
          "normalCrownPercent": {
            "type": "number",
            "description": "Normal crown magnitude in percent. Default 2."
          },
          "sideFriction": {
            "type": "number",
            "description": "Side friction factor. Default is a fitted curve falling with speed."
          },
          "laneWidthFt": {
            "type": "number",
            "description": "Width of one rotated lane, ft. Default 12."
          },
          "lanesRotated": {
            "type": "number",
            "description": "Lanes rotated about the pivot. Default 1."
          },
          "maxRelativeGradientPercent": {
            "type": "number",
            "description": "Maximum relative gradient, percent. Default falls with speed."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": []
      }
    }
    read_superelevationAnswer

    Read the superelevation transition for every curve: the full superelevation rate, the runoff and tangent runout lengths, and the station landmarks where normal crown ends, the runoff begins, full banking is reached at the PC, held to the PT, and released. Also reports the cross slope of each side at any station you ask about.

    View tool JSON
    {
      "name": "read_superelevation",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the superelevation transition for every curve: the full superelevation rate, the runoff and tangent runout lengths, and the station landmarks where normal crown ends, the runoff begins, full banking is reached at the PC, held to the PT, and released. Also reports the cross slope of each side at any station you ask about.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "atStation": {
            "type": "number",
            "description": "Optional station in feet. Returns the left and right cross slope THERE, plus which phase of the rotation that station is in -- normal crown, runout, runoff, or full super. Must lie within the alignment, and is range-checked even when no banking policy is set. ⛔ With NO policy there is no banking anywhere, so no slopes are returned: the cross slope is then the template's own and read_cross_section reports the actual section."
          }
        },
        "required": []
      }
    }
    read_pending_changesAnswer

    List the changes you have authored that a licensed engineer has NOT yet confirmed. Everything an agent applies is stamped agent-proposed and held here until a person confirms it in the Studio. While anything is pending, the LandXML deliverable cannot be produced. ⛔ There is deliberately no tool that confirms them: an agent can never be the confirming party. Report the list to the engineer and ask them to confirm.

    View tool JSON
    {
      "name": "read_pending_changes",
      "kind": "answer",
      "impl": "imperative",
      "description": "List the changes you have authored that a licensed engineer has NOT yet confirmed. Everything an agent applies is stamped agent-proposed and held here until a person confirms it in the Studio. While anything is pending, the LandXML deliverable cannot be produced. ⛔ There is deliberately no tool that confirms them: an agent can never be the confirming party. Report the list to the engineer and ask them to confirm.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    undo_last_changeAction

    Undo the most recent change YOU made, restoring the design exactly as it was before it. ⛔ This only works while the change is still unconfirmed. Once a licensed engineer has confirmed your work you cannot silently revert it -- that would undo something a person has already stood behind. Author a new, visible change instead, which lands in the ledger and needs its own confirmation.

    View tool JSON
    {
      "name": "undo_last_change",
      "kind": "act",
      "impl": "imperative",
      "description": "Undo the most recent change YOU made, restoring the design exactly as it was before it. ⛔ This only works while the change is still unconfirmed. Once a licensed engineer has confirmed your work you cannot silently revert it -- that would undo something a person has already stood behind. Author a new, visible change instead, which lands in the ledger and needs its own confirmation.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    propose_alternativesAction

    Offer the engineer two to four DIFFERENT versions of the design and let them choose. Each alternative is a complete road plus a short rationale; the app computes every one honestly -- length, curve count, tightest radius, lowest K, and criteria compliance at a design speed -- and shows them side by side. ⛔ NOTHING is applied, and there is deliberately no tool that adopts an alternative: ranking them needs judgement about site, budget and right-of-way that you do not have, and choosing one is the decision a licensed engineer is paid to make. Present the comparison and let them pick. Use this when the engineer asks an open question -- what are my options for this curve, show me a cheaper alignment -- rather than naming a specific value.

    View tool JSON
    {
      "name": "propose_alternatives",
      "kind": "act",
      "impl": "imperative",
      "description": "Offer the engineer two to four DIFFERENT versions of the design and let them choose. Each alternative is a complete road plus a short rationale; the app computes every one honestly -- length, curve count, tightest radius, lowest K, and criteria compliance at a design speed -- and shows them side by side. ⛔ NOTHING is applied, and there is deliberately no tool that adopts an alternative: ranking them needs judgement about site, budget and right-of-way that you do not have, and choosing one is the decision a licensed engineer is paid to make. Present the comparison and let them pick. Use this when the engineer asks an open question -- what are my options for this curve, show me a cheaper alignment -- rather than naming a specific value.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "question": {
            "type": "string",
            "description": "The choice being put to the engineer, e.g. three alignments for the river crossing."
          },
          "designSpeedMph": {
            "type": "number",
            "description": "Optional. When given, each alternative is also judged against it."
          },
          "emax": {
            "type": "number",
            "description": "Maximum superelevation rate as a decimal for the criteria check. Default 0.06."
          },
          "alternatives": {
            "type": "array",
            "description": "Two to four alternatives. Each is { label, rationale, design } where design has the same shape propose_full_design takes: name, beginStation, startE, startN, startAzimuthDeg, elements, pvis.",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "question",
          "alternatives"
        ]
      }
    }
    export_staking_csvAction

    Export construction staking: for every station at the interval you choose, the coordinates and elevation of the centreline and of each template point, as CSV a survey crew can load. Offsets are signed -- negative left of centreline, positive right. This is the file a crew physically sets the road out from, so like the LandXML it is refused until a licensed engineer has confirmed every outstanding change.

    View tool JSON
    {
      "name": "export_staking_csv",
      "kind": "act",
      "impl": "imperative",
      "description": "Export construction staking: for every station at the interval you choose, the coordinates and elevation of the centreline and of each template point, as CSV a survey crew can load. Offsets are signed -- negative left of centreline, positive right. This is the file a crew physically sets the road out from, so like the LandXML it is refused until a licensed engineer has confirmed every outstanding change.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "intervalFt": {
            "type": "number",
            "description": "Station interval in feet. 25 or 50 is typical; 10 for tight urban work."
          },
          "includeOffsets": {
            "type": "boolean",
            "description": "false gives centreline only. Default true (every template point)."
          }
        },
        "required": [
          "intervalFt"
        ]
      }
    }
    read_design_documentAnswer

    Read the whole design as a portable document, plus a link that reproduces it exactly. Send that link to the licensed engineer who has to review and seal the work -- it carries the entire design in the URL fragment, so nothing is uploaded anywhere and no account is needed. Use this whenever the engineer asks to save, share, hand off or keep a copy.

    View tool JSON
    {
      "name": "read_design_document",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the whole design as a portable document, plus a link that reproduces it exactly. Send that link to the licensed engineer who has to review and seal the work -- it carries the entire design in the URL fragment, so nothing is uploaded anywhere and no account is needed. Use this whenever the engineer asks to save, share, hand off or keep a copy.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    load_design_documentAction

    Replace the current design with one from a saved document or a shared link. ⛔ DESTRUCTIVE: everything currently on screen is replaced. Preview first (omit commit) to see what the incoming design computes to before you apply it. Accepts either the document read_design_document returns, or the bare design inside it.

    View tool JSON
    {
      "name": "load_design_document",
      "kind": "act",
      "impl": "imperative",
      "description": "Replace the current design with one from a saved document or a shared link. ⛔ DESTRUCTIVE: everything currently on screen is replaced. Preview first (omit commit) to see what the incoming design computes to before you apply it. Accepts either the document read_design_document returns, or the bare design inside it.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "document": {
            "type": "object",
            "description": "The document to load, as returned by read_design_document."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "document"
        ]
      }
    }
    set_coordinate_systemAction

    Set the project coordinate reference system. This is what georeferences the LandXML, so OpenRoads or Civil 3D places the alignment in the right part of the world rather than at an arbitrary origin. Call read_coordinate_systems first to see the zones this project offers. Grid coordinates are state-plane; ground coordinates are scaled to surface distances, which is what a survey crew measures.

    View tool JSON
    {
      "name": "set_coordinate_system",
      "kind": "act",
      "impl": "imperative",
      "description": "Set the project coordinate reference system. This is what georeferences the LandXML, so OpenRoads or Civil 3D places the alignment in the right part of the world rather than at an arbitrary origin. Call read_coordinate_systems first to see the zones this project offers. Grid coordinates are state-plane; ground coordinates are scaled to surface distances, which is what a survey crew measures.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "zone": {
            "type": "string",
            "description": "Zone key, e.g. GA-West. Get the list from read_coordinate_systems. Pass an EMPTY STRING for local coordinates -- no georeferencing, which is what the Studio's \"None\" option selects."
          },
          "basis": {
            "type": "string",
            "enum": [
              "grid",
              "ground"
            ],
            "description": "Grid (state plane) or ground (surface) distances."
          },
          "combinedScaleFactor": {
            "type": "number",
            "description": "REQUIRED when basis is \"ground\": ground distances are grid distances divided by this. Ground coordinates without it cannot be reconciled with a grid or with what a survey crew measures, and the schema refuses them."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "zone"
        ]
      }
    }
    read_coordinate_systemsAnswer

    List the coordinate reference systems this project offers, and which one is selected. The CRS georeferences the LandXML export.

    View tool JSON
    {
      "name": "read_coordinate_systems",
      "kind": "answer",
      "impl": "imperative",
      "description": "List the coordinate reference systems this project offers, and which one is selected. The CRS georeferences the LandXML export.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    import_landxmlAction

    Read an existing alignment out of a LandXML file and load it as the design. This is how a road that already exists -- in OpenRoads, in Civil 3D, in a survey deliverable -- gets in here, instead of starting from scratch. Give it the file's text. If the file holds several alignments, name the one you want or take the first. ⛔ DESTRUCTIVE: this replaces the current design. Preview first (omit commit). ⛔ It REFUSES rather than approximating: a file using spiral transitions is rejected with the count, because this kernel models tangents and circular curves only and quietly dropping a spiral would change the geometry of a road somebody is going to build. Metric files are converted to US survey feet and say so.

    View tool JSON
    {
      "name": "import_landxml",
      "kind": "act",
      "impl": "imperative",
      "description": "Read an existing alignment out of a LandXML file and load it as the design. This is how a road that already exists -- in OpenRoads, in Civil 3D, in a survey deliverable -- gets in here, instead of starting from scratch. Give it the file's text. If the file holds several alignments, name the one you want or take the first. ⛔ DESTRUCTIVE: this replaces the current design. Preview first (omit commit). ⛔ It REFUSES rather than approximating: a file using spiral transitions is rejected with the count, because this kernel models tangents and circular curves only and quietly dropping a spiral would change the geometry of a road somebody is going to build. Metric files are converted to US survey feet and say so.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "xml": {
            "type": "string",
            "description": "The full text of the LandXML file."
          },
          "alignmentName": {
            "type": "string",
            "description": "Optional. Which alignment to take when the file holds several."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "xml"
        ]
      }
    }
    read_groundAnswer

    Read the existing ground under the road: for each station, the ground elevation, the design elevation, and the difference. POSITIVE is FILL (the road sits above ground), NEGATIVE is CUT (it sits below). Also returns the extremes and the balance points where the road crosses ground level. Stations that fall outside the surveyed surface report no ground rather than a guess -- a road can run past the edge of a survey, and inventing ground there is how a design gets built wrong. Requires a ground surface: import one with import_landxml.

    View tool JSON
    {
      "name": "read_ground",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the existing ground under the road: for each station, the ground elevation, the design elevation, and the difference. POSITIVE is FILL (the road sits above ground), NEGATIVE is CUT (it sits below). Also returns the extremes and the balance points where the road crosses ground level. Stations that fall outside the surveyed surface report no ground rather than a guess -- a road can run past the edge of a survey, and inventing ground there is how a design gets built wrong. Requires a ground surface: import one with import_landxml.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fromStationFt": {
            "type": "number",
            "description": "Start the returned rows at this station. Replies carry at most 60 stations; when the road needs more, the reply says so and gives the station to resume from. The summary figures always describe the WHOLE road, not the page."
          },
          "intervalFt": {
            "type": "number",
            "description": "Station interval to sample at, in feet. Default 50. Stations land on whole multiples of this from the begin station -- 50 gives 25+00, 25+50, 26+00 -- the way cross sections are cut on a plan set. The end station is always sampled, so the LAST interval is usually shorter than the rest. Sampling is capped at 400 stations, so on a long road the step is widened to fit; intervalFt in the reply is the step actually used and requestedIntervalFt is what was asked for."
          }
        },
        "required": []
      }
    }
    read_terrain_extentAnswer

    Read the bounds of the loaded ground surface, and whether the alignment sits inside it. Use this before reasoning about cut and fill: a road that leaves the survey has no ground to be compared against for part of its length.

    View tool JSON
    {
      "name": "read_terrain_extent",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the bounds of the loaded ground surface, and whether the alignment sits inside it. Use this before reasoning about cut and fill: a road that leaves the survey has no ground to be compared against for part of its length.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    place_roadside_itemAction

    Place guardrail, concrete barrier, a pavement marking or curb along the road, between two stations, on one side, at an offset from the centreline. It is drawn in 3D exactly where you put it. Offset is a positive distance -- side carries the direction. A pavement marking must state its pattern, because solid and dashed mean different things to a driver. ⛔ This tool does NOT decide whether a guardrail is WARRANTED. Warrant depends on fill height, side slope and clear zone, and is a judgement a licensed engineer is paid to make. You may place what the engineer asks for and report what you placed; you may not conclude that a road needs protection.

    View tool JSON
    {
      "name": "place_roadside_item",
      "kind": "act",
      "impl": "imperative",
      "description": "Place guardrail, concrete barrier, a pavement marking or curb along the road, between two stations, on one side, at an offset from the centreline. It is drawn in 3D exactly where you put it. Offset is a positive distance -- side carries the direction. A pavement marking must state its pattern, because solid and dashed mean different things to a driver. ⛔ This tool does NOT decide whether a guardrail is WARRANTED. Warrant depends on fill height, side slope and clear zone, and is a judgement a licensed engineer is paid to make. You may place what the engineer asks for and report what you placed; you may not conclude that a road needs protection.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Short stable id, e.g. gr-left-1. Used to change or remove this item later."
          },
          "kind": {
            "type": "string",
            "enum": [
              "guardrail",
              "concrete-barrier",
              "pavement-marking",
              "curb"
            ],
            "description": "What it is."
          },
          "side": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ],
            "description": "Which side of the centreline it runs along."
          },
          "beginStationFt": {
            "type": "number",
            "description": "Station where it starts, in feet."
          },
          "endStationFt": {
            "type": "number",
            "description": "Station where it ends, in feet. Must be greater than the start."
          },
          "offsetFt": {
            "type": "number",
            "description": "Distance from centreline in feet, always positive."
          },
          "heightFt": {
            "type": "number",
            "description": "Height above the road surface in feet. Defaults by kind."
          },
          "pattern": {
            "type": "string",
            "enum": [
              "solid",
              "dashed",
              "double-solid"
            ],
            "description": "Required for a pavement marking."
          },
          "note": {
            "type": "string",
            "description": "Optional note, e.g. a standard detail number."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "id",
          "kind",
          "side",
          "beginStationFt",
          "endStationFt",
          "offsetFt"
        ]
      }
    }
    remove_roadside_itemAction

    Remove one roadside item by its id. ⛔ DESTRUCTIVE: the item and its authored placement are gone. Preview first.

    View tool JSON
    {
      "name": "remove_roadside_item",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove one roadside item by its id. ⛔ DESTRUCTIVE: the item and its authored placement are gone. Preview first.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The item's id."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "id"
        ]
      }
    }
    read_roadsideAnswer

    Read every roadside item on the design, with a quantity take-off by kind -- count and total length in feet, which is what goes on a bid schedule. Also reports any placement problems.

    View tool JSON
    {
      "name": "read_roadside",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read every roadside item on the design, with a quantity take-off by kind -- count and total length in feet, which is what goes on a bid schedule. Also reports any placement problems.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    set_segment_materialAction

    State what a template segment is made of -- asphalt, concrete, gravel, grass or earth. The 3D view draws each material differently and puts an edge line where pavement meets something that is not pavement. ⛔ Material is never inferred from a segment's NAME: a shoulder is asphalt on one project and gravel on the next, and guessing would put a surface on the drawing that nobody authored. A segment with no material stated is drawn neutrally.

    View tool JSON
    {
      "name": "set_segment_material",
      "kind": "act",
      "impl": "imperative",
      "description": "State what a template segment is made of -- asphalt, concrete, gravel, grass or earth. The 3D view draws each material differently and puts an edge line where pavement meets something that is not pavement. ⛔ Material is never inferred from a segment's NAME: a shoulder is asphalt on one project and gravel on the next, and guessing would put a surface on the drawing that nobody authored. A segment with no material stated is drawn neutrally.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "template": {
            "type": "string",
            "description": "Template name, e.g. 2-lane."
          },
          "side": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ],
            "description": "Which side of the centreline."
          },
          "index": {
            "type": "integer",
            "description": "1-based segment index, counting outward from the centreline."
          },
          "material": {
            "type": "string",
            "enum": [
              "asphalt",
              "concrete",
              "gravel",
              "grass",
              "earth"
            ],
            "description": "What it is made of."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "template",
          "side",
          "index",
          "material"
        ]
      }
    }
    read_design_sectionsAnswer

    Read the AS-DESIGNED cross sections that came with an imported LandXML -- the surfaces the original designer produced, station by station, each named and sided. On a real file these are the pavement structure: a wearing course, a formation level, and the ground beneath. ⚠ Not every named surface is roadway. Width tells them apart, and is reported for each: on the file this was measured against, the wearing course spans 38.6 ft and the soil section spans 10,208 ft. Narrowest first, so the pavement comes to hand. ⛔ These are REFERENCE, not your design. They are the original designer's sections, held separately so they cannot be confused with the corridor this app sweeps from a template.

    View tool JSON
    {
      "name": "read_design_sections",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the AS-DESIGNED cross sections that came with an imported LandXML -- the surfaces the original designer produced, station by station, each named and sided. On a real file these are the pavement structure: a wearing course, a formation level, and the ground beneath. ⚠ Not every named surface is roadway. Width tells them apart, and is reported for each: on the file this was measured against, the wearing course spans 38.6 ft and the soil section spans 10,208 ft. Narrowest first, so the pavement comes to hand. ⛔ These are REFERENCE, not your design. They are the original designer's sections, held separately so they cannot be confused with the corridor this app sweeps from a template.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    read_site_featuresAnswer

    Read the EXISTING site imported from a survey LandXML -- buildings, kerbs, sidewalks, lot lines, edge of pavement. This is what is already on the ground before anything is designed, and it is the context a new alignment has to fit into. Returns the site extent, so you can place an alignment inside it rather than guessing at coordinates. ⛔ Feature names are carried exactly as the file wrote them and are NOT interpreted. "BLDG1|1094" is a building on one survey and could be anything on the next; the grouping in the summary is a label taken from the file's own separator, not a classification.

    View tool JSON
    {
      "name": "read_site_features",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the EXISTING site imported from a survey LandXML -- buildings, kerbs, sidewalks, lot lines, edge of pavement. This is what is already on the ground before anything is designed, and it is the context a new alignment has to fit into. Returns the site extent, so you can place an alignment inside it rather than guessing at coordinates. ⛔ Feature names are carried exactly as the file wrote them and are NOT interpreted. \"BLDG1|1094\" is a building on one survey and could be anything on the next; the grouping in the summary is a label taken from the file's own separator, not a classification.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    check_design_criteriaAnswer

    Judge the whole design against a design speed and return a verdict for every horizontal curve, every vertical curve and every grade. Each verdict says pass or fail, the value the design has, the value the criterion requires, and the relationship used to get there. Failing verdicts tell you what would comply -- a minimum radius, or the curve length that would reach the required K. IMPORTANT: this computes criteria from engineering relationships using the coefficients you supply. The defaults are illustrative, NOT an adopted agency standard. Supply your agency's side friction, reaction time, deceleration, sight heights and maximum grade to judge against your own criteria. The app applies the engineering; it does not ship somebody else's table.

    View tool JSON
    {
      "name": "check_design_criteria",
      "kind": "answer",
      "impl": "imperative",
      "description": "Judge the whole design against a design speed and return a verdict for every horizontal curve, every vertical curve and every grade. Each verdict says pass or fail, the value the design has, the value the criterion requires, and the relationship used to get there. Failing verdicts tell you what would comply -- a minimum radius, or the curve length that would reach the required K. IMPORTANT: this computes criteria from engineering relationships using the coefficients you supply. The defaults are illustrative, NOT an adopted agency standard. Supply your agency's side friction, reaction time, deceleration, sight heights and maximum grade to judge against your own criteria. The app applies the engineering; it does not ship somebody else's table.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "designSpeedMph": {
            "type": "number",
            "description": "Design speed in mph. Required -- criteria are meaningless without it."
          },
          "emax": {
            "type": "number",
            "description": "Maximum superelevation rate as a decimal, e.g. 0.06 for 6 percent. Default 0.06."
          },
          "sideFriction": {
            "type": "number",
            "description": "Side friction factor at the design speed. Default is a fitted approximation."
          },
          "reactionTimeS": {
            "type": "number",
            "description": "Driver perception-reaction time in seconds. Default 2.5."
          },
          "decelerationFtS2": {
            "type": "number",
            "description": "Deceleration rate in ft/s^2. Default 11.2."
          },
          "eyeHeightFt": {
            "type": "number",
            "description": "Driver eye height in feet. Default 3.5."
          },
          "objectHeightFt": {
            "type": "number",
            "description": "Object height in feet. Default 2.0."
          },
          "maxGradePercent": {
            "type": "number",
            "description": "Maximum grade in percent. Default 8."
          }
        },
        "required": [
          "designSpeedMph"
        ]
      }
    }
    export_landxmlAction

    Export the design as LandXML 1.2, ready to import into Bentley OpenRoads Designer (Geometry -> Import Geometry) or Autodesk Civil 3D as a native alignment and profile. This export has been field-tested: ORD reproduced the curve table to 0.01 ft.

    View tool JSON
    {
      "name": "export_landxml",
      "kind": "act",
      "impl": "imperative",
      "description": "Export the design as LandXML 1.2, ready to import into Bentley OpenRoads Designer (Geometry -> Import Geometry) or Autodesk Civil 3D as a native alignment and profile. This export has been field-tested: ORD reproduced the curve table to 0.01 ft.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    propose_full_designAction

    Propose an ENTIRE road at once: project setup, all horizontal elements and all PVIs. ⛔ DESTRUCTIVE: this REPLACES the existing geometry wholesale (templates and drops are kept). Preview it first and show the engineer what changes. Use this when the engineer describes a road in words rather than editing one value. You supply the parameters and your engineering rationale; the deterministic kernel computes every station, curve and elevation, and validates the result. Conventions: US survey feet; stations in feet (1000 = 10+00); startAzimuthDeg is clockwise from north. The profile must span the alignment exactly -- the first PVI at the begin station and the last at the computed end station -- and end PVIs carry no vertical curve. Prefer radii generous for the design speed (45 mph about 710 ft minimum, 55 mph about 1060 ft; 1.5-3x minimum where right-of-way allows) and keep grades under about 6-8 percent. State the K values you targeted in the rationale.

    View tool JSON
    {
      "name": "propose_full_design",
      "kind": "act",
      "impl": "imperative",
      "description": "Propose an ENTIRE road at once: project setup, all horizontal elements and all PVIs. ⛔ DESTRUCTIVE: this REPLACES the existing geometry wholesale (templates and drops are kept). Preview it first and show the engineer what changes. Use this when the engineer describes a road in words rather than editing one value. You supply the parameters and your engineering rationale; the deterministic kernel computes every station, curve and elevation, and validates the result. Conventions: US survey feet; stations in feet (1000 = 10+00); startAzimuthDeg is clockwise from north. The profile must span the alignment exactly -- the first PVI at the begin station and the last at the computed end station -- and end PVIs carry no vertical curve. Prefer radii generous for the design speed (45 mph about 710 ft minimum, 55 mph about 1060 ft; 1.5-3x minimum where right-of-way allows) and keep grades under about 6-8 percent. State the K values you targeted in the rationale.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Alignment name."
          },
          "rationale": {
            "type": "string",
            "description": "Brief engineering rationale: why these radii, grades and K values."
          },
          "beginStation": {
            "type": "number",
            "description": "Begin station in feet."
          },
          "startE": {
            "type": "number",
            "description": "Start easting, US survey feet."
          },
          "startN": {
            "type": "number",
            "description": "Start northing, US survey feet."
          },
          "startAzimuthDeg": {
            "type": "number",
            "description": "Start heading, degrees clockwise from north (0-360)."
          },
          "elements": {
            "type": "array",
            "description": "Horizontal elements in order. Each is {type:'tangent',length} or {type:'arc',radius,deltaDeg,direction} or {type:'deflection',deflectionDeg,direction}.",
            "items": {
              "type": "object"
            }
          },
          "pvis": {
            "type": "array",
            "description": "Vertical PVIs in increasing station order, each {station,elevation,curveLength?}. At least two. The first and last must not carry curveLength.",
            "items": {
              "type": "object"
            }
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "name",
          "rationale",
          "beginStation",
          "startE",
          "startN",
          "startAzimuthDeg",
          "elements",
          "pvis"
        ]
      }
    }
    set_project_setupAction

    Set the project name, begin station, start coordinates and start heading. startAzimuthDeg is degrees clockwise from north (0 = N, 90 = E, 180 = S, 270 = W). Coordinates are US survey feet in the selected state plane zone; for Georgia West, easting is around 2,200,000 and northing around 1,350,000.

    View tool JSON
    {
      "name": "set_project_setup",
      "kind": "act",
      "impl": "imperative",
      "description": "Set the project name, begin station, start coordinates and start heading. startAzimuthDeg is degrees clockwise from north (0 = N, 90 = E, 180 = S, 270 = W). Coordinates are US survey feet in the selected state plane zone; for Georgia West, easting is around 2,200,000 and northing around 1,350,000.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Alignment name."
          },
          "beginStationFt": {
            "type": "number",
            "description": "Begin station in feet; 1000 means station 10+00."
          },
          "startEastingFt": {
            "type": "number",
            "description": "Start easting, US survey feet."
          },
          "startNorthingFt": {
            "type": "number",
            "description": "Start northing, US survey feet."
          },
          "startAzimuthDeg": {
            "type": "number",
            "description": "Start heading, degrees clockwise from north."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": []
      }
    }
    add_horizontal_elementAction

    Append a horizontal element to the alignment. Elements run in order from the start point. A tangent is a straight run of a given length. An arc is a circular curve with a radius and a delta (deflection angle) turning left or right. A deflection is an angle point and is only legal for small bearing changes under 10 degrees. Radius guidance: for 45 mph prefer about 710 ft minimum, 55 mph about 1060 ft, and use 1.5 to 3 times the minimum where right-of-way allows. NOTE: adding an element lengthens the alignment, and the profile is stationed BY the alignment -- so you will normally need set_pvi to move the last PVI to the new end station.

    View tool JSON
    {
      "name": "add_horizontal_element",
      "kind": "act",
      "impl": "imperative",
      "description": "Append a horizontal element to the alignment. Elements run in order from the start point. A tangent is a straight run of a given length. An arc is a circular curve with a radius and a delta (deflection angle) turning left or right. A deflection is an angle point and is only legal for small bearing changes under 10 degrees. Radius guidance: for 45 mph prefer about 710 ft minimum, 55 mph about 1060 ft, and use 1.5 to 3 times the minimum where right-of-way allows. NOTE: adding an element lengthens the alignment, and the profile is stationed BY the alignment -- so you will normally need set_pvi to move the last PVI to the new end station.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tangent",
              "arc",
              "deflection"
            ],
            "description": "Element type."
          },
          "lengthFt": {
            "type": "number",
            "description": "Tangent length in feet. Required for type tangent."
          },
          "radiusFt": {
            "type": "number",
            "description": "Curve radius in feet. Required for type arc."
          },
          "deltaDeg": {
            "type": "number",
            "description": "Curve deflection angle in degrees. Greater than 0 and LESS THAN 180 -- at exactly 180 the two tangents are parallel, never meet, and the tangent and external distances are undefined. Required for type arc."
          },
          "deflectionDeg": {
            "type": "number",
            "description": "Angle point deflection in degrees, under 10. Required for type deflection."
          },
          "direction": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ],
            "description": "Turn direction for arc or deflection."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "type"
        ]
      }
    }
    set_horizontal_elementAction

    Change one existing horizontal element, identified by its 1-based index in the alignment. Only the fields you supply change. Changing a tangent length or an arc radius or delta moves the alignment end station, so the profile normally needs updating too.

    View tool JSON
    {
      "name": "set_horizontal_element",
      "kind": "act",
      "impl": "imperative",
      "description": "Change one existing horizontal element, identified by its 1-based index in the alignment. Only the fields you supply change. Changing a tangent length or an arc radius or delta moves the alignment end station, so the profile normally needs updating too.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "1-based index of the element to change."
          },
          "lengthFt": {
            "type": "number",
            "description": "New tangent length in feet."
          },
          "radiusFt": {
            "type": "number",
            "description": "New curve radius in feet."
          },
          "deltaDeg": {
            "type": "number",
            "description": "New curve delta in degrees. Greater than 0 and LESS THAN 180 -- at exactly 180 the two tangents are parallel, never meet, and the tangent and external distances are undefined."
          },
          "direction": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ],
            "description": "New turn direction."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "index"
        ]
      }
    }
    remove_horizontal_elementAction

    Remove one horizontal element by its 1-based index. ⛔ DESTRUCTIVE: the element and its authored values are gone. This removal can be reversed with `undo_last_change` while it remains an unconfirmed agent change. Preview first. This also shortens the alignment, so the profile's last PVI moves to the new end station.

    View tool JSON
    {
      "name": "remove_horizontal_element",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove one horizontal element by its 1-based index. ⛔ DESTRUCTIVE: the element and its authored values are gone. This removal can be reversed with `undo_last_change` while it remains an unconfirmed agent change. Preview first. This also shortens the alignment, so the profile's last PVI moves to the new end station.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "1-based index of the element to remove."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "index"
        ]
      }
    }
    set_pviAction

    Change one point of vertical intersection by its 1-based index: its station, its elevation, or its vertical curve length. The first and last PVI must sit exactly at the alignment begin and end stations and must NOT carry a curve. Interior PVIs may carry a symmetric parabolic curve; adjacent curves must not overlap. K guidance: at 45 mph aim for K of at least 61 on crests and 79 in sags, and scale with speed.

    View tool JSON
    {
      "name": "set_pvi",
      "kind": "act",
      "impl": "imperative",
      "description": "Change one point of vertical intersection by its 1-based index: its station, its elevation, or its vertical curve length. The first and last PVI must sit exactly at the alignment begin and end stations and must NOT carry a curve. Interior PVIs may carry a symmetric parabolic curve; adjacent curves must not overlap. K guidance: at 45 mph aim for K of at least 61 on crests and 79 in sags, and scale with speed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "1-based index of the PVI."
          },
          "stationFt": {
            "type": "number",
            "description": "New PVI station in feet. ⛔ NOT settable on the FIRST or LAST PVI: those are derived from the alignment, and passing a different value is refused rather than quietly normalised. Change the road's begin station or its element lengths instead."
          },
          "elevationFt": {
            "type": "number",
            "description": "New PVI elevation in feet. Settable on every PVI, endpoints included."
          },
          "curveLengthFt": {
            "type": "number",
            "description": "New vertical curve length in feet. Use 0 to remove the curve."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "index"
        ]
      }
    }
    add_pviAction

    Insert a new PVI. PVIs are kept in increasing station order automatically. A new interior PVI may carry a vertical curve; the end PVIs may not.

    View tool JSON
    {
      "name": "add_pvi",
      "kind": "act",
      "impl": "imperative",
      "description": "Insert a new PVI. PVIs are kept in increasing station order automatically. A new interior PVI may carry a vertical curve; the end PVIs may not.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "stationFt": {
            "type": "number",
            "description": "PVI station in feet."
          },
          "elevationFt": {
            "type": "number",
            "description": "PVI elevation in feet."
          },
          "curveLengthFt": {
            "type": "number",
            "description": "Optional vertical curve length in feet."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "stationFt",
          "elevationFt"
        ]
      }
    }
    remove_pviAction

    Remove a PVI by its 1-based index. ⛔ DESTRUCTIVE: its station, elevation and vertical curve are gone. This removal can be reversed with `undo_last_change` while it remains an unconfirmed agent change. Preview first. The first and last PVI define the profile's span, so removing one normally leaves the profile no longer matching the alignment.

    View tool JSON
    {
      "name": "remove_pvi",
      "kind": "act",
      "impl": "imperative",
      "description": "Remove a PVI by its 1-based index. ⛔ DESTRUCTIVE: its station, elevation and vertical curve are gone. This removal can be reversed with `undo_last_change` while it remains an unconfirmed agent change. Preview first. The first and last PVI define the profile's span, so removing one normally leaves the profile no longer matching the alignment.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "1-based index of the PVI to remove."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "index"
        ]
      }
    }
    set_template_segmentAction

    Change one segment of a roadway template: its width or its cross slope. Segments are listed outward from the centreline on each side. A normal travel lane is 12 ft at -2 percent; a shoulder is commonly 6.5 ft at -4 percent. Negative slope falls away from the centreline.

    View tool JSON
    {
      "name": "set_template_segment",
      "kind": "act",
      "impl": "imperative",
      "description": "Change one segment of a roadway template: its width or its cross slope. Segments are listed outward from the centreline on each side. A normal travel lane is 12 ft at -2 percent; a shoulder is commonly 6.5 ft at -4 percent. Negative slope falls away from the centreline.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "template": {
            "type": "string",
            "description": "Template name, e.g. \"2-lane\"."
          },
          "side": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ],
            "description": "Which side of the centreline."
          },
          "index": {
            "type": "integer",
            "description": "1-based segment index, counting outward from the centreline."
          },
          "widthFt": {
            "type": "number",
            "description": "New segment width in feet."
          },
          "slopePercent": {
            "type": "number",
            "description": "New cross slope in percent; negative falls away from centreline."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "template",
          "side",
          "index"
        ]
      }
    }
    read_pavement_layersAnswer

    Read the AUTHORED pavement structure of every template: the ordered courses an engineer stated, top course first, with each thickness in inches exactly as authored and the total. ⛔ Nothing here is designed or recommended. This app does not compute a required structure, a structural number, a pavement life, or compliance with any standard -- it reports what a person stated and what it adds up to. A template with no stack has not had one authored; that is not a claim that it needs none.

    View tool JSON
    {
      "name": "read_pavement_layers",
      "kind": "answer",
      "impl": "imperative",
      "description": "Read the AUTHORED pavement structure of every template: the ordered courses an engineer stated, top course first, with each thickness in inches exactly as authored and the total. ⛔ Nothing here is designed or recommended. This app does not compute a required structure, a structural number, a pavement life, or compliance with any standard -- it reports what a person stated and what it adds up to. A template with no stack has not had one authored; that is not a claim that it needs none.",
      "inputSchema": {
        "type": "object",
        "properties": {},
        "required": []
      }
    }
    set_pavement_layersAction

    Replace one template's COMPLETE ordered pavement structure. Give the courses top first, each with a name and a thickness in inches, and optionally the material as free text. ⛔ DESTRUCTIVE: this replaces the whole stack, it does not merge into it. Preview first (omit commit). An EMPTY array is a deliberate remove-all. ⛔ This is AUTHORING, not designing. Do not propose a structure as though the app had computed one: thicknesses come from the engineer or from a standard they are applying, and nothing here checks adequacy. Material is free text and is never inferred from a layer's name. Duplicate names are allowed -- order is what identifies a course.

    View tool JSON
    {
      "name": "set_pavement_layers",
      "kind": "act",
      "impl": "imperative",
      "description": "Replace one template's COMPLETE ordered pavement structure. Give the courses top first, each with a name and a thickness in inches, and optionally the material as free text. ⛔ DESTRUCTIVE: this replaces the whole stack, it does not merge into it. Preview first (omit commit). An EMPTY array is a deliberate remove-all. ⛔ This is AUTHORING, not designing. Do not propose a structure as though the app had computed one: thicknesses come from the engineer or from a standard they are applying, and nothing here checks adequacy. Material is free text and is never inferred from a layer's name. Duplicate names are allowed -- order is what identifies a course.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "template": {
            "type": "string",
            "description": "Which template's structure to replace. See read_design or read_pavement_layers."
          },
          "layers": {
            "type": "array",
            "description": "The complete stack, TOP COURSE FIRST. Each item is {name, thicknessIn, material?}. thicknessIn is inches and must be greater than zero. An empty array removes every layer.",
            "items": {
              "type": "object"
            }
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "template",
          "layers"
        ]
      }
    }
    set_template_dropAction

    Change which template applies over a station range, or where a drop boundary sits. Drops are stationed by the alignment: the first begins at the alignment begin station and the last ends at the alignment end station, which is derived and cannot be set.

    View tool JSON
    {
      "name": "set_template_drop",
      "kind": "act",
      "impl": "imperative",
      "description": "Change which template applies over a station range, or where a drop boundary sits. Drops are stationed by the alignment: the first begins at the alignment begin station and the last ends at the alignment end station, which is derived and cannot be set.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "1-based index of the drop."
          },
          "template": {
            "type": "string",
            "description": "Template name to apply over this range."
          },
          "toStationFt": {
            "type": "number",
            "description": "Boundary station in feet. Ignored for the last drop, which is derived."
          },
          "transitionLengthFt": {
            "type": "number",
            "description": "Optional taper length in feet, blending from the previous template."
          },
          "commit": {
            "type": "boolean",
            "description": "false (the default) PREVIEWS: it computes the consequence and changes nothing. true applies the change. Preview first; a licensed engineer confirms."
          }
        },
        "required": [
          "index"
        ]
      }
    }