EPANET MCP Server
Allows generating a junction/pipe skeleton from real OpenStreetMap road data for a bounding box, with a reservoir placed at the nearest waterway and ground elevations sampled from a DEM.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@EPANET MCP ServerLoad network and run 24-hour hydraulic simulation, then show results."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
EPANET MCP Server
An MCP server that puts the EPANET hydraulic/water-quality engine in front of AI assistants (Claude Desktop, Cursor, VS Code Copilot, Claude Code, …) over stdio — no cloud round-trip, no browser.
It lets an AI assistant load an EPANET .inp/.net model, inspect it, run simulations, read per-node/per-link results, and make validated edits, all locally.
Tools
Network I/O —
load_network,save_network,list_networksInspection —
get_network_summary,get_nodes,get_links,get_coordinatesSimulation —
run_simulation,get_node_results,get_link_resultsMutation (engine-validated, results-invalidating) —
set_pipe_diameter,set_junction_demand,set_pump_speed,set_valve_setting,set_node_elevation,set_demand_pattern,add_tank,remove_tank,add_valveModel building —
create_network,assign_demands,sample_elevations,fetch_road_network,generate_network_from_bboxDesign helpers —
lookup_pipe_diameters,recommend_diameter,friction_loss,calculate_minor_loss,pipe_sizing_wizard,pump_selection,list_fitting_kfactorsOptimization —
optimize_network,run_candidate
generate_network_from_bbox auto-lays out a junction/pipe skeleton from real OpenStreetMap road data for a bounding box, with a reservoir placed at the nearest waterway and ground elevations sampled from a bundled IFSAR 10 m DEM.
Related MCP server: idfkit-mcp
Prerequisites
Requirement | Version |
Node.js | 20.x or 21.x |
OS | Windows, macOS, or Linux — transport is stdio, no network ports opened |
Install
npm installRun locally
The data directory the server reads from (load_network) and writes to (save_network) is path-contained — the server refuses any file outside it.
mkdir -p data
cp your-model.inp data/
export EPANET_DATA_DIR=$(pwd)/data
npm startThe server boots and waits for a client on stdio.
Wire it to an AI app
Claude Desktop
Edit claude_desktop_config.json (%APPDATA%\Claude\claude_desktop_config.json on Windows, ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"epanet": {
"command": "npm",
"args": ["start"],
"cwd": "<absolute path to this repo>",
"env": {
"EPANET_DATA_DIR": "<absolute path to this repo>/data"
}
}
}
}Cursor / VS Code
Same shape works in Cursor (%APPDATA%\Cursor\User\globalStorage\mcp.json) or VS Code (%APPDATA%\Code\User\mcp.json) — command: "npm", same args/env.
Configuration
The server reads these environment variables:
Env var | Default | Purpose |
| cwd | Folder |
| unset | Folder the DEM/elevation tools read from |
| unset | RS256 public key for optional token-mode auth |
| unset | Loopback URL for token validation |
| unset | Expected JWT |
| unset | Expected JWT |
| unset | Static bearer token (CI use) |
| unset | Path to a file containing the bearer token |
Auth is off by default; set the EPANET_AUTH_* variables to gate the server behind an RS256 bearer token.
Tests
npm testUnit tests drive the in-memory MCP transport against committed .inp fixtures — they don't require a running server.
Build a packaged installer
npm run package:win # or package:mac / package:linuxProduces a self-contained installer (vendored Node runtime, no system Node required) under dist/.
License
MIT — see LICENSE.
Available Tools
33 toolsadd_tankA
Add a storage tank at a strategic location: a new tank node plus a connector pipe attaching it to an existing node — a junction (e.g. a low-pressure junction that needs pressure support) or, optionally, a reservoir. The edit is validated against the EPANET engine before it is applied — unique ids, realistic geometry, the edited model must re-parse with the tank and pipe present, node/link counts must increase by exactly one each, and the edited model must still solve hydraulically if the base model did. Previous simulation results are invalidated; re-run run_simulation to see the effect.
| Name | Required | Description | Default |
|---|---|---|---|
| pipeId | Yes | New unique pipe id connecting the junction to the tank (1-31 characters, no spaces and none of: + - . ;). | |
| tankId | Yes | New unique tank id (1-31 characters, no spaces and none of: + - . ;). | |
| diameter | Yes | Tank diameter (model's length units). | |
| maxLevel | Yes | Maximum water level above the tank bottom (model's units); must exceed minLevel. | |
| minLevel | Yes | Minimum water level above the tank bottom (model's units). | |
| elevation | Yes | Tank bottom elevation in the model's units (m for SI, ft for US). | |
| minVolume | No | Minimum volume; defaults to 0. | |
| networkId | Yes | The network id returned by load_network. | |
| junctionId | No | Id of an existing junction to attach the tank to (use get_nodes to list junction ids; a low-pressure junction is a good candidate). Provide exactly one of junctionId or reservoirId. | |
| pipeLength | Yes | Length of the connector pipe (model's length units). | |
| reservoirId | No | Id of an existing reservoir to attach the tank to instead of a junction (use get_nodes to list reservoir ids). Provide exactly one of junctionId or reservoirId. | |
| initialLevel | Yes | Initial water level above the tank bottom (model's units). | |
| pipeDiameter | Yes | Diameter of the connector pipe (mm for SI models, inches for US-unit models). | |
| pipeRoughness | No | Roughness of the connector pipe (default 100 for H-W/C-M models, 0.25 for D-W models). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explicitly states that the edit is validated against the EPANET engine (checking unique ids, realistic geometry, re-parse, count increments, and hydraulic solvability), that previous simulation results are invalidated, and that run_simulation must be re-run. This is thorough and goes beyond a simple side-effect statement, giving the agent a clear model of outcomes and failure risks.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the purpose and then delivering validation and side-effect details. It is structured logically and each sentence earns its place. While it is slightly verbose in listing validation specifics, that information is valuable and not redundant. It avoids filler and would benefit only from trimming minor redundancy in the validation list.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (14 parameters, no output schema, no annotations), the description covers the core action, the validation process, and the invalidation of previous results. It does not specify the exact return value or error messages, but those are not expected without an output schema. It also does not mention prerequisites beyond requiring networkId and a target node, though these are in the schema. Overall, it is sufficiently complete for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents all 14 parameters at 100% coverage, so the baseline is 3. The description adds minimal parameter-specific semantics: it clarifies that the tool adds a tank and pipe together, and implies that pipe-related parameters refer to the connector pipe, but it does not provide additional format or constraint details beyond what the schema already states. It does not compensate for any coverage gaps because none exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Add'), a concrete resource ('a storage tank'), and explains the mechanism: a new tank node plus a connector pipe attached to an existing junction or reservoir. This clearly distinguishes it from sibling tools like add_valve (valve) and remove_tank (removal). The purpose is unambiguous and immediately actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides usage context by suggesting a junction that needs pressure support ('a low-pressure junction that needs pressure support') and mentions the alternative of a reservoir. It does not explicitly exclude alternatives or contrast with other modification tools, but the stated use case is clear enough for an agent to decide when to invoke this tool. A brief 'when not to use' would elevate it further.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
add_valveA
Insert a pressure-reducing valve (PRV) in series with an existing pipe: the pipe is split — a new junction is created at a fraction along it, the original pipe is shortened to that junction, and a new PRV link runs from the junction to the pipe's downstream node, capping pressure there at the requested setting (e.g. to protect low-lying tap stands from excess static head). The edit is validated against the EPANET engine before it is applied — unique ids, realistic bounds, the edited model must re-parse with the junction as a junction, the valve as a PRV with the requested setting, and the pipe shortened as requested, node/link counts must increase by exactly one each, and the edited model must still solve hydraulically if the base model did. Previous simulation results are invalidated; re-run run_simulation to see the effect.
| Name | Required | Description | Default |
|---|---|---|---|
| linkId | Yes | Id of the pipe to split with the valve (use get_links to list pipe ids). The PRV is inserted in series: the pipe is shortened and a new junction is created at the split point, so the valve caps pressure at the pipe's downstream node (node2) at the setting. | |
| setting | Yes | PRV pressure setting in the model's pressure units (m for SI models, psi for US-unit models). Range: 0 to 10000. | |
| valveId | Yes | New unique valve id (1-31 characters, no spaces and none of: + - . ;). | |
| diameter | No | Diameter of the new valve (mm for SI models, inches for US-unit models); defaults to the split pipe's diameter. | |
| minorLoss | No | Minor-loss coefficient of the new valve; defaults to 0. | |
| networkId | Yes | The network id returned by load_network. | |
| splitPosition | No | Where along the pipe (fraction from node1 toward node2) the split junction sits; defaults to 0.9 (near the downstream end, so most of the pipe keeps its length). | |
| splitJunctionId | No | New unique junction id at the split point; defaults to '<valveId>J'. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it excels: it details the split behavior, validation against EPANET (unique ids, bounds, re-parse, counts increase by exactly one, hydraulic solvability), and side effects (invalidation of previous simulation results). This is thorough and honest about the tool's impact, exceeding typical descriptions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence adds value: from the core action to validation details and re-run guidance. It is front-loaded with the primary purpose and then elaborates. Slightly long, but no filler; a 4 reflects appropriate structure without being overly terse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having no output schema, the description covers essential operational context: validation criteria, side effects, and follow-up (re-run run_simulation). It does not explicitly state the return value, but given the tool's complexity and the absence of an output schema, a brief mention of what it returns would be helpful; otherwise, it is complete for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful context by explaining how parameters interact (e.g., linkId splits the pipe, setting caps pressure at downstream node) and clarifies defaults (splitPosition defaults to 0.9, diameter defaults to pipe's). This goes slightly beyond the schema, justifying a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Insert a pressure-reducing valve (PRV) in series with an existing pipe') and explains the mechanism (pipe split, junction creation, PRV link). It distinguishes itself from sibling tools like set_valve_setting by focusing on creating a new valve rather than modifying an existing one, and from add_tank by targeting pipes. The example use case (protect low-lying tap stands) further clarifies intent.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool via the example (protect against excess static head) and notes that previous simulation results are invalidated, prompting re-running run_simulation. However, it does not explicitly contrast with alternatives such as set_valve_setting or add_tank, nor does it state when NOT to use it. The guidance is present but not explicit in routing the agent among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
assign_demandsA
Convert a population table into per-node base demands for a loaded network: demand = people × litersPerCapitaPerDay × peakingFactor ÷ 86400, converted from liters/second into the model's flow units (so GPM/CFS/MGD models get the right numbers automatically). The computed demands replace each junction's base demand through the same guarded, engine-validated path as set_junction_demand: every junction must exist, junctions with demand categories in the [DEMANDS] section are rejected (they override the [JUNCTIONS] column), each computed demand must be within the model's demand bounds, and the edited model must re-parse with exactly the requested demands and unchanged node/link counts. Previous simulation results are invalidated — re-run run_simulation afterwards. This is the 'population in, demands out' step of the GIS workflow (mcp_gis_roadmap.md Phase 3).
| Name | Required | Description | Default |
|---|---|---|---|
| networkId | Yes | The network id returned by load_network. | |
| perCapita | Yes | Per-capita consumption rate. Required — demands are never guessed from a default rate. | |
| population | Yes | Population table: one entry per junction. Each nodeId must be unique and must be an existing junction. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and does so excellently. It discloses the entire validation procedure: junction existence checks, rejection of demand-category junctions that override the [JUNCTIONS] column, demand bound enforcement, and re-parse verification with unchanged node/link counts. It also explicitly states that previous simulation results are invalidated and instructs to re-run run_simulation. No annotation contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, formula, validation, side effects, and workflow context. It is front-loaded with the primary action, then provides necessary constraints and caveats. No fluff or redundancy; the structure is logical and scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of three parameters with nested objects and no output schema, the description covers all critical aspects: what the tool does, how it computes, validation rules, side effects, and usage context. An agent has everything needed to decide when to call it and what to expect. The lack of a return-value description is irrelevant given the tool's action-oriented nature and the absence of an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds significant meaning beyond the field-level descriptions. It explains the calculation formula (demand = people × litersPerCapitaPerDay × peakingFactor ÷ 86400), the automatic unit conversion to the model's flow units, and the purpose of each parameter in context (e.g., 'Zero sets the demand to 0'). This goes well beyond the schema's per-field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource: 'Convert a population table into per-node base demands for a loaded network.' It includes the exact formula and explicitly distinguishes itself from single-junction demand setting by referencing the same validation path as set_junction_demand. The purpose is unambiguous and clearly differentiated from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use it: 'This is the "population in, demands out" step of the GIS workflow (mcp_gis_roadmap.md Phase 3).' It also implicitly contrasts with set_junction_demand by mentioning 'the same guarded, engine-validated path,' and provides the critical prerequisite that all junctions must exist and certain demand categories are rejected. This gives clear context for selection without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
calculate_minor_lossA
Calculate total minor (dynamic) head loss through a set of pipe fittings using the K-factor method: h = K × v² / (2g). Provide a pipe diameter, flow rate, and a list of fitting types with quantities. Each fitting's K-factor is looked up from the built-in database (use list_fitting_kfactors to see available types), or supply a customK for non-standard fittings. Returns: flow velocity, individual fitting losses, total minor loss, total equivalent length of pipe, and pressure drop. Use this to account for valves, elbows, tees, and other fittings when sizing pipes or pumps.
| Name | Required | Description | Default |
|---|---|---|---|
| fittings | Yes | List of fittings. Each entry has a type (key from list_fitting_kfactors), optional quantity, and optional customK override. | |
| flowRate | Yes | Flow rate in the given units. | |
| flowUnits | Yes | Flow units matching EPANET's [OPTIONS] Units. | |
| diameterMm | Yes | Pipe inner diameter in mm (at the fitting location). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden. It transparently explains the calculation method (K-factor formula), how K-factors are obtained (database lookup or customK), and what outputs to expect. It does not explicitly state that the operation is read-only, but 'Calculate' implies no side effects. It also lacks caveats about invalid fitting types, but this is a minor gap for a pure calculation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences, each earning its place: the first gives the purpose and formula, the second details inputs and the K-factor lookup mechanism, and the third lists return values and the primary use case. No fluff, perfectly front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of an output schema, the description appropriately enumerates all return values (flow velocity, individual fitting losses, total minor loss, equivalent length, pressure drop). It also explains how to discover available fitting types via `list_fitting_kfactors` and covers the key parameters. The description leaves nothing essential for an agent to safely call the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by explaining the K-factor formula, the relationship between flow rate and diameter, and the purpose of `customK` (to override or supply a K-factor for non-standard fittings). It also clarifies that `type` must be a key from `list_fitting_kfactors`, which is not fully apparent from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Calculate') and resource ('minor (dynamic) head loss through a set of pipe fittings') with a precise formula. It distinguishes itself from the sibling `friction_loss` by focusing on fittings and the K-factor method, while naming the exact return values. The tool's scope is unambiguous and well-delimited.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Use this to account for valves, elbows, tees, and other fittings when sizing pipes or pumps,' giving a clear intended use case. It also points to `list_fitting_kfactors` for available types, which is a cooperative sibling. However, it does not explicitly contrasts with `friction_loss` for straight-pipe scenarios, though the phrasing 'minor head loss' makes the distinction implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
create_networkA
Build a new hydraulic model from scratch — no file needed. Supply junctions, reservoirs (e.g. a river intake) and optional tanks with elevations, plus pipes with lengths and diameters; optional x/y coordinates per node are written into a [COORDINATES] section so the model has real geometry. The spec is validated (unique ids, real pipe endpoints, realistic bounds) and the generated INP is re-opened through the EPANET engine: it must parse with exactly the requested node/link counts. Solvability is reported (solves: true/false) but not enforced, so a skeleton network can be created and filled in later. Creates a normal session: run_simulation, set_* edits, optimize_network and save_network all work on it immediately. This is the first step of the GIS workflow; for an auto-layout from real streets use generate_network_from_bbox (Phase 4) instead — see mcp_gis_roadmap.md.
| Name | Required | Description | Default |
|---|---|---|---|
| pipes | Yes | Pipes: id, two existing node ids, length, diameter (mm for SI, inches for US), optional roughness/minor-loss/status. | |
| tanks | No | Optional tanks: id, bottom elevation, water levels above it, diameter, optional min volume and x/y. | |
| title | No | Model title; defaults to 'Generated network'. | |
| units | No | Flow units for the model; defaults to LPS. US units (GPM/CFS/MGD/IMGD/AFD) use feet/inches and psi; SI units use metres/mm. | |
| headloss | No | Headloss formula; defaults to H-W (Hazen-Williams). Affects the default pipe roughness: the default pipe material is HDPE, so 130 (H-W/C-M) or 0.25 mm (D-W). | |
| junctions | Yes | Junctions: id, ground elevation (m or ft — optional when sampled from IFSAR via x/y), optional base demand (flow units) and projected x/y coordinates. | |
| reservoirs | Yes | Reservoirs (e.g. a river intake): id, fixed head (m or ft), optional x/y coordinates. | |
| elevationSource | No | Ground-elevation source. Defaults to the bundled IFSAR 10 m DEM: any junction without an explicit elevation is sampled from it using the junction's x/y coordinates, so no elevation guessing is the default. Set type ifsar-10m with coordinates wgs84 (default) or { utmZone }. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It reveals that the spec is validated (unique ids, real endpoints, bounds), that the INP is re-opened through the EPANET engine and must parse with exact counts, that solvability is reported but not enforced (allowing skeleton networks), and that it creates a normal session enabling other tools to operate immediately. These are concrete behavioral traits beyond the schema, giving the agent a realistic model of execution and side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence contributes: purpose, required inputs, validation behavior, solvability semantics, session integration, and routing to the alternative. The key constraint (first step of GIS workflow, use generate_network_from_bbox instead) is front-loaded near the end but clearly separated. It is appropriately sized for the tool's complexity, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex (8 parameters, nested objects, multiple behavioral details), and there is no output schema. The description explains many behaviors but does not explicitly state the return value — it only implies a session by saying 'Creates a normal session.' It also doesn't describe what happens on validation failure (beyond implying rejection). Given the complexity and absent output schema, an agent might be unsure what it gets back (e.g., a session ID) and how to use it. This is a real gap, so 3 is appropriate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds some value beyond the schema: it mentions that optional x/y coordinates are written into a [COORDINATES] section, clarifies that reservoirs are e.g. a river intake, and explains the elevation sampling default indirectly. It doesn't re-document each parameter but reinforces key relationships (e.g., pipes with lengths/diameters) and the purpose of geometry. This is a modest improvement over the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Build a new hydraulic model from scratch' — a specific verb and resource that immediately conveys the action and object. It distinguishes itself from the sibling generate_network_from_bbox by explicitly stating it creates a model from user-supplied components rather than auto-layout from streets. The reference to the GIS workflow positions it clearly as the first step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool: 'This is the first step of the GIS workflow.' It also gives a direct alternative and condition: 'for an auto-layout from real streets use generate_network_from_bbox (Phase 4) instead.' This is unambiguous routing with a clear exclusion, matching the top-tier example.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
fetch_road_networkA
Fetch the road network for a geographic bounding box from OpenStreetMap (fixed public Overpass endpoint only — never Nominatim, never a caller-supplied URL) and return structured road geometry and attributes for future EPANET network generation: OSM way id, name, highway classification, full WGS84 geometry, length (m), and lanes/maxspeed/surface/oneway/bridge/tunnel where OSM has them (missing tags come back null). When waterwayTypes is set, matching linear waterway ways (river/stream/brook/canal/drain/ditch — for river-intake placement) are fetched in the same request and returned under waterways with way id, name, waterway class, geometry, length (m), and width/intermittent/tunnel. The bounding box is validated (ranges, min < max, per-axis span and total area caps) and the results are capped (maxResults, default 500, hard cap 5000) and pageable (offset; roads and waterways are paged independently with the same offset/maxResults). The Overpass query requests only the requested highway/waterway classes (roadTypes/waterwayTypes whitelists; roadTypes defaults to the standard drivable set, waterwayTypes is off unless given), carries a descriptive User-Agent, has a 30 s timeout and a 25 MB response cap, and fails closed on any Overpass error/timeout. Identical (bbox, roadTypes, waterwayTypes) requests are served from a short-lived in-memory cache. PURE READ: no network session, model, or file is touched — nothing is generated or optimized yet. Data © OpenStreetMap contributors, licensed ODbL (https://www.openstreetmap.org/copyright).
| Name | Required | Description | Default |
|---|---|---|---|
| maxLat | Yes | North latitude (WGS84 degrees) of the bounding box. | |
| maxLon | Yes | East longitude (WGS84 degrees) of the bounding box. | |
| minLat | Yes | South latitude (WGS84 degrees) of the bounding box. | |
| minLon | Yes | West longitude (WGS84 degrees) of the bounding box. | |
| offset | No | Zero-based page offset; combine with maxResults to page through large areas (roads are ordered by OSM way id). | |
| roadTypes | No | Highway classes to fetch, e.g. ["residential", "tertiary"]. Defaults to the standard drivable set (motorway/trunk/primary/secondary/tertiary/unclassified/residential/living_street/road/service/track). Unknown values are rejected, never silently dropped. | |
| maxResults | No | Page size (default 500, hard cap 5000); combine with offset to page through large areas. | |
| waterwayTypes | No | Waterway classes to fetch alongside the roads, e.g. ["river", "stream", "canal"] for river-intake placement. Linear channels only: river/stream/brook/canal/drain/ditch. When set, matching waterway ways are returned under `waterways` (way id, name, waterway class, geometry, length, width/intermittent/tunnel) in the same request. Unknown values are rejected, never silently dropped. When omitted, only roads are fetched. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it delivers comprehensively. It discloses the fixed endpoint, the 30-second timeout, 25 MB response cap, fail-closed behavior on Overpass errors, bounding box validation and caps, result capping and pagination, caching of identical requests, and its pure-read nature affecting no state. It even includes licensing attribution. This is far beyond the minimum and leaves no major behavioral surprise.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence carries distinct information—purpose, waterway addition, validation/caps, technical constraints, caching, licensing, and read-only nature. It is front-loaded with the core purpose and then layers details. The structure is logical and there is minimal redundancy. It could arguably be tightened, but for a tool of this complexity (8 parameters, dual output types, pagination), the length is justified. Only a minor reduction in verbosity would earn a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must fully explain what the tool returns, and it does: it specifies the exact attributes for roads (way id, name, highway type, geometry, length, and optional tags) and for waterways (way id, name, class, geometry, length, and width/intermittent/tunnel). It also covers error handling, defaults, paging, and caching. An agent has everything needed to invoke the tool correctly and interpret the result without any further reference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While schema description coverage is 100%, the description adds substantial semantics beyond the schema. It enumerates the default roadTypes set, states that unknown values are rejected (never silently dropped), specifies the allowed waterway types ('river/stream/brook/canal/drain/ditch'), clarifies that roads and waterways are paged independently with the same offset/maxResults, and describes the output structure under `roads` and `waterways`. This transforms the parameters from bare field names into actionable guidance on how to compose valid requests and interpret results.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with a specific verb ('Fetch') and resource ('road network for a geographic bounding box from OpenStreetMap'), and immediately distinguishes it from any other geocoding or URL-based fetching by stating the fixed Overpass endpoint and excluding Nominatim and caller-supplied URLs. It also clarifies the output is 'structured road geometry and attributes for future EPANET network generation', differentiating it from sibling tools like generate_network_from_bbox which would perform downstream generation. This makes the tool's scope unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies usage as a data-fetching step for later EPANET generation ('for future EPANET network generation') and emphasizes it is read-only ('PURE READ: no network session, model, or file is touched — nothing is generated or optimized yet'). While it does not explicitly name alternative tools or state 'when not to use', the context of the sibling list and the explicit read-only note makes its role clear. It stops short of an explicit routing instruction but is strong enough that an agent would know when to choose it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
friction_lossA
Calculate friction loss (head loss and pressure drop) in a full-bore water pipe. Supports two methods: Hazen-Williams (empirical, uses C-factor, water-only) and Darcy-Weisbach (physics-based, uses absolute roughness ε, universally applicable). Returns head loss per metre, total head loss over the pipe length, pressure drop, flow velocity, Reynolds number, and the Darcy friction factor. Roughness presets are available for common pipe materials (hdpe, pvc, di-cement, steel-new, steel-aged, etc.) or supply custom values. Use this to validate pipe sizing from recommend_diameter or to compare friction losses across materials/ diameters.
| Name | Required | Description | Default |
|---|---|---|---|
| method | Yes | Friction-loss method: 'hazen-williams' (empirical, water-only, uses C-factor) or 'darcy-weisbach' (physics-based, uses pipe roughness height ε). | |
| preset | No | Roughness preset: sets roughnessC or roughnessEpsilonMm automatically. 'custom' (default) requires explicit roughness values. | |
| lengthM | Yes | Pipe length in metres for the total head-loss calculation. | |
| flowRate | Yes | Design flow rate in the given flow units. | |
| flowUnits | Yes | Flow units matching EPANET's [OPTIONS] Units. | |
| diameterMm | Yes | Pipe inner diameter in mm (the value from lookup_pipe_diameters or set_pipe_diameter). | |
| roughnessC | No | Hazen-Williams C-factor (required for hazen-williams method). Typical: 150 (PVC/HDPE), 140 (new DI/steel), 100 (aged steel). | |
| roughnessEpsilonMm | No | Darcy-Weisbach absolute roughness height ε in mm (required for darcy-weisbach method). Typical: 0.007 (PVC/HDPE), 0.045 (new steel), 0.26 (new cast iron), 1.0 (concrete). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It lists the outputs (head loss per metre, total head loss, pressure drop, flow velocity, Reynolds number, Darcy friction factor) and explains the applicability of each method (Hazen-Williams water-only, Darcy-Weisbach universal). It does not explicitly address edge cases or error handling, but for a calculation tool the behavioral traits are well covered.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: it starts with the core function, then explains methods and outputs, followed by presets and usage guidance. Every sentence contributes to understanding the tool, with no redundancy or fluff. The structure appropriately front-loads the most critical information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (8 parameters, 5 required, two methods, presets) and the absence of an output schema, the description is remarkably complete. It covers what the tool does, the two methods and their distinctions, all return values, the availability of presets, and explicit usage context relative to siblings. An agent has all the information needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds minimal extra meaning beyond the schema: it mentions roughness presets and custom values, but the schema already documents each preset and its effect. No additional parameter semantics are provided that would elevate the score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: to calculate friction loss (head loss and pressure drop) in a full-bore water pipe. It specifies two distinct calculation methods (Hazen-Williams and Darcy-Weisbach) and explicitly differentiates itself from sibling tools by mentioning validation of pipe sizing from recommend_diameter and comparison across materials/diameters.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use the tool: 'Use this to validate pipe sizing from recommend_diameter or to compare friction losses across materials/diameters.' It names a specific sibling tool and gives clear use cases, fulfilling the 'explicit when/alternatives' criterion effectively.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_network_from_bboxA
Build a water network automatically from real streets — the one-call GIS layout (roadmap Phase 4, native tool). Fetch OSM highway+waterway ways for a bbox (or reuse a saved extract via osmExtract/osmFile), derive the junction/pipe skeleton: the connected component containing the road nearest the river, dead-end spurs pruned (minDeadEndM, default 30 m), roads decimated to ~spacingM (default 150 m) junction spacing, and pipe diameters from the road class as HDPE (PE100) INTERNAL bores at SDR 11 — e.g. trunk 290, primary 258, secondary 205, tertiary 164, residential 90, service 74 mm — with the default pipe material HDPE (Hazen-Williams C = 130). The reservoir is placed at the nearest OSM waterway point to river and connected to the nearest junction by an intake pipe; ground elevations are sampled from the bundled IFSAR 10 m DEM (never guessed, same fail-closed contract as create_network elevationSource). The resulting model is engine-validated and becomes a normal session (networkId): run_simulation, assign_demands, optimize_network and save_network all work on it immediately. The bbox mode calls the public Overpass API (fixed endpoint, 30 s timeout, 25 MB response cap); pass osmExtract or osmFile instead to work from a saved extract with no network. Provide exactly one of bbox / osmExtract / osmFile, plus river and a positive reservoirHead (the intake/pump discharge head — a design input, never guessed).
| Name | Required | Description | Default |
|---|---|---|---|
| bbox | No | Bounding box (WGS84) to fetch OSM highway+waterway ways from Overpass. Provide exactly one of bbox / osmExtract / osmFile. | |
| river | Yes | The water source: the reservoir is placed at the nearest OSM waterway point to this coordinate (falling back to the coordinate itself when the extract has no waterways). | |
| title | No | Model title; defaults to 'Auto-layout network'. | |
| osmFile | No | A saved OSM extract JSON file (with an 'elements' array), relative to the server data directory. Provide exactly one of bbox / osmExtract / osmFile. | |
| spacingM | No | Target junction spacing along roads (m); default 150. Lower = more junctions, higher = a coarser skeleton. | |
| osmExtract | No | Inline OSM elements (Overpass 'out body' JSON) to lay out instead of fetching live. Provide exactly one of bbox / osmExtract / osmFile. | |
| minDeadEndM | No | Dead-end chains shorter than this (m) are pruned; default 30. 0 keeps every dead-end branch. | |
| reservoirHead | Yes | Reservoir head in the model's length units (e.g. meters) — the intake/pump discharge head. Required; never guessed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure, and it does so thoroughly. It details the entire pipeline: OSM fetch, skeleton derivation, dead-end pruning, road decimation, deterministic diameter mapping (with explicit values), reservoir placement, DEM sampling that never guesses, engine validation, and immediate post-processing availability. It also discloses network constraints (Overpass endpoint, timeout, response cap) and the never-guessed contracts for elevation and reservoir head.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph, but every sentence carries meaningful information. It is front-loaded with the core purpose and then expands into operational details and constraints. While lengthy, it avoids redundancy and is well-organized with a logical flow from inputs to processing to outputs. It is not overly terse, but the complexity justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 8 parameters, nested objects, and no output schema, the description is remarkably complete. It specifies parameter defaults, behavior, external dependencies, and the resulting model lifecycle (networkId, immediate support for run_simulation, assign_demands, etc.). It also covers error-prone aspects like the requirement of exactly one input mode and the fail-closed elevation contract. An agent would be well-equipped to invoke this tool correctly without additional lookup.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial semantic value beyond the schema. It explains the effect of each parameter in context: spacingM controls junction density, minDeadEndM prunes short branches, river guides reservoir placement to the nearest waterway, and reservoirHead is a design input that must be positive. For nested objects like osmExtract and osmFile, it clarifies their relationship to bbox and the offline workflow. This goes well beyond the raw schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear, specific verb and resource: 'Build a water network automatically from real streets — the one-call GIS layout.' It distinguishes itself from siblings like fetch_road_network and create_network by positioning as the consolidated layout tool and explicitly noting it is the Phase 4 native tool. The purpose is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs to provide exactly one of bbox / osmExtract / osmFile along with river and reservoirHead, and explains the trade-off between live Overpass calls and saved extracts. It also references the fail-closed contract shared with create_network, giving context on when this tool behaves similarly. It does not explicitly list exclusions versus siblings, but the guidance is strong enough for an agent to choose appropriately.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_coordinatesA
Read the model's node coordinates (the [COORDINATES] section) without saving a file — pure read, nothing is modified. Returns each requested node's stored x/y (the model's own coordinate system) plus, when coordinates is given, its WGS84 lat/lon (coordinates: 'wgs84' means x is longitude/y is latitude; {utmZone} means x/y are UTM easting/northing meters in that zone). Nodes without stored coordinates come back in missingIds — never invented. Pass specific node ids to keep the response small, or page with offset + the 250-item cap. This is the geometry half of the GIS workflow: get_coordinates to inspect where nodes are, then sample_elevations for real IFSAR ground elevations at those points.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Zero-based index of the first node to return; combine with the 250-item cap to page through large networks. | |
| nodeIds | No | Node ids to inspect. Omit to list all nodes (capped at 250 per page); nodes without stored coordinates are reported in missingIds, never invented. | |
| networkId | Yes | The network id returned by load_network. | |
| coordinates | No | How the model's stored x/y map to WGS84. When provided, each node also gets lat/lon; when omitted, only the raw stored x/y are returned. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly states 'pure read, nothing is modified', discloses that nodes without stored coordinates are returned in missingIds and 'never invented', and explains the coordinate mapping semantics (WGS84 vs UTM). This is comprehensive behavioral transparency for a read operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the core purpose, then expands to cover return behavior, pagination, and workflow context. Every sentence adds value—there is no filler or redundant restatement. The structure flows logically from what to expectations and use cases.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 4 parameters (1 required) and no output schema, the description covers all essential context: it specifies the read-only nature, explains the meaning of the coordinates parameter, describes the missingIds behavior, and gives pagination strategy. It also situates the tool within the broader GIS workflow with sample_elevations. An agent has everything needed to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds marginal value beyond the schema: it reiterates the coordinate mapping for 'wgs84' and UTM zones, and offers usage tips like passing specific node ids to keep the response small. However, these are more usage guidelines than new parameter semantics; the schema already documents each parameter's purpose and constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a clear verb and resource: 'Read the model's node coordinates (the [COORDINATES] section) without saving a file'. It explicitly states the tool is read-only and differentiates it from the sibling tool sample_elevations by positioning it as the 'geometry half' of the GIS workflow. This leaves no ambiguity about what the tool does or how it differs from related tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit guidance on when to use the tool: it explains how to narrow results by passing specific node ids, how to page with offset and the 250-item cap, and it directly names the alternative (sample_elevations) and when to use that instead. This gives an agent clear decision criteria without needing to infer.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_link_resultsA
Query simulation results for links (flow, velocity, headloss, unitHeadloss, quality, status, setting, head). Defaults to the last timestep and includes min/max/mean over time unless timesteps are given. Link ids are capped at 250, timesteps at 100. Pass the runId returned by run_simulation to pin results to a specific run; omit for the latest run. headloss is TOTAL headloss (unit headloss x length/1000 for pipes; valves report the raw column value). unitHeadloss is the raw per-1000-unit value. Pumps report head (head added, positive when pumping normally); their headloss/unitHeadloss are null. status is a raw EPANET status code (legend in units.status); statusLabel/statusWarning are decoded per link type. Units and a qualityAnalyzed flag are included in every response.
| Name | Required | Description | Default |
|---|---|---|---|
| runId | No | The run id returned by run_simulation. Omit to use the latest run. | |
| offset | No | Zero-based index of the first link to return; combine with the cap to page through large networks. | |
| linkIds | No | Link ids to query. Omit for all links (capped at 250 per page). | |
| networkId | Yes | The network id returned by load_network. | |
| timesteps | No | Zero-based reporting timestep indices. Omit to get the last timestep plus min/max/mean over time. | |
| properties | No | Result properties to return. Defaults to flow. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it excels. It discloses defaults (last timestep, min/max/mean), caps (250 links, 100 timesteps), runId behavior, and special cases for pumps (head vs headloss), status decoding, and the qualityAnalyzed flag. This level of detail prevents misinterpretation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than typical but every sentence adds information. It's front-loaded with the core purpose and then covers defaults, limits, runId usage, and property semantics. No redundant or filler content; the density is justified by the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description compensates by outlining return characteristics (units, qualityAnalyzed flag, statusLabel/statusWarning). It explains all edge cases and default behaviors, making it effectively complete for an agent to call correctly without external knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so each parameter has a basic description. The tool description adds substantial value by explaining semantic nuances: the meaning of headloss (total vs unit), pump-specific behavior, and how timesteps/runId interplay affect results. This goes beyond the schema's literal field names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Query simulation results for links' and enumerates the exact properties available (flow, velocity, headloss, etc.). This immediately distinguishes it from sibling tools like get_links (network structure) and get_node_results. It also clarifies it's about simulation results, not static network data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: defaults to last timestep, explains how to pin to a specific run with runId, and mentions caps for paging. It doesn't explicitly state when not to use it or name alternatives, but the context is sufficient for an agent to select it appropriately for querying link results.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_linksA
Inspect static properties of network links (pipes: length/diameter/roughness; pumps: speed/power/head curve; valves: diameter/setting). Pass specific link ids to keep the response small; omit to get a capped listing.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Zero-based index of the first link to return; combine with the 250-item cap to page through large networks. | |
| linkIds | No | Link ids to inspect. Omit to list all links (capped at 250 per page). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses that the tool returns a capped listing (250 items), supports paging via 'offset', and that omitting 'linkIds' returns a large listing. It also conveys read-only intent through 'Inspect' and 'static properties'. It does not describe the response format in detail, but the listed property types give a reasonable picture. No contradictions with annotations (none exist).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with zero filler. The first sentence states the core purpose and enumerates the properties; the second provides the crucial usage tip about 'linkIds' and the cap. All information is front-loaded and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (read-only listing with three params), the description is largely complete. It covers the purpose, property types, parameter usage, and paging behavior. The absence of an output schema is partially compensated by listing the specific properties per link type. The only minor gap is lack of explicit mention of the response container format, but this is not critical for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaningful context beyond the schema: it explains the 250-item cap, the paging behavior with 'offset', and how 'linkIds' affects response size. This extra usage context helps the agent choose parameter values correctly, thus exceeding the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Inspect') and a clear resource ('static properties of network links'), then enumerates the exact properties for each link type (pipes, pumps, valves). This distinguishes it from sibling tools like get_nodes (node properties) and get_link_results (simulation results), so an agent can immediately tell what this tool is for.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance on when to pass 'linkIds' (to keep the response small) versus when to omit (to get a capped listing). It also implies the tool is for static data, which separates it from get_link_results (likely dynamic). However, it does not explicitly name alternatives or state when not to use them, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_network_summaryB
Return a summary of a loaded network: counts, simulation timing, units, quality type, and node/link id previews.
| Name | Required | Description | Default |
|---|---|---|---|
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. It says 'Return a summary' which implies a read-only operation, but it does not disclose side effects, error behavior if the network is not loaded, or any rate limits. For a read tool this is acceptable but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the action and immediately lists what is included. There is no fluff; every clause adds meaning. It is appropriately sized for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one parameter and no output schema, the description names the categories of data returned but not their format or structure. It gives an agent enough to know what to expect conceptually, but lacks detail on exact fields or units, which might be necessary for downstream processing. It is adequate but could be richer.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, networkId, is fully described in the input schema as 'The network id returned by load_network.' The description adds no additional semantics beyond what the schema already provides, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return a summary') and identifies the resource ('loaded network'), plus enumerates the exact content ('counts, simulation timing, units, quality type, and node/link id previews'). This distinguishes it from sibling tools like get_nodes or get_links which target specific elements, though it does not explicitly name an alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states 'of a loaded network', implying the network must be loaded first, but provides no explicit when-to-use vs alternatives (e.g., when you need a high-level overview rather than detailed node results). No exclusions or preferred contexts are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_node_resultsA
Query simulation results for nodes. Defaults to the last timestep and includes min/max/mean over time unless timesteps are given. Node ids are capped at 250, timesteps at 100. Pass the runId returned by run_simulation to pin results to a specific run; omit for the latest run. Units and a qualityAnalyzed flag are included in every response. Demand for tanks/reservoirs is net inflow; tank pressure is 0 by definition.
| Name | Required | Description | Default |
|---|---|---|---|
| runId | No | The run id returned by run_simulation. Omit to use the latest run. | |
| offset | No | Zero-based index of the first node to return; combine with the cap to page through large networks. | |
| nodeIds | No | Node ids to query. Omit for all nodes (capped at 250 per page). | |
| networkId | Yes | The network id returned by load_network. | |
| timesteps | No | Zero-based reporting timestep indices. Omit to get the last timestep plus min/max/mean over time. | |
| properties | No | Result properties to return. Defaults to pressure. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully assumes the burden of behavioral disclosure. It details default timestep behavior, inclusion of min/max/mean, caps on nodeIds and timesteps, runId handling, output flags (units, qualityAnalyzed), and special cases for tanks/reservoirs. This is comprehensive and leaves little to inference.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise yet dense, front-loaded with the core purpose, then systematically covering defaults, limits, run selection, output flags, and edge cases. Each sentence contributes valuable information without redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite lacking an output schema and annotations, the description covers all essential aspects for correct invocation: defaults, caps, run selection, output flags, and node-specific behavior. It is self-sufficient for an agent to call this tool reliably given its complexity and parameter count.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already describes all parameters at 100% coverage, but the description adds extra meaning: it explains pagination semantics for offset, default property behavior, and special node-type nuances like net inflow for tanks/reservoirs and zero tank pressure. This goes beyond the schema and enhances the agent's understanding.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource, 'Query simulation results for nodes,' which immediately makes the tool's purpose clear. It is distinct from siblings like get_link_results (links) and get_nodes (network structure), and the description adds specificity with defaults and limits.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool (for node simulation results) and explains parameter behaviors like runId selection, pagination via offset, and default timestep handling. However, it does not explicitly contrast with alternatives such as get_nodes or get_link_results, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_nodesA
Inspect static properties of network nodes (junctions: elevation/demand; reservoirs: head; tanks: levels/diameter). Pass specific node ids to keep the response small; omit to get a capped listing.
| Name | Required | Description | Default |
|---|---|---|---|
| offset | No | Zero-based index of the first node to return; combine with the 250-item cap to page through large networks. | |
| nodeIds | No | Node ids to inspect. Omit to list all nodes (capped at 250 per page). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool inspects static properties and that listing is capped (with paging via offset), which covers the key behavior. However, it does not mention potential errors (e.g., invalid networkId) or explicitly state it is read-only (though 'inspect' implies it). It also doesn't describe the response format, but that is less critical. Moderate coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, with the core purpose front-loaded. Every sentence adds value: the first defines the scope, the second provides usage guidance. Zero waste and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only inspection tool with three parameters fully documented in the schema, the description covers the essential operational aspects: the scope of properties, the 250-item cap, and paging via offset. It does not elaborate on response structure, but that is not critical given the simple nature. Minor omission: no mention of error cases, but overall it is complete enough for safe invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the description adds minimal new meaning. It reinforces the purpose of nodeIds ('keep the response small') and clarifies the cap, but the schema already documents all parameters. The description does not introduce new syntactic details, so it meets the baseline for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'inspect' and clearly names the resource 'network nodes', listing the properties per node type (junctions, reservoirs, tanks). This distinguishes it from sibling tools like get_node_results (dynamic results) and get_links, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells the agent when to pass nodeIds (to keep response small) vs omit (to get a capped listing), giving clear conditional usage. It does not explicitly name alternatives or exclusions, but the context of being a read-only inspection tool is clear. The guidance is sufficient for basic selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_fitting_kfactorsA
List K-factors (minor loss coefficients) for common pipe fittings. Returns a table of fitting names, K-factors, categories, and equivalent-length ratios. Filter by category: valve, elbow, tee, other, or all. Use this to find the correct K-factor before calling calculate_minor_loss, or to compare loss characteristics of different fitting types.
| Name | Required | Description | Default |
|---|---|---|---|
| category | No | Filter by fitting category: valve, elbow, tee, other, or all (default). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses the return format ('Returns a table…') and implies a read-only operation by the nature of 'List'. It does not mention permissions or side effects, but for a list operation these are not expected. The description gives sufficient behavioral context for safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core resource and output. Every sentence serves a purpose: the first defines the resource and return content, the second covers filtering and usage context. No filler or repetition, making it compact and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with one optional parameter, the description is nearly complete. It covers what the tool does, what it returns, the filter options, and the use case. It lacks explicit mention of default behavior (all when category omitted) but that is already in the schema. Given the simplicity, this is adequate with only minor omissions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of the parameter (category) with a clear description and enum values. The tool description simply repeats the enum list without adding new meaning. With high schema coverage, a baseline of 3 applies; no additional semantic value is provided beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'K-factors for common pipe fittings', and further specifies the output contents (fitting names, K-factors, categories, equivalent-length ratios). It also distinguishes itself from siblings by naming calculate_minor_loss as the dependent tool, making its role in the workflow explicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool: 'Use this to find the correct K-factor before calling calculate_minor_loss, or to compare loss characteristics of different fitting types.' This provides clear usage context and even names the sibling tool, covering the when and why without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_networksA
List the networks currently loaded in this server session (id, source file, whether results exist). Use to recover a network id after losing it.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. The description implies a read-only query by stating it 'lists' current session state, but it does not explicitly state that it is non-destructive, nor does it describe any error conditions or performance characteristics. While it does disclose what information is returned, it could be more explicit about the absence of side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded. The first sentence states the core function and output fields, and the second sentence adds a specific use case. Every word earns its place; there is no redundancy or filler. It is a model of efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple no-parameter list tool without an output schema, the description adequately conveys what the tool does, when to use it, and what information it returns (id, source file, whether results exist). It does not detail the exact return format, but that is not critical for such a simple operation. The description is sufficient for an agent to decide when and how to use it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
This tool has zero parameters, so there is nothing to document. The schema is empty, and the description does not need to compensate for missing parameter details. According to the rubric, a baseline of 4 is appropriate when there are no parameters, as the description cannot add extra meaning beyond what is already absent.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('List') and the resource ('networks currently loaded in this server session'), and specifies the exact data fields returned (id, source file, whether results exist). This is specific enough to differentiate it from sibling tools like load_network (which loads) or get_network_summary (which focuses on a single network).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides a concrete use case: 'Use to recover a network id after losing it.' This gives the agent clear guidance on when to invoke this tool. It does not explicitly list alternatives for other scenarios, but the context implies that other tools exist for loading, summarizing, or modifying networks, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
load_networkA
Load an EPANET INP model from the server's data directory into a named session. Returns the network id and counts.
| Name | Required | Description | Default |
|---|---|---|---|
| inputFile | Yes | INP file name, relative to the server data directory (absolute paths must still resolve inside it). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full responsibility for disclosing behavior. It describes the action and output but does not mention whether the operation is safe (read-only) or destructive (e.g., overwrites an existing session), what permissions are required, or what happens on errors. This is a significant gap for a tool that mutates session state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise (two sentences), front-loads the action and primary object, and contains no filler or redundant phrases. It efficiently conveys the core purpose and expected output.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter tool without an output schema, the description covers the main action and mentions the return value, but the return is vague ('network id and counts') without specifying what counts refer to (nodes, links, etc.). It also omits any prerequisite conditions or session-handling semantics, leaving some ambiguity for an agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with the inputFile parameter already explained as 'relative to the server data directory'. The description's mention of the 'server's data directory' adds no new meaning beyond the schema. It does not clarify path syntax, allowed extensions, or edge cases, so the description adds minimal value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Load'), the resource ('EPANET INP model'), the origin ('server's data directory'), and the destination ('named session'). It also mentions the output ('network id and counts'). This distinguishes it from sibling tools like create_network or generate_network_from_bbox, which have different verbs and resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for loading an existing INP model from the server, but it does not explicitly state when to use this tool over alternatives such as create_network or generate_network_from_bbox. No exclusions or alternative recommendations are provided, so the agent must infer based on the verb 'load' alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_pipe_diametersA
Look up standard pipe inner diameters for common water-distribution materials. Returns a table of standard sizes with nominal diameter, outer diameter, wall thickness, and the resulting inner diameter — the value EPANET uses for hydraulic modeling. Materials: HDPE (ISO 4427, PE100 SDR 11), PVC (AWWA C900 DR 18), ductile iron (ISO 2531 class K9), carbon steel in three variants: steel-medium (ISO 4200 medium series), steel-sch40 (ANSI B36.10 Schedule 40/STD), steel-sch80 (ANSI B36.10 Schedule 80/XS). Filter by material, minimum/maximum nominal size, and display units (mm, inches, or both). Use this when sizing pipes, choosing a standard diameter for set_pipe_diameter, or comparing materials for a given nominal size.
| Name | Required | Description | Default |
|---|---|---|---|
| units | No | Display units for inner diameter: 'mm' (default), 'inches', or 'both' (side-by-side). Nominal sizes always show their native designation. | |
| material | Yes | Pipe material to look up: hdpe (HDPE PE100, ISO 4427), pvc (AWWA C900), di (ductile iron, ISO 2531), steel-medium (ISO 4200 medium series), steel-sch40 (ANSI Sch 40/STD), steel-sch80 (ANSI Sch 80/XS), or all for a combined listing. | |
| maxNominal | No | Maximum nominal diameter to include. Omit for all sizes up to the largest. | |
| minNominal | No | Minimum nominal diameter (DN for metric materials, inches for steel) to include. Omit for all sizes. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses what the tool returns (a table of standard sizes with four columns), the material standards (e.g., HDPE PE100, PVC AWWA C900), and filter options. It implies a read-only lookup operation, though it doesn't explicitly state that it has no side effects—but for a lookup tool that's inferable.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is information-dense but not overly long. It front-loads the purpose, then lists materials and filtering options, and ends with use cases. Each sentence adds value, and the structure is logical. It could be slightly more concise but is well organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (four parameters, multiple material standards, no output schema), the description covers the return format, material options, filter behavior, and use cases. It does not provide an example output or mention edge cases like units for steel inputs, but it is sufficient for an agent to call the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaning beyond the schema by explaining that nominal sizes always show their native designation, that units default to 'mm', and that min/max filters can be omitted for all sizes. It also clarifies the material enum values with standards, enriching the schema definitions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the specific verb 'look up' and the resource 'standard pipe inner diameters for common water-distribution materials', and clarifies it returns a table with nominal, outer, wall thickness, and inner diameters. It distinguishes from siblings like pipe_sizing_wizard by focusing on standard size lookup rather than computation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this when sizing pipes, choosing a standard diameter for set_pipe_diameter, or comparing materials for a given nominal size.' It gives clear when-to-use contexts but does not contrast with alternative tools or mention when not to use it, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
optimize_networkA
Search for the best combination of edits by evaluating an explicit grid of candidate choices on COPIES of a loaded network. For each variable (pipe diameter, junction demand, pump speed, or add_tank placement) you list the choices to try — for add_tank, the nodes to attach a tank to (junctions or reservoirs; plus, by default, the baseline with no tank, so 'try a tank at J2 vs R1 vs none' is one variable); every combination is validated against the EPANET engine and simulated, and the combination that minimizes/maximizes the chosen metric is returned with its full aggregate results. The base model and its stored results are NEVER modified. The search space (product of all choice lists) must fit within maxEvaluations (default 20, up to 100).
| Name | Required | Description | Default |
|---|---|---|---|
| quality | No | Also run water-quality analysis. Requires the model to have quality configured ([OPTIONS] Quality). | |
| networkId | Yes | The network id returned by load_network. | |
| objective | Yes | ||
| variables | Yes | The assets and candidate values to search over. Every combination is evaluated on a copy of the model; the base model is never modified. | |
| maxEvaluations | No | Maximum number of candidate combinations to evaluate (default 20). The full search space (product of all values lists) must fit within this limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses that the tool evaluates on copies, never modifies the base model or stored results, validates each combination against the EPANET engine, and returns the best combination with full aggregate results. It also notes the search space limit. It does not mention potential failure modes or timeout behavior, but covers the most important behavioral traits for safe usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph but well-structured: it leads with the core purpose, then explains the variable types, the add_tank nuance, the non-destructive nature, and the constraint. Every sentence adds useful information, and it is appropriately sized for a tool with this complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with nested objects, five parameters including a complex variables array, and no output schema, the description covers the essential context: what it does, how the search space is constructed, the safety guarantee, and that it returns the best combination with full aggregate results. It does not detail the exact return structure, but the absence of an output schema makes that a minor gap given the description's clarity on the high-level outcome.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (80%), so the schema already documents each parameter. The description adds semantic value by explaining the concept of variables as a grid, detailing the add_tank baseline behavior (includeNone default true, 'try a tank at J2 vs R1 vs none' as one variable), and clarifying that the base model is never modified—context that helps an agent correctly construct the variables array and interpret the networkId parameter's role.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool searches for the best combination of edits by evaluating an explicit grid of candidate choices on copies of a loaded network. It lists the specific variable types (pipe diameter, junction demand, pump speed, add_tank placement) and explicitly notes the base model is never modified, distinguishing it from the many set_* siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use this tool: when you need to explore combinations of edits without modifying the base model. It states the search space constraint (maxEvaluations) and the non-destructive nature, which are key usage guidelines. However, it does not explicitly contrast with alternatives like run_candidate or the individual set_* tools, though the 'search' and 'copies' language makes the distinction clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pipe_sizing_wizardA
End-to-end pipe sizing wizard: given a flow rate, pipe length, and material, finds every standard pipe size that satisfies velocity AND friction-loss constraints, then ranks them by suitability. Chains velocity-based diameter recommendation with Hazen-Williams or Darcy-Weisbach friction-loss validation in a single call. Supports velocity presets (distribution/transmission/service/suction), roughness presets (hdpe/pvc/di-cement/steel-new etc.), and optional max head-loss or max pressure-drop filters. Returns the top N candidates ranked by a composite score (60% velocity closeness + 40% head-loss efficiency). Each candidate includes: nominal size, inner diameter, velocity, head loss per metre, total head loss, pressure drop, Reynolds number, flow regime, and the friction factor. Use this to make a single validated pipe selection without calling recommend_diameter and friction_loss separately.
| Name | Required | Description | Default |
|---|---|---|---|
| topN | No | Number of top-ranked candidates to return (default 5, max 20). | |
| method | No | Friction-loss method (default: hazen-williams). | |
| lengthM | Yes | Pipe length in metres for head-loss calculation. | |
| flowRate | Yes | Design flow rate in the given flow units. | |
| material | No | Restrict to a single material. Omit to search all. | |
| flowUnits | Yes | Flow units matching EPANET's [OPTIONS] Units. | |
| roughnessC | No | Hazen-Williams C-factor. Required when method is hazen-williams and no preset. | |
| maxVelocity | No | Maximum velocity in m/s (default 2.0). | |
| minVelocity | No | Minimum velocity in m/s (default 0.5). | |
| maxHeadLossM | No | Maximum allowed total head loss in metres. Candidates exceeding this are excluded. | |
| velocityPreset | No | Velocity-range preset. 'custom' (default) uses min/maxVelocity. | |
| roughnessPreset | No | Roughness preset (sets roughnessC or roughnessEpsilonMm automatically). | |
| maxPressureDropBar | No | Maximum allowed pressure drop in bar. Candidates exceeding this are excluded. | |
| roughnessEpsilonMm | No | Darcy-Weisbach roughness ε in mm. Required when method is darcy-weisbach and no preset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure, and it does so thoroughly. It describes the chaining of velocity and friction-loss computations, the composite scoring (60% velocity closeness + 40% head-loss efficiency), the filters (max head-loss, max pressure-drop), and the detailed output fields (velocity, head loss, Reynolds number, etc.). It even notes preset behaviors. This is far beyond a typical description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place. It front-loads the core purpose in the first sentence, then logically flows through the chaining mechanism, presets, filters, output details, and usage recommendation. It avoids redundancy and clearly structures information for quick comprehension.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (14 parameters, no output schema), the description is extraordinarily complete. It enumerates all output fields, explains the ranking criteria, specifies parameter requirements, and provides usage context. The absence of an output schema is compensated by the detailed output description. An agent has everything needed to decide when and how to invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema description coverage is 100%, the description adds significant meaning beyond the schema. It explains how parameters interact (e.g., roughnessC is required when method is hazen-williams and no preset, roughnessEpsilonMm for darcy-weisbach), how velocityPreset 'custom' uses min/maxVelocity, and how the ranking score weights parameters. This enriches the raw schema definitions, providing context that helps the agent select and configure parameters correctly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'End-to-end pipe sizing wizard' that finds standard pipe sizes satisfying velocity and friction-loss constraints and ranks them. It explicitly names the resource (pipe sizes) and the actions (size, validate, rank). It also differentiates itself from siblings by stating it chains recommend_diameter and friction_loss in a single call, making it distinct.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use: 'Use this to make a single validated pipe selection without calling recommend_diameter and friction_loss separately.' This names the alternatives (recommend_diameter, friction_loss) and the condition (need for a combined validated selection). It also implies when not to use—if only a diameter recommendation is needed, one would use the simpler tools. This is strong guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pump_selectionA
Size a centrifugal pump for a required flow rate and total dynamic head. Computes hydraulic power, brake (shaft) power, motor nameplate power with safety factor, specific speed for pump-type classification (radial/mixed/axial flow), NPSH available from suction conditions, and suggests standard motor sizes and compatible speeds. Estimates pump efficiency automatically from the power level, or accept a user-specified value. Returns a complete pump sizing summary suitable for procurement or EPANET pump-curve entry. Use this after pipe_sizing_wizard to size the pump for a validated pipe network.
| Name | Required | Description | Default |
|---|---|---|---|
| speed | No | Motor speed in RPM. If omitted, the tool suggests compatible speeds. | |
| flowRate | Yes | Required flow rate at the duty point. | |
| flowUnits | Yes | Flow units matching EPANET's [OPTIONS] Units. | |
| efficiency | No | Assumed pump efficiency at BEP (0.3–0.95). Omit for automatic estimation based on power level. | |
| totalHeadM | Yes | Total dynamic head (TDH) in metres — the sum of static head, friction losses, and velocity head the pump must overcome. | |
| fluidDensity | No | Fluid density in kg/m³ (default 998 for water at 20 °C). Change for other fluids. | |
| safetyFactor | No | Motor sizing safety factor (default 1.15). Accounts for power curve shape and starting current. | |
| suctionLiftM | No | Suction lift in metres (positive = pump is above water level; negative = flood suction). Default 0 (at water level). Used for NPSH calculation. | |
| suctionFrictionM | No | Friction loss in the suction pipe in metres (default 0.5). Used for NPSH calculation. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It does describe computations and that it 'returns a summary', hinting at a read-only calculation. However, it never explicitly states that it does not modify network data or that it's non-destructive. It also doesn't mention any side effects or prerequisites beyond the network being validated, though it implies necessity. The lack of a clear 'this is a pure calculation' statement puts it below what a fully transparent description would provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences: the first states purpose and outputs, the second adds detail on efficiency estimation, and the third provides usage context. It's front-loaded with the core function and then adds context. No filler or redundancy. It's slightly longer than necessary but every sentence carries meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no output schema, the description lists the major output types (hydraulic power, brake power, motor nameplate power, specific speed, NPSH, motor sizes) which gives a good idea of the return content. It doesn't specify the exact format or field names, but that's a minor gap for a sizing summary. It also mentions compatibility with EPANET entry, covering practical use. It's fairly complete for a tool without output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already has a clear description (e.g., flowUnits lists EPANET units, efficiency has range and meaning). The tool description adds minimal new semantic value — it restates that efficiency can be omitted for automatic estimation (already in schema) and mentions outputs tied to specific inputs, but doesn't enrich parameter meaning beyond schema. Since coverage is high, baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Size a centrifugal pump' — a specific verb and resource. It enumerates outputs (power, specific speed, NPSH, motor sizes) and also states when it's used ('after pipe_sizing_wizard'), which distinguishes it from the pipe-related sibling tools. So an agent will immediately know what it does and how it fits with others.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this after pipe_sizing_wizard' and mentions 'validated pipe network' — a clear prerequisite and sequencing instruction. It doesn't list alternatives because no other pump tool exists, but it tells the agent the right place in the workflow. That's explicit and unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recommend_diameterA
Recommend standard pipe diameters for a given flow rate and target velocity range. Given a design flow (in any EPANET flow unit) and an acceptable velocity window, computes the ideal inner diameter using Q = v × πd²/4, then returns every standard pipe size (from HDPE, PVC, ductile iron, or steel in medium/Sch 40/Sch 80 variants) whose inner diameter produces a velocity within the range. Each recommendation includes the resulting velocity, an approximate Reynolds number (for turbulence check), and the standard it comes from. Use presets (distribution, transmission, service, suction) for typical velocity ranges, or specify custom min/max. Pipe diameters returned are the inner-diameter values to use with set_pipe_diameter.
| Name | Required | Description | Default |
|---|---|---|---|
| preset | No | Velocity-range preset: distribution (0.6–1.5 m/s, water mains), transmission (1.0–2.5 m/s, large mains), service (0.5–1.2 m/s, service connections), suction (0.8–1.5 m/s, pump suction). 'custom' (default) uses minVelocity/maxVelocity. | |
| flowRate | Yes | Design flow rate in the given flow units (e.g. 10 for 10 LPS, 150 for 150 GPM). | |
| material | No | Restrict recommendations to a single material. Omit to search all materials. | |
| flowUnits | Yes | Flow units matching EPANET's [OPTIONS] Units. SI: LPS (L/s), LPM (L/min), MLD (ML/d), CMH (m³/h), CMD (m³/d). US: GPM, CFS (ft³/s), MGD, IMGD, AFD. | |
| maxVelocity | No | Maximum acceptable velocity in m/s (default 2.0). Above this, erosion and water-hammer risk increases. | |
| minVelocity | No | Minimum acceptable velocity in m/s (default 0.5). Below this, sedimentation risk increases. For US flow units this is still m/s — the tool converts internally. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the computation method (using Q = v × πd²/4), the filtering logic (returns every standard size whose inner diameter produces a velocity within the range), and the output content (resulting velocity, Reynolds number, standard). It also clarifies that returned diameters are inner-diameter values to be used with set_pipe_diameter. It does not disclose potential edge cases (e.g., no matches) or the accuracy of the Reynolds approximation, but the core behavior is transparently described. Slight deduction for not mentioning limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, around five sentences, with the core purpose front-loaded. Each sentence adds value: it explains the input, the formula, the filtering, the output, and the presets, ending with a practical tip about using the returned diameters. There is no redundant or filler content. The structure is logical and easy to parse for an AI agent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, 3 enums) and lack of an output schema, the description is largely complete. It covers the computation method, the materials, the presets, and the output fields (velocity, Reynolds number, standard). It also connects to set_pipe_diameter. However, it does not describe the exact output format (e.g., whether it returns a list of objects) or potential error conditions, and it could mention how to handle cases where no diameter fits. These are minor gaps but enough to prevent a perfect score.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema: it explains the relationship between flow, velocity, and diameter, the material variants (HDPE, PVC, ductile iron, steel medium/Sch 40/Sch 80), and notes that for US flow units the velocity ranges are still in m/s (the tool converts internally). This clarifies how parameters like material and minVelocity/maxVelocity interact with the calculation. The added context justifies a score above the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the exact purpose: 'Recommend standard pipe diameters for a given flow rate and target velocity range.' It names the specific verb (recommend), resource (standard pipe diameters), and the input constraints (flow rate, velocity range). It clearly distinguishes itself from sibling tools like lookup_pipe_diameters (which lists sizes) and pipe_sizing_wizard (which likely performs a full design) by focusing on velocity-based recommendation. The description also specifies the calculation method (Q = v × πd²/4) and the output details, making its purpose unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use the tool: 'Given a design flow... and an acceptable velocity window' and offers presets for common scenarios ('distribution, transmission, service, suction'). It also tells the user to 'specify custom min/max' for custom ranges. However, it does not explicitly mention alternatives or when not to use this tool (e.g., for full pipe sizing, use pipe_sizing_wizard). Despite this, the guidance is sufficient for an agent to select the tool correctly based on the task.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_tankA
Remove a storage tank and every pipe attached to it (the inverse of add_tank). The edit is validated against the EPANET engine before it is applied — unique id, the edited model must re-parse with the tank and its connector pipes gone, node count must decrease by exactly one and link count by exactly the removed pipes, and a previously-solvable network must still solve. If controls or rules reference the tank, the engine rejects the edit (fail-closed) rather than leaving a dangling reference.
| Name | Required | Description | Default |
|---|---|---|---|
| tankId | Yes | Id of the tank to remove (use get_nodes to list tank ids). Removing a tank also removes every pipe attached to it. The edit is validated against the EPANET engine before it is applied — the edited model must re-parse with the tank and its pipes gone, node/link counts must decrease by exactly the removed assets, and a previously-solvable network must still solve. If controls or rules reference the tank, the engine rejects the edit (fail-closed) rather than leaving a dangling reference. | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It thoroughly explains the cascade removal of attached pipes, the EPANET engine validation steps (re-parse, node/link count checks, solvability requirement), and the fail-closed behavior on dangling references. This is exceptionally transparent about both expected outcomes and failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences but packs essential information: the core action and a dense but relevant explanation of validation and failure conditions. Every clause contributes to understanding the tool's behavior, and the primary purpose is front-loaded. It is concise without being under-specified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (cascade deletion, engine validation, fail-closed logic) and the absence of annotations or an output schema, the description covers all critical aspects: what it does, side effects, validation guarantees, and rejection conditions. Nothing an agent needs to safely invoke and interpret the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the tankId parameter description repeats the tool-level description, adding no new information. The networkId parameter is briefly described as returning from load_network, which is concise but sufficient. Since the schema already documents parameters adequately, the tool description adds marginal value beyond it, aligning with the baseline of 3 for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Remove'), a clear resource ('storage tank and every pipe attached to it'), and explicitly positions it as 'the inverse of add_tank', which distinguishes it from the sibling add_tank. This gives an agent immediate understanding of the tool's function and scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context by naming it as the inverse of add_tank, implying it should be used to undo an add_tank operation. It also describes the fail-closed behavior when controls/rules reference the tank, which is an important usage condition. However, it does not explicitly state alternative tools or scenarios where this tool should not be used, though no obvious direct alternative exists among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_candidateA
Evaluate a scenario: apply a batch of edits (pipe diameters, junction demands, pump speeds) to a COPY of a loaded network, validate the copy against the EPANET engine, run a simulation, and return the aggregate results (same shape as run_simulation). The base model and its stored results are NEVER modified, so candidates can be compared freely and previous runs stay valid.
| Name | Required | Description | Default |
|---|---|---|---|
| edits | Yes | The edits to evaluate. They are applied to a COPY of the model and simulated; the base model and its stored results are never modified. | |
| quality | No | Also run water-quality analysis. Requires the model to have quality configured ([OPTIONS] Quality). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explicitly discloses that edits are applied to a copy, that validation against the EPANET engine occurs, that a simulation runs, and crucially that the base model and stored results are NEVER modified. This full side-effect disclosure is exactly what an agent needs, given the absence of annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no waste. It front-loads the core action and process, then delivers the critical non-modification caveat in a separate sentence. Every word contributes to the agent's understanding, making it appropriately concise and well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 parameters (one a nested array) and no output schema, the description thoughtfully points to the return shape ('same shape as run_simulation'), describes the validation and simulation steps, and guarantees no side effects. This covers the essential information an agent needs to invoke it correctly, including what to expect back, without requiring an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, meaning every parameter (networkId, edits, quality) already has detailed descriptions. The tool description adds no parameter-specific meaning beyond restating that edits are applied to a copy (which is already in the schema's edits description). With high schema coverage, the baseline is 3, and no additional semantic value is provided.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Evaluate') and resource ('a scenario'), and enumerates the exact actions: applying batch edits to a copy, validating, running a simulation, and returning results. It differentiates itself from run_simulation by explicitly noting it operates on a COPY and returns the same shape, and it lists the edit kinds, making it clearly distinct from set_* and run_simulation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use: for evaluating candidate edits without altering the base, and it contrasts with run_simulation by noting the same return shape. The phrase 'candidates can be compared freely and previous runs stay valid' gives clear context for scenario testing. It doesn't explicitly say 'use this instead of run_simulation when you want to test changes', but the intent is readily inferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
run_simulationA
Run the EPANET hydraulic simulation for a loaded network and return aggregate results (min/max/average pressure and flow, pump energy, warnings). Results are stored so get_node_results / get_link_results can query them.
| Name | Required | Description | Default |
|---|---|---|---|
| quality | No | Also run water-quality analysis. Requires the model to have quality configured ([OPTIONS] Quality). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It discloses that the simulation stores results for later querying, which is a side effect, and describes the nature of the output (aggregate results and warnings). It stops short of explicitly stating whether the simulation mutates the network model (though 'simulation' implies it does not) or detailing error conditions, but it covers the primary behavioral traits an agent needs to call it correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero filler. The main purpose is front-loaded, the results are listed succinctly, and the storage side effect is stated at the end. Every clause earns its place, making this an exemplary concise definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description names the types of results (min/max/average pressure and flow, pump energy, warnings) and notes that results are stored for downstream querying. It clearly states the prerequisite of a loaded network. It does not explicitly mention what happens on failure (e.g., if the network is invalid) or how warnings are returned, but these are minor gaps given the level of detail provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both networkId and quality are already well-documented in the input schema. The description adds no additional meaning beyond what the schema provides—it mentions quality's requirement but that is already in the schema's description. Per the calibration baseline, when the schema covers all parameters, a score of 3 is appropriate unless the description offers supplementary context, which it does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Run', the resource 'EPANET hydraulic simulation', and the context 'for a loaded network'. It also enumerates what results are returned (min/max/average pressure and flow, pump energy, warnings) and distinguishes itself from query tools like get_node_results and get_link_results by noting that results are stored for those tools to query. This makes the purpose unmistakable and differentiates it from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the prerequisite 'for a loaded network', implying a load before use. It also tells the agent that results are stored so that get_node_results and get_link_results can query them, which effectively indicates the appropriate complementary tools to use afterward. However, it does not explicitly say when not to use this tool or mention any alternatives for running simulations (e.g., run_candidate or optimize_network), leaving some room for ambiguity in a larger workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sample_elevationsA
Sample real ground elevations from the bundled IFSAR 10 m DEM (Philippines) for WGS84 points, or for the nodes of a loaded network whose x/y coordinates are WGS84 (or UTM with a zone). Pure read — nothing is modified. Returns elevation in meters per point, bilinearly interpolated from the 2x2 pixel neighborhood; points outside the tile grid or over nodata come back with elevation null. The bundled DEM is the default elevation source for create_network (elevationSource), so this is the first call in the GIS workflow: sample, then build or set_node_elevation. Configure the data folder with EPANET_DEM_DIR (defaults to the repo's apps/app/public/dem/ifsar-10m).
| Name | Required | Description | Default |
|---|---|---|---|
| points | No | WGS84 points to sample. Provide exactly one of points or networkId. | |
| source | No | Elevation source; defaults to the bundled IFSAR 10 m DEM. | |
| nodeIds | No | When sampling a network, restrict to these node ids; omit for all nodes with coordinates. | |
| networkId | No | Sample the loaded network's node coordinates instead of explicit points. Provide exactly one of points or networkId. | |
| coordinates | No | How the network's stored x/y coordinates map to WGS84 (defaults to wgs84). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full burden and delivers: it explicitly says 'Pure read — nothing is modified' and discloses return behavior (elevation meters per point, null for outside/nodata, bilinear interpolation from 2x2 neighborhood). It also explains coordinate mapping (WGS84 or UTM with zone) and configuration via EPANET_DEM_DIR, covering key behavioral aspects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but each sentence carries weight: it covers purpose, behavior, workflow context, and configuration in a logical flow. It is not overly terse, but the content justifies the length and the core purpose is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 5 parameters, no output schema, and no annotations, the description covers essential details: return value per point, null handling, interpolation, coordinate system alternatives, and its place in the workflow. An agent has enough information to call it correctly and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds meaning by explaining the mutual exclusivity of points and networkId, the interpretation of the coordinates parameter (WGS84 vs UTM zone), and the default for the source parameter. It goes beyond the schema's bare field descriptions without repeating them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('sample'), the resource ('real ground elevations from the bundled IFSAR 10 m DEM'), and the subjects (WGS84 points or network nodes). It also distinguishes from siblings like set_node_elevation by noting it is the first step in the GIS workflow, making the tool's role unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use this tool ('the first call in the GIS workflow: sample, then build or set_node_elevation') and describes the two usage modes (explicit points vs network nodes), including coordinate handling. It also mentions the default elevation source for create_network, giving clear context for integration.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_networkA
Write the current state of a loaded network (including any set_* edits applied so far) to a file in the server's data directory: EPANET INP text (format 'inp', default) or the app's .net container (format 'net', which embeds the INP text — load_network reads both). The model is re-validated through the EPANET engine before writing, and existing files are not overwritten unless overwrite: true. Use this to persist edits: after saving, load_network can read the file back on a fresh session or server restart.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | Output format: 'inp' (EPANET text, the default) or 'net' (the app's .net container, which embeds the INP text). | |
| networkId | Yes | The network id returned by load_network. | |
| overwrite | No | Allow replacing an existing file. Default false: saving over an existing file is refused unless this is true. | |
| outputFile | No | File name to write, relative to the server's data directory (absolute paths must still resolve inside it). Defaults to '<networkId>.inp' (or '<networkId>.net' for format 'net'). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and covers key behaviors: re-validation through the EPANET engine before writing, refusal to overwrite existing files unless explicitly allowed, and the fact that it writes to the server's data directory. It does not mention failure modes (e.g., what happens if validation fails) or return values, but the stated traits are meaningful and useful.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences and each adds value: the first defines the action and formats, the second describes validation and overwrite safety, and the third gives the primary use case. It is front-loaded with the core action and readably compact, though slightly longer than strictly necessary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema and moderate parameter count, the description covers the essential aspects: what it does, what formats, how safety is handled, and when to use it. It does not specify the return value (e.g., success message or file path) or error conditions, but for most agents the described behavior is sufficient to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already has 100% coverage with descriptive comments for each parameter, so the description adds limited new meaning. It reinforces the format semantics (net embeds INP) and default file naming, but these are also present in the schema. The baseline of 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('write') and resource ('current state of a loaded network'), and clearly distinguishes it from the sibling load_network by emphasizing persistence. The two formats (inp and net) are explicitly named, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this to persist edits' and explains that load_network can read the file back after a restart, which tells the agent exactly when to invoke it. It also cautions that existing files are not overwritten unless overwrite: true, providing a clear usage constraint with no alternative tool needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_demand_patternA
Add or replace a demand pattern ([PATTERNS]) and attach it to one or more junctions, so base demands vary over the simulation (e.g. an hourly diurnal curve with morning and evening peaks). The edit is validated against the EPANET engine before it is applied: the pattern id must be valid, each multiplier must be between 0 and 10 (and not all zero), every listed junction must exist and be a junction, and the edited model must re-parse with the pattern present at exactly the requested length and values, attached to each junction's demand, with node/link counts unchanged. A previously-solvable model must still solve. An existing pattern with the same id is replaced in place; a junction already using a pattern gets this one instead. Previous simulation results are invalidated — re-run run_simulation afterwards (get_node_results with timesteps returns the hourly variation).
| Name | Required | Description | Default |
|---|---|---|---|
| networkId | Yes | The network id returned by load_network. | |
| patternId | Yes | New or existing demand pattern id (1-31 characters, no spaces and none of: + - . ;). An existing pattern with this id is replaced in place. | |
| junctionIds | Yes | Junctions whose demand should follow this pattern (use get_nodes to list ids). The pattern column is set on each junction's demand (the [JUNCTIONS] demand column, or its [DEMANDS] entries when the model defines demands there). | |
| multipliers | Yes | Multipliers applied to the base demand, one per pattern period (24 values for an hourly diurnal pattern). Each must be between 0 and 10; an all-zero pattern is rejected. The average multiplier scales the daily total — use values averaging 1.0 to keep the daily demand unchanged. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden — and it delivers extensively: EPANET validation rules (id validity, multiplier bounds 0–10, non-all-zero, junction existence/type), model re-parse guarantee with unchanged node/link counts, solvability preservation, precise replacement semantics (in-place overwrite, junctions re-assigned), and invalidation of prior simulation results. This is exemplary disclosure of behavior beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long (~150 words in a dense block) but every sentence earns its place given the tool's complexity — validation rules, replacement semantics, and post-conditions are all load-bearing, not filler. The essential purpose is front-loaded before the validation details, though a slight structural tightening would help.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter tool with no output schema and no annotations, the description is remarkably complete: it covers validation/failure modes, replacement behavior, effect on existing patterns and junctions, invalidation of results, and the correct follow-up steps. An agent has everything needed to invoke it correctly and understand consequences.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds genuine value on top: it explains that 24 multiplier values correspond to an hourly diurnal pattern, that the average multiplier scales the daily total, and suggests averaging 1.0 to keep daily demand unchanged. It also clarifies the junctionIds semantics (the [JUNCTIONS] demand column or [DEMANDS] entries) beyond the schema's summary.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource+target ('Add or replace a demand pattern and attach it to one or more junctions') and the reason (make base demands vary over simulation, with the diurnal-curve example). This distinguishes it cleanly from siblings like set_junction_demand (static per-junction demand) and assign_demands, so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context of when to use ('so base demands vary over the simulation') and routes forward with explicit tool names: use get_nodes to list junction ids, re-run run_simulation afterwards, and get_node_results with timesteps to see hourly variation. It does not, however, name the static-demand alternative (set_junction_demand) as a when-not-to-use exclusion, falling just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_junction_demandA
Change the base demand of a junction in a loaded network. The edit is validated against the EPANET engine before it is applied: the node must exist and be a junction, the value must be within realistic bounds, and the edited model must re-parse with the requested demand. Junctions whose demand is overridden by the [DEMANDS] section are rejected. Previous simulation results for the network are invalidated (they describe the old model) — re-run run_simulation afterwards.
| Name | Required | Description | Default |
|---|---|---|---|
| demand | Yes | New base demand in the model's flow units (e.g. LPS or GPM). A negative value represents flow into the network. Range: -1,000,000 to 1,000,000. | |
| nodeId | Yes | Id of the junction to change (use get_nodes to list junction ids). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Given no annotations are provided, the description carries full responsibility for behavioral disclosure. It clearly states that the edit is validated against the EPANET engine, what conditions cause rejection, that previous simulation results are invalidated, and that re-running run_simulation is required. This is comprehensive and goes beyond what typical descriptions offer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose in the first sentence, followed by a second sentence that packs validation details, rejection conditions, and the simulation invalidation notice. Every phrase earns its place; there is no fluff or redundancy. The length is appropriate for the complexity of the operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description covers all essential aspects an agent needs: the operation's validity checks, rejection scenarios, and the consequence that simulation results are stale. It even mentions the flow-unit context (inherited from schema) and practical next steps. Nothing critical is missing for correctly invoking and understanding the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already fully documents all three parameters (demand, nodeId, networkId), including ranges and references to other tools. The description adds no extra semantic information beyond what the schema provides. Baseline of 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Change'), resource ('base demand of a junction'), and context ('in a loaded network'). This clearly distinguishes it from siblings like set_demand_pattern (which sets demand patterns) and set_node_elevation (which changes elevation). The purpose is unambiguous and the tool's role is obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly name alternative tools, but it explains key usage conditions: the node must be a junction, junctions overridden by [DEMANDS] are rejected, and the simulation must be re-run afterward. This gives actionable guidance on when the tool can be used and its impacts. It doesn't explicitly say 'use set_demand_pattern for patterns' but the sibling context fills that gap. Slight deduction for lacking an explicit alternative comparison.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_node_elevationA
Change the elevation of a junction, reservoir (its fixed head), or tank (its bottom elevation) in a loaded network. The edit is validated against the EPANET engine before it is applied: the node must exist and be a junction/reservoir/tank, the value must be within realistic bounds for the model's units, and the edited model must re-parse with the requested elevation. Previous simulation results for the network are invalidated (they describe the old model) — re-run run_simulation afterwards.
| Name | Required | Description | Default |
|---|---|---|---|
| nodeId | Yes | Id of the junction, reservoir, or tank to change (use get_nodes to list node ids and their current elevations). For a reservoir this sets its fixed head. | |
| elevation | Yes | New elevation in the model's native units (m for SI models, ft for US-unit models). Realistic bounds are enforced: -500 to 9000 m or -2000 to 30000 ft (negative = below sea level). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It clearly discloses validation behavior (against EPANET, node type, unit bounds, re-parse) and the side effect that previous simulation results are invalidated. It stops short of describing the response/return format on success or failure, but the validation details provide a realistic picture of expected behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences and front-loaded with the purpose. The second sentence is dense but informative, covering validation requirements. It is not overly verbose for the complexity of the operation, though it could be tightened slightly without losing value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with three parameters and no output schema, the description covers the essential context: what it does, what constraints are validated, and the side effect on simulation results. It does not explicitly state what the tool returns or error behavior, but given the validation description, an agent can infer success/failure semantics. Overall quite complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents each parameter's meaning including the reservoir/tank distinction and elevation units/bounds. The tool description adds no extra parameter-level detail beyond what the schema provides, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Change') and a precise resource ('elevation of a junction, reservoir, or tank'), and clarifies the special meaning for reservoirs (fixed head) and tanks (bottom elevation). This distinguishes it clearly from sibling set_* tools like set_pipe_diameter or set_junction_demand.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear context on when to use the tool (changing node elevation) and the prerequisite of a loaded network, plus the follow-up action (re-run run_simulation). However, it does not explicitly name alternatives or state when not to use this tool, though the sibling set of tools implies it is for elevation only.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_pipe_diameterA
Change the diameter of a pipe in a loaded network. The edit is validated against the EPANET engine before it is applied: the pipe must exist and be a pipe, the value must be within realistic bounds for the model's units, and the edited model must re-parse with the requested diameter. Previous simulation results for the network are invalidated (they describe the old model) — re-run run_simulation afterwards.
| Name | Required | Description | Default |
|---|---|---|---|
| linkId | Yes | Id of the pipe to resize (use get_links to list pipe ids). | |
| diameter | Yes | New diameter in the model's native units (mm for SI models, inches for US-unit models). Realistic bounds are enforced: 1–10000 mm or 0.01–400 inches. | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It covers validation (pipe exists, is a pipe, value within realistic bounds), the requirement that the edited model re-parse, and the side effect of invalidating previous simulation results. It stops short of describing the exact error handling or return value, but the key behavioral traits are transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense sentence that packs the core action, validation rules, and side effect clearly. It front-loads the primary purpose and uses no filler. Every clause contributes essential information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with no output schema, the description covers the essential aspects: what it does, the validation constraints, and the invalidation of simulation results with a follow-up suggestion. It could mention the exact failure behavior or response format, but given the tool's simplicity and the schema coverage, this is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage with descriptions for all three parameters, including units and realistic bounds for diameter. The description adds contextual value (e.g., that the pipe must exist and be a pipe, and that validation occurs), but it does not add new parameter-level semantics beyond the schema. Since schema coverage is high, a baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Change the diameter of a pipe in a loaded network.' It clearly distinguishes this from sibling tools (e.g., set_junction_demand, set_pump_speed) by targeting pipe diameter specifically, and preemptively clarifies that the target must be a pipe, not just any link.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for when to use this tool: after loading a network, and it explicitly states that previous simulation results are invalidated and that run_simulation should be re-run afterwards. This gives the agent a concrete follow-up action. It does not explicitly mention alternatives, but the sibling tools are distinct enough that not naming them is acceptable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_pump_speedA
Change the relative speed setting of a pump in a loaded network. The edit is validated against the EPANET engine before it is applied: the link must exist and be a pump, the value must be within realistic bounds, and the edited model must re-parse with the requested speed. If the pump has no SPEED property yet, one is appended to its [PUMPS] line. Previous simulation results for the network are invalidated (they describe the old model) — re-run run_simulation afterwards.
| Name | Required | Description | Default |
|---|---|---|---|
| speed | Yes | New relative speed setting (dimensionless; 1.0 = nominal design speed). Range: 0.1 to 4.0. | |
| linkId | Yes | Id of the pump to change (use get_links to list pump ids and their current speed). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure. It excels: it states validation against EPANET (link must exist and be a pump, bounds, re-parsing), details the side effect of appending SPEED if missing, and explicitly warns that previous simulation results are invalidated and instructs re-running run_simulation. This is exemplary transparency for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the purpose, then covers validation and side effects in a logical order. It is informative without being verbose. Slightly long but every clause adds necessary context, making it concise relative to the complexity covered.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the action, validation, side effects, and a follow-up action (re-run simulation). It leaves out the return value or error handling details, but given there is no output schema, an agent might expect some indication of what the tool returns (e.g., success or updated link info). Still, for a mutation tool, the key context (invalidation and next step) is provided.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3 without additional description. The description adds minimal parameter-level insight beyond the schema; it mentions the relative speed setting and validation bounds but does not elaborate on formats or units beyond what schema already states. The schema's own parameter descriptions are thorough, so the description adds little extra value here.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Change the relative speed setting of a pump') with a specific resource ('pump in a loaded network') and scope. It distinguishes itself from sibling tools like set_pipe_diameter and set_valve_setting by focusing on pump speed, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use (when you need to adjust a pump's speed) and provides a prerequisite (network must be loaded). It does not explicitly name alternatives or exclusion conditions, but the association with pump-specific behavior is clear enough. The schema hint to use get_links for pump IDs is in the schema, not the main description, so the main description lacks explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_valve_settingA
Change the setting of a valve (PRV/PSV/PBV pressure, FCV flow, TCV loss coefficient) in a loaded network. The edit is validated against the EPANET engine before it is applied: the link must exist and be a valve, the value must be within realistic bounds for the valve type and the model's units, and the edited model must re-parse with the requested setting. GPV valves are rejected (their setting is a headloss curve id). Previous simulation results for the network are invalidated (they describe the old model) — re-run run_simulation afterwards.
| Name | Required | Description | Default |
|---|---|---|---|
| linkId | Yes | Id of the valve to change (use get_links to list valve ids and their current settings). | |
| setting | Yes | New valve setting in the valve type's units: PRV/PSV/PBV a pressure (m or psi), FCV a flow (e.g. LPS), TCV a dimensionless loss coefficient. Never negative. GPV valves are not supported (their setting is a headloss curve id). | |
| networkId | Yes | The network id returned by load_network. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full behavioral burden. It discloses that the edit is validated against EPANET (link must exist and be a valve, value within realistic bounds, model re-parse), that GPV valves are rejected, and that prior simulation results are invalidated with a directive to re-run run_simulation. This is comprehensive and transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the purpose with valve types, the second details validation and side effects. It is front-loaded with the core action, and every clause adds value without redundancy. Highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool, the description covers prerequisites (loaded network), validation constraints, rejection case (GPV), and a required follow-up (re-run simulation). Combined with the rich parameter schema, there is no missing critical information an agent needs to invoke and use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema descriptions for all three parameters are already thorough (e.g., setting explains units per valve type and the GPV exclusion; linkId references get_links; networkId references load_network). With 100% schema coverage, the description adds little parameter-specific meaning beyond reinforcing the validation and invalidation behavior. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'Change the setting of a valve' and explicitly enumerates valve types and the corresponding setting meaning (PRV/PSV/PBV pressure, FCV flow, TCV loss coefficient). This distinguishes it from siblings like set_pipe_diameter or set_pump_speed, and the initial sentence immediately conveys scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context: it operates on a loaded network, validates against EPANET, and notes that previous simulation results are invalidated, implying when to use it. It also explicitly excludes GPV valves, giving a 'when not to use' condition. However, it does not explicitly contrast with add_valve (adding a valve vs. editing an existing one) or mention alternative tools for other edit types.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
33 tool updates
v0.1.0- First observed
add_tank - First observed
add_valve - First observed
assign_demands - First observed
calculate_minor_loss - First observed
create_network - First observed
fetch_road_network - First observed
friction_loss - First observed
generate_network_from_bbox - First observed
get_coordinates - First observed
get_link_results - First observed
get_links - First observed
get_network_summary - First observed
get_node_results - First observed
get_nodes - First observed
list_fitting_kfactors - First observed
list_networks - First observed
load_network - First observed
lookup_pipe_diameters - First observed
optimize_network - First observed
pipe_sizing_wizard - First observed
pump_selection - First observed
recommend_diameter - First observed
remove_tank - First observed
run_candidate - First observed
run_simulation - First observed
sample_elevations - First observed
save_network - First observed
set_demand_pattern - First observed
set_junction_demand - First observed
set_node_elevation - First observed
set_pipe_diameter - First observed
set_pump_speed - First observed
set_valve_setting
TDQS
Scored across 33 tools
Each tool has a clearly distinct purpose, even within the design/sizing cluster (e.g., recommend_diameter vs. pipe_sizing_wizard, friction_loss vs. calculate_minor_loss). The set_* tools target different properties, and generate_network_from_bbox vs. fetch_road_network are separate phases. No two tools appear to do the same thing.
The majority of tools follow the verb_noun snake_case pattern (load_network, run_simulation, set_pipe_diameter). A few tools break this pattern with noun-first names (friction_loss, pipe_sizing_wizard, pump_selection), but the overall style is consistent and readable.
33 tools is on the high side, but the server covers a comprehensive range: network lifecycle, simulation, editing, optimization, GIS integration, and hydraulic design. Each tool is justified by the domain's breadth, so the count feels appropriate rather than excessive.
The tool surface is remarkably complete: create/load/save/list networks, run simulations, inspect and edit all key elements, add/remove tanks/valves, optimize, and a full set of design tools (diameter, friction, pump sizing, minor losses, GIS sampling). No obvious dead ends; only a delete_network is missing, which is a minor gap.
Maintenance
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Run AI customer support from your terminal: conversations, knowledge base, and chat widget.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceA water treatment process simulation engine that exposes WaterTAP capabilities through MCP and CLI adapters, enabling AI agents to build, solve, and optimize flowsheets using natural language.1MIT

idfkit-mcpofficial
AlicenseAqualityBmaintenanceEnables AI assistants to create, edit, and simulate EnergyPlus building energy models via natural language. Supports schema exploration, model editing, simulation execution, and documentation search.393MIT- AlicenseNot gradedqualityBmaintenanceEnables AI clients to interact with EDA projects via natural language by wrapping EDI's gRPC interface, CLI tools, and ANSYS HFSS as MCP tools supporting SSE and stdio transports.2MIT
- AlicenseBqualityDmaintenanceEnables LLMs to load, simulate, modify, and generate what-if scenarios for EPANET water-distribution network models through natural language, leveraging the ePyT Python Toolkit.443MIT