Skip to main content
Glama
hjlrosales

EPANET MCP Server

by hjlrosales

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/Oload_network, save_network, list_networks

  • Inspectionget_network_summary, get_nodes, get_links, get_coordinates

  • Simulationrun_simulation, get_node_results, get_link_results

  • Mutation (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_valve

  • Model buildingcreate_network, assign_demands, sample_elevations, fetch_road_network, generate_network_from_bbox

  • Design helperslookup_pipe_diameters, recommend_diameter, friction_loss, calculate_minor_loss, pipe_sizing_wizard, pump_selection, list_fitting_kfactors

  • Optimizationoptimize_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 install

Run 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 start

The 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

EPANET_DATA_DIR

cwd

Folder load_network/save_network may read/write

EPANET_DEM_DIR

unset

Folder the DEM/elevation tools read from

EPANET_AUTH_PUBLIC_KEY

unset

RS256 public key for optional token-mode auth

EPANET_AUTH_VALIDATE_URL

unset

Loopback URL for token validation

EPANET_AUTH_ISSUER

unset

Expected JWT iss

EPANET_AUTH_AUDIENCE

unset

Expected JWT aud

EPANET_AUTH_TOKEN

unset

Static bearer token (CI use)

EPANET_AUTH_TOKEN_FILE

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 test

Unit 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:linux

Produces a self-contained installer (vendored Node runtime, no system Node required) under dist/.

License

MIT — see LICENSE.

Available Tools

33 tools
add_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pipeIdYesNew unique pipe id connecting the junction to the tank (1-31 characters, no spaces and none of: + - . ;).
tankIdYesNew unique tank id (1-31 characters, no spaces and none of: + - . ;).
diameterYesTank diameter (model's length units).
maxLevelYesMaximum water level above the tank bottom (model's units); must exceed minLevel.
minLevelYesMinimum water level above the tank bottom (model's units).
elevationYesTank bottom elevation in the model's units (m for SI, ft for US).
minVolumeNoMinimum volume; defaults to 0.
networkIdYesThe network id returned by load_network.
junctionIdNoId 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.
pipeLengthYesLength of the connector pipe (model's length units).
reservoirIdNoId 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.
initialLevelYesInitial water level above the tank bottom (model's units).
pipeDiameterYesDiameter of the connector pipe (mm for SI models, inches for US-unit models).
pipeRoughnessNoRoughness of the connector pipe (default 100 for H-W/C-M models, 0.25 for D-W models).

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
linkIdYesId 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.
settingYesPRV pressure setting in the model's pressure units (m for SI models, psi for US-unit models). Range: 0 to 10000.
valveIdYesNew unique valve id (1-31 characters, no spaces and none of: + - . ;).
diameterNoDiameter of the new valve (mm for SI models, inches for US-unit models); defaults to the split pipe's diameter.
minorLossNoMinor-loss coefficient of the new valve; defaults to 0.
networkIdYesThe network id returned by load_network.
splitPositionNoWhere 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).
splitJunctionIdNoNew unique junction id at the split point; defaults to '<valveId>J'.

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
networkIdYesThe network id returned by load_network.
perCapitaYesPer-capita consumption rate. Required — demands are never guessed from a default rate.
populationYesPopulation table: one entry per junction. Each nodeId must be unique and must be an existing junction.

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
fittingsYesList of fittings. Each entry has a type (key from list_fitting_kfactors), optional quantity, and optional customK override.
flowRateYesFlow rate in the given units.
flowUnitsYesFlow units matching EPANET's [OPTIONS] Units.
diameterMmYesPipe inner diameter in mm (at the fitting location).

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
pipesYesPipes: id, two existing node ids, length, diameter (mm for SI, inches for US), optional roughness/minor-loss/status.
tanksNoOptional tanks: id, bottom elevation, water levels above it, diameter, optional min volume and x/y.
titleNoModel title; defaults to 'Generated network'.
unitsNoFlow units for the model; defaults to LPS. US units (GPM/CFS/MGD/IMGD/AFD) use feet/inches and psi; SI units use metres/mm.
headlossNoHeadloss 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).
junctionsYesJunctions: id, ground elevation (m or ft — optional when sampled from IFSAR via x/y), optional base demand (flow units) and projected x/y coordinates.
reservoirsYesReservoirs (e.g. a river intake): id, fixed head (m or ft), optional x/y coordinates.
elevationSourceNoGround-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

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
maxLatYesNorth latitude (WGS84 degrees) of the bounding box.
maxLonYesEast longitude (WGS84 degrees) of the bounding box.
minLatYesSouth latitude (WGS84 degrees) of the bounding box.
minLonYesWest longitude (WGS84 degrees) of the bounding box.
offsetNoZero-based page offset; combine with maxResults to page through large areas (roads are ordered by OSM way id).
roadTypesNoHighway 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.
maxResultsNoPage size (default 500, hard cap 5000); combine with offset to page through large areas.
waterwayTypesNoWaterway 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

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
methodYesFriction-loss method: 'hazen-williams' (empirical, water-only, uses C-factor) or 'darcy-weisbach' (physics-based, uses pipe roughness height ε).
presetNoRoughness preset: sets roughnessC or roughnessEpsilonMm automatically. 'custom' (default) requires explicit roughness values.
lengthMYesPipe length in metres for the total head-loss calculation.
flowRateYesDesign flow rate in the given flow units.
flowUnitsYesFlow units matching EPANET's [OPTIONS] Units.
diameterMmYesPipe inner diameter in mm (the value from lookup_pipe_diameters or set_pipe_diameter).
roughnessCNoHazen-Williams C-factor (required for hazen-williams method). Typical: 150 (PVC/HDPE), 140 (new DI/steel), 100 (aged steel).
roughnessEpsilonMmNoDarcy-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

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
bboxNoBounding box (WGS84) to fetch OSM highway+waterway ways from Overpass. Provide exactly one of bbox / osmExtract / osmFile.
riverYesThe 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).
titleNoModel title; defaults to 'Auto-layout network'.
osmFileNoA saved OSM extract JSON file (with an 'elements' array), relative to the server data directory. Provide exactly one of bbox / osmExtract / osmFile.
spacingMNoTarget junction spacing along roads (m); default 150. Lower = more junctions, higher = a coarser skeleton.
osmExtractNoInline OSM elements (Overpass 'out body' JSON) to lay out instead of fetching live. Provide exactly one of bbox / osmExtract / osmFile.
minDeadEndMNoDead-end chains shorter than this (m) are pruned; default 30. 0 keeps every dead-end branch.
reservoirHeadYesReservoir head in the model's length units (e.g. meters) — the intake/pump discharge head. Required; never guessed.

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNoZero-based index of the first node to return; combine with the 250-item cap to page through large networks.
nodeIdsNoNode ids to inspect. Omit to list all nodes (capped at 250 per page); nodes without stored coordinates are reported in missingIds, never invented.
networkIdYesThe network id returned by load_network.
coordinatesNoHow 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

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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_network_summaryB

Return a summary of a loaded network: counts, simulation timing, units, quality type, and node/link id previews.

ParametersJSON Schema
NameRequiredDescriptionDefault
networkIdYesThe network id returned by load_network.

TDQS

B3.1/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
runIdNoThe run id returned by run_simulation. Omit to use the latest run.
offsetNoZero-based index of the first node to return; combine with the cap to page through large networks.
nodeIdsNoNode ids to query. Omit for all nodes (capped at 250 per page).
networkIdYesThe network id returned by load_network.
timestepsNoZero-based reporting timestep indices. Omit to get the last timestep plus min/max/mean over time.
propertiesNoResult properties to return. Defaults to pressure.

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNoZero-based index of the first node to return; combine with the 250-item cap to page through large networks.
nodeIdsNoNode ids to inspect. Omit to list all nodes (capped at 250 per page).
networkIdYesThe network id returned by load_network.

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
categoryNoFilter by fitting category: valve, elbow, tee, other, or all (default).

TDQS

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
inputFileYesINP file name, relative to the server data directory (absolute paths must still resolve inside it).

TDQS

A3.5/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
unitsNoDisplay units for inner diameter: 'mm' (default), 'inches', or 'both' (side-by-side). Nominal sizes always show their native designation.
materialYesPipe 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.
maxNominalNoMaximum nominal diameter to include. Omit for all sizes up to the largest.
minNominalNoMinimum nominal diameter (DN for metric materials, inches for steel) to include. Omit for all sizes.

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
qualityNoAlso run water-quality analysis. Requires the model to have quality configured ([OPTIONS] Quality).
networkIdYesThe network id returned by load_network.
objectiveYes
variablesYesThe assets and candidate values to search over. Every combination is evaluated on a copy of the model; the base model is never modified.
maxEvaluationsNoMaximum number of candidate combinations to evaluate (default 20). The full search space (product of all values lists) must fit within this limit.

TDQS

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
topNNoNumber of top-ranked candidates to return (default 5, max 20).
methodNoFriction-loss method (default: hazen-williams).
lengthMYesPipe length in metres for head-loss calculation.
flowRateYesDesign flow rate in the given flow units.
materialNoRestrict to a single material. Omit to search all.
flowUnitsYesFlow units matching EPANET's [OPTIONS] Units.
roughnessCNoHazen-Williams C-factor. Required when method is hazen-williams and no preset.
maxVelocityNoMaximum velocity in m/s (default 2.0).
minVelocityNoMinimum velocity in m/s (default 0.5).
maxHeadLossMNoMaximum allowed total head loss in metres. Candidates exceeding this are excluded.
velocityPresetNoVelocity-range preset. 'custom' (default) uses min/maxVelocity.
roughnessPresetNoRoughness preset (sets roughnessC or roughnessEpsilonMm automatically).
maxPressureDropBarNoMaximum allowed pressure drop in bar. Candidates exceeding this are excluded.
roughnessEpsilonMmNoDarcy-Weisbach roughness ε in mm. Required when method is darcy-weisbach and no preset.

TDQS

A5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
speedNoMotor speed in RPM. If omitted, the tool suggests compatible speeds.
flowRateYesRequired flow rate at the duty point.
flowUnitsYesFlow units matching EPANET's [OPTIONS] Units.
efficiencyNoAssumed pump efficiency at BEP (0.3–0.95). Omit for automatic estimation based on power level.
totalHeadMYesTotal dynamic head (TDH) in metres — the sum of static head, friction losses, and velocity head the pump must overcome.
fluidDensityNoFluid density in kg/m³ (default 998 for water at 20 °C). Change for other fluids.
safetyFactorNoMotor sizing safety factor (default 1.15). Accounts for power curve shape and starting current.
suctionLiftMNoSuction lift in metres (positive = pump is above water level; negative = flood suction). Default 0 (at water level). Used for NPSH calculation.
suctionFrictionMNoFriction loss in the suction pipe in metres (default 0.5). Used for NPSH calculation.

TDQS

A4.1/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
presetNoVelocity-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.
flowRateYesDesign flow rate in the given flow units (e.g. 10 for 10 LPS, 150 for 150 GPM).
materialNoRestrict recommendations to a single material. Omit to search all materials.
flowUnitsYesFlow 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.
maxVelocityNoMaximum acceptable velocity in m/s (default 2.0). Above this, erosion and water-hammer risk increases.
minVelocityNoMinimum 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

A4.4/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tankIdYesId 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.
networkIdYesThe network id returned by load_network.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
editsYesThe edits to evaluate. They are applied to a COPY of the model and simulated; the base model and its stored results are never modified.
qualityNoAlso run water-quality analysis. Requires the model to have quality configured ([OPTIONS] Quality).
networkIdYesThe network id returned by load_network.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
qualityNoAlso run water-quality analysis. Requires the model to have quality configured ([OPTIONS] Quality).
networkIdYesThe network id returned by load_network.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
pointsNoWGS84 points to sample. Provide exactly one of points or networkId.
sourceNoElevation source; defaults to the bundled IFSAR 10 m DEM.
nodeIdsNoWhen sampling a network, restrict to these node ids; omit for all nodes with coordinates.
networkIdNoSample the loaded network's node coordinates instead of explicit points. Provide exactly one of points or networkId.
coordinatesNoHow the network's stored x/y coordinates map to WGS84 (defaults to wgs84).

TDQS

A4.8/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
formatNoOutput format: 'inp' (EPANET text, the default) or 'net' (the app's .net container, which embeds the INP text).
networkIdYesThe network id returned by load_network.
overwriteNoAllow replacing an existing file. Default false: saving over an existing file is refused unless this is true.
outputFileNoFile 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

A4.3/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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).

ParametersJSON Schema
NameRequiredDescriptionDefault
networkIdYesThe network id returned by load_network.
patternIdYesNew or existing demand pattern id (1-31 characters, no spaces and none of: + - . ;). An existing pattern with this id is replaced in place.
junctionIdsYesJunctions 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).
multipliersYesMultipliers 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

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
demandYesNew 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.
nodeIdYesId of the junction to change (use get_nodes to list junction ids).
networkIdYesThe network id returned by load_network.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
nodeIdYesId 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.
elevationYesNew 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).
networkIdYesThe network id returned by load_network.

TDQS

A4.1/5.0
Behavior4/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
linkIdYesId of the pipe to resize (use get_links to list pipe ids).
diameterYesNew 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.
networkIdYesThe network id returned by load_network.

TDQS

A4.2/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
speedYesNew relative speed setting (dimensionless; 1.0 = nominal design speed). Range: 0.1 to 4.0.
linkIdYesId of the pump to change (use get_links to list pump ids and their current speed).
networkIdYesThe network id returned by load_network.

TDQS

A4.3/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
linkIdYesId of the valve to change (use get_links to list valve ids and their current settings).
settingYesNew 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).
networkIdYesThe network id returned by load_network.

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 33 tool updatesv0.1.0
    • First observedadd_tank
    • First observedadd_valve
    • First observedassign_demands
    • First observedcalculate_minor_loss
    • First observedcreate_network
    • First observedfetch_road_network
    • First observedfriction_loss
    • First observedgenerate_network_from_bbox
    • First observedget_coordinates
    • First observedget_link_results
    • First observedget_links
    • First observedget_network_summary
    • First observedget_node_results
    • First observedget_nodes
    • First observedlist_fitting_kfactors
    • First observedlist_networks
    • First observedload_network
    • First observedlookup_pipe_diameters
    • First observedoptimize_network
    • First observedpipe_sizing_wizard
    • First observedpump_selection
    • First observedrecommend_diameter
    • First observedremove_tank
    • First observedrun_candidate
    • First observedrun_simulation
    • First observedsample_elevations
    • First observedsave_network
    • First observedset_demand_pattern
    • First observedset_junction_demand
    • First observedset_node_elevation
    • First observedset_pipe_diameter
    • First observedset_pump_speed
    • First observedset_valve_setting

TDQS

A4.1/5.0

Scored across 33 tools

Disambiguation5/5

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.

Naming Consistency4/5

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.

Tool Count4/5

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.

Completeness5/5

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

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables AI assistants to create, edit, and simulate EnergyPlus building energy models via natural language. Supports schema exploration, model editing, simulation execution, and documentation search.
    39
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables 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.
    2
    MIT